diff --git a/0001-cmd-comile-Add-sw64-port.patch b/0001-cmd-comile-Add-sw64-port.patch new file mode 100644 index 0000000000000000000000000000000000000000..c0a4995d5d4777e346146e8c611d5c2360358a76 --- /dev/null +++ b/0001-cmd-comile-Add-sw64-port.patch @@ -0,0 +1,15278 @@ +diff --git a/src/cmd/compile/internal/base/flag.go b/src/cmd/compile/internal/base/flag.go +index 31ea8622b9..ac008b5fb1 100644 +--- a/src/cmd/compile/internal/base/flag.go ++++ b/src/cmd/compile/internal/base/flag.go +@@ -280,7 +280,7 @@ func ParseFlags() { + if Flag.Race && !platform.RaceDetectorSupported(buildcfg.GOOS, buildcfg.GOARCH) { + log.Fatalf("%s/%s does not support -race", buildcfg.GOOS, buildcfg.GOARCH) + } +- if (*Flag.Shared || *Flag.Dynlink || *Flag.LinkShared) && !Ctxt.Arch.InFamily(sys.AMD64, sys.ARM, sys.ARM64, sys.I386, sys.Loong64, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X) { ++ if (*Flag.Shared || *Flag.Dynlink || *Flag.LinkShared) && !Ctxt.Arch.InFamily(sys.AMD64, sys.ARM, sys.ARM64, sys.I386, sys.Loong64, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X, sys.SW64) { + log.Fatalf("%s/%s does not support -shared", buildcfg.GOOS, buildcfg.GOARCH) + } + parseSpectre(Flag.Spectre) // left as string for RecordFlags +diff --git a/src/cmd/compile/internal/ssa/_gen/SW64.rules b/src/cmd/compile/internal/ssa/_gen/SW64.rules +new file mode 100644 +index 0000000000..7ecf82d2ac +--- /dev/null ++++ b/src/cmd/compile/internal/ssa/_gen/SW64.rules +@@ -0,0 +1,816 @@ ++// 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. ++ ++// Lowering arithmetic ++(Add(Ptr|64|32|16|8) ...) => (ADDV ...) ++(Add(32|64)F ...) => (FADD(S|D) ...) ++ ++(Sub(Ptr|64|32|16|8) ...) => (SUBV ...) ++(Sub(32|64)F ...) => (FSUB(S|D) ...) ++ ++// (x + y) / 2 with x>=y => (x - y) / 2 + y ++(Avg64u x y) => (ADDV (SRLconst (SUBV x y) [1]) y) ++ ++(Mul(64|32|16|8) ...) => (MUL(L|W|W|W) ...) ++(Mul(32|64)F ...) => (FMUL(S|D) ...) ++ ++(Hmul64 x y) => ( SUBV (SUBV (UMULH x y) (MULL (SRLconst x [63]) y)) (MULL (SRLconst y [63]) x) ) ++(Hmul64u ...) => (UMULH ...) ++(Hmul32 x y) => (SRAconst (MULL (SignExt32to64 x) (SignExt32to64 y)) [32]) ++(Hmul32u x y) => (SRLconst (MULL (ZeroExt32to64 x) (ZeroExt32to64 y)) [32]) ++ ++ ++(Convert ...) => (MOVVconvert ...) ++(GetClosurePtr ...) => (LoweredGetClosurePtr ...) ++(GetCallerSP ...) => (LoweredGetCallerSP ...) ++(GetCallerPC ...) => (LoweredGetCallerPC ...) ++// Write barrier. ++(WB ...) => (LoweredWB ...) ++ ++(Signmask x) => (SRAconst x [63]) ++(Div64 x y) && buildcfg.GOSW64 <=3 => ++ (SUBV (XOR // negate the result if one operand is negative ++ (Select0 (CALLudiv ++ ++ (SUBV (XOR x (Signmask x)) (Signmask x)) // negate x if negative ++ (SUBV (XOR y (Signmask y)) (Signmask y)))) // negate y if negative ++ (Signmask (XOR x y))) (Signmask (XOR x y))) ++(Div64 [false] x y) && buildcfg.GOSW64 >=4 => (DIVV x y) ++(Div64u x y) && buildcfg.GOSW64 <=3 => (Select0 (CALLudiv x y)) ++(Div64u x y) && buildcfg.GOSW64 >=4 => (UDIVV x y) ++(Div32 x y) && buildcfg.GOSW64 <=3 => (Div64 (SignExt32to64 x) (SignExt32to64 y)) ++(Div32 x y) && buildcfg.GOSW64 >=4 => (DIVW x y) ++(Div32u x y) && buildcfg.GOSW64 <=3 => (Div64u (ZeroExt32to64 x) (ZeroExt32to64 y)) ++(Div32u x y) && buildcfg.GOSW64 >=4 => (UDIVW x y) ++(Div16 x y) => (Div64 (SignExt16to64 x) (SignExt16to64 y)) ++(Div16u x y) => (Div64u (ZeroExt16to64 x) (ZeroExt16to64 y)) ++(Div8 x y) => (Div64 (SignExt8to64 x) (SignExt8to64 y)) ++(Div8u x y) => (Div64u (ZeroExt8to64 x) (ZeroExt8to64 y)) ++(Div(32|64)F ...) => (FDIV(S|D) ...) ++ ++ ++(Mod64 x y) => ++ (SUBV (XOR // negate the result if x is negative ++ (Select1 (CALLudiv ++ (SUBV (XOR x (Signmask x)) (Signmask x)) // negate x if negative ++ (SUBV (XOR y (Signmask y)) (Signmask y)))) // negate y if negative ++ (Signmask x)) (Signmask x)) ++(Mod64u x y) => (Select1 (CALLudiv x y)) ++(Mod32 x y) => (Mod64 (SignExt32to64 x) (SignExt32to64 y)) ++(Mod32u x y) => (Mod64u (ZeroExt32to64 x) (ZeroExt32to64 y)) ++(Mod16 x y) => (Mod64 (SignExt16to64 x) (SignExt16to64 y)) ++(Mod16u x y) => (Mod64u (ZeroExt16to64 x) (ZeroExt16to64 y)) ++(Mod8 x y) => (Mod64 (SignExt8to64 x) (SignExt8to64 y)) ++(Mod8u x y) => (Mod64u (ZeroExt8to64 x) (ZeroExt8to64 y)) ++ ++ ++// Lowering float <=> int ++(Cvt32to32F x) => (FCVTLS (IFMOVD x)) ++(Cvt32to64F x) => (FCVTLD (IFMOVD (SignExt32to64 x))) ++(Cvt64to32F ...) => (FCVTLS ...) ++(Cvt64to64F ...) => (FCVTLD ...) ++(Cvt32Fto32 x) => (FIMOVS (FCVTLW (FCVTDL_Z (FCVTSD x)))) ++(Cvt64Fto32 x) => (FIMOVS (FCVTLW (FCVTDL_Z x))) ++(Cvt32Fto64 x) => (FIMOVD (FCVTDL_Z (FCVTSD x))) ++(Cvt64Fto64 x) => (FIMOVD (FCVTDL_Z x)) ++(Cvt32Fto64F ...) => (FCVTSD ...) ++(Cvt64Fto32F ...) => (FCVTDS ...) ++ ++(CvtBoolToUint8 ...) => (Copy ...) ++ ++(Round(32|64)F ...) => (Copy ...) ++ ++// count trailing zero ++// 64 - CLZ(x&-x - 1) ++(Ctz(32|64)NonZero ...) => (Ctz(32|64) ...) ++(Ctz64 ...) => (CTTZ ...) ++(Ctz32 x) => (SUBV (CTTZ (ZeroExt32to64 x)) (MULLconst (CMPEQ (ZeroExt32to64 x) (MOVVconst [0]) ) [32])) ++ ++//count bits ++(PopCount64 ...) => (CTPOP ...) ++(PopCount32 x) => (CTPOP (ZeroExt32to64 x)) ++(PopCount16 x) => (CTPOP (ZeroExt16to64 x)) ++(PopCount8 x) => (CTPOP (ZeroExt8to64 x)) ++ ++(Floor ...) => (FCVTDL_N ...) ++(Ceil ...) => (FCVTDL_P ...) ++(Trunc ...) => (FCVTDL_Z ...) ++(Round ...) => (FCVTDL_G ...) ++(Abs ...) => (FABS ...) ++(Copysign x y) => (FCPYS y x) ++(Sqrt ...) => (FSQRTD ...) ++(Sqrt32 ...) => (FSQRTS ...) ++ ++// Lowering constants ++(Const(64|32|16|8) [val]) => (MOVVconst [int64(val)]) ++(Const(32|64)F [val]) => (MOV(F|D)const [float64(val)]) ++(ConstNil) => (MOVVconst [0]) ++(ConstBool [t]) => (MOVVconst [b2i(t)]) ++ ++(Slicemask x) => (SRAconst (NEGV x) [63]) ++ ++// Lowering boolean ops ++(AndB ...) => (AND ...) ++(OrB ...) => (BIS ...) ++(EqB x y) => (XOR (MOVVconst [1]) (XOR x y) ) ++(NeqB ...) => (XOR ...) ++(Not x) => (XORconst x [1]) ++ ++(And(64|32|16|8) ...) => (AND ...) ++ ++(Or(64|32|16|8) ...) => (BIS ...) ++ ++(Xor(64|32|16|8) ...) => (XOR ...) ++ ++// unary ops ++(Neg(64|32|16|8) ...) => (NEGV ...) ++(Neg(32|64)F ...) => (NEG(F|D) ...) ++ ++(Com(64|32|16|8) x) => (ORNOT (MOVVconst [0]) x) ++ ++ ++// shifts ++// hardware instruction uses only the low 6 bits of the shift ++// we compare to 64 to ensure Go semantics for large shifts ++//shifts constant ++(Lsh64x64 x (Const64 [c])) && uint64(c) < 64 => (SLLconst x [c]) ++(Rsh64x64 x (Const64 [c])) && uint64(c) < 64 => (SRAconst x [c]) ++(Rsh64Ux64 x (Const64 [c])) && uint64(c) < 64 => (SRLconst x [c]) ++(Lsh32x64 x (Const64 [c])) && uint64(c) < 32 => (SLLconst (ZeroExt32to64 x) [c]) ++(Rsh32x64 x (Const64 [c])) && uint64(c) < 32 => (SRAconst (SignExt32to64 x) [c]) ++(Rsh32Ux64 x (Const64 [c])) && uint64(c) < 32 => (SRLconst (ZeroExt32to64 x) [c]) ++(Lsh16x64 x (Const64 [c])) && uint64(c) < 16 => (SLLconst (ZeroExt16to64 x) [c]) ++(Rsh16x64 x (Const64 [c])) && uint64(c) < 16 => (SRAconst (SignExt16to64 x) [c]) ++(Rsh16Ux64 x (Const64 [c])) && uint64(c) < 16 => (SRLconst (ZeroExt16to64 x) [c]) ++(Lsh8x64 x (Const64 [c])) && uint64(c) < 8 => (SLLconst (ZeroExt8to64 x) [c]) ++(Rsh8x64 x (Const64 [c])) && uint64(c) < 8 => (SRAconst (SignExt8to64 x) [c]) ++(Rsh8Ux64 x (Const64 [c])) && uint64(c) < 8 => (SRLconst (ZeroExt8to64 x) [c]) ++ ++// large constant signed right shift, we leave the sign bit ++(Rsh64x64 x (Const64 [c])) && uint64(c) >= 64 => (SRAconst x [63]) ++(Rsh32x64 x (Const64 [c])) && uint64(c) >= 32 => (SRAconst (SignExt32to64 x) [63]) ++(Rsh16x64 x (Const64 [c])) && uint64(c) >= 16 => (SRAconst (SignExt16to64 x) [63]) ++(Rsh8x64 x (Const64 [c])) && uint64(c) >= 8 => (SRAconst (SignExt8to64 x) [63]) ++ ++// constant shifts ++(Rsh64x64 x (MOVVconst [c])) && uint64(c) >= 64 => (SRAconst x [63]) ++(Rsh32x64 x (MOVVconst [c])) && uint64(c) >= 32 => (SRAconst (SignExt32to64 x) [63]) ++(Rsh16x64 x (MOVVconst [c])) && uint64(c) >= 16 => (SRAconst (SignExt16to64 x) [63]) ++(Rsh8x64 x (MOVVconst [c])) && uint64(c) >= 8 => (SRAconst (SignExt8to64 x) [63]) ++ ++(Lsh64x64 x (MOVVconst [c])) && uint64(c) < 64 => (SLLconst x [c]) ++(Rsh64x64 x (MOVVconst [c])) && uint64(c) < 64 => (SRAconst x [c]) ++(Rsh64Ux64 x (MOVVconst [c])) && uint64(c) < 64 => (SRLconst x [c]) ++(Lsh32x64 x (MOVVconst [c])) && uint64(c) < 32 => (SLLconst (ZeroExt32to64 x) [c]) ++(Rsh32x64 x (MOVVconst [c])) && uint64(c) < 32 => (SRAconst (SignExt32to64 x) [c]) ++(Rsh32Ux64 x (MOVVconst [c])) && uint64(c) < 32 => (SRLconst (ZeroExt32to64 x) [c]) ++(Lsh16x64 x (MOVVconst [c])) && uint64(c) < 16 => (SLLconst (ZeroExt16to64 x) [c]) ++(Rsh16x64 x (MOVVconst [c])) && uint64(c) < 16 => (SRAconst (SignExt16to64 x) [c]) ++(Rsh16Ux64 x (MOVVconst [c])) && uint64(c) < 16 => (SRLconst (ZeroExt16to64 x) [c]) ++(Lsh8x64 x (MOVVconst [c])) && uint64(c) < 8 => (SLLconst (ZeroExt8to64 x) [c]) ++(Rsh8x64 x (MOVVconst [c])) && uint64(c) < 8 => (SRAconst (SignExt8to64 x) [c]) ++(Rsh8Ux64 x (MOVVconst [c])) && uint64(c) < 8 => (SRLconst (ZeroExt8to64 x) [c]) ++ ++(Lsh64x64 x y) => (AND (NEGV (CMPULT y (MOVVconst [64]))) (SLL x y)) ++(Lsh64x32 x y) => (AND (NEGV (CMPULT (ZeroExt32to64 y) (MOVVconst [64]))) (SLL x (ZeroExt32to64 y))) ++(Lsh64x16 x y) => (AND (NEGV (CMPULT (ZeroExt16to64 y) (MOVVconst [64]))) (SLL x (ZeroExt16to64 y))) ++(Lsh64x8 x y) => (AND (NEGV (CMPULT (ZeroExt8to64 y) (MOVVconst [64]))) (SLL x (ZeroExt8to64 y))) ++ ++(Lsh32x64 x y) => (AND (NEGV (CMPULT y (MOVVconst [64]))) (SLL x y)) ++(Lsh32x32 x y) => (AND (NEGV (CMPULT (ZeroExt32to64 y) (MOVVconst [64]))) (SLL x (ZeroExt32to64 y))) ++(Lsh32x16 x y) => (AND (NEGV (CMPULT (ZeroExt16to64 y) (MOVVconst [64]))) (SLL x (ZeroExt16to64 y))) ++(Lsh32x8 x y) => (AND (NEGV (CMPULT (ZeroExt8to64 y) (MOVVconst [64]))) (SLL x (ZeroExt8to64 y))) ++ ++(Lsh16x64 x y) => (AND (NEGV (CMPULT y (MOVVconst [64]))) (SLL x y)) ++(Lsh16x32 x y) => (AND (NEGV (CMPULT (ZeroExt32to64 y) (MOVVconst [64]))) (SLL x (ZeroExt32to64 y))) ++(Lsh16x16 x y) => (AND (NEGV (CMPULT (ZeroExt16to64 y) (MOVVconst [64]))) (SLL x (ZeroExt16to64 y))) ++(Lsh16x8 x y) => (AND (NEGV (CMPULT (ZeroExt8to64 y) (MOVVconst [64]))) (SLL x (ZeroExt8to64 y))) ++ ++(Lsh8x64 x y) => (AND (NEGV (CMPULT y (MOVVconst [64]))) (SLL x y)) ++(Lsh8x32 x y) => (AND (NEGV (CMPULT (ZeroExt32to64 y) (MOVVconst [64]))) (SLL x (ZeroExt32to64 y))) ++(Lsh8x16 x y) => (AND (NEGV (CMPULT (ZeroExt16to64 y) (MOVVconst [64]))) (SLL x (ZeroExt16to64 y))) ++(Lsh8x8 x y) => (AND (NEGV (CMPULT (ZeroExt8to64 y) (MOVVconst [64]))) (SLL x (ZeroExt8to64 y))) ++ ++(Rsh64Ux64 x y) => (AND (NEGV (CMPULT y (MOVVconst [64]))) (SRL x y)) ++(Rsh64Ux32 x y) => (AND (NEGV (CMPULT (ZeroExt32to64 y) (MOVVconst [64]))) (SRL x (ZeroExt32to64 y))) ++(Rsh64Ux16 x y) => (AND (NEGV (CMPULT (ZeroExt16to64 y) (MOVVconst [64]))) (SRL x (ZeroExt16to64 y))) ++(Rsh64Ux8 x y) => (AND (NEGV (CMPULT (ZeroExt8to64 y) (MOVVconst [64]))) (SRL x (ZeroExt8to64 y))) ++ ++(Rsh32Ux64 x y) => (AND (NEGV (CMPULT y (MOVVconst [64]))) (SRL (ZeroExt32to64 x) y)) ++(Rsh32Ux32 x y) => (AND (NEGV (CMPULT (ZeroExt32to64 y) (MOVVconst [64]))) (SRL (ZeroExt32to64 x) (ZeroExt32to64 y))) ++(Rsh32Ux16 x y) => (AND (NEGV (CMPULT (ZeroExt16to64 y) (MOVVconst [64]))) (SRL (ZeroExt32to64 x) (ZeroExt16to64 y))) ++(Rsh32Ux8 x y) => (AND (NEGV (CMPULT (ZeroExt8to64 y) (MOVVconst [64]))) (SRL (ZeroExt32to64 x) (ZeroExt8to64 y))) ++ ++(Rsh16Ux64 x y) => (AND (NEGV (CMPULT y (MOVVconst [64]))) (SRL (ZeroExt16to64 x) y)) ++(Rsh16Ux32 x y) => (AND (NEGV (CMPULT (ZeroExt32to64 y) (MOVVconst [64]))) (SRL (ZeroExt16to64 x) (ZeroExt32to64 y))) ++(Rsh16Ux16 x y) => (AND (NEGV (CMPULT (ZeroExt16to64 y) (MOVVconst [64]))) (SRL (ZeroExt16to64 x) (ZeroExt16to64 y))) ++(Rsh16Ux8 x y) => (AND (NEGV (CMPULT (ZeroExt8to64 y) (MOVVconst [64]))) (SRL (ZeroExt16to64 x) (ZeroExt8to64 y))) ++ ++(Rsh8Ux64 x y) => (AND (NEGV (CMPULT y (MOVVconst [64]))) (SRL (ZeroExt8to64 x) y)) ++(Rsh8Ux32 x y) => (AND (NEGV (CMPULT (ZeroExt32to64 y) (MOVVconst [64]))) (SRL (ZeroExt8to64 x) (ZeroExt32to64 y))) ++(Rsh8Ux16 x y) => (AND (NEGV (CMPULT (ZeroExt16to64 y) (MOVVconst [64]))) (SRL (ZeroExt8to64 x) (ZeroExt16to64 y))) ++(Rsh8Ux8 x y) => (AND (NEGV (CMPULT (ZeroExt8to64 y) (MOVVconst [64]))) (SRL (ZeroExt8to64 x) (ZeroExt8to64 y))) ++ ++(Rsh64x64 x y) => (SRA x (BIS (NEGV (CMPULT (MOVVconst [63]) y)) y)) ++(Rsh64x32 x y) => (SRA x (BIS (NEGV (CMPULT (MOVVconst [63]) (ZeroExt32to64 y))) (ZeroExt32to64 y))) ++(Rsh64x16 x y) => (SRA x (BIS (NEGV (CMPULT (MOVVconst [63]) (ZeroExt16to64 y))) (ZeroExt16to64 y))) ++(Rsh64x8 x y) => (SRA x (BIS (NEGV (CMPULT (MOVVconst [63]) (ZeroExt8to64 y))) (ZeroExt8to64 y))) ++ ++(Rsh32x64 x y) => (SRA (SignExt32to64 x) (BIS (NEGV (CMPULT (MOVVconst [63]) y)) y)) ++(Rsh32x32 x y) => (SRA (SignExt32to64 x) (BIS (NEGV (CMPULT (MOVVconst [63]) (ZeroExt32to64 y))) (ZeroExt32to64 y))) ++(Rsh32x16 x y) => (SRA (SignExt32to64 x) (BIS (NEGV (CMPULT (MOVVconst [63]) (ZeroExt16to64 y))) (ZeroExt16to64 y))) ++(Rsh32x8 x y) => (SRA (SignExt32to64 x) (BIS (NEGV (CMPULT (MOVVconst [63]) (ZeroExt8to64 y))) (ZeroExt8to64 y))) ++ ++ ++(Rsh16x64 x y) => (SRA (SignExt16to64 x) (BIS (NEGV (CMPULT (MOVVconst [63]) y)) y)) ++(Rsh16x32 x y) => (SRA (SignExt16to64 x) (BIS (NEGV (CMPULT (MOVVconst [63]) (ZeroExt32to64 y))) (ZeroExt32to64 y))) ++(Rsh16x16 x y) => (SRA (SignExt16to64 x) (BIS (NEGV (CMPULT (MOVVconst [63]) (ZeroExt16to64 y))) (ZeroExt16to64 y))) ++(Rsh16x8 x y) => (SRA (SignExt16to64 x) (BIS (NEGV (CMPULT (MOVVconst [63]) (ZeroExt8to64 y))) (ZeroExt8to64 y))) ++ ++(Rsh8x64 x y) => (SRA (SignExt8to64 x) (BIS (NEGV (CMPULT (MOVVconst [63]) y)) y)) ++(Rsh8x32 x y) => (SRA (SignExt8to64 x) (BIS (NEGV (CMPULT (MOVVconst [63]) (ZeroExt32to64 y))) (ZeroExt32to64 y))) ++(Rsh8x16 x y) => (SRA (SignExt8to64 x) (BIS (NEGV (CMPULT (MOVVconst [63]) (ZeroExt16to64 y))) (ZeroExt16to64 y))) ++(Rsh8x8 x y) => (SRA (SignExt8to64 x) (BIS (NEGV (CMPULT (MOVVconst [63]) (ZeroExt8to64 y))) (ZeroExt8to64 y))) ++ ++//absorb shifts into ops ++//(ADDV x0:(SLLconst x [2]) y) && clobberIfDead(x0) => (S4ADDV x y) ++//(ADDV x0:(SLLconst x [3]) y) && clobberIfDead(x0) => (S8ADDV x y) ++ ++// truncations ++// Because we ignore high parts of registers, truncates are just copies. ++(Trunc16to8 ...) => (Copy ...) ++(Trunc32to8 ...) => (Copy ...) ++(Trunc32to16 ...) => (Copy ...) ++(Trunc64to8 ...) => (Copy ...) ++(Trunc64to16 ...) => (Copy ...) ++(Trunc64to32 ...) => (Copy ...) ++ ++// Zero-/Sign-extensions ++(ZeroExt8to16 ...) => (MOVBUreg ...) ++(ZeroExt8to32 ...) => (MOVBUreg ...) ++(ZeroExt16to32 ...) => (MOVHUreg ...) ++(ZeroExt8to64 ...) => (MOVBUreg ...) ++(ZeroExt16to64 ...) => (MOVHUreg ...) ++(ZeroExt32to64 ...) => (MOVWUreg ...) ++ ++ ++(SignExt8to16 ...) => (MOVBreg ...) ++(SignExt8to32 ...) => (MOVBreg ...) ++(SignExt16to32 ...) => (MOVHreg ...) ++(SignExt8to64 ...) => (MOVBreg ...) ++(SignExt16to64 ...) => (MOVHreg ...) ++(SignExt32to64 ...) => (MOVWreg ...) ++ ++// Lowering comparisons ++//(Greater8U x y) => (CMPULT (ZeroExt8to64 y) (ZeroExt8to64 x)) ++//(Greater16U x y) => (CMPULT (ZeroExt16to64 y) (ZeroExt16to64 x)) ++//(Greater32U x y) => (CMPULT (ZeroExt32to64 y) (ZeroExt32to64 x)) ++//(Greater64U x y) => (CMPULT y x) ++// ++//(Greater8 x y) => (CMPLT (SignExt8to64 y) (SignExt8to64 x)) ++//(Greater16 x y) => (CMPLT (SignExt16to64 y) (SignExt16to64 x)) ++//(Greater32 x y) => (CMPLT (SignExt32to64 y) (SignExt32to64 x)) ++//(Greater64 x y) => (CMPLT y x) ++//(Greater(32|64)F x y) => (FEqual (FCMPLT y x)) ++// ++//(Geq8 x y) => (CMPLE (SignExt8to64 y) (SignExt8to64 x)) ++//(Geq16 x y) => (CMPLE (SignExt16to64 y) (SignExt16to64 x)) ++//(Geq32 x y) => (CMPLE (SignExt32to64 y) (SignExt32to64 x)) ++//(Geq64 x y) => (CMPLE y x) ++//(Geq(32|64)F x y) => (FEqual (FCMPLE y x)) ++// ++//(Geq8U x y) => (CMPULE (ZeroExt8to64 y) (ZeroExt8to64 x)) ++//(Geq16U x y) => (CMPULE (ZeroExt16to64 y) (ZeroExt16to64 x)) ++//(Geq32U x y) => (CMPULE (ZeroExt32to64 y) (ZeroExt32to64 x)) ++//(Geq64U x y) => (CMPULE y x) ++ ++ ++(Eq8 x y) => (CMPEQ (ZeroExt8to64 x) (ZeroExt8to64 y)) ++(Eq16 x y) => (CMPEQ (ZeroExt16to64 x) (ZeroExt16to64 y)) ++(Eq32 x y) => (CMPEQ (ZeroExt32to64 x) (ZeroExt32to64 y)) ++(Eq64 ...) => (CMPEQ ...) ++(EqPtr ...) => (CMPEQ ...) ++(Eq(32|64)F x y) => (FEqual (FCMPEQ x y)) ++ ++(Neq8 x y) => (Not (CMPEQ (ZeroExt8to64 x) (ZeroExt8to64 y))) ++(Neq16 x y) => (Not (CMPEQ (ZeroExt16to64 x) (ZeroExt16to64 y))) ++(Neq32 x y) => (Not (CMPEQ (ZeroExt32to64 x) (ZeroExt32to64 y))) ++(Neq64 x y) => (Not (CMPEQ x y)) ++(NeqPtr x y) => (Not (CMPEQ x y)) ++(Neq(32|64)F x y) => (FNotEqual (FCMPEQ x y)) ++ ++(Less8 x y) => (CMPLT (SignExt8to64 x) (SignExt8to64 y)) ++(Less16 x y) => (CMPLT (SignExt16to64 x) (SignExt16to64 y)) ++(Less32 x y) => (CMPLT (SignExt32to64 x) (SignExt32to64 y)) ++(Less64 ...) => (CMPLT ...) ++(Less(32|64)F x y) => (FEqual (FCMPLT x y)) ++ ++(Less8U x y) => (CMPULT (ZeroExt8to64 x) (ZeroExt8to64 y)) ++(Less16U x y) => (CMPULT (ZeroExt16to64 x) (ZeroExt16to64 y)) ++(Less32U x y) => (CMPULT (ZeroExt32to64 x) (ZeroExt32to64 y)) ++(Less64U ...) => (CMPULT ...) ++ ++(Leq8 x y) => (CMPLE (SignExt8to64 x) (SignExt8to64 y)) ++(Leq16 x y) => (CMPLE (SignExt16to64 x) (SignExt16to64 y)) ++(Leq32 x y) => (CMPLE (SignExt32to64 x) (SignExt32to64 y)) ++(Leq64 ...) => (CMPLE ...) ++(Leq(32|64)F x y) => (FEqual (FCMPLE x y)) ++ ++(Leq8U x y) => (CMPULE (ZeroExt8to64 x) (ZeroExt8to64 y)) ++(Leq16U x y) => (CMPULE (ZeroExt16to64 x) (ZeroExt16to64 y)) ++(Leq32U x y) => (CMPULE (ZeroExt32to64 x) (ZeroExt32to64 y)) ++(Leq64U ...) => (CMPULE ...) ++ ++ ++(OffPtr [off] ptr:(SP)) && is32Bit(off) => (SYMADDR [int32(off)] ptr) ++(OffPtr [off] ptr) => (ADDVconst [off] ptr) ++ ++(Addr {sym} base) => (SYMADDR {sym} base) ++(LocalAddr {sym} base mem) && t.Elem().HasPointers() => (SYMADDR {sym} (SPanchored base mem)) ++(LocalAddr {sym} base _) && !t.Elem().HasPointers() => (SYMADDR {sym} base) ++ ++// loads ++(Load ptr mem) && t.IsBoolean() => (MOVBUload ptr mem) ++(Load ptr mem) && (is8BitInt(t) && t.IsSigned()) => (MOVBload ptr mem) ++(Load ptr mem) && (is8BitInt(t) && !t.IsSigned()) => (MOVBUload ptr mem) ++(Load ptr mem) && (is16BitInt(t) && t.IsSigned()) => (MOVHload ptr mem) ++(Load ptr mem) && (is16BitInt(t) && !t.IsSigned()) => (MOVHUload ptr mem) ++(Load ptr mem) && (is32BitInt(t) && t.IsSigned()) => (MOVWload ptr mem) ++(Load ptr mem) && (is32BitInt(t) && !t.IsSigned()) => (MOVWUload ptr mem) ++(Load ptr mem) && (is64BitInt(t) || isPtr(t)) => (MOVVload ptr mem) ++(Load ptr mem) && is32BitFloat(t) => (MOVFload ptr mem) ++(Load ptr mem) && is64BitFloat(t) => (MOVDload ptr mem) ++ ++// fold address into load/store ++(MOVBload [off1] {sym} (ADDVconst [off2] ptr) mem) && is16Bit(int64(off1)+off2) => (MOVBload [off1+int32(off2)] {sym} ptr mem) ++(MOVBUload [off1] {sym} (ADDVconst [off2] ptr) mem) && is16Bit(int64(off1)+off2) => (MOVBUload [off1+int32(off2)] {sym} ptr mem) ++(MOVHload [off1] {sym} (ADDVconst [off2] ptr) mem) && is16Bit(int64(off1)+off2) => (MOVHload [off1+int32(off2)] {sym} ptr mem) ++(MOVHUload [off1] {sym} (ADDVconst [off2] ptr) mem) && is16Bit(int64(off1)+off2) => (MOVHUload [off1+int32(off2)] {sym} ptr mem) ++(MOVWload [off1] {sym} (ADDVconst [off2] ptr) mem) && is16Bit(int64(off1)+off2) => (MOVWload [off1+int32(off2)] {sym} ptr mem) ++(MOVWUload [off1] {sym} (ADDVconst [off2] ptr) mem) && is16Bit(int64(off1)+off2) => (MOVWUload [off1+int32(off2)] {sym} ptr mem) ++(MOVVload [off1] {sym} (ADDVconst [off2] ptr) mem) && is16Bit(int64(off1)+off2) => (MOVVload [off1+int32(off2)] {sym} ptr mem) ++(MOVFload [off1] {sym} (ADDVconst [off2] ptr) mem) && is16Bit(int64(off1)+off2) => (MOVFload [off1+int32(off2)] {sym} ptr mem) ++(MOVDload [off1] {sym} (ADDVconst [off2] ptr) mem) && is16Bit(int64(off1)+off2) => (MOVDload [off1+int32(off2)] {sym} ptr mem) ++ ++(MOVBstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is16Bit(int64(off1)+off2) => (MOVBstore [off1+int32(off2)] {sym} ptr val mem) ++(MOVHstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is16Bit(int64(off1)+off2) => (MOVHstore [off1+int32(off2)] {sym} ptr val mem) ++(MOVWstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is16Bit(int64(off1)+off2) => (MOVWstore [off1+int32(off2)] {sym} ptr val mem) ++(MOVVstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is16Bit(int64(off1)+off2) => (MOVVstore [off1+int32(off2)] {sym} ptr val mem) ++(MOVFstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is16Bit(int64(off1)+off2) => (MOVFstore [off1+int32(off2)] {sym} ptr val mem) ++(MOVDstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is16Bit(int64(off1)+off2) => (MOVDstore [off1+int32(off2)] {sym} ptr val mem) ++(MOVBstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) && is16Bit(int64(off1)+off2) => (MOVBstorezero [off1+int32(off2)] {sym} ptr mem) ++(MOVHstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) && is16Bit(int64(off1)+off2) => (MOVHstorezero [off1+int32(off2)] {sym} ptr mem) ++(MOVWstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) && is16Bit(int64(off1)+off2) => (MOVWstorezero [off1+int32(off2)] {sym} ptr mem) ++(MOVVstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) && is16Bit(int64(off1)+off2) => (MOVVstorezero [off1+int32(off2)] {sym} ptr mem) ++ ++// stores ++(Store {t} ptr val mem) && t.Size() == 1 => (MOVBstore ptr val mem) ++(Store {t} ptr val mem) && t.Size() == 2 => (MOVHstore ptr val mem) ++(Store {t} ptr val mem) && t.Size() == 4 && !is32BitFloat(val.Type) => (MOVWstore ptr val mem) ++(Store {t} ptr val mem) && t.Size() == 8 && !is64BitFloat(val.Type) => (MOVVstore ptr val mem) ++(Store {t} ptr val mem) && t.Size() == 4 && is32BitFloat(val.Type) => (MOVFstore ptr val mem) ++(Store {t} ptr val mem) && t.Size() == 8 && is64BitFloat(val.Type) => (MOVDstore ptr val mem) ++ ++// zeroing ++(Zero [0] _ mem) => mem ++(Zero [1] ptr mem) => (MOVBstore ptr (MOVVconst [0]) mem) ++(Zero [2] {t} ptr mem) && t.Alignment()%2 == 0 => ++ (MOVHstore ptr (MOVVconst [0]) mem) ++(Zero [2] ptr mem) => ++ (MOVBstore [1] ptr (MOVVconst [0]) ++ (MOVBstore [0] ptr (MOVVconst [0]) mem)) ++(Zero [4] {t} ptr mem) && t.Alignment()%4 == 0 => ++ (MOVWstore ptr (MOVVconst [0]) mem) ++(Zero [4] {t} ptr mem) && t.Alignment()%2 == 0 => ++ (MOVHstore [2] ptr (MOVVconst [0]) ++ (MOVHstore [0] ptr (MOVVconst [0]) mem)) ++ ++(Zero [4] ptr mem) => ++ (MOVBstore [3] ptr (MOVVconst [0]) ++ (MOVBstore [2] ptr (MOVVconst [0]) ++ (MOVBstore [1] ptr (MOVVconst [0]) ++ (MOVBstore [0] ptr (MOVVconst [0]) mem)))) ++(Zero [8] {t} ptr mem) && t.Alignment()%8 == 0 => ++ (MOVVstore ptr (MOVVconst [0]) mem) ++(Zero [8] {t} ptr mem) && t.Alignment()%4 == 0 => ++ (MOVWstore [4] ptr (MOVVconst [0]) ++ (MOVWstore [0] ptr (MOVVconst [0]) mem)) ++(Zero [8] {t} ptr mem) && t.Alignment()%2 == 0 => ++ (MOVHstore [6] ptr (MOVVconst [0]) ++ (MOVHstore [4] ptr (MOVVconst [0]) ++ (MOVHstore [2] ptr (MOVVconst [0]) ++ (MOVHstore [0] ptr (MOVVconst [0]) mem)))) ++ ++(Zero [3] ptr mem) => ++ (MOVBstore [2] ptr (MOVVconst [0]) ++ (MOVBstore [1] ptr (MOVVconst [0]) ++ (MOVBstore [0] ptr (MOVVconst [0]) mem))) ++(Zero [6] {t} ptr mem) && t.Alignment()%2 == 0 => ++ (MOVHstore [4] ptr (MOVVconst [0]) ++ (MOVHstore [2] ptr (MOVVconst [0]) ++ (MOVHstore [0] ptr (MOVVconst [0]) mem))) ++(Zero [12] {t} ptr mem) && t.Alignment()%4 == 0 => ++ (MOVWstore [8] ptr (MOVVconst [0]) ++ (MOVWstore [4] ptr (MOVVconst [0]) ++ (MOVWstore [0] ptr (MOVVconst [0]) mem))) ++(Zero [16] {t} ptr mem) && t.Alignment()%8 == 0 => ++ (MOVVstore [8] ptr (MOVVconst [0]) ++ (MOVVstore [0] ptr (MOVVconst [0]) mem)) ++(Zero [24] {t} ptr mem) && (t.Alignment()%8 == 0 || buildcfg.GOSW64 >=4) => ++ (MOVVstore [16] ptr (MOVVconst [0]) ++ (MOVVstore [8] ptr (MOVVconst [0]) ++ (MOVVstore [0] ptr (MOVVconst [0]) mem))) ++(Zero [32] {t} ptr mem) && (t.Alignment()%8 == 0 || buildcfg.GOSW64 >=4) => ++ (MOVVstore [24] ptr (MOVVconst [0]) ++ (MOVVstore [16] ptr (MOVVconst [0]) ++ (MOVVstore [8] ptr (MOVVconst [0]) ++ (MOVVstore [0] ptr (MOVVconst [0]) mem)))) ++ ++// medium zeroing uses a duff device ++// 8, and 128 are magic constants, see runtime/mkduff.go ++(Zero [s] {t} ptr mem) ++ && s%8 == 0 && s > 24 && s <= 8*128 ++ && t.Alignment()%8 == 0 && !config.noDuffDevice => ++ (DUFFZERO [8 * (128 - int64(s/8))] ptr mem) ++ ++// large or unaligned zeroing uses a loop ++(Zero [s] {t} ptr mem) ++ && (s > 8*128 || config.noDuffDevice) || t.Alignment()%8 != 0 => ++ (LoweredZero [t.Alignment()] ++ ptr ++ (ADDVconst ptr [s-moveSize(t.Alignment(), config)]) ++ mem) ++ ++// moves ++(Move [0] _ _ mem) => mem ++(Move [1] dst src mem) => (MOVBstore dst (MOVBload src mem) mem) ++(Move [2] {t} dst src mem) && t.Alignment()%2 == 0 => ++ (MOVHstore dst (MOVHload src mem) mem) ++(Move [2] dst src mem) => ++ (MOVBstore [1] dst (MOVBload [1] src mem) ++ (MOVBstore dst (MOVBload src mem) mem)) ++(Move [4] {t} dst src mem) && t.Alignment()%4 == 0 => ++ (MOVWstore dst (MOVWload src mem) mem) ++(Move [4] {t} dst src mem) && t.Alignment()%2 == 0 => ++ (MOVHstore [2] dst (MOVHload [2] src mem) ++ (MOVHstore dst (MOVHload src mem) mem)) ++ ++(Move [4] dst src mem) => ++ (MOVBstore [3] dst (MOVBload [3] src mem) ++ (MOVBstore [2] dst (MOVBload [2] src mem) ++ (MOVBstore [1] dst (MOVBload [1] src mem) ++ (MOVBstore dst (MOVBload src mem) mem)))) ++(Move [8] {t} dst src mem) && t.Alignment()%8 == 0 => ++ (MOVVstore dst (MOVVload src mem) mem) ++(Move [8] {t} dst src mem) && t.Alignment()%4 == 0 => ++ (MOVWstore [4] dst (MOVWload [4] src mem) ++ (MOVWstore dst (MOVWload src mem) mem)) ++(Move [8] {t} dst src mem) && t.Alignment()%2 == 0 => ++ (MOVHstore [6] dst (MOVHload [6] src mem) ++ (MOVHstore [4] dst (MOVHload [4] src mem) ++ (MOVHstore [2] dst (MOVHload [2] src mem) ++ (MOVHstore dst (MOVHload src mem) mem)))) ++ ++(Move [3] dst src mem) => ++ (MOVBstore [2] dst (MOVBload [2] src mem) ++ (MOVBstore [1] dst (MOVBload [1] src mem) ++ (MOVBstore dst (MOVBload src mem) mem))) ++(Move [6] {t} dst src mem) && t.Alignment()%2 == 0 => ++ (MOVHstore [4] dst (MOVHload [4] src mem) ++ (MOVHstore [2] dst (MOVHload [2] src mem) ++ (MOVHstore dst (MOVHload src mem) mem))) ++(Move [12] {t} dst src mem) && t.Alignment()%4 == 0 => ++ (MOVWstore [8] dst (MOVWload [8] src mem) ++ (MOVWstore [4] dst (MOVWload [4] src mem) ++ (MOVWstore dst (MOVWload src mem) mem))) ++(Move [16] {t} dst src mem) && t.Alignment()%8 == 0 => ++ (MOVVstore [8] dst (MOVVload [8] src mem) ++ (MOVVstore dst (MOVVload src mem) mem)) ++(Move [24] {t} dst src mem) && t.Alignment()%8 == 0 => ++ (MOVVstore [16] dst (MOVVload [16] src mem) ++ (MOVVstore [8] dst (MOVVload [8] src mem) ++ (MOVVstore dst (MOVVload src mem) mem))) ++ ++// large or unaligned move uses a loop ++(Move [s] {t} dst src mem) ++ && s > 24 && logLargeCopy(v, s) || t.Alignment()%8 != 0 => ++ (LoweredMove [t.Alignment()] ++ dst ++ src ++ (ADDVconst src [s-moveSize(t.Alignment(), config)]) ++ mem) ++ ++ ++// calls ++(StaticCall ...) => (CALLstatic ...) ++(ClosureCall ...) => (CALLclosure ...) ++(InterCall ...) => (CALLinter ...) ++(TailCall ...) => (CALLtail ...) ++ ++// checks ++(NilCheck ...) => (LoweredNilCheck ...) ++//(IsNonNil ptr) => (Greater64U ptr (MOVVconst [0])) ++(IsNonNil ptr) => (CMPULT (MOVVconst [0]) ptr) ++(IsInBounds ...) => (CMPULT ...) ++(IsSliceInBounds ...) => (CMPULE ...) ++ ++// (If cond yes no) => (NE cond yes no) ++(If cond yes no) => (LBS cond yes no) ++ ++(LBS (CMPEQ x y) yes no) => (NE (CMPEQ x y) yes no) ++(LBS (XORconst (CMPEQ x y) [1]) yes no) => (EQ (CMPEQ x y) yes no) ++(LBS (CMPLT x y) yes no) => (NE (CMPLT x y) yes no) ++(LBS (CMPULT x y) yes no) => (NE (CMPULT x y) yes no) ++(LBS (CMPLE x y) yes no) => (NE (CMPLE x y) yes no) ++(LBS (CMPULE x y) yes no) => (NE (CMPULE x y) yes no) ++(LBS (FEqual cc) yes no) => (FNE cc yes no) ++(LBS (FNotEqual cc) yes no) => (FEQ cc yes no) ++ ++ ++// fold address into load/store ++(MOVBload [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVBload [off1+int32(off2)] {sym} ptr mem) ++(MOVBUload [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVBUload [off1+int32(off2)] {sym} ptr mem) ++(MOVHload [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVHload [off1+int32(off2)] {sym} ptr mem) ++(MOVHUload [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVHUload [off1+int32(off2)] {sym} ptr mem) ++(MOVWload [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVWload [off1+int32(off2)] {sym} ptr mem) ++(MOVWUload [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVWUload [off1+int32(off2)] {sym} ptr mem) ++(MOVVload [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVVload [off1+int32(off2)] {sym} ptr mem) ++(MOVFload [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVFload [off1+int32(off2)] {sym} ptr mem) ++(MOVDload [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVDload [off1+int32(off2)] {sym} ptr mem) ++ ++(MOVBstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) => (MOVBstore [off1+int32(off2)] {sym} ptr val mem) ++(MOVHstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) => (MOVHstore [off1+int32(off2)] {sym} ptr val mem) ++(MOVWstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) => (MOVWstore [off1+int32(off2)] {sym} ptr val mem) ++(MOVVstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) => (MOVVstore [off1+int32(off2)] {sym} ptr val mem) ++(MOVFstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) => (MOVFstore [off1+int32(off2)] {sym} ptr val mem) ++(MOVDstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) => (MOVDstore [off1+int32(off2)] {sym} ptr val mem) ++(MOVBstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVBstorezero [off1+int32(off2)] {sym} ptr mem) ++(MOVHstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVHstorezero [off1+int32(off2)] {sym} ptr mem) ++(MOVWstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVWstorezero [off1+int32(off2)] {sym} ptr mem) ++(MOVVstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVVstorezero [off1+int32(off2)] {sym} ptr mem) ++ ++(MOVBload [off1] {sym1} (SYMADDR [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && ++ is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => ++ (MOVBload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) ++(MOVBUload [off1] {sym1} (SYMADDR [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && ++ is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => ++ (MOVBUload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) ++(MOVHload [off1] {sym1} (SYMADDR [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && ++ is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => ++ (MOVHload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) ++(MOVHUload [off1] {sym1} (SYMADDR [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && ++ is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => ++ (MOVHUload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) ++(MOVWload [off1] {sym1} (SYMADDR [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && ++ is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => ++ (MOVWload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) ++(MOVWUload [off1] {sym1} (SYMADDR [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && ++ is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => ++ (MOVWUload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) ++(MOVVload [off1] {sym1} (SYMADDR [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && ++ is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => ++ (MOVVload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) ++(MOVFload [off1] {sym1} (SYMADDR [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && ++ is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => ++ (MOVFload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) ++(MOVDload [off1] {sym1} (SYMADDR [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && ++ is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => ++ (MOVDload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) ++ ++ ++(MOVBstore [off1] {sym1} (SYMADDR [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && ++ is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => ++ (MOVBstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) ++(MOVHstore [off1] {sym1} (SYMADDR [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && ++ is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => ++ (MOVHstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) ++(MOVWstore [off1] {sym1} (SYMADDR [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && ++ is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => ++ (MOVWstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) ++(MOVVstore [off1] {sym1} (SYMADDR [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && ++ is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => ++ (MOVVstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) ++(MOVFstore [off1] {sym1} (SYMADDR [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && ++ is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => ++ (MOVFstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) ++(MOVDstore [off1] {sym1} (SYMADDR [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && ++ is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => ++ (MOVDstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) ++(MOVBstorezero [off1] {sym1} (SYMADDR [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && ++ is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => ++ (MOVBstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) ++(MOVHstorezero [off1] {sym1} (SYMADDR [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && ++ is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => ++ (MOVHstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) ++(MOVWstorezero [off1] {sym1} (SYMADDR [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && ++ is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => ++ (MOVWstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) ++(MOVVstorezero [off1] {sym1} (SYMADDR [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && ++ is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) => ++ (MOVVstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) ++ ++// store zero ++(MOVBstore [off] {sym} ptr (MOVVconst [0]) mem) => (MOVBstorezero [off] {sym} ptr mem) ++(MOVHstore [off] {sym} ptr (MOVVconst [0]) mem) => (MOVHstorezero [off] {sym} ptr mem) ++(MOVWstore [off] {sym} ptr (MOVVconst [0]) mem) => (MOVWstorezero [off] {sym} ptr mem) ++(MOVVstore [off] {sym} ptr (MOVVconst [0]) mem) => (MOVVstorezero [off] {sym} ptr mem) ++ ++// don't extend after proper load ++(MOVBUreg x:(MOVBUload _ _)) => (MOVVreg x) ++(MOVHUreg x:(MOVBUload _ _)) => (MOVVreg x) ++(MOVHUreg x:(MOVHUload _ _)) => (MOVVreg x) ++(MOVWreg x:(MOVWload _ _)) => (MOVVreg x) ++(MOVWUreg x:(MOVBUload _ _)) => (MOVVreg x) ++(MOVWUreg x:(MOVHUload _ _)) => (MOVVreg x) ++ ++// fold double extensions ++(MOVBreg x:(MOVBreg _)) => (MOVVreg x) ++(MOVBUreg x:(MOVBUreg _)) => (MOVVreg x) ++(MOVHreg x:(MOVBreg _)) => (MOVVreg x) ++(MOVHreg x:(MOVHreg _)) => (MOVVreg x) ++(MOVHUreg x:(MOVBUreg _)) => (MOVVreg x) ++(MOVHUreg x:(MOVHUreg _)) => (MOVVreg x) ++(MOVWreg x:(MOVBreg _)) => (MOVVreg x) ++(MOVWreg x:(MOVHreg _)) => (MOVVreg x) ++(MOVWreg x:(MOVWreg _)) => (MOVVreg x) ++(MOVWUreg x:(MOVBUreg _)) => (MOVVreg x) ++(MOVWUreg x:(MOVHUreg _)) => (MOVVreg x) ++(MOVWUreg x:(MOVWUreg _)) => (MOVVreg x) ++ ++// don't extend before store ++(MOVBstore [off] {sym} ptr (MOVBreg x) mem) => (MOVBstore [off] {sym} ptr x mem) ++(MOVBstore [off] {sym} ptr (MOVBUreg x) mem) => (MOVBstore [off] {sym} ptr x mem) ++(MOVBstore [off] {sym} ptr (MOVHreg x) mem) => (MOVBstore [off] {sym} ptr x mem) ++(MOVBstore [off] {sym} ptr (MOVHUreg x) mem) => (MOVBstore [off] {sym} ptr x mem) ++(MOVBstore [off] {sym} ptr (MOVWreg x) mem) => (MOVBstore [off] {sym} ptr x mem) ++(MOVBstore [off] {sym} ptr (MOVWUreg x) mem) => (MOVBstore [off] {sym} ptr x mem) ++(MOVHstore [off] {sym} ptr (MOVHreg x) mem) => (MOVHstore [off] {sym} ptr x mem) ++(MOVHstore [off] {sym} ptr (MOVHUreg x) mem) => (MOVHstore [off] {sym} ptr x mem) ++(MOVHstore [off] {sym} ptr (MOVWreg x) mem) => (MOVHstore [off] {sym} ptr x mem) ++(MOVHstore [off] {sym} ptr (MOVWUreg x) mem) => (MOVHstore [off] {sym} ptr x mem) ++(MOVWstore [off] {sym} ptr (MOVWreg x) mem) => (MOVWstore [off] {sym} ptr x mem) ++(MOVWstore [off] {sym} ptr (MOVWUreg x) mem) => (MOVWstore [off] {sym} ptr x mem) ++ ++// if a register move has only 1 use, just use the same register without emitting instruction ++// MOVVnop doesn't emit instruction, only for ensuring the type. ++(MOVVreg x) && x.Uses == 1 => (MOVVnop x) ++ ++// TODO: we should be able to get rid of MOVVnop all together. ++// But for now, this is enough to get rid of lots of them. ++(MOVVnop (MOVVconst [c])) => (MOVVconst [c]) ++ ++// fold constant into arithmatic ops ++(ADDV x (MOVVconst [c])) && is32Bit(c) && !t.IsPtr() => (ADDVconst [c] x) ++(SUBV x (MOVVconst [c])) && is32Bit(c) => (SUBVconst [c] x) ++(MULW x (MOVVconst [c])) && is32Bit(c) => (MULWconst [c] x) ++(MULL x (MOVVconst [c])) => (MULLconst [c] x) ++(AND x (MOVVconst [c])) && is32Bit(c) => (ANDconst [c] x) ++(BIS x (MOVVconst [c])) && is32Bit(c) => (BISconst [c] x) ++(XOR x (MOVVconst [c])) && is32Bit(c) => (XORconst [c] x) ++(ORNOT x (MOVVconst [c])) && is32Bit(c) => (ORNOTconst [c] x) ++ ++(CMPEQ x (MOVVconst [c])) && is32Bit(c) => (CMPEQconst [c] x) ++(CMPLT x (MOVVconst [c])) && is32Bit(c) => (CMPLTconst [c] x) ++(CMPLE x (MOVVconst [c])) && is32Bit(c) => (CMPLEconst [c] x) ++(CMPULT x (MOVVconst [c])) && is32Bit(c) => (CMPULTconst [c] x) ++(CMPULE x (MOVVconst [c])) && is32Bit(c) => (CMPULEconst [c] x) ++ ++(SEXTB (MOVVconst [c])) => (MOVVconst [int64(int8(c))]) ++(ANDconst (MOVVconst [c]) [255]) => (MOVVconst [int64(uint8(c))]) ++(SEXTH (MOVVconst [c])) => (MOVVconst [int64(int16(c))]) ++(ANDconst (MOVVconst [c]) [65535]) => (MOVVconst [int64(uint16(c))]) ++(ADDWconst (MOVVconst [c]) [0]) => (MOVVconst [int64(int32(c))]) ++(ANDconst (MOVVconst [c]) [0xffffffff]) => (MOVVconst [int64(uint32(c))]) ++ ++(MOVBreg (MOVVconst [c])) => (MOVVconst [int64(int8(c))]) ++(MOVBUreg (MOVVconst [c])) => (MOVVconst [int64(uint8(c))]) ++(MOVHreg (MOVVconst [c])) => (MOVVconst [int64(int16(c))]) ++(MOVHUreg (MOVVconst [c])) => (MOVVconst [int64(uint16(c))]) ++(MOVWreg (MOVVconst [c])) => (MOVVconst [int64(int32(c))]) ++(MOVWUreg (MOVVconst [c])) => (MOVVconst [int64(uint32(c))]) ++(MOVVreg (MOVVconst [c])) => (MOVVconst [c]) ++ ++// generic simplifications ++(ADDV x (NEGV y)) => (SUBV x y) ++(SUBV x x) => (MOVVconst [0]) ++(SUBV (MOVVconst [0]) x) => (NEGV x) ++(AND x x) => x ++(BIS x x) => x ++(XOR x x) => (MOVVconst [0]) ++ ++ ++// remove redundant *const ops ++(ADDVconst [0] x) => x ++(SUBVconst [0] x) => x ++(ANDconst [0] _) => (MOVVconst [0]) ++(ANDconst [-1] x) => x ++(BISconst [0] x) => x ++(BISconst [-1] _) => (MOVVconst [-1]) ++(XORconst [0] x) => x ++// (MULLconst [0] x) => (MOVVconst [0]) ++// (MULLconst [-1] x) => (NEGV x) ++// (MULLconst [1] x) => x ++ ++// generic constant folding ++(ADDVconst [c] (MOVVconst [d])) => (MOVVconst [c+d]) ++(ADDVconst [c] (ADDVconst [d] x)) && is32Bit(c+d) => (ADDVconst [c+d] x) ++(ADDVconst [c] (SUBVconst [d] x)) && is32Bit(c-d) => (ADDVconst [c-d] x) ++(SUBVconst [c] (MOVVconst [d])) => (MOVVconst [d-c]) ++(SUBVconst [c] (SUBVconst [d] x)) && is32Bit(-c-d) => (ADDVconst [-c-d] x) ++(SUBVconst [c] (ADDVconst [d] x)) && is32Bit(-c+d) => (ADDVconst [-c+d] x) ++(SLLconst [c] (MOVVconst [d])) => (MOVVconst [int64(d)< (MOVVconst [int64(uint64(d)>>uint64(c))]) ++(SRAconst [c] (MOVVconst [d])) => (MOVVconst [int64(d)>>uint64(c)]) ++(ANDconst [c] (MOVVconst [d])) => (MOVVconst [c&d]) ++(ANDconst [c] (ANDconst [d] x)) => (ANDconst [c&d] x) ++(BISconst [c] (MOVVconst [d])) => (MOVVconst [c|d]) ++(BISconst [c] (BISconst [d] x)) && is32Bit(c|d) => (BISconst [c|d] x) ++(XORconst [c] (MOVVconst [d])) => (MOVVconst [c^d]) ++(XORconst [c] (XORconst [d] x)) && is32Bit(c^d) => (XORconst [c^d] x) ++(NEGV (MOVVconst [c])) => (MOVVconst [-c]) ++ ++// mul by specific constant ++//(MULLconst [c] x) && isPowerOfTwo64(c-1) && c>=3 => (ADDV (SLLconst x [log64(c-1)]) x) ++//(MULLconst [c] x) && isPowerOfTwo64(c+1) && c>=7 => (SUBV (SLLconst x [log64(c+1)]) x) ++//(MULLconst [c] x) && c%3 == 0 && isPowerOfTwo64(c/3) => (SLLconst (ADDV (SLLconst x [1]) x) [log64(c/3)]) ++//(MULLconst [c] x) && c%5 == 0 && isPowerOfTwo64(c/5) => (SLLconst (S4ADDV x x) [log64(c/5)]) ++//(MULLconst [c] x) && c%7 == 0 && isPowerOfTwo64(c/7) => (SLLconst (S8SUBV x x) [log64(c/7)]) ++//(MULLconst [c] x) && c%9 == 0 && isPowerOfTwo64(c/9) => (SLLconst (S8ADDV x x) [log64(c/9)]) ++ ++// fold offset into address ++(ADDVconst [off1] (SYMADDR [off2] {sym} ptr)) && is32Bit(off1+int64(off2)) => (SYMADDR [int32(off1)+off2] {sym} ptr) ++ ++(NE (XORconst cmp:(CMPEQ _ _) [1]) yes no) => (EQ cmp yes no) ++(EQ (XORconst cmp:(CMPEQ _ _) [1]) yes no) => (NE cmp yes no) ++(NE (XORconst cmp:(CMPEQconst _) [1]) yes no) => (EQ cmp yes no) ++(EQ (XORconst cmp:(CMPEQconst _) [1]) yes no) => (NE cmp yes no) ++ ++(NE (CMPEQconst x [0]) yes no) => (EQ x yes no) ++(EQ (CMPEQconst x [0]) yes no) => (NE x yes no) ++(NE (CMPLTconst x [0]) yes no) => (LT x yes no) ++(EQ (CMPLTconst x [0]) yes no) => (GE x yes no) ++(NE (CMPLEconst x [0]) yes no) => (LE x yes no) ++(EQ (CMPLEconst x [0]) yes no) => (GT x yes no) ++(NE (CMPLTconst x [1]) yes no) => (LE x yes no) ++(EQ (CMPLTconst x [1]) yes no) => (GT x yes no) ++(NE (CMPULTconst x [1]) yes no) => (EQ x yes no) ++(EQ (CMPULTconst x [1]) yes no) => (NE x yes no) ++(NE (CMPULEconst x [0]) yes no) => (EQ x yes no) ++(EQ (CMPULEconst x [0]) yes no) => (NE x yes no) ++ ++(NE (CMPEQ x (MOVVconst [0])) yes no) => (EQ x yes no) ++(EQ (CMPEQ x (MOVVconst [0])) yes no) => (NE x yes no) ++(NE (CMPLT x (MOVVconst [0])) yes no) => (LT x yes no) ++(EQ (CMPLT x (MOVVconst [0])) yes no) => (GE x yes no) ++(NE (CMPLT x (MOVVconst [1])) yes no) => (LE x yes no) ++(EQ (CMPLT x (MOVVconst [1])) yes no) => (GT x yes no) ++(NE (CMPLE x (MOVVconst [0])) yes no) => (LE x yes no) ++(EQ (CMPLE x (MOVVconst [0])) yes no) => (GT x yes no) ++(NE (CMPULT x (MOVVconst [1])) yes no) => (EQ x yes no) ++(EQ (CMPULT x (MOVVconst [1])) yes no) => (NE x yes no) ++(NE (CMPULE x (MOVVconst [0])) yes no) => (EQ x yes no) ++(EQ (CMPULE x (MOVVconst [0])) yes no) => (NE x yes no) ++(NE (CMPEQ (MOVVconst [0]) x) yes no) => (EQ x yes no) ++(EQ (CMPEQ (MOVVconst [0]) x) yes no) => (NE x yes no) ++(NE (CMPLT (MOVVconst [0]) x) yes no) => (GT x yes no) ++(EQ (CMPLT (MOVVconst [0]) x) yes no) => (LE x yes no) ++(NE (CMPLE (MOVVconst [0]) x) yes no) => (GE x yes no) ++(EQ (CMPLE (MOVVconst [0]) x) yes no) => (LT x yes no) ++(NE (CMPLE (MOVVconst [1]) x) yes no) => (GT x yes no) ++(EQ (CMPLE (MOVVconst [1]) x) yes no) => (LE x yes no) ++(NE (CMPULT (MOVVconst [0]) x) yes no) => (NE x yes no) ++(EQ (CMPULT (MOVVconst [0]) x) yes no) => (EQ x yes no) ++(NE (CMPULE (MOVVconst [1]) x) yes no) => (NE x yes no) ++(EQ (CMPULE (MOVVconst [1]) x) yes no) => (EQ x yes no) ++ ++(NE (FNotEqual cmp) yes no) => (FEQ cmp yes no) ++(NE (FEqual cmp) yes no) => (FNE cmp yes no) ++(EQ (FNotEqual cmp) yes no) => (FNE cmp yes no) ++(EQ (FEqual cmp) yes no) => (FEQ cmp yes no) ++ ++(JumpTable idx) => (JUMPTABLE {makeJumpTableSym(b)} idx (SYMADDR {makeJumpTableSym(b)} (SB))) ++ ++(PanicBounds [kind] x y mem) && boundsABI(kind) == 0 => (LoweredPanicBoundsA [kind] x y mem) ++(PanicBounds [kind] x y mem) && boundsABI(kind) == 1 => (LoweredPanicBoundsB [kind] x y mem) ++(PanicBounds [kind] x y mem) && boundsABI(kind) == 2 => (LoweredPanicBoundsC [kind] x y mem) ++ ++// rotates ++(RotateLeft8 x (MOVVconst [c])) => (Or8 (Lsh8x64 x (MOVVconst [c&7])) (Rsh8Ux64 x (MOVVconst [-c&7]))) ++(RotateLeft16 x (MOVVconst [c])) => (Or16 (Lsh16x64 x (MOVVconst [c&15])) (Rsh16Ux64 x (MOVVconst [-c&15]))) ++(RotateLeft32 x (MOVVconst [c])) => (Or32 (Lsh32x64 x (MOVVconst [c&31])) (Rsh32Ux64 x (MOVVconst [-c&31]))) ++(RotateLeft64 x (MOVVconst [c])) => (Or64 (Lsh64x64 x (MOVVconst [c&63])) (Rsh64Ux64 x (MOVVconst [-c&63]))) ++ ++// atomic intrinsics ++(AtomicLoad(8|32|64) ...) => (LoweredAtomicLoad(8|32|64) ...) ++(AtomicLoadPtr ...) => (LoweredAtomicLoad64 ...) ++ ++(AtomicStore(8|32|64) ...) => (LoweredAtomicStore(8|32|64) ...) ++(AtomicStorePtrNoWB ...) => (LoweredAtomicStore64 ...) ++ ++(AtomicExchange(32|64) ...) => (LoweredAtomicExchange(32|64) ...) ++ ++(AtomicAdd(32|64) ...) => (LoweredAtomicAdd(32|64) ...) ++ ++(AtomicCompareAndSwap32 ptr old new mem) => (LoweredAtomicCas32 ptr (SignExt32to64 old) new mem) ++(AtomicCompareAndSwap64 ...) => (LoweredAtomicCas64 ...) +diff --git a/src/cmd/compile/internal/ssa/_gen/SW64Ops.go b/src/cmd/compile/internal/ssa/_gen/SW64Ops.go +new file mode 100644 +index 0000000000..fa93636b2d +--- /dev/null ++++ b/src/cmd/compile/internal/ssa/_gen/SW64Ops.go +@@ -0,0 +1,519 @@ ++// 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 main ++ ++import "strings" ++ ++// Notes: ++// - Integer types live in the low portion of registers. Upper portions are junk. ++// - Boolean types use the low-order byte of a register. 0=false, 1=true. ++// Upper bytes are junk. ++// - *const instructions may use a constant larger than the instruction can encode. ++// In this case the assembler expands to multiple instructions and uses tmp ++// register (R28). ++ ++// Suffixes encode the bit width of various instructions. ++// V (vlong) = 64 bit ++// WU (word) = 32 bit unsigned ++// W (word) = 32 bit ++// H (half word) = 16 bit ++// HU = 16 bit unsigned ++// B (byte) = 8 bit ++// BU = 8 bit unsigned ++// F (float) = 32 bit float ++// D (double) = 64 bit float ++ ++// Note: registers not used in regalloc are not included in this list, ++// so that regmask stays within int64 ++// Be careful when hand coding regmasks. ++var regNamesSW64 = []string{ ++ "R0", ++ "R1", ++ "R2", ++ "R3", ++ "R4", ++ "R5", ++ "R6", ++ "R7", ++ "R8", ++ "R9", ++ "R10", ++ "R11", ++ "R12", ++ "R13", ++ "R14", ++ "g", //R15 ++ "R16", ++ "R17", ++ "R18", ++ "R19", ++ "R20", ++ "R21", ++ "R22", ++ "R23", ++ "R24", ++ "R25", //REGCTXT ++ "R26", //link register ++ //"R27", //PV ++ //"R28", REGTMP ++ //"R29", REGSB ++ "SP", //R30 ++ "R31", // REGZERO ++ ++ "F0", ++ "F1", ++ "F2", ++ "F3", ++ "F4", ++ "F5", ++ "F6", ++ "F7", ++ "F8", ++ "F9", ++ "F10", ++ "F11", ++ "F12", ++ "F13", ++ "F14", ++ "F15", ++ "F16", ++ "F17", ++ "F18", ++ "F19", ++ "F20", ++ "F21", ++ "F22", ++ "F23", ++ "F24", ++ "F25", ++ "F26", ++ "F27", ++ "F28", ++ "F29", ++ "F30", ++ "F31", ++ ++ // pseudo-registers ++ "SB", ++} ++ ++func init() { ++ // Make map from reg names to reg integers. ++ if len(regNamesSW64) > 64 { ++ panic("too many registers") ++ } ++ num := map[string]int{} ++ for i, name := range regNamesSW64 { ++ num[name] = i ++ } ++ buildReg := func(s string) regMask { ++ m := regMask(0) ++ for _, r := range strings.Split(s, " ") { ++ if n, ok := num[r]; ok { ++ m |= regMask(1) << uint(n) ++ continue ++ } ++ panic("register " + r + " not found") ++ } ++ return m ++ } ++ ++ // Common individual register masks ++ var ( ++ gp = buildReg("R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25") ++ gpg = gp | buildReg("g") ++ gpsp = gp | buildReg("SP") ++ gpspg = gpg | buildReg("SP") ++ gpspsbg = gpspg | buildReg("SB") ++ fp = buildReg("F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30") ++ fp_src = buildReg("F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20") ++ fp_dst = buildReg("F21 F22 F23 F24 F25 F26 F27 F28 F29 F30") ++ callerSave = gp | fp | buildReg("g") // runtime.setg (and anything calling it) may clobber g ++ ++ r1 = buildReg("R1") ++ r2 = buildReg("R2") ++ r3 = buildReg("R3") ++ r4 = buildReg("R4") ++ ) ++ // Common regInfo ++ var ( ++ gp01 = regInfo{inputs: nil, outputs: []regMask{gp}} ++ gp11 = regInfo{inputs: []regMask{gpg}, outputs: []regMask{gp}} ++ gp11sp = regInfo{inputs: []regMask{gpspg}, outputs: []regMask{gp}} ++ gp21 = regInfo{inputs: []regMask{gpg, gpg}, outputs: []regMask{gp}} ++ //gp2hilo = regInfo{inputs: []regMask{gpg, gpg}, outputs: []regMask{hi, lo}} ++ gpload = regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{gp}} ++ gpstore = regInfo{inputs: []regMask{gpspsbg, gpg}} ++ gpstore0 = regInfo{inputs: []regMask{gpspsbg}} ++ gpxchg = regInfo{inputs: []regMask{gpspsbg, gpg}, outputs: []regMask{gp}} ++ gpcas = regInfo{inputs: []regMask{gpspsbg, gpg, gpg}, outputs: []regMask{gp}} ++ fp01 = regInfo{inputs: nil, outputs: []regMask{fp}} ++ fp11 = regInfo{inputs: []regMask{fp}, outputs: []regMask{fp}} ++ ffp11 = regInfo{inputs: []regMask{fp_src}, outputs: []regMask{fp_dst}} ++ //fp1flags = regInfo{inputs: []regMask{fp}} ++ //fpgp = regInfo{inputs: []regMask{fp}, outputs: []regMask{gp}} ++ //gpfp = regInfo{inputs: []regMask{gp}, outputs: []regMask{fp}} ++ fp21 = regInfo{inputs: []regMask{fp, fp}, outputs: []regMask{fp}} ++ ffp21 = regInfo{inputs: []regMask{fp_src, fp_src}, outputs: []regMask{fp_dst}} ++ //fp31 = regInfo{inputs: []regMask{fp, fp, fp}, outputs: []regMask{fp}} ++ // fp2flags = regInfo{inputs: []regMask{fp, fp}} ++ fpload = regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{fp}} ++ fpstore = regInfo{inputs: []regMask{gpspsbg, fp}} ++ readflags = regInfo{inputs: []regMask{fp}, outputs: []regMask{gp}} ++ ifp11 = regInfo{inputs: []regMask{gp}, outputs: []regMask{fp}} ++ fip11 = regInfo{inputs: []regMask{fp}, outputs: []regMask{gp}} ++ ) ++ ops := []opData{ ++ // binary ops ++ {name: "ADDV", argLength: 2, reg: gp21, asm: "ADDL", commutative: true}, ++ {name: "ADDVconst", argLength: 1, reg: gp11sp, asm: "ADDL", aux: "Int64"}, ++ {name: "ADDW", argLength: 2, reg: gp21, asm: "ADDW", commutative: true}, ++ {name: "ADDWconst", argLength: 1, reg: gp11sp, asm: "ADDW", aux: "Int32"}, ++ {name: "S4ADDV", argLength: 2, reg: gp21, asm: "S4ADDL"}, ++ {name: "S8ADDV", argLength: 2, reg: gp21, asm: "S8ADDL"}, ++ {name: "SUBV", argLength: 2, reg: gp21, asm: "SUBL"}, ++ {name: "SUBVconst", argLength: 1, reg: gp11sp, asm: "SUBL", aux: "Int64"}, ++ {name: "S4SUBV", argLength: 2, reg: gp21, asm: "S4SUBL"}, ++ {name: "S8SUBV", argLength: 2, reg: gp21, asm: "S8SUBL"}, ++ {name: "DIVV", argLength: 2, reg: gp21, asm: "DIVL"}, ++ {name: "DIVVconst", argLength: 1, reg: gp11sp, asm: "DIVL", aux: "Int64"}, ++ {name: "UDIVV", argLength: 2, reg: gp21, asm: "UDIVL"}, ++ {name: "DIVW", argLength: 2, reg: gp21, asm: "DIVW"}, ++ {name: "UDIVW", argLength: 2, reg: gp21, asm: "UDIVW"}, ++ {name: "MULW", argLength: 2, reg: gp21, asm: "MULW", commutative: true}, ++ {name: "MULWconst", argLength: 1, reg: gp11sp, asm: "MULW", aux: "Int64"}, ++ {name: "MULL", argLength: 2, reg: gp21, asm: "MULL", commutative: true}, ++ {name: "MULLconst", argLength: 1, reg: gp11sp, asm: "MULL", aux: "Int64"}, ++ {name: "UMULH", argLength: 2, reg: gp21, asm: "UMULH", commutative: true}, ++ {name: "UMULHconst", argLength: 1, reg: gp11sp, asm: "UMULH", aux: "Int64"}, ++ // udiv runtime call for soft division ++ // output0 = arg0/arg1, output1 = arg0%arg1 ++ // see ../../../../../runtime/vlop_arm.s ++ { ++ name: "CALLudiv", ++ argLength: 2, ++ reg: regInfo{ ++ inputs: []regMask{buildReg("R1"), buildReg("R0")}, ++ outputs: []regMask{buildReg("R0"), buildReg("R1")}, ++ clobbers: buildReg("R2 R3 R4 R5 R26"), ++ }, ++ clobberFlags: true, ++ typ: "(UInt64,UInt64)", ++ call: false, ++ }, ++ ++ {name: "FADDD", argLength: 2, reg: ffp21, asm: "FADDD", commutative: true}, ++ {name: "FADDS", argLength: 2, reg: ffp21, asm: "FADDS", commutative: true}, ++ {name: "FSUBD", argLength: 2, reg: ffp21, asm: "FSUBD"}, ++ {name: "FSUBS", argLength: 2, reg: ffp21, asm: "FSUBS"}, ++ {name: "FMULD", argLength: 2, reg: ffp21, asm: "FMULD", commutative: true}, ++ {name: "FMULS", argLength: 2, reg: ffp21, asm: "FMULS", commutative: true}, ++ {name: "FDIVD", argLength: 2, reg: ffp21, asm: "FDIVD"}, ++ {name: "FDIVS", argLength: 2, reg: ffp21, asm: "FDIVS"}, ++ {name: "FCPYS", argLength: 2, reg: fp21, asm: "FCPYS"}, ++ {name: "FABS", argLength: 1, reg: fp11, asm: "FCPYS"}, ++ {name: "IFMOVD", argLength: 1, reg: ifp11, asm: "IFMOVD", typ: "Float64"}, ++ {name: "IFMOVS", argLength: 1, reg: ifp11, asm: "IFMOVS", typ: "Float32"}, ++ {name: "FIMOVD", argLength: 1, reg: fip11, asm: "FIMOVD", typ: "Int64"}, ++ {name: "FIMOVS", argLength: 1, reg: fip11, asm: "FIMOVS", typ: "Int32"}, ++ {name: "FCVTSD", argLength: 1, reg: ffp11, asm: "FCVTSD", typ: "Float64"}, ++ {name: "FCVTDS", argLength: 1, reg: ffp11, asm: "FCVTDS"}, ++ {name: "FCVTDL", argLength: 1, reg: fp11, asm: "FCVTDL"}, ++ {name: "FCVTLS", argLength: 1, reg: fp11, asm: "FCVTLS"}, ++ {name: "FCVTLD", argLength: 1, reg: fp11, asm: "FCVTLD"}, ++ {name: "FCVTLW", argLength: 1, reg: fp11, asm: "FCVTLW", typ: "Float32"}, ++ {name: "FCVTWL", argLength: 1, reg: fp11, asm: "FCVTWL", typ: "Float64"}, ++ ++ {name: "FSQRTS", argLength: 1, reg: fp11, asm: "FSQRTS"}, ++ {name: "FSQRTD", argLength: 1, reg: ffp11, asm: "FSQRTD"}, ++ {name: "FCVTDL_Z", argLength: 1, reg: fp11, typ: "Float64", asm: "FCVTDL_Z", resultNotInArgs: true}, ++ {name: "FCVTDL_P", argLength: 1, reg: fp11, asm: "FCVTDL_P", resultNotInArgs: true}, ++ {name: "FCVTDL_G", argLength: 1, reg: fp11, asm: "FCVTDL_G", resultNotInArgs: true}, ++ {name: "FCVTDL_N", argLength: 1, reg: fp11, asm: "FCVTDL_N", resultNotInArgs: true}, ++ ++ {name: "AND", argLength: 2, reg: gp21, asm: "AND", commutative: true}, ++ {name: "ANDconst", argLength: 1, reg: gp11, asm: "AND", aux: "Int64"}, ++ {name: "BIS", argLength: 2, reg: gp21, asm: "BIS", commutative: true}, ++ {name: "BISconst", argLength: 1, reg: gp11, asm: "BIS", aux: "Int64"}, ++ {name: "XOR", argLength: 2, reg: gp21, asm: "XOR", commutative: true}, ++ {name: "XORconst", argLength: 1, reg: gp11, asm: "XOR", aux: "Int64"}, ++ ++ {name: "ZAPNOTconst", argLength: 1, reg: gp11sp, asm: "ZAPNOT", aux: "Int64"}, ++ ++ {name: "ORNOT", argLength: 2, reg: gp21, asm: "ORNOT"}, ++ {name: "ORNOTconst", argLength: 1, reg: gp11, asm: "ORNOT", aux: "Int64"}, ++ {name: "NEGV", argLength: 1, reg: gp11, asm: "SUBL"}, // -arg0 ++ {name: "NEGF", argLength: 1, reg: fp11, asm: "FCPYSN"}, // -arg0, float32 ++ {name: "NEGD", argLength: 1, reg: fp11, asm: "FCPYSN"}, // -arg0, float64 ++ ++ // shifts ++ {name: "SLL", argLength: 2, reg: gp21, asm: "SLL"}, // arg0 << arg1, shift amount is mod 64 ++ {name: "SLLconst", argLength: 1, reg: gp11, asm: "SLL", aux: "Int64"}, // arg0 << auxInt ++ {name: "SRL", argLength: 2, reg: gp21, asm: "SRL"}, // arg0 >> arg1, unsigned, shift amount is mod 64 ++ {name: "SRLconst", argLength: 1, reg: gp11, asm: "SRL", typ: "UInt64", aux: "Int64"}, // arg0 >> auxInt, unsigned ++ {name: "SRA", argLength: 2, reg: gp21, asm: "SRA"}, // arg0 >> arg1, signed, shift amount is mod 64 ++ {name: "SRAconst", argLength: 1, reg: gp11, asm: "SRA", aux: "Int64"}, // arg0 >> auxInt, signed ++ ++ {name: "CTTZ", argLength: 1, reg: gp11, asm: "CTTZ", typ: "UInt64"}, ++ {name: "CTLZ", argLength: 1, reg: gp11, asm: "CTLZ"}, ++ {name: "CTPOP", argLength: 1, reg: gp11, asm: "CTPOP"}, ++ {name: "SEXTB", argLength: 1, reg: gp11, asm: "SEXTB"}, ++ {name: "SEXTBconst", argLength: 0, reg: gp01, aux: "Int64", asm: "SEXTB"}, ++ {name: "SEXTH", argLength: 1, reg: gp11, asm: "SEXTH"}, ++ {name: "SEXTHconst", argLength: 0, reg: gp01, aux: "Int64", asm: "SEXTH"}, ++ ++ // arg0 + auxInt + aux.(*gc.Sym), arg0=SP/SB ++ {name: "SYMADDR", argLength: 1, reg: regInfo{inputs: []regMask{buildReg("SP") | buildReg("SB")}, outputs: []regMask{gp}}, aux: "SymOff", asm: "SYMADDR", rematerializeable: true, symEffect: "Addr"}, ++ ++ {name: "MOVVconst", argLength: 0, reg: gp01, aux: "Int64", asm: "LDI", typ: "UInt64", rematerializeable: true}, // auxint ++ {name: "MOVFconst", argLength: 0, reg: fp01, aux: "Float64", asm: "LDF", typ: "Float32", rematerializeable: true}, // auxint as 32-bit float ++ {name: "MOVDconst", argLength: 0, reg: fp01, aux: "Float64", asm: "LDI", typ: "Float64", rematerializeable: true}, // auxint as 64-bit float ++ ++ {name: "MOVBstorezero", argLength: 2, reg: gpstore0, asm: "STB", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store zero byte to arg0+aux. arg1=mem ++ {name: "MOVHstorezero", argLength: 2, reg: gpstore0, asm: "STH", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store zero 2 bytes to ... ++ {name: "MOVWstorezero", argLength: 2, reg: gpstore0, asm: "STW", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store zero 4 bytes to ... ++ {name: "MOVVstorezero", argLength: 2, reg: gpstore0, asm: "STL", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store zero 8 bytes to ... ++ ++ {name: "MOVBload", argLength: 2, reg: gpload, aux: "SymOff", asm: "LDBU", typ: "Int8", faultOnNilArg0: true, symEffect: "Read"}, // load from arg0 + auxInt + aux. arg1=mem. ++ {name: "MOVBUload", argLength: 2, reg: gpload, aux: "SymOff", asm: "LDBU", typ: "UInt8", faultOnNilArg0: true, symEffect: "Read"}, // load from arg0 + auxInt + aux. arg1=mem. ++ {name: "MOVHload", argLength: 2, reg: gpload, aux: "SymOff", asm: "LDHU", typ: "Int16", faultOnNilArg0: true, symEffect: "Read"}, // load from arg0 + auxInt + aux. arg1=mem. ++ {name: "MOVHUload", argLength: 2, reg: gpload, aux: "SymOff", asm: "LDHU", typ: "UInt16", faultOnNilArg0: true, symEffect: "Read"}, // load from arg0 + auxInt + aux. arg1=mem. ++ {name: "MOVWload", argLength: 2, reg: gpload, aux: "SymOff", asm: "LDW", typ: "Int32", faultOnNilArg0: true, symEffect: "Read"}, // load from arg0 + auxInt + aux. arg1=mem. ++ {name: "MOVWUload", argLength: 2, reg: gpload, aux: "SymOff", asm: "LDW", typ: "UInt32", faultOnNilArg0: true, symEffect: "Read"}, // load from arg0 + auxInt + aux. arg1=mem. ++ {name: "MOVVload", argLength: 2, reg: gpload, aux: "SymOff", asm: "LDL", typ: "UInt64", faultOnNilArg0: true, symEffect: "Read"}, // load from arg0 + auxInt + aux. arg1=mem. ++ {name: "MOVFload", argLength: 2, reg: fpload, aux: "SymOff", asm: "FLDS", typ: "Float32", faultOnNilArg0: true, symEffect: "Read"}, // load from arg0 + auxInt + aux. arg1=mem. ++ {name: "MOVDload", argLength: 2, reg: fpload, aux: "SymOff", asm: "FLDD", typ: "Float64", faultOnNilArg0: true, symEffect: "Read"}, // load from arg0 + auxInt + aux. arg1=mem. ++ ++ {name: "MOVBstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "STB", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 1 byte of arg1 to arg0 + auxInt + aux. arg2=mem. ++ {name: "MOVHstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "STH", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 2 bytes of arg1 to arg0 + auxInt + aux. arg2=mem. ++ {name: "MOVWstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "STW", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 4 bytes of arg1 to arg0 + auxInt + aux. arg2=mem. ++ {name: "MOVVstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "STL", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 8 bytes of arg1 to arg0 + auxInt + aux. arg2=mem. ++ {name: "MOVFstore", argLength: 3, reg: fpstore, aux: "SymOff", asm: "FSTS", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 4 bytes of arg1 to arg0 + auxInt + aux. arg2=mem. ++ {name: "MOVDstore", argLength: 3, reg: fpstore, aux: "SymOff", asm: "FSTD", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 8 bytes of arg1 to arg0 + auxInt + aux. arg2=mem. ++ ++ {name: "MOVBreg", argLength: 1, reg: gp11, asm: "MOVB"}, // move from arg0, sign-extended from byte ++ {name: "MOVBUreg", argLength: 1, reg: gp11, asm: "MOVBU"}, // move from arg0, unsign-extended from byte ++ {name: "MOVHreg", argLength: 1, reg: gp11, asm: "MOVH"}, // move from arg0, sign-extended from half ++ {name: "MOVHUreg", argLength: 1, reg: gp11, asm: "MOVHU"}, // move from arg0, unsign-extended from half ++ {name: "MOVWreg", argLength: 1, reg: gp11, asm: "MOVW"}, // move from arg0, sign-extended from word ++ {name: "MOVWUreg", argLength: 1, reg: gp11, asm: "MOVWU"}, // move from arg0, unsign-extended from word ++ {name: "MOVVreg", argLength: 1, reg: gp11, asm: "MOVV"}, // move from arg0 ++ ++ {name: "MOVVnop", argLength: 1, reg: regInfo{inputs: []regMask{gp}, outputs: []regMask{gp}}, resultInArg0: true}, // nop, return arg0 in same register ++ ++ {name: "CMPULE", argLength: 2, reg: gp21, asm: "CMPULE", typ: "Bool"}, // 1 if arg ++ {name: "CMPULEconst", argLength: 1, typ: "Bool", reg: gp11, asm: "CMPULE", aux: "Int64"}, ++ {name: "CMPULT", argLength: 2, reg: gp21, asm: "CMPULT", typ: "Bool"}, // 1 if arg ++ {name: "CMPULTconst", argLength: 1, typ: "Bool", reg: gp11, asm: "CMPULT", aux: "Int64"}, ++ {name: "CMPLE", argLength: 2, reg: gp21, asm: "CMPLE", typ: "Bool"}, // 1 if arg ++ {name: "CMPLEconst", argLength: 1, typ: "Bool", reg: gp11, asm: "CMPLE", aux: "Int64"}, ++ {name: "CMPLT", argLength: 2, reg: gp21, asm: "CMPLT", typ: "Bool"}, // 1 if arg ++ {name: "CMPLTconst", argLength: 1, typ: "Bool", reg: gp11, asm: "CMPLT", aux: "Int64"}, ++ {name: "CMPEQ", argLength: 2, reg: gp21, asm: "CMPEQ", typ: "Bool"}, ++ {name: "CMPEQconst", argLength: 1, typ: "Bool", reg: gp11, asm: "CMPEQ", aux: "Int64"}, ++ ++ {name: "FCMPLE", argLength: 2, reg: ffp21, asm: "FCMPLE", typ: "Float64"}, // 1 if arg ++ {name: "FCMPLT", argLength: 2, reg: ffp21, asm: "FCMPLT", typ: "Float64"}, // 1 if arg ++ {name: "FCMPEQ", argLength: 2, reg: ffp21, asm: "FCMPEQ", typ: "Float64"}, ++ {name: "FCMPUN", argLength: 2, reg: ffp21, asm: "FCMPUN", typ: "Float64"}, ++ ++ {name: "CALLstatic", argLength: -1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call static function aux.(*obj.LSym). last arg=mem, auxint=argsize, returns mem ++ {name: "CALLtail", argLength: -1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true, tailCall: true}, // tail call static function aux.(*obj.LSym). last arg=mem, auxint=argsize, returns mem ++ {name: "CALLclosure", argLength: -1, reg: regInfo{inputs: []regMask{gpsp, buildReg("R25"), 0}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},// call function via closure. arg0=codeptr, arg1=closure, last arg=mem, auxint=argsize, returns mem ++ {name: "CALLinter", argLength: -1, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call fn by pointer. arg0=codeptr, last arg=mem, auxint=argsize, returns mem ++ ++ // duffzero ++ { ++ name: "DUFFZERO", ++ aux: "Int64", ++ argLength: 2, ++ reg: regInfo{ ++ inputs: []regMask{gp}, ++ clobbers: buildReg("R1"), ++ }, ++ faultOnNilArg0: true, ++ }, ++ ++ //LoweredZero ++ { ++ name: "LoweredZero", ++ aux: "Int64", ++ argLength: 3, ++ reg: regInfo{ ++ inputs: []regMask{buildReg("R1"), gp}, ++ clobbers: buildReg("R1"), ++ }, ++ clobberFlags: true, ++ faultOnNilArg0: true, ++ }, ++ ++ //LoweredMove ++ { ++ name: "LoweredMove", ++ aux: "Int64", ++ argLength: 4, ++ reg: regInfo{ ++ inputs: []regMask{buildReg("R2"), buildReg("R1"), gp}, ++ clobbers: buildReg("R1 R2"), ++ }, ++ clobberFlags: true, ++ faultOnNilArg0: true, ++ faultOnNilArg1: true, ++ }, ++ ++ // pseudo-ops ++ {name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gpg}}, nilCheck: true, faultOnNilArg0: true}, // panic if arg0 is nil. arg1=mem. ++ ++ // Scheduler ensures LoweredGetClosurePtr occurs only in entry block, ++ // and sorts it to the very beginning of the block to prevent other ++ // use of R25 (sw64.REGCTXT, the closure pointer) ++ {name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("R25")}}, zeroWidth: true}, ++ ++ // LoweredGetCallerSP returns the SP of the caller of the current function. arg0=mem ++ {name: "LoweredGetCallerSP", argLength: 1, reg: gp01, rematerializeable: true}, ++ ++ // LoweredGetCallerPC evaluates to the PC to which its "caller" will return. ++ // I.e., if f calls g "calls" getcallerpc, ++ // the result should be the PC within f that g will return to. ++ // See runtime/stubs.go for a more detailed discussion. ++ {name: "LoweredGetCallerPC", reg: gp01, rematerializeable: true}, ++ ++ // MOVDconvert converts between pointers and integers. ++ // We have a special op for this so as to not confuse GC ++ // (particularly stack maps). It takes a memory arg so it ++ // gets correctly ordered with respect to GC safepoints. ++ // arg0=ptr/int arg1=mem, output=int/ptr ++ {name: "MOVVconvert", argLength: 2, reg: gp11, asm: "LDI"}, ++ ++// {name: "Equal", argLength: 1, reg: readflags}, // bool, true flags encode x==y false otherwise. ++// {name: "NotEqual", argLength: 1, reg: readflags}, // bool, true flags encode x!=y false otherwise. ++// {name: "LessThan", argLength: 1, reg: readflags}, // bool, true flags encode signed xy false otherwise. ++// {name: "GreaterEqual", argLength: 1, reg: readflags}, // bool, true flags encode signed x>=y false otherwise. ++// {name: "FLessThan", argLength: 1, reg: readflags}, // bool, true flags encode floating-point xy false otherwise. ++// {name: "FGreaterEqual", argLength: 1, reg: readflags}, // bool, true flags encode floating-point x>=y false otherwise. ++ {name: "FEqual", argLength: 1, reg: readflags}, ++ {name: "FNotEqual", argLength: 1, reg: readflags}, ++ ++ // LoweredWB invokes runtime.gcWriteBarrier. arg0=mem, auxint=# of buffer entries needed ++ // It saves all GP registers if necessary, ++ // but clobbers R26 (LR) because it's a call ++ // and R28 (REGTMP). ++ {name: "LoweredWB", argLength: 1, reg: regInfo{clobbers: (callerSave &^ gpg) | buildReg("R26"), outputs: []regMask{buildReg("R14")}}, clobberFlags: true, aux: "Int64"}, ++ ++ // There are three of these functions so that they can have three different register inputs. ++ // When we check 0 <= c <= cap (A), then 0 <= b <= c (B), then 0 <= a <= b (C), we want the ++ // default registers to match so we don't need to copy registers around unnecessarily. ++ {name: "LoweredPanicBoundsA", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r3, r4}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go). ++ {name: "LoweredPanicBoundsB", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r2, r3}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go). ++ {name: "LoweredPanicBoundsC", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r1, r2}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go). ++ ++ // atomic loads. ++ // load from arg0. arg1=mem. ++ // returns so they can be properly ordered with other loads. ++ {name: "LoweredAtomicLoad8", argLength: 2, reg: gpload, faultOnNilArg0: true}, ++ {name: "LoweredAtomicLoad32", argLength: 2, reg: gpload, faultOnNilArg0: true}, ++ {name: "LoweredAtomicLoad64", argLength: 2, reg: gpload, faultOnNilArg0: true}, ++ ++ // atomic stores. ++ // store arg1 to arg0. arg2=mem. returns memory. ++ {name: "LoweredAtomicStore8", argLength: 3, reg: gpstore, faultOnNilArg0: true, hasSideEffects: true}, ++ {name: "LoweredAtomicStore32", argLength: 3, reg: gpstore, faultOnNilArg0: true, hasSideEffects: true}, ++ {name: "LoweredAtomicStore64", argLength: 3, reg: gpstore, faultOnNilArg0: true, hasSideEffects: true}, ++ ++ // atomic exchange. ++ // store arg1 to arg0. arg2=mem. returns . ++ // MEMB ++ // LLDx Rout, (Rarg0) ++ // LDI Rtmp, 1 ++ // WR_F Rtmp ++ // BIS Rarg1, R31, Rtmp ++ // LSTx Rtmp, (Rarg0) ++ // RD_F Rtmp ++ // BEQ Rtmp, -6(PC) ++ // MEMB ++ {name: "LoweredAtomicExchange32", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true}, ++ {name: "LoweredAtomicExchange64", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true}, ++ ++ // atomic add. ++ // *arg0 += arg1. arg2=mem. returns . ++ // MEMB ++ // LLDx Rout, (Rarg0) ++ // LDI Rtmp, 1 ++ // WR_F Rtmp ++ // ADDL Rarg1, Rout, Rtmp ++ // LSTx Rtmp, (Rarg0) ++ // RD_F Rtmp ++ // BEQ Rtmp, -6(PC) ++ // ADDL Rarg1, Rout, Rout ++ // MEMB ++ {name: "LoweredAtomicAdd32", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true}, ++ {name: "LoweredAtomicAdd64", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true}, ++ ++ // atomic compare and swap. ++ // arg0 = pointer, arg1 = old value, arg2 = new value, arg3 = memory. ++ // if *arg0 == arg1 { ++ // *arg0 = arg2 ++ // return (true, memory) ++ // } else { ++ // return (false, memory) ++ // } ++ // MEMB ++ // LLDx Rout, (Rarg0) ++ // CMPEQ Rout, Rarg1, Rout ++ // WR_F Rout ++ // BIS Rarg2, R31, Rtmp ++ // LSTx Rtmp, (Rarg0) ++ // RD_F Rtmp ++ // BEQ Rout, 2(PC) ++ // BEQ Rtmp, -7(PC) ++ // MEMB ++ {name: "LoweredAtomicCas32", argLength: 4, reg: gpcas, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true}, ++ {name: "LoweredAtomicCas64", argLength: 4, reg: gpcas, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true}, ++ } ++ ++ blocks := []blockData{ ++ {name: "NE", controls: 1}, ++ {name: "EQ", controls: 1}, ++ {name: "LT", controls: 1}, ++ {name: "LE", controls: 1}, ++ {name: "GT", controls: 1}, ++ {name: "GE", controls: 1}, ++ {name: "FNE", controls: 1}, ++ {name: "FEQ", controls: 1}, ++ {name: "FLE", controls: 1}, ++ {name: "FLT", controls: 1}, ++ {name: "FGE", controls: 1}, ++ {name: "FGT", controls: 1}, ++ {name: "LBC", controls: 1}, ++ {name: "LBS", controls: 1}, ++ // JUMPTABLE implements jump tables. ++ // Aux is the symbol (an *obj.LSym) for the jump table. ++ // control[0] is the index into the jump table. ++ // control[1] is the address of the jump table (the address of the symbol stored in Aux). ++ {name: "JUMPTABLE", controls: 2, aux: "Sym"}, ++ ++ } ++ ++ archs = append(archs, arch{ ++ name: "SW64", ++ pkg: "cmd/internal/obj/sw64", ++ genfile: "../../sw64/ssa.go", ++ ops: ops, ++ blocks: blocks, ++ regnames: regNamesSW64, ++ gpregmask: gp, ++ fpregmask: fp, ++ // Integer parameters passed in register R16-R24 ++ ParamIntRegNames: "R16 R17 R18 R19 R20 R21 R22 R23 R24", ++ // Float parameters passed in register F16-F24 ++ ParamFloatRegNames: "F16 F17 F18 F19 F20 F21 F22 F23 F24", ++ framepointerreg: -1, // not used ++ linkreg: int8(num["R26"]), ++ }) ++} +diff --git a/src/cmd/compile/internal/ssa/config.go b/src/cmd/compile/internal/ssa/config.go +index d674cca009..99878d9f8d 100644 +--- a/src/cmd/compile/internal/ssa/config.go ++++ b/src/cmd/compile/internal/ssa/config.go +@@ -351,6 +351,21 @@ func NewConfig(arch string, types Types, ctxt *obj.Link, optimize, softfloat boo + c.noDuffDevice = true + c.useAvg = false + c.useHmul = false ++ case "sw64": ++ c.PtrSize = 8 ++ c.RegSize = 8 ++ c.lowerBlock = rewriteBlockSW64 ++ c.lowerValue = rewriteValueSW64 ++ c.registers = registersSW64[:] ++ c.gpRegMask = gpRegMaskSW64 ++ c.fpRegMask = fpRegMaskSW64 ++ c.intParamRegs = paramIntRegSW64 ++ c.floatParamRegs = paramFloatRegSW64 ++ c.FPReg = framepointerRegSW64 ++ c.LinkReg = linkRegSW64 ++ c.hasGReg = true ++ c.noDuffDevice = true ++ c.BigEndian = false + default: + ctxt.Diag("arch %s not implemented", arch) + } +diff --git a/src/cmd/compile/internal/ssa/debug_lines_test.go b/src/cmd/compile/internal/ssa/debug_lines_test.go +index 857cce785f..cfb439dddd 100644 +--- a/src/cmd/compile/internal/ssa/debug_lines_test.go ++++ b/src/cmd/compile/internal/ssa/debug_lines_test.go +@@ -45,7 +45,7 @@ func testGoArch() string { + + func hasRegisterABI() bool { + switch testGoArch() { +- case "amd64", "arm64", "loong64", "ppc64", "ppc64le", "riscv": ++ case "amd64", "arm64", "loong64", "ppc64", "ppc64le", "riscv", "sw64": + return true + } + return false +diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go +index df1ddfa69e..aacea63fe3 100644 +--- a/src/cmd/compile/internal/ssa/opGen.go ++++ b/src/cmd/compile/internal/ssa/opGen.go +@@ -11,6 +11,7 @@ import ( + "cmd/internal/obj/ppc64" + "cmd/internal/obj/riscv" + "cmd/internal/obj/s390x" ++ "cmd/internal/obj/sw64" + "cmd/internal/obj/wasm" + "cmd/internal/obj/x86" + ) +@@ -161,6 +162,22 @@ const ( + BlockS390XCLIJ + BlockS390XCLGIJ + ++ BlockSW64NE ++ BlockSW64EQ ++ BlockSW64LT ++ BlockSW64LE ++ BlockSW64GT ++ BlockSW64GE ++ BlockSW64FNE ++ BlockSW64FEQ ++ BlockSW64FLE ++ BlockSW64FLT ++ BlockSW64FGE ++ BlockSW64FGT ++ BlockSW64LBC ++ BlockSW64LBS ++ BlockSW64JUMPTABLE ++ + BlockPlain + BlockIf + BlockDefer +@@ -317,6 +334,22 @@ var blockString = [...]string{ + BlockS390XCLIJ: "CLIJ", + BlockS390XCLGIJ: "CLGIJ", + ++ BlockSW64NE: "NE", ++ BlockSW64EQ: "EQ", ++ BlockSW64LT: "LT", ++ BlockSW64LE: "LE", ++ BlockSW64GT: "GT", ++ BlockSW64GE: "GE", ++ BlockSW64FNE: "FNE", ++ BlockSW64FEQ: "FEQ", ++ BlockSW64FLE: "FLE", ++ BlockSW64FLT: "FLT", ++ BlockSW64FGE: "FGE", ++ BlockSW64FGT: "FGT", ++ BlockSW64LBC: "LBC", ++ BlockSW64LBS: "LBS", ++ BlockSW64JUMPTABLE: "JUMPTABLE", ++ + BlockPlain: "Plain", + BlockIf: "If", + BlockDefer: "Defer", +@@ -2854,6 +2887,156 @@ const ( + OpS390XLoweredMove + OpS390XLoweredZero + ++ OpSW64ADDV ++ OpSW64ADDVconst ++ OpSW64ADDW ++ OpSW64ADDWconst ++ OpSW64S4ADDV ++ OpSW64S8ADDV ++ OpSW64SUBV ++ OpSW64SUBVconst ++ OpSW64S4SUBV ++ OpSW64S8SUBV ++ OpSW64DIVV ++ OpSW64DIVVconst ++ OpSW64UDIVV ++ OpSW64DIVW ++ OpSW64UDIVW ++ OpSW64MULW ++ OpSW64MULWconst ++ OpSW64MULL ++ OpSW64MULLconst ++ OpSW64UMULH ++ OpSW64UMULHconst ++ OpSW64CALLudiv ++ OpSW64FADDD ++ OpSW64FADDS ++ OpSW64FSUBD ++ OpSW64FSUBS ++ OpSW64FMULD ++ OpSW64FMULS ++ OpSW64FDIVD ++ OpSW64FDIVS ++ OpSW64FCPYS ++ OpSW64FABS ++ OpSW64IFMOVD ++ OpSW64IFMOVS ++ OpSW64FIMOVD ++ OpSW64FIMOVS ++ OpSW64FCVTSD ++ OpSW64FCVTDS ++ OpSW64FCVTDL ++ OpSW64FCVTLS ++ OpSW64FCVTLD ++ OpSW64FCVTLW ++ OpSW64FCVTWL ++ OpSW64FSQRTS ++ OpSW64FSQRTD ++ OpSW64FCVTDL_Z ++ OpSW64FCVTDL_P ++ OpSW64FCVTDL_G ++ OpSW64FCVTDL_N ++ OpSW64AND ++ OpSW64ANDconst ++ OpSW64BIS ++ OpSW64BISconst ++ OpSW64XOR ++ OpSW64XORconst ++ OpSW64ZAPNOTconst ++ OpSW64ORNOT ++ OpSW64ORNOTconst ++ OpSW64NEGV ++ OpSW64NEGF ++ OpSW64NEGD ++ OpSW64SLL ++ OpSW64SLLconst ++ OpSW64SRL ++ OpSW64SRLconst ++ OpSW64SRA ++ OpSW64SRAconst ++ OpSW64CTTZ ++ OpSW64CTLZ ++ OpSW64CTPOP ++ OpSW64SEXTB ++ OpSW64SEXTBconst ++ OpSW64SEXTH ++ OpSW64SEXTHconst ++ OpSW64SYMADDR ++ OpSW64MOVVconst ++ OpSW64MOVFconst ++ OpSW64MOVDconst ++ OpSW64MOVBstorezero ++ OpSW64MOVHstorezero ++ OpSW64MOVWstorezero ++ OpSW64MOVVstorezero ++ OpSW64MOVBload ++ OpSW64MOVBUload ++ OpSW64MOVHload ++ OpSW64MOVHUload ++ OpSW64MOVWload ++ OpSW64MOVWUload ++ OpSW64MOVVload ++ OpSW64MOVFload ++ OpSW64MOVDload ++ OpSW64MOVBstore ++ OpSW64MOVHstore ++ OpSW64MOVWstore ++ OpSW64MOVVstore ++ OpSW64MOVFstore ++ OpSW64MOVDstore ++ OpSW64MOVBreg ++ OpSW64MOVBUreg ++ OpSW64MOVHreg ++ OpSW64MOVHUreg ++ OpSW64MOVWreg ++ OpSW64MOVWUreg ++ OpSW64MOVVreg ++ OpSW64MOVVnop ++ OpSW64CMPULE ++ OpSW64CMPULEconst ++ OpSW64CMPULT ++ OpSW64CMPULTconst ++ OpSW64CMPLE ++ OpSW64CMPLEconst ++ OpSW64CMPLT ++ OpSW64CMPLTconst ++ OpSW64CMPEQ ++ OpSW64CMPEQconst ++ OpSW64FCMPLE ++ OpSW64FCMPLT ++ OpSW64FCMPEQ ++ OpSW64FCMPUN ++ OpSW64CALLstatic ++ OpSW64CALLtail ++ OpSW64CALLclosure ++ OpSW64CALLinter ++ OpSW64DUFFZERO ++ OpSW64LoweredZero ++ OpSW64LoweredMove ++ OpSW64LoweredNilCheck ++ OpSW64LoweredGetClosurePtr ++ OpSW64LoweredGetCallerSP ++ OpSW64LoweredGetCallerPC ++ OpSW64MOVVconvert ++ OpSW64FEqual ++ OpSW64FNotEqual ++ OpSW64LoweredWB ++ OpSW64LoweredPanicBoundsA ++ OpSW64LoweredPanicBoundsB ++ OpSW64LoweredPanicBoundsC ++ OpSW64LoweredAtomicLoad8 ++ OpSW64LoweredAtomicLoad32 ++ OpSW64LoweredAtomicLoad64 ++ OpSW64LoweredAtomicStore8 ++ OpSW64LoweredAtomicStore32 ++ OpSW64LoweredAtomicStore64 ++ OpSW64LoweredAtomicExchange32 ++ OpSW64LoweredAtomicExchange64 ++ OpSW64LoweredAtomicAdd32 ++ OpSW64LoweredAtomicAdd64 ++ OpSW64LoweredAtomicCas32 ++ OpSW64LoweredAtomicCas64 ++ + OpWasmLoweredStaticCall + OpWasmLoweredTailCall + OpWasmLoweredClosureCall +@@ -38673,821 +38856,2871 @@ var opcodeTable = [...]opInfo{ + }, + + { +- name: "LoweredStaticCall", +- auxType: auxCallOff, +- argLen: 1, +- call: true, ++ name: "ADDV", ++ argLen: 2, ++ commutative: true, ++ asm: sw64.AADDL, + reg: regInfo{ +- clobbers: 844424930131967, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 g ++ inputs: []inputInfo{ ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ {1, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, + }, + }, + { +- name: "LoweredTailCall", +- auxType: auxCallOff, +- argLen: 1, +- call: true, +- tailCall: true, ++ name: "ADDVconst", ++ auxType: auxInt64, ++ argLen: 1, ++ asm: sw64.AADDL, + reg: regInfo{ +- clobbers: 844424930131967, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 g ++ inputs: []inputInfo{ ++ {0, 201326591}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 SP ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, + }, + }, + { +- name: "LoweredClosureCall", +- auxType: auxCallOff, +- argLen: 3, +- call: true, ++ name: "ADDW", ++ argLen: 2, ++ commutative: true, ++ asm: sw64.AADDW, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 +- {1, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ {1, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, +- clobbers: 844424930131967, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 g + }, + }, + { +- name: "LoweredInterCall", +- auxType: auxCallOff, +- argLen: 2, +- call: true, ++ name: "ADDWconst", ++ auxType: auxInt32, ++ argLen: 1, ++ asm: sw64.AADDW, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 201326591}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 SP ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, +- clobbers: 844424930131967, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 g + }, + }, + { +- name: "LoweredAddr", +- auxType: auxSymOff, +- argLen: 1, +- rematerializeable: true, +- symEffect: SymAddr, ++ name: "S4ADDV", ++ argLen: 2, ++ asm: sw64.AS4ADDL, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ {1, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + }, + }, + { +- name: "LoweredMove", +- auxType: auxInt64, +- argLen: 3, ++ name: "S8ADDV", ++ argLen: 2, ++ asm: sw64.AS8ADDL, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 +- {1, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ {1, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + }, + }, + { +- name: "LoweredZero", +- auxType: auxInt64, +- argLen: 2, ++ name: "SUBV", ++ argLen: 2, ++ asm: sw64.ASUBL, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ {1, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + }, + }, + { +- name: "LoweredGetClosurePtr", +- argLen: 0, ++ name: "SUBVconst", ++ auxType: auxInt64, ++ argLen: 1, ++ asm: sw64.ASUBL, + reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 201326591}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 SP ++ }, + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + }, + }, + { +- name: "LoweredGetCallerPC", +- argLen: 0, +- rematerializeable: true, ++ name: "S4SUBV", ++ argLen: 2, ++ asm: sw64.AS4SUBL, + reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ {1, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + }, + }, + { +- name: "LoweredGetCallerSP", +- argLen: 1, +- rematerializeable: true, ++ name: "S8SUBV", ++ argLen: 2, ++ asm: sw64.AS8SUBL, + reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ {1, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + }, + }, + { +- name: "LoweredNilCheck", +- argLen: 2, +- nilCheck: true, +- faultOnNilArg0: true, ++ name: "DIVV", ++ argLen: 2, ++ asm: sw64.ADIVL, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ {1, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + }, + }, + { +- name: "LoweredWB", ++ name: "DIVVconst", + auxType: auxInt64, + argLen: 1, ++ asm: sw64.ADIVL, + reg: regInfo{ +- clobbers: 844424930131967, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 g ++ inputs: []inputInfo{ ++ {0, 201326591}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 SP ++ }, + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + }, + }, + { +- name: "LoweredConvert", ++ name: "UDIVV", + argLen: 2, ++ asm: sw64.AUDIVL, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ {1, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + }, + }, + { +- name: "Select", +- argLen: 3, +- asm: wasm.ASelect, ++ name: "DIVW", ++ argLen: 2, ++ asm: sw64.ADIVW, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP +- {1, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP +- {2, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ {1, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + }, + }, + { +- name: "I64Load8U", +- auxType: auxInt64, +- argLen: 2, +- asm: wasm.AI64Load8U, ++ name: "UDIVW", ++ argLen: 2, ++ asm: sw64.AUDIVW, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1407374883618815}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP SB ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ {1, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + }, + }, + { +- name: "I64Load8S", +- auxType: auxInt64, +- argLen: 2, +- asm: wasm.AI64Load8S, ++ name: "MULW", ++ argLen: 2, ++ commutative: true, ++ asm: sw64.AMULW, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1407374883618815}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP SB ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ {1, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + }, + }, + { +- name: "I64Load16U", ++ name: "MULWconst", + auxType: auxInt64, +- argLen: 2, +- asm: wasm.AI64Load16U, ++ argLen: 1, ++ asm: sw64.AMULW, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1407374883618815}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP SB ++ {0, 201326591}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 SP + }, + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + }, + }, + { +- name: "I64Load16S", +- auxType: auxInt64, +- argLen: 2, +- asm: wasm.AI64Load16S, ++ name: "MULL", ++ argLen: 2, ++ commutative: true, ++ asm: sw64.AMULL, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1407374883618815}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP SB ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ {1, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + }, + }, + { +- name: "I64Load32U", ++ name: "MULLconst", + auxType: auxInt64, +- argLen: 2, +- asm: wasm.AI64Load32U, ++ argLen: 1, ++ asm: sw64.AMULL, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1407374883618815}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP SB ++ {0, 201326591}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 SP + }, + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + }, + }, + { +- name: "I64Load32S", +- auxType: auxInt64, +- argLen: 2, +- asm: wasm.AI64Load32S, ++ name: "UMULH", ++ argLen: 2, ++ commutative: true, ++ asm: sw64.AUMULH, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1407374883618815}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP SB ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ {1, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + }, + }, + { +- name: "I64Load", ++ name: "UMULHconst", + auxType: auxInt64, +- argLen: 2, +- asm: wasm.AI64Load, ++ argLen: 1, ++ asm: sw64.AUMULH, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1407374883618815}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP SB ++ {0, 201326591}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 SP + }, + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + }, + }, + { +- name: "I64Store8", +- auxType: auxInt64, +- argLen: 3, +- asm: wasm.AI64Store8, ++ name: "CALLudiv", ++ argLen: 2, ++ clobberFlags: true, + reg: regInfo{ + inputs: []inputInfo{ +- {1, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP +- {0, 1407374883618815}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP SB ++ {0, 2}, // R1 ++ {1, 1}, // R0 ++ }, ++ clobbers: 67108924, // R2 R3 R4 R5 R26 ++ outputs: []outputInfo{ ++ {0, 1}, // R0 ++ {1, 2}, // R1 + }, + }, + }, + { +- name: "I64Store16", +- auxType: auxInt64, +- argLen: 3, +- asm: wasm.AI64Store16, ++ name: "FADDD", ++ argLen: 2, ++ commutative: true, ++ asm: sw64.AFADDD, + reg: regInfo{ + inputs: []inputInfo{ +- {1, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP +- {0, 1407374883618815}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP SB ++ {0, 1125899369971712}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 ++ {1, 1125899369971712}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 ++ }, ++ outputs: []outputInfo{ ++ {0, 1151795604700004352}, // F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 + }, + }, + }, + { +- name: "I64Store32", +- auxType: auxInt64, +- argLen: 3, +- asm: wasm.AI64Store32, ++ name: "FADDS", ++ argLen: 2, ++ commutative: true, ++ asm: sw64.AFADDS, + reg: regInfo{ + inputs: []inputInfo{ +- {1, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP +- {0, 1407374883618815}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP SB ++ {0, 1125899369971712}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 ++ {1, 1125899369971712}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 ++ }, ++ outputs: []outputInfo{ ++ {0, 1151795604700004352}, // F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 + }, + }, + }, + { +- name: "I64Store", +- auxType: auxInt64, +- argLen: 3, +- asm: wasm.AI64Store, ++ name: "FSUBD", ++ argLen: 2, ++ asm: sw64.AFSUBD, + reg: regInfo{ + inputs: []inputInfo{ +- {1, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP +- {0, 1407374883618815}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP SB ++ {0, 1125899369971712}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 ++ {1, 1125899369971712}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 ++ }, ++ outputs: []outputInfo{ ++ {0, 1151795604700004352}, // F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 + }, + }, + }, + { +- name: "F32Load", +- auxType: auxInt64, +- argLen: 2, +- asm: wasm.AF32Load, ++ name: "FSUBS", ++ argLen: 2, ++ asm: sw64.AFSUBS, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1407374883618815}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP SB ++ {0, 1125899369971712}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 ++ {1, 1125899369971712}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 + }, + outputs: []outputInfo{ +- {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 ++ {0, 1151795604700004352}, // F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 + }, + }, + }, + { +- name: "F64Load", +- auxType: auxInt64, +- argLen: 2, +- asm: wasm.AF64Load, ++ name: "FMULD", ++ argLen: 2, ++ commutative: true, ++ asm: sw64.AFMULD, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 1407374883618815}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP SB ++ {0, 1125899369971712}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 ++ {1, 1125899369971712}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 + }, + outputs: []outputInfo{ +- {0, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 ++ {0, 1151795604700004352}, // F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 + }, + }, + }, + { +- name: "F32Store", +- auxType: auxInt64, +- argLen: 3, +- asm: wasm.AF32Store, ++ name: "FMULS", ++ argLen: 2, ++ commutative: true, ++ asm: sw64.AFMULS, + reg: regInfo{ + inputs: []inputInfo{ +- {1, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 +- {0, 1407374883618815}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP SB ++ {0, 1125899369971712}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 ++ {1, 1125899369971712}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 ++ }, ++ outputs: []outputInfo{ ++ {0, 1151795604700004352}, // F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 + }, + }, + }, + { +- name: "F64Store", +- auxType: auxInt64, +- argLen: 3, +- asm: wasm.AF64Store, ++ name: "FDIVD", ++ argLen: 2, ++ asm: sw64.AFDIVD, + reg: regInfo{ + inputs: []inputInfo{ +- {1, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 +- {0, 1407374883618815}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP SB ++ {0, 1125899369971712}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 ++ {1, 1125899369971712}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 + }, +- }, +- }, +- { +- name: "I64Const", +- auxType: auxInt64, +- argLen: 0, +- rematerializeable: true, +- reg: regInfo{ + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 1151795604700004352}, // F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 + }, + }, + }, + { +- name: "F32Const", +- auxType: auxFloat32, +- argLen: 0, +- rematerializeable: true, ++ name: "FDIVS", ++ argLen: 2, ++ asm: sw64.AFDIVS, + reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 1125899369971712}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 ++ {1, 1125899369971712}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 ++ }, + outputs: []outputInfo{ +- {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 ++ {0, 1151795604700004352}, // F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 + }, + }, + }, + { +- name: "F64Const", +- auxType: auxFloat64, +- argLen: 0, +- rematerializeable: true, ++ name: "FCPYS", ++ argLen: 2, ++ asm: sw64.AFCPYS, + reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 1152921504069976064}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 ++ {1, 1152921504069976064}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 ++ }, + outputs: []outputInfo{ +- {0, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 ++ {0, 1152921504069976064}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 + }, + }, + }, + { +- name: "I64Eqz", ++ name: "FABS", + argLen: 1, +- asm: wasm.AI64Eqz, ++ asm: sw64.AFCPYS, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ {0, 1152921504069976064}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 + }, + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 1152921504069976064}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 + }, + }, + }, + { +- name: "I64Eq", +- argLen: 2, +- asm: wasm.AI64Eq, ++ name: "IFMOVD", ++ argLen: 1, ++ asm: sw64.AIFMOVD, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP +- {1, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 1152921504069976064}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 + }, + }, + }, + { +- name: "I64Ne", +- argLen: 2, +- asm: wasm.AI64Ne, ++ name: "IFMOVS", ++ argLen: 1, ++ asm: sw64.AIFMOVS, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP +- {1, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 1152921504069976064}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 + }, + }, + }, + { +- name: "I64LtS", +- argLen: 2, +- asm: wasm.AI64LtS, ++ name: "FIMOVD", ++ argLen: 1, ++ asm: sw64.AFIMOVD, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP +- {1, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ {0, 1152921504069976064}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 + }, + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + }, + }, + { +- name: "I64LtU", +- argLen: 2, +- asm: wasm.AI64LtU, ++ name: "FIMOVS", ++ argLen: 1, ++ asm: sw64.AFIMOVS, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP +- {1, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ {0, 1152921504069976064}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 + }, + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + }, + }, + { +- name: "I64GtS", +- argLen: 2, +- asm: wasm.AI64GtS, ++ name: "FCVTSD", ++ argLen: 1, ++ asm: sw64.AFCVTSD, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP +- {1, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ {0, 1125899369971712}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 + }, + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 1151795604700004352}, // F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 + }, + }, + }, + { +- name: "I64GtU", +- argLen: 2, +- asm: wasm.AI64GtU, ++ name: "FCVTDS", ++ argLen: 1, ++ asm: sw64.AFCVTDS, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP +- {1, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ {0, 1125899369971712}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 + }, + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 1151795604700004352}, // F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 + }, + }, + }, + { +- name: "I64LeS", +- argLen: 2, +- asm: wasm.AI64LeS, ++ name: "FCVTDL", ++ argLen: 1, ++ asm: sw64.AFCVTDL, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP +- {1, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ {0, 1152921504069976064}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 + }, + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 1152921504069976064}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 + }, + }, + }, + { +- name: "I64LeU", +- argLen: 2, +- asm: wasm.AI64LeU, ++ name: "FCVTLS", ++ argLen: 1, ++ asm: sw64.AFCVTLS, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP +- {1, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ {0, 1152921504069976064}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 + }, + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 1152921504069976064}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 + }, + }, + }, + { +- name: "I64GeS", +- argLen: 2, +- asm: wasm.AI64GeS, ++ name: "FCVTLD", ++ argLen: 1, ++ asm: sw64.AFCVTLD, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP +- {1, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ {0, 1152921504069976064}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 + }, + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 1152921504069976064}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 + }, + }, + }, + { +- name: "I64GeU", +- argLen: 2, +- asm: wasm.AI64GeU, ++ name: "FCVTLW", ++ argLen: 1, ++ asm: sw64.AFCVTLW, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP +- {1, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ {0, 1152921504069976064}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 + }, + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 1152921504069976064}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 + }, + }, + }, + { +- name: "F32Eq", +- argLen: 2, +- asm: wasm.AF32Eq, ++ name: "FCVTWL", ++ argLen: 1, ++ asm: sw64.AFCVTWL, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 +- {1, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 ++ {0, 1152921504069976064}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 + }, + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 1152921504069976064}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 + }, + }, + }, + { +- name: "F32Ne", +- argLen: 2, +- asm: wasm.AF32Ne, ++ name: "FSQRTS", ++ argLen: 1, ++ asm: sw64.AFSQRTS, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 +- {1, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 ++ {0, 1152921504069976064}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 + }, + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 1152921504069976064}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 + }, + }, + }, + { +- name: "F32Lt", +- argLen: 2, +- asm: wasm.AF32Lt, ++ name: "FSQRTD", ++ argLen: 1, ++ asm: sw64.AFSQRTD, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 +- {1, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 ++ {0, 1125899369971712}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 + }, + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 1151795604700004352}, // F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 + }, + }, + }, + { +- name: "F32Gt", +- argLen: 2, +- asm: wasm.AF32Gt, ++ name: "FCVTDL_Z", ++ argLen: 1, ++ resultNotInArgs: true, ++ asm: sw64.AFCVTDL_Z, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 +- {1, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 ++ {0, 1152921504069976064}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 + }, + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 1152921504069976064}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 + }, + }, + }, + { +- name: "F32Le", +- argLen: 2, +- asm: wasm.AF32Le, ++ name: "FCVTDL_P", ++ argLen: 1, ++ resultNotInArgs: true, ++ asm: sw64.AFCVTDL_P, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 +- {1, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 ++ {0, 1152921504069976064}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 + }, + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 1152921504069976064}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 + }, + }, + }, + { +- name: "F32Ge", +- argLen: 2, +- asm: wasm.AF32Ge, ++ name: "FCVTDL_G", ++ argLen: 1, ++ resultNotInArgs: true, ++ asm: sw64.AFCVTDL_G, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 +- {1, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 ++ {0, 1152921504069976064}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 + }, + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 1152921504069976064}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 + }, + }, + }, + { +- name: "F64Eq", +- argLen: 2, +- asm: wasm.AF64Eq, ++ name: "FCVTDL_N", ++ argLen: 1, ++ resultNotInArgs: true, ++ asm: sw64.AFCVTDL_N, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 +- {1, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 ++ {0, 1152921504069976064}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 + }, + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 1152921504069976064}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 + }, + }, + }, + { +- name: "F64Ne", +- argLen: 2, +- asm: wasm.AF64Ne, ++ name: "AND", ++ argLen: 2, ++ commutative: true, ++ asm: sw64.AAND, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 +- {1, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ {1, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + }, + }, + { +- name: "F64Lt", +- argLen: 2, +- asm: wasm.AF64Lt, ++ name: "ANDconst", ++ auxType: auxInt64, ++ argLen: 1, ++ asm: sw64.AAND, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 +- {1, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + }, + }, + { +- name: "F64Gt", +- argLen: 2, +- asm: wasm.AF64Gt, ++ name: "BIS", ++ argLen: 2, ++ commutative: true, ++ asm: sw64.ABIS, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 +- {1, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ {1, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + }, + }, + { +- name: "F64Le", +- argLen: 2, +- asm: wasm.AF64Le, ++ name: "BISconst", ++ auxType: auxInt64, ++ argLen: 1, ++ asm: sw64.ABIS, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 +- {1, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + }, + }, + { +- name: "F64Ge", +- argLen: 2, +- asm: wasm.AF64Ge, ++ name: "XOR", ++ argLen: 2, ++ commutative: true, ++ asm: sw64.AXOR, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 +- {1, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ {1, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + }, + }, + { +- name: "I64Add", +- argLen: 2, +- asm: wasm.AI64Add, ++ name: "XORconst", ++ auxType: auxInt64, ++ argLen: 1, ++ asm: sw64.AXOR, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP +- {1, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + }, + }, + { +- name: "I64AddConst", ++ name: "ZAPNOTconst", + auxType: auxInt64, + argLen: 1, +- asm: wasm.AI64Add, ++ asm: sw64.AZAPNOT, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ {0, 201326591}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 SP + }, + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + }, + }, + { +- name: "I64Sub", ++ name: "ORNOT", + argLen: 2, +- asm: wasm.AI64Sub, ++ asm: sw64.AORNOT, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP +- {1, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ {1, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + }, + }, + { +- name: "I64Mul", +- argLen: 2, +- asm: wasm.AI64Mul, ++ name: "ORNOTconst", ++ auxType: auxInt64, ++ argLen: 1, ++ asm: sw64.AORNOT, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP +- {1, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + }, + }, + { +- name: "I64DivS", +- argLen: 2, +- asm: wasm.AI64DivS, ++ name: "NEGV", ++ argLen: 1, ++ asm: sw64.ASUBL, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP +- {1, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 + }, + }, + }, + { +- name: "I64DivU", +- argLen: 2, +- asm: wasm.AI64DivU, ++ name: "NEGF", ++ argLen: 1, ++ asm: sw64.AFCPYSN, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP +- {1, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ {0, 1152921504069976064}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 + }, + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 1152921504069976064}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 + }, + }, + }, + { +- name: "I64RemS", +- argLen: 2, +- asm: wasm.AI64RemS, ++ name: "NEGD", ++ argLen: 1, ++ asm: sw64.AFCPYSN, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP +- {1, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ {0, 1152921504069976064}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 + }, + outputs: []outputInfo{ +- {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {0, 1152921504069976064}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 + }, + }, + }, + { +- name: "I64RemU", ++ name: "SLL", + argLen: 2, +- asm: wasm.AI64RemU, ++ asm: sw64.ASLL, + reg: regInfo{ + inputs: []inputInfo{ +- {0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP +- {1, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ {1, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "SLLconst", ++ auxType: auxInt64, ++ argLen: 1, ++ asm: sw64.ASLL, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "SRL", ++ argLen: 2, ++ asm: sw64.ASRL, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ {1, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "SRLconst", ++ auxType: auxInt64, ++ argLen: 1, ++ asm: sw64.ASRL, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "SRA", ++ argLen: 2, ++ asm: sw64.ASRA, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ {1, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "SRAconst", ++ auxType: auxInt64, ++ argLen: 1, ++ asm: sw64.ASRA, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "CTTZ", ++ argLen: 1, ++ asm: sw64.ACTTZ, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "CTLZ", ++ argLen: 1, ++ asm: sw64.ACTLZ, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "CTPOP", ++ argLen: 1, ++ asm: sw64.ACTPOP, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "SEXTB", ++ argLen: 1, ++ asm: sw64.ASEXTB, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "SEXTBconst", ++ auxType: auxInt64, ++ argLen: 0, ++ asm: sw64.ASEXTB, ++ reg: regInfo{ ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "SEXTH", ++ argLen: 1, ++ asm: sw64.ASEXTH, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "SEXTHconst", ++ auxType: auxInt64, ++ argLen: 0, ++ asm: sw64.ASEXTH, ++ reg: regInfo{ ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "SYMADDR", ++ auxType: auxSymOff, ++ argLen: 1, ++ rematerializeable: true, ++ symEffect: SymAddr, ++ asm: sw64.ASYMADDR, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 2305843009347911680}, // SP SB ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "MOVVconst", ++ auxType: auxInt64, ++ argLen: 0, ++ rematerializeable: true, ++ asm: sw64.ALDI, ++ reg: regInfo{ ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "MOVFconst", ++ auxType: auxFloat64, ++ argLen: 0, ++ rematerializeable: true, ++ asm: sw64.ALDF, ++ reg: regInfo{ ++ outputs: []outputInfo{ ++ {0, 1152921504069976064}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 ++ }, ++ }, ++ }, ++ { ++ name: "MOVDconst", ++ auxType: auxFloat64, ++ argLen: 0, ++ rematerializeable: true, ++ asm: sw64.ALDI, ++ reg: regInfo{ ++ outputs: []outputInfo{ ++ {0, 1152921504069976064}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 ++ }, ++ }, ++ }, ++ { ++ name: "MOVBstorezero", ++ auxType: auxSymOff, ++ argLen: 2, ++ faultOnNilArg0: true, ++ symEffect: SymWrite, ++ asm: sw64.ASTB, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 2305843009415020543}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 SP SB ++ }, ++ }, ++ }, ++ { ++ name: "MOVHstorezero", ++ auxType: auxSymOff, ++ argLen: 2, ++ faultOnNilArg0: true, ++ symEffect: SymWrite, ++ asm: sw64.ASTH, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 2305843009415020543}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 SP SB ++ }, ++ }, ++ }, ++ { ++ name: "MOVWstorezero", ++ auxType: auxSymOff, ++ argLen: 2, ++ faultOnNilArg0: true, ++ symEffect: SymWrite, ++ asm: sw64.ASTW, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 2305843009415020543}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 SP SB ++ }, ++ }, ++ }, ++ { ++ name: "MOVVstorezero", ++ auxType: auxSymOff, ++ argLen: 2, ++ faultOnNilArg0: true, ++ symEffect: SymWrite, ++ asm: sw64.ASTL, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 2305843009415020543}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 SP SB ++ }, ++ }, ++ }, ++ { ++ name: "MOVBload", ++ auxType: auxSymOff, ++ argLen: 2, ++ faultOnNilArg0: true, ++ symEffect: SymRead, ++ asm: sw64.ALDBU, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 2305843009415020543}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 SP SB ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "MOVBUload", ++ auxType: auxSymOff, ++ argLen: 2, ++ faultOnNilArg0: true, ++ symEffect: SymRead, ++ asm: sw64.ALDBU, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 2305843009415020543}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 SP SB ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "MOVHload", ++ auxType: auxSymOff, ++ argLen: 2, ++ faultOnNilArg0: true, ++ symEffect: SymRead, ++ asm: sw64.ALDHU, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 2305843009415020543}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 SP SB ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "MOVHUload", ++ auxType: auxSymOff, ++ argLen: 2, ++ faultOnNilArg0: true, ++ symEffect: SymRead, ++ asm: sw64.ALDHU, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 2305843009415020543}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 SP SB ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "MOVWload", ++ auxType: auxSymOff, ++ argLen: 2, ++ faultOnNilArg0: true, ++ symEffect: SymRead, ++ asm: sw64.ALDW, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 2305843009415020543}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 SP SB ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "MOVWUload", ++ auxType: auxSymOff, ++ argLen: 2, ++ faultOnNilArg0: true, ++ symEffect: SymRead, ++ asm: sw64.ALDW, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 2305843009415020543}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 SP SB ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "MOVVload", ++ auxType: auxSymOff, ++ argLen: 2, ++ faultOnNilArg0: true, ++ symEffect: SymRead, ++ asm: sw64.ALDL, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 2305843009415020543}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 SP SB ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "MOVFload", ++ auxType: auxSymOff, ++ argLen: 2, ++ faultOnNilArg0: true, ++ symEffect: SymRead, ++ asm: sw64.AFLDS, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 2305843009415020543}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 SP SB ++ }, ++ outputs: []outputInfo{ ++ {0, 1152921504069976064}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 ++ }, ++ }, ++ }, ++ { ++ name: "MOVDload", ++ auxType: auxSymOff, ++ argLen: 2, ++ faultOnNilArg0: true, ++ symEffect: SymRead, ++ asm: sw64.AFLDD, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 2305843009415020543}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 SP SB ++ }, ++ outputs: []outputInfo{ ++ {0, 1152921504069976064}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 ++ }, ++ }, ++ }, ++ { ++ name: "MOVBstore", ++ auxType: auxSymOff, ++ argLen: 3, ++ faultOnNilArg0: true, ++ symEffect: SymWrite, ++ asm: sw64.ASTB, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {1, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ {0, 2305843009415020543}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 SP SB ++ }, ++ }, ++ }, ++ { ++ name: "MOVHstore", ++ auxType: auxSymOff, ++ argLen: 3, ++ faultOnNilArg0: true, ++ symEffect: SymWrite, ++ asm: sw64.ASTH, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {1, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ {0, 2305843009415020543}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 SP SB ++ }, ++ }, ++ }, ++ { ++ name: "MOVWstore", ++ auxType: auxSymOff, ++ argLen: 3, ++ faultOnNilArg0: true, ++ symEffect: SymWrite, ++ asm: sw64.ASTW, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {1, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ {0, 2305843009415020543}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 SP SB ++ }, ++ }, ++ }, ++ { ++ name: "MOVVstore", ++ auxType: auxSymOff, ++ argLen: 3, ++ faultOnNilArg0: true, ++ symEffect: SymWrite, ++ asm: sw64.ASTL, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {1, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ {0, 2305843009415020543}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 SP SB ++ }, ++ }, ++ }, ++ { ++ name: "MOVFstore", ++ auxType: auxSymOff, ++ argLen: 3, ++ faultOnNilArg0: true, ++ symEffect: SymWrite, ++ asm: sw64.AFSTS, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 2305843009415020543}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 SP SB ++ {1, 1152921504069976064}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 ++ }, ++ }, ++ }, ++ { ++ name: "MOVDstore", ++ auxType: auxSymOff, ++ argLen: 3, ++ faultOnNilArg0: true, ++ symEffect: SymWrite, ++ asm: sw64.AFSTD, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 2305843009415020543}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 SP SB ++ {1, 1152921504069976064}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 ++ }, ++ }, ++ }, ++ { ++ name: "MOVBreg", ++ argLen: 1, ++ asm: sw64.AMOVB, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "MOVBUreg", ++ argLen: 1, ++ asm: sw64.AMOVBU, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "MOVHreg", ++ argLen: 1, ++ asm: sw64.AMOVH, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "MOVHUreg", ++ argLen: 1, ++ asm: sw64.AMOVHU, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "MOVWreg", ++ argLen: 1, ++ asm: sw64.AMOVW, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "MOVWUreg", ++ argLen: 1, ++ asm: sw64.AMOVWU, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "MOVVreg", ++ argLen: 1, ++ asm: sw64.AMOVV, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "MOVVnop", ++ argLen: 1, ++ resultInArg0: true, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "CMPULE", ++ argLen: 2, ++ asm: sw64.ACMPULE, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ {1, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "CMPULEconst", ++ auxType: auxInt64, ++ argLen: 1, ++ asm: sw64.ACMPULE, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "CMPULT", ++ argLen: 2, ++ asm: sw64.ACMPULT, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ {1, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "CMPULTconst", ++ auxType: auxInt64, ++ argLen: 1, ++ asm: sw64.ACMPULT, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "CMPLE", ++ argLen: 2, ++ asm: sw64.ACMPLE, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ {1, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "CMPLEconst", ++ auxType: auxInt64, ++ argLen: 1, ++ asm: sw64.ACMPLE, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "CMPLT", ++ argLen: 2, ++ asm: sw64.ACMPLT, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ {1, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "CMPLTconst", ++ auxType: auxInt64, ++ argLen: 1, ++ asm: sw64.ACMPLT, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "CMPEQ", ++ argLen: 2, ++ asm: sw64.ACMPEQ, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ {1, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "CMPEQconst", ++ auxType: auxInt64, ++ argLen: 1, ++ asm: sw64.ACMPEQ, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "FCMPLE", ++ argLen: 2, ++ asm: sw64.AFCMPLE, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 1125899369971712}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 ++ {1, 1125899369971712}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 ++ }, ++ outputs: []outputInfo{ ++ {0, 1151795604700004352}, // F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 ++ }, ++ }, ++ }, ++ { ++ name: "FCMPLT", ++ argLen: 2, ++ asm: sw64.AFCMPLT, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 1125899369971712}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 ++ {1, 1125899369971712}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 ++ }, ++ outputs: []outputInfo{ ++ {0, 1151795604700004352}, // F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 ++ }, ++ }, ++ }, ++ { ++ name: "FCMPEQ", ++ argLen: 2, ++ asm: sw64.AFCMPEQ, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 1125899369971712}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 ++ {1, 1125899369971712}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 ++ }, ++ outputs: []outputInfo{ ++ {0, 1151795604700004352}, // F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 ++ }, ++ }, ++ }, ++ { ++ name: "FCMPUN", ++ argLen: 2, ++ asm: sw64.AFCMPUN, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 1125899369971712}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 ++ {1, 1125899369971712}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 ++ }, ++ outputs: []outputInfo{ ++ {0, 1151795604700004352}, // F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 ++ }, ++ }, ++ }, ++ { ++ name: "CALLstatic", ++ auxType: auxCallOff, ++ argLen: -1, ++ clobberFlags: true, ++ call: true, ++ reg: regInfo{ ++ clobbers: 1152921504137084927, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 ++ }, ++ }, ++ { ++ name: "CALLtail", ++ auxType: auxCallOff, ++ argLen: -1, ++ clobberFlags: true, ++ call: true, ++ tailCall: true, ++ reg: regInfo{ ++ clobbers: 1152921504137084927, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 ++ }, ++ }, ++ { ++ name: "CALLclosure", ++ auxType: auxCallOff, ++ argLen: -1, ++ clobberFlags: true, ++ call: true, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {1, 33554432}, // R25 ++ {0, 201293823}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 SP ++ }, ++ clobbers: 1152921504137084927, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 ++ }, ++ }, ++ { ++ name: "CALLinter", ++ auxType: auxCallOff, ++ argLen: -1, ++ clobberFlags: true, ++ call: true, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ clobbers: 1152921504137084927, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 ++ }, ++ }, ++ { ++ name: "DUFFZERO", ++ auxType: auxInt64, ++ argLen: 2, ++ faultOnNilArg0: true, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ clobbers: 2, // R1 ++ }, ++ }, ++ { ++ name: "LoweredZero", ++ auxType: auxInt64, ++ argLen: 3, ++ clobberFlags: true, ++ faultOnNilArg0: true, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 2}, // R1 ++ {1, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ clobbers: 2, // R1 ++ }, ++ }, ++ { ++ name: "LoweredMove", ++ auxType: auxInt64, ++ argLen: 4, ++ clobberFlags: true, ++ faultOnNilArg0: true, ++ faultOnNilArg1: true, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 4}, // R2 ++ {1, 2}, // R1 ++ {2, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ clobbers: 6, // R1 R2 ++ }, ++ }, ++ { ++ name: "LoweredNilCheck", ++ argLen: 2, ++ nilCheck: true, ++ faultOnNilArg0: true, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "LoweredGetClosurePtr", ++ argLen: 0, ++ zeroWidth: true, ++ reg: regInfo{ ++ outputs: []outputInfo{ ++ {0, 33554432}, // R25 ++ }, ++ }, ++ }, ++ { ++ name: "LoweredGetCallerSP", ++ argLen: 1, ++ rematerializeable: true, ++ reg: regInfo{ ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "LoweredGetCallerPC", ++ argLen: 0, ++ rematerializeable: true, ++ reg: regInfo{ ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "MOVVconvert", ++ argLen: 2, ++ asm: sw64.ALDI, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "FEqual", ++ argLen: 1, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 1152921504069976064}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "FNotEqual", ++ argLen: 1, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 1152921504069976064}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "LoweredWB", ++ auxType: auxInt64, ++ argLen: 1, ++ clobberFlags: true, ++ reg: regInfo{ ++ clobbers: 1152921504137084928, // R26 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 ++ outputs: []outputInfo{ ++ {0, 16384}, // R14 ++ }, ++ }, ++ }, ++ { ++ name: "LoweredPanicBoundsA", ++ auxType: auxInt64, ++ argLen: 3, ++ call: true, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 8}, // R3 ++ {1, 16}, // R4 ++ }, ++ }, ++ }, ++ { ++ name: "LoweredPanicBoundsB", ++ auxType: auxInt64, ++ argLen: 3, ++ call: true, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 4}, // R2 ++ {1, 8}, // R3 ++ }, ++ }, ++ }, ++ { ++ name: "LoweredPanicBoundsC", ++ auxType: auxInt64, ++ argLen: 3, ++ call: true, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 2}, // R1 ++ {1, 4}, // R2 ++ }, ++ }, ++ }, ++ { ++ name: "LoweredAtomicLoad8", ++ argLen: 2, ++ faultOnNilArg0: true, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 2305843009415020543}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 SP SB ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "LoweredAtomicLoad32", ++ argLen: 2, ++ faultOnNilArg0: true, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 2305843009415020543}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 SP SB ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "LoweredAtomicLoad64", ++ argLen: 2, ++ faultOnNilArg0: true, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 2305843009415020543}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 SP SB ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "LoweredAtomicStore8", ++ argLen: 3, ++ faultOnNilArg0: true, ++ hasSideEffects: true, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {1, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ {0, 2305843009415020543}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 SP SB ++ }, ++ }, ++ }, ++ { ++ name: "LoweredAtomicStore32", ++ argLen: 3, ++ faultOnNilArg0: true, ++ hasSideEffects: true, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {1, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ {0, 2305843009415020543}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 SP SB ++ }, ++ }, ++ }, ++ { ++ name: "LoweredAtomicStore64", ++ argLen: 3, ++ faultOnNilArg0: true, ++ hasSideEffects: true, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {1, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ {0, 2305843009415020543}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 SP SB ++ }, ++ }, ++ }, ++ { ++ name: "LoweredAtomicExchange32", ++ argLen: 3, ++ resultNotInArgs: true, ++ faultOnNilArg0: true, ++ hasSideEffects: true, ++ unsafePoint: true, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {1, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ {0, 2305843009415020543}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 SP SB ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "LoweredAtomicExchange64", ++ argLen: 3, ++ resultNotInArgs: true, ++ faultOnNilArg0: true, ++ hasSideEffects: true, ++ unsafePoint: true, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {1, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ {0, 2305843009415020543}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 SP SB ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "LoweredAtomicAdd32", ++ argLen: 3, ++ resultNotInArgs: true, ++ faultOnNilArg0: true, ++ hasSideEffects: true, ++ unsafePoint: true, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {1, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ {0, 2305843009415020543}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 SP SB ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "LoweredAtomicAdd64", ++ argLen: 3, ++ resultNotInArgs: true, ++ faultOnNilArg0: true, ++ hasSideEffects: true, ++ unsafePoint: true, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {1, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ {0, 2305843009415020543}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 SP SB ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "LoweredAtomicCas32", ++ argLen: 4, ++ resultNotInArgs: true, ++ faultOnNilArg0: true, ++ hasSideEffects: true, ++ unsafePoint: true, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {1, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ {2, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ {0, 2305843009415020543}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 SP SB ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ { ++ name: "LoweredAtomicCas64", ++ argLen: 4, ++ resultNotInArgs: true, ++ faultOnNilArg0: true, ++ hasSideEffects: true, ++ unsafePoint: true, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {1, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ {2, 67108863}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ {0, 2305843009415020543}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 g R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 SP SB ++ }, ++ outputs: []outputInfo{ ++ {0, 67076095}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 ++ }, ++ }, ++ }, ++ ++ { ++ name: "LoweredStaticCall", ++ auxType: auxCallOff, ++ argLen: 1, ++ call: true, ++ reg: regInfo{ ++ clobbers: 844424930131967, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 g ++ }, ++ }, ++ { ++ name: "LoweredTailCall", ++ auxType: auxCallOff, ++ argLen: 1, ++ call: true, ++ tailCall: true, ++ reg: regInfo{ ++ clobbers: 844424930131967, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 g ++ }, ++ }, ++ { ++ name: "LoweredClosureCall", ++ auxType: auxCallOff, ++ argLen: 3, ++ call: true, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {1, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ clobbers: 844424930131967, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 g ++ }, ++ }, ++ { ++ name: "LoweredInterCall", ++ auxType: auxCallOff, ++ argLen: 2, ++ call: true, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ clobbers: 844424930131967, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 g ++ }, ++ }, ++ { ++ name: "LoweredAddr", ++ auxType: auxSymOff, ++ argLen: 1, ++ rematerializeable: true, ++ symEffect: SymAddr, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ }, ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "LoweredMove", ++ auxType: auxInt64, ++ argLen: 3, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ {1, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "LoweredZero", ++ auxType: auxInt64, ++ argLen: 2, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "LoweredGetClosurePtr", ++ argLen: 0, ++ reg: regInfo{ ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "LoweredGetCallerPC", ++ argLen: 0, ++ rematerializeable: true, ++ reg: regInfo{ ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "LoweredGetCallerSP", ++ argLen: 1, ++ rematerializeable: true, ++ reg: regInfo{ ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "LoweredNilCheck", ++ argLen: 2, ++ nilCheck: true, ++ faultOnNilArg0: true, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "LoweredWB", ++ auxType: auxInt64, ++ argLen: 1, ++ reg: regInfo{ ++ clobbers: 844424930131967, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 g ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "LoweredConvert", ++ argLen: 2, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "Select", ++ argLen: 3, ++ asm: wasm.ASelect, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ {1, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ {2, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ }, ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "I64Load8U", ++ auxType: auxInt64, ++ argLen: 2, ++ asm: wasm.AI64Load8U, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 1407374883618815}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP SB ++ }, ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "I64Load8S", ++ auxType: auxInt64, ++ argLen: 2, ++ asm: wasm.AI64Load8S, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 1407374883618815}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP SB ++ }, ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "I64Load16U", ++ auxType: auxInt64, ++ argLen: 2, ++ asm: wasm.AI64Load16U, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 1407374883618815}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP SB ++ }, ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "I64Load16S", ++ auxType: auxInt64, ++ argLen: 2, ++ asm: wasm.AI64Load16S, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 1407374883618815}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP SB ++ }, ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "I64Load32U", ++ auxType: auxInt64, ++ argLen: 2, ++ asm: wasm.AI64Load32U, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 1407374883618815}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP SB ++ }, ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "I64Load32S", ++ auxType: auxInt64, ++ argLen: 2, ++ asm: wasm.AI64Load32S, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 1407374883618815}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP SB ++ }, ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "I64Load", ++ auxType: auxInt64, ++ argLen: 2, ++ asm: wasm.AI64Load, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 1407374883618815}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP SB ++ }, ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "I64Store8", ++ auxType: auxInt64, ++ argLen: 3, ++ asm: wasm.AI64Store8, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {1, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ {0, 1407374883618815}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP SB ++ }, ++ }, ++ }, ++ { ++ name: "I64Store16", ++ auxType: auxInt64, ++ argLen: 3, ++ asm: wasm.AI64Store16, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {1, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ {0, 1407374883618815}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP SB ++ }, ++ }, ++ }, ++ { ++ name: "I64Store32", ++ auxType: auxInt64, ++ argLen: 3, ++ asm: wasm.AI64Store32, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {1, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ {0, 1407374883618815}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP SB ++ }, ++ }, ++ }, ++ { ++ name: "I64Store", ++ auxType: auxInt64, ++ argLen: 3, ++ asm: wasm.AI64Store, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {1, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ {0, 1407374883618815}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP SB ++ }, ++ }, ++ }, ++ { ++ name: "F32Load", ++ auxType: auxInt64, ++ argLen: 2, ++ asm: wasm.AF32Load, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 1407374883618815}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP SB ++ }, ++ outputs: []outputInfo{ ++ {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 ++ }, ++ }, ++ }, ++ { ++ name: "F64Load", ++ auxType: auxInt64, ++ argLen: 2, ++ asm: wasm.AF64Load, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 1407374883618815}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP SB ++ }, ++ outputs: []outputInfo{ ++ {0, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 ++ }, ++ }, ++ }, ++ { ++ name: "F32Store", ++ auxType: auxInt64, ++ argLen: 3, ++ asm: wasm.AF32Store, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {1, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 ++ {0, 1407374883618815}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP SB ++ }, ++ }, ++ }, ++ { ++ name: "F64Store", ++ auxType: auxInt64, ++ argLen: 3, ++ asm: wasm.AF64Store, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {1, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 ++ {0, 1407374883618815}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP SB ++ }, ++ }, ++ }, ++ { ++ name: "I64Const", ++ auxType: auxInt64, ++ argLen: 0, ++ rematerializeable: true, ++ reg: regInfo{ ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "F32Const", ++ auxType: auxFloat32, ++ argLen: 0, ++ rematerializeable: true, ++ reg: regInfo{ ++ outputs: []outputInfo{ ++ {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 ++ }, ++ }, ++ }, ++ { ++ name: "F64Const", ++ auxType: auxFloat64, ++ argLen: 0, ++ rematerializeable: true, ++ reg: regInfo{ ++ outputs: []outputInfo{ ++ {0, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 ++ }, ++ }, ++ }, ++ { ++ name: "I64Eqz", ++ argLen: 1, ++ asm: wasm.AI64Eqz, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ }, ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "I64Eq", ++ argLen: 2, ++ asm: wasm.AI64Eq, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ {1, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ }, ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "I64Ne", ++ argLen: 2, ++ asm: wasm.AI64Ne, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ {1, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ }, ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "I64LtS", ++ argLen: 2, ++ asm: wasm.AI64LtS, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ {1, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ }, ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "I64LtU", ++ argLen: 2, ++ asm: wasm.AI64LtU, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ {1, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ }, ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "I64GtS", ++ argLen: 2, ++ asm: wasm.AI64GtS, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ {1, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ }, ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "I64GtU", ++ argLen: 2, ++ asm: wasm.AI64GtU, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ {1, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ }, ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "I64LeS", ++ argLen: 2, ++ asm: wasm.AI64LeS, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ {1, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ }, ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "I64LeU", ++ argLen: 2, ++ asm: wasm.AI64LeU, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ {1, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ }, ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "I64GeS", ++ argLen: 2, ++ asm: wasm.AI64GeS, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ {1, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ }, ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "I64GeU", ++ argLen: 2, ++ asm: wasm.AI64GeU, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ {1, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ }, ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "F32Eq", ++ argLen: 2, ++ asm: wasm.AF32Eq, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 ++ {1, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 ++ }, ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "F32Ne", ++ argLen: 2, ++ asm: wasm.AF32Ne, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 ++ {1, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 ++ }, ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "F32Lt", ++ argLen: 2, ++ asm: wasm.AF32Lt, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 ++ {1, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 ++ }, ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "F32Gt", ++ argLen: 2, ++ asm: wasm.AF32Gt, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 ++ {1, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 ++ }, ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "F32Le", ++ argLen: 2, ++ asm: wasm.AF32Le, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 ++ {1, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 ++ }, ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "F32Ge", ++ argLen: 2, ++ asm: wasm.AF32Ge, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 ++ {1, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 ++ }, ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "F64Eq", ++ argLen: 2, ++ asm: wasm.AF64Eq, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 ++ {1, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 ++ }, ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "F64Ne", ++ argLen: 2, ++ asm: wasm.AF64Ne, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 ++ {1, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 ++ }, ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "F64Lt", ++ argLen: 2, ++ asm: wasm.AF64Lt, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 ++ {1, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 ++ }, ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "F64Gt", ++ argLen: 2, ++ asm: wasm.AF64Gt, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 ++ {1, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 ++ }, ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "F64Le", ++ argLen: 2, ++ asm: wasm.AF64Le, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 ++ {1, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 ++ }, ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "F64Ge", ++ argLen: 2, ++ asm: wasm.AF64Ge, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 ++ {1, 281470681743360}, // F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31 ++ }, ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "I64Add", ++ argLen: 2, ++ asm: wasm.AI64Add, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ {1, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ }, ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "I64AddConst", ++ auxType: auxInt64, ++ argLen: 1, ++ asm: wasm.AI64Add, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ }, ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "I64Sub", ++ argLen: 2, ++ asm: wasm.AI64Sub, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ {1, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ }, ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "I64Mul", ++ argLen: 2, ++ asm: wasm.AI64Mul, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ {1, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ }, ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "I64DivS", ++ argLen: 2, ++ asm: wasm.AI64DivS, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ {1, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ }, ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "I64DivU", ++ argLen: 2, ++ asm: wasm.AI64DivU, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ {1, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ }, ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "I64RemS", ++ argLen: 2, ++ asm: wasm.AI64RemS, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ {1, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ }, ++ outputs: []outputInfo{ ++ {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ++ }, ++ }, ++ }, ++ { ++ name: "I64RemU", ++ argLen: 2, ++ asm: wasm.AI64RemU, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP ++ {1, 281474976776191}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 SP + }, + outputs: []outputInfo{ + {0, 65535}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 +@@ -42942,6 +45175,77 @@ var fpRegMaskS390X = regMask(4294901760) + var specialRegMaskS390X = regMask(0) + var framepointerRegS390X = int8(-1) + var linkRegS390X = int8(14) ++var registersSW64 = [...]Register{ ++ {0, sw64.REG_R0, 0, "R0"}, ++ {1, sw64.REG_R1, 1, "R1"}, ++ {2, sw64.REG_R2, 2, "R2"}, ++ {3, sw64.REG_R3, 3, "R3"}, ++ {4, sw64.REG_R4, 4, "R4"}, ++ {5, sw64.REG_R5, 5, "R5"}, ++ {6, sw64.REG_R6, 6, "R6"}, ++ {7, sw64.REG_R7, 7, "R7"}, ++ {8, sw64.REG_R8, 8, "R8"}, ++ {9, sw64.REG_R9, 9, "R9"}, ++ {10, sw64.REG_R10, 10, "R10"}, ++ {11, sw64.REG_R11, 11, "R11"}, ++ {12, sw64.REG_R12, 12, "R12"}, ++ {13, sw64.REG_R13, 13, "R13"}, ++ {14, sw64.REG_R14, 14, "R14"}, ++ {15, sw64.REGG, -1, "g"}, ++ {16, sw64.REG_R16, 15, "R16"}, ++ {17, sw64.REG_R17, 16, "R17"}, ++ {18, sw64.REG_R18, 17, "R18"}, ++ {19, sw64.REG_R19, 18, "R19"}, ++ {20, sw64.REG_R20, 19, "R20"}, ++ {21, sw64.REG_R21, 20, "R21"}, ++ {22, sw64.REG_R22, 21, "R22"}, ++ {23, sw64.REG_R23, 22, "R23"}, ++ {24, sw64.REG_R24, 23, "R24"}, ++ {25, sw64.REG_R25, 24, "R25"}, ++ {26, sw64.REG_R26, -1, "R26"}, ++ {27, sw64.REGSP, -1, "SP"}, ++ {28, sw64.REG_R31, -1, "R31"}, ++ {29, sw64.REG_F0, -1, "F0"}, ++ {30, sw64.REG_F1, -1, "F1"}, ++ {31, sw64.REG_F2, -1, "F2"}, ++ {32, sw64.REG_F3, -1, "F3"}, ++ {33, sw64.REG_F4, -1, "F4"}, ++ {34, sw64.REG_F5, -1, "F5"}, ++ {35, sw64.REG_F6, -1, "F6"}, ++ {36, sw64.REG_F7, -1, "F7"}, ++ {37, sw64.REG_F8, -1, "F8"}, ++ {38, sw64.REG_F9, -1, "F9"}, ++ {39, sw64.REG_F10, -1, "F10"}, ++ {40, sw64.REG_F11, -1, "F11"}, ++ {41, sw64.REG_F12, -1, "F12"}, ++ {42, sw64.REG_F13, -1, "F13"}, ++ {43, sw64.REG_F14, -1, "F14"}, ++ {44, sw64.REG_F15, -1, "F15"}, ++ {45, sw64.REG_F16, -1, "F16"}, ++ {46, sw64.REG_F17, -1, "F17"}, ++ {47, sw64.REG_F18, -1, "F18"}, ++ {48, sw64.REG_F19, -1, "F19"}, ++ {49, sw64.REG_F20, -1, "F20"}, ++ {50, sw64.REG_F21, -1, "F21"}, ++ {51, sw64.REG_F22, -1, "F22"}, ++ {52, sw64.REG_F23, -1, "F23"}, ++ {53, sw64.REG_F24, -1, "F24"}, ++ {54, sw64.REG_F25, -1, "F25"}, ++ {55, sw64.REG_F26, -1, "F26"}, ++ {56, sw64.REG_F27, -1, "F27"}, ++ {57, sw64.REG_F28, -1, "F28"}, ++ {58, sw64.REG_F29, -1, "F29"}, ++ {59, sw64.REG_F30, -1, "F30"}, ++ {60, sw64.REG_F31, -1, "F31"}, ++ {61, 0, -1, "SB"}, ++} ++var paramIntRegSW64 = []int8{16, 17, 18, 19, 20, 21, 22, 23, 24} ++var paramFloatRegSW64 = []int8{45, 46, 47, 48, 49, 50, 51, 52, 53} ++var gpRegMaskSW64 = regMask(67076095) ++var fpRegMaskSW64 = regMask(1152921504069976064) ++var specialRegMaskSW64 = regMask(0) ++var framepointerRegSW64 = int8(-1) ++var linkRegSW64 = int8(26) + var registersWasm = [...]Register{ + {0, wasm.REG_R0, 0, "R0"}, + {1, wasm.REG_R1, 1, "R1"}, +diff --git a/src/cmd/compile/internal/ssa/regalloc.go b/src/cmd/compile/internal/ssa/regalloc.go +index 08ce0d16a6..33ae0127d8 100644 +--- a/src/cmd/compile/internal/ssa/regalloc.go ++++ b/src/cmd/compile/internal/ssa/regalloc.go +@@ -691,6 +691,8 @@ func (s *regAllocState) init(f *Func) { + // nothing to do + case "loong64": // R2 (aka TP) already reserved. + // nothing to do ++ case "sw64": ++ // nothing to do + case "ppc64le": // R2 already reserved. + // nothing to do + case "riscv64": // X3 (aka GP) and X4 (aka TP) already reserved. +diff --git a/src/cmd/compile/internal/ssa/rewriteSW64.go b/src/cmd/compile/internal/ssa/rewriteSW64.go +new file mode 100644 +index 0000000000..dda8354fb1 +--- /dev/null ++++ b/src/cmd/compile/internal/ssa/rewriteSW64.go +@@ -0,0 +1,8723 @@ ++// Code generated from _gen/SW64.rules using 'go generate'; DO NOT EDIT. ++ ++package ssa ++ ++import "internal/buildcfg" ++import "cmd/compile/internal/types" ++ ++func rewriteValueSW64(v *Value) bool { ++ switch v.Op { ++ case OpAbs: ++ v.Op = OpSW64FABS ++ return true ++ case OpAdd16: ++ v.Op = OpSW64ADDV ++ return true ++ case OpAdd32: ++ v.Op = OpSW64ADDV ++ return true ++ case OpAdd32F: ++ v.Op = OpSW64FADDS ++ return true ++ case OpAdd64: ++ v.Op = OpSW64ADDV ++ return true ++ case OpAdd64F: ++ v.Op = OpSW64FADDD ++ return true ++ case OpAdd8: ++ v.Op = OpSW64ADDV ++ return true ++ case OpAddPtr: ++ v.Op = OpSW64ADDV ++ return true ++ case OpAddr: ++ return rewriteValueSW64_OpAddr(v) ++ case OpAnd16: ++ v.Op = OpSW64AND ++ return true ++ case OpAnd32: ++ v.Op = OpSW64AND ++ return true ++ case OpAnd64: ++ v.Op = OpSW64AND ++ return true ++ case OpAnd8: ++ v.Op = OpSW64AND ++ return true ++ case OpAndB: ++ v.Op = OpSW64AND ++ return true ++ case OpAtomicAdd32: ++ v.Op = OpSW64LoweredAtomicAdd32 ++ return true ++ case OpAtomicAdd64: ++ v.Op = OpSW64LoweredAtomicAdd64 ++ return true ++ case OpAtomicCompareAndSwap32: ++ return rewriteValueSW64_OpAtomicCompareAndSwap32(v) ++ case OpAtomicCompareAndSwap64: ++ v.Op = OpSW64LoweredAtomicCas64 ++ return true ++ case OpAtomicExchange32: ++ v.Op = OpSW64LoweredAtomicExchange32 ++ return true ++ case OpAtomicExchange64: ++ v.Op = OpSW64LoweredAtomicExchange64 ++ return true ++ case OpAtomicLoad32: ++ v.Op = OpSW64LoweredAtomicLoad32 ++ return true ++ case OpAtomicLoad64: ++ v.Op = OpSW64LoweredAtomicLoad64 ++ return true ++ case OpAtomicLoad8: ++ v.Op = OpSW64LoweredAtomicLoad8 ++ return true ++ case OpAtomicLoadPtr: ++ v.Op = OpSW64LoweredAtomicLoad64 ++ return true ++ case OpAtomicStore32: ++ v.Op = OpSW64LoweredAtomicStore32 ++ return true ++ case OpAtomicStore64: ++ v.Op = OpSW64LoweredAtomicStore64 ++ return true ++ case OpAtomicStore8: ++ v.Op = OpSW64LoweredAtomicStore8 ++ return true ++ case OpAtomicStorePtrNoWB: ++ v.Op = OpSW64LoweredAtomicStore64 ++ return true ++ case OpAvg64u: ++ return rewriteValueSW64_OpAvg64u(v) ++ case OpCeil: ++ v.Op = OpSW64FCVTDL_P ++ return true ++ case OpClosureCall: ++ v.Op = OpSW64CALLclosure ++ return true ++ case OpCom16: ++ return rewriteValueSW64_OpCom16(v) ++ case OpCom32: ++ return rewriteValueSW64_OpCom32(v) ++ case OpCom64: ++ return rewriteValueSW64_OpCom64(v) ++ case OpCom8: ++ return rewriteValueSW64_OpCom8(v) ++ case OpConst16: ++ return rewriteValueSW64_OpConst16(v) ++ case OpConst32: ++ return rewriteValueSW64_OpConst32(v) ++ case OpConst32F: ++ return rewriteValueSW64_OpConst32F(v) ++ case OpConst64: ++ return rewriteValueSW64_OpConst64(v) ++ case OpConst64F: ++ return rewriteValueSW64_OpConst64F(v) ++ case OpConst8: ++ return rewriteValueSW64_OpConst8(v) ++ case OpConstBool: ++ return rewriteValueSW64_OpConstBool(v) ++ case OpConstNil: ++ return rewriteValueSW64_OpConstNil(v) ++ case OpConvert: ++ v.Op = OpSW64MOVVconvert ++ return true ++ case OpCopysign: ++ return rewriteValueSW64_OpCopysign(v) ++ case OpCtz32: ++ return rewriteValueSW64_OpCtz32(v) ++ case OpCtz32NonZero: ++ v.Op = OpCtz32 ++ return true ++ case OpCtz64: ++ v.Op = OpSW64CTTZ ++ return true ++ case OpCtz64NonZero: ++ v.Op = OpCtz64 ++ return true ++ case OpCvt32Fto32: ++ return rewriteValueSW64_OpCvt32Fto32(v) ++ case OpCvt32Fto64: ++ return rewriteValueSW64_OpCvt32Fto64(v) ++ case OpCvt32Fto64F: ++ v.Op = OpSW64FCVTSD ++ return true ++ case OpCvt32to32F: ++ return rewriteValueSW64_OpCvt32to32F(v) ++ case OpCvt32to64F: ++ return rewriteValueSW64_OpCvt32to64F(v) ++ case OpCvt64Fto32: ++ return rewriteValueSW64_OpCvt64Fto32(v) ++ case OpCvt64Fto32F: ++ v.Op = OpSW64FCVTDS ++ return true ++ case OpCvt64Fto64: ++ return rewriteValueSW64_OpCvt64Fto64(v) ++ case OpCvt64to32F: ++ v.Op = OpSW64FCVTLS ++ return true ++ case OpCvt64to64F: ++ v.Op = OpSW64FCVTLD ++ return true ++ case OpCvtBoolToUint8: ++ v.Op = OpCopy ++ return true ++ case OpDiv16: ++ return rewriteValueSW64_OpDiv16(v) ++ case OpDiv16u: ++ return rewriteValueSW64_OpDiv16u(v) ++ case OpDiv32: ++ return rewriteValueSW64_OpDiv32(v) ++ case OpDiv32F: ++ v.Op = OpSW64FDIVS ++ return true ++ case OpDiv32u: ++ return rewriteValueSW64_OpDiv32u(v) ++ case OpDiv64: ++ return rewriteValueSW64_OpDiv64(v) ++ case OpDiv64F: ++ v.Op = OpSW64FDIVD ++ return true ++ case OpDiv64u: ++ return rewriteValueSW64_OpDiv64u(v) ++ case OpDiv8: ++ return rewriteValueSW64_OpDiv8(v) ++ case OpDiv8u: ++ return rewriteValueSW64_OpDiv8u(v) ++ case OpEq16: ++ return rewriteValueSW64_OpEq16(v) ++ case OpEq32: ++ return rewriteValueSW64_OpEq32(v) ++ case OpEq32F: ++ return rewriteValueSW64_OpEq32F(v) ++ case OpEq64: ++ v.Op = OpSW64CMPEQ ++ return true ++ case OpEq64F: ++ return rewriteValueSW64_OpEq64F(v) ++ case OpEq8: ++ return rewriteValueSW64_OpEq8(v) ++ case OpEqB: ++ return rewriteValueSW64_OpEqB(v) ++ case OpEqPtr: ++ v.Op = OpSW64CMPEQ ++ return true ++ case OpFloor: ++ v.Op = OpSW64FCVTDL_N ++ return true ++ case OpGetCallerPC: ++ v.Op = OpSW64LoweredGetCallerPC ++ return true ++ case OpGetCallerSP: ++ v.Op = OpSW64LoweredGetCallerSP ++ return true ++ case OpGetClosurePtr: ++ v.Op = OpSW64LoweredGetClosurePtr ++ return true ++ case OpHmul32: ++ return rewriteValueSW64_OpHmul32(v) ++ case OpHmul32u: ++ return rewriteValueSW64_OpHmul32u(v) ++ case OpHmul64: ++ return rewriteValueSW64_OpHmul64(v) ++ case OpHmul64u: ++ v.Op = OpSW64UMULH ++ return true ++ case OpInterCall: ++ v.Op = OpSW64CALLinter ++ return true ++ case OpIsInBounds: ++ v.Op = OpSW64CMPULT ++ return true ++ case OpIsNonNil: ++ return rewriteValueSW64_OpIsNonNil(v) ++ case OpIsSliceInBounds: ++ v.Op = OpSW64CMPULE ++ return true ++ case OpLeq16: ++ return rewriteValueSW64_OpLeq16(v) ++ case OpLeq16U: ++ return rewriteValueSW64_OpLeq16U(v) ++ case OpLeq32: ++ return rewriteValueSW64_OpLeq32(v) ++ case OpLeq32F: ++ return rewriteValueSW64_OpLeq32F(v) ++ case OpLeq32U: ++ return rewriteValueSW64_OpLeq32U(v) ++ case OpLeq64: ++ v.Op = OpSW64CMPLE ++ return true ++ case OpLeq64F: ++ return rewriteValueSW64_OpLeq64F(v) ++ case OpLeq64U: ++ v.Op = OpSW64CMPULE ++ return true ++ case OpLeq8: ++ return rewriteValueSW64_OpLeq8(v) ++ case OpLeq8U: ++ return rewriteValueSW64_OpLeq8U(v) ++ case OpLess16: ++ return rewriteValueSW64_OpLess16(v) ++ case OpLess16U: ++ return rewriteValueSW64_OpLess16U(v) ++ case OpLess32: ++ return rewriteValueSW64_OpLess32(v) ++ case OpLess32F: ++ return rewriteValueSW64_OpLess32F(v) ++ case OpLess32U: ++ return rewriteValueSW64_OpLess32U(v) ++ case OpLess64: ++ v.Op = OpSW64CMPLT ++ return true ++ case OpLess64F: ++ return rewriteValueSW64_OpLess64F(v) ++ case OpLess64U: ++ v.Op = OpSW64CMPULT ++ return true ++ case OpLess8: ++ return rewriteValueSW64_OpLess8(v) ++ case OpLess8U: ++ return rewriteValueSW64_OpLess8U(v) ++ case OpLoad: ++ return rewriteValueSW64_OpLoad(v) ++ case OpLocalAddr: ++ return rewriteValueSW64_OpLocalAddr(v) ++ case OpLsh16x16: ++ return rewriteValueSW64_OpLsh16x16(v) ++ case OpLsh16x32: ++ return rewriteValueSW64_OpLsh16x32(v) ++ case OpLsh16x64: ++ return rewriteValueSW64_OpLsh16x64(v) ++ case OpLsh16x8: ++ return rewriteValueSW64_OpLsh16x8(v) ++ case OpLsh32x16: ++ return rewriteValueSW64_OpLsh32x16(v) ++ case OpLsh32x32: ++ return rewriteValueSW64_OpLsh32x32(v) ++ case OpLsh32x64: ++ return rewriteValueSW64_OpLsh32x64(v) ++ case OpLsh32x8: ++ return rewriteValueSW64_OpLsh32x8(v) ++ case OpLsh64x16: ++ return rewriteValueSW64_OpLsh64x16(v) ++ case OpLsh64x32: ++ return rewriteValueSW64_OpLsh64x32(v) ++ case OpLsh64x64: ++ return rewriteValueSW64_OpLsh64x64(v) ++ case OpLsh64x8: ++ return rewriteValueSW64_OpLsh64x8(v) ++ case OpLsh8x16: ++ return rewriteValueSW64_OpLsh8x16(v) ++ case OpLsh8x32: ++ return rewriteValueSW64_OpLsh8x32(v) ++ case OpLsh8x64: ++ return rewriteValueSW64_OpLsh8x64(v) ++ case OpLsh8x8: ++ return rewriteValueSW64_OpLsh8x8(v) ++ case OpMod16: ++ return rewriteValueSW64_OpMod16(v) ++ case OpMod16u: ++ return rewriteValueSW64_OpMod16u(v) ++ case OpMod32: ++ return rewriteValueSW64_OpMod32(v) ++ case OpMod32u: ++ return rewriteValueSW64_OpMod32u(v) ++ case OpMod64: ++ return rewriteValueSW64_OpMod64(v) ++ case OpMod64u: ++ return rewriteValueSW64_OpMod64u(v) ++ case OpMod8: ++ return rewriteValueSW64_OpMod8(v) ++ case OpMod8u: ++ return rewriteValueSW64_OpMod8u(v) ++ case OpMove: ++ return rewriteValueSW64_OpMove(v) ++ case OpMul16: ++ v.Op = OpSW64MULW ++ return true ++ case OpMul32: ++ v.Op = OpSW64MULW ++ return true ++ case OpMul32F: ++ v.Op = OpSW64FMULS ++ return true ++ case OpMul64: ++ v.Op = OpSW64MULL ++ return true ++ case OpMul64F: ++ v.Op = OpSW64FMULD ++ return true ++ case OpMul8: ++ v.Op = OpSW64MULW ++ return true ++ case OpNeg16: ++ v.Op = OpSW64NEGV ++ return true ++ case OpNeg32: ++ v.Op = OpSW64NEGV ++ return true ++ case OpNeg32F: ++ v.Op = OpSW64NEGF ++ return true ++ case OpNeg64: ++ v.Op = OpSW64NEGV ++ return true ++ case OpNeg64F: ++ v.Op = OpSW64NEGD ++ return true ++ case OpNeg8: ++ v.Op = OpSW64NEGV ++ return true ++ case OpNeq16: ++ return rewriteValueSW64_OpNeq16(v) ++ case OpNeq32: ++ return rewriteValueSW64_OpNeq32(v) ++ case OpNeq32F: ++ return rewriteValueSW64_OpNeq32F(v) ++ case OpNeq64: ++ return rewriteValueSW64_OpNeq64(v) ++ case OpNeq64F: ++ return rewriteValueSW64_OpNeq64F(v) ++ case OpNeq8: ++ return rewriteValueSW64_OpNeq8(v) ++ case OpNeqB: ++ v.Op = OpSW64XOR ++ return true ++ case OpNeqPtr: ++ return rewriteValueSW64_OpNeqPtr(v) ++ case OpNilCheck: ++ v.Op = OpSW64LoweredNilCheck ++ return true ++ case OpNot: ++ return rewriteValueSW64_OpNot(v) ++ case OpOffPtr: ++ return rewriteValueSW64_OpOffPtr(v) ++ case OpOr16: ++ v.Op = OpSW64BIS ++ return true ++ case OpOr32: ++ v.Op = OpSW64BIS ++ return true ++ case OpOr64: ++ v.Op = OpSW64BIS ++ return true ++ case OpOr8: ++ v.Op = OpSW64BIS ++ return true ++ case OpOrB: ++ v.Op = OpSW64BIS ++ return true ++ case OpPanicBounds: ++ return rewriteValueSW64_OpPanicBounds(v) ++ case OpPopCount16: ++ return rewriteValueSW64_OpPopCount16(v) ++ case OpPopCount32: ++ return rewriteValueSW64_OpPopCount32(v) ++ case OpPopCount64: ++ v.Op = OpSW64CTPOP ++ return true ++ case OpPopCount8: ++ return rewriteValueSW64_OpPopCount8(v) ++ case OpRotateLeft16: ++ return rewriteValueSW64_OpRotateLeft16(v) ++ case OpRotateLeft32: ++ return rewriteValueSW64_OpRotateLeft32(v) ++ case OpRotateLeft64: ++ return rewriteValueSW64_OpRotateLeft64(v) ++ case OpRotateLeft8: ++ return rewriteValueSW64_OpRotateLeft8(v) ++ case OpRound: ++ v.Op = OpSW64FCVTDL_G ++ return true ++ case OpRound32F: ++ v.Op = OpCopy ++ return true ++ case OpRound64F: ++ v.Op = OpCopy ++ return true ++ case OpRsh16Ux16: ++ return rewriteValueSW64_OpRsh16Ux16(v) ++ case OpRsh16Ux32: ++ return rewriteValueSW64_OpRsh16Ux32(v) ++ case OpRsh16Ux64: ++ return rewriteValueSW64_OpRsh16Ux64(v) ++ case OpRsh16Ux8: ++ return rewriteValueSW64_OpRsh16Ux8(v) ++ case OpRsh16x16: ++ return rewriteValueSW64_OpRsh16x16(v) ++ case OpRsh16x32: ++ return rewriteValueSW64_OpRsh16x32(v) ++ case OpRsh16x64: ++ return rewriteValueSW64_OpRsh16x64(v) ++ case OpRsh16x8: ++ return rewriteValueSW64_OpRsh16x8(v) ++ case OpRsh32Ux16: ++ return rewriteValueSW64_OpRsh32Ux16(v) ++ case OpRsh32Ux32: ++ return rewriteValueSW64_OpRsh32Ux32(v) ++ case OpRsh32Ux64: ++ return rewriteValueSW64_OpRsh32Ux64(v) ++ case OpRsh32Ux8: ++ return rewriteValueSW64_OpRsh32Ux8(v) ++ case OpRsh32x16: ++ return rewriteValueSW64_OpRsh32x16(v) ++ case OpRsh32x32: ++ return rewriteValueSW64_OpRsh32x32(v) ++ case OpRsh32x64: ++ return rewriteValueSW64_OpRsh32x64(v) ++ case OpRsh32x8: ++ return rewriteValueSW64_OpRsh32x8(v) ++ case OpRsh64Ux16: ++ return rewriteValueSW64_OpRsh64Ux16(v) ++ case OpRsh64Ux32: ++ return rewriteValueSW64_OpRsh64Ux32(v) ++ case OpRsh64Ux64: ++ return rewriteValueSW64_OpRsh64Ux64(v) ++ case OpRsh64Ux8: ++ return rewriteValueSW64_OpRsh64Ux8(v) ++ case OpRsh64x16: ++ return rewriteValueSW64_OpRsh64x16(v) ++ case OpRsh64x32: ++ return rewriteValueSW64_OpRsh64x32(v) ++ case OpRsh64x64: ++ return rewriteValueSW64_OpRsh64x64(v) ++ case OpRsh64x8: ++ return rewriteValueSW64_OpRsh64x8(v) ++ case OpRsh8Ux16: ++ return rewriteValueSW64_OpRsh8Ux16(v) ++ case OpRsh8Ux32: ++ return rewriteValueSW64_OpRsh8Ux32(v) ++ case OpRsh8Ux64: ++ return rewriteValueSW64_OpRsh8Ux64(v) ++ case OpRsh8Ux8: ++ return rewriteValueSW64_OpRsh8Ux8(v) ++ case OpRsh8x16: ++ return rewriteValueSW64_OpRsh8x16(v) ++ case OpRsh8x32: ++ return rewriteValueSW64_OpRsh8x32(v) ++ case OpRsh8x64: ++ return rewriteValueSW64_OpRsh8x64(v) ++ case OpRsh8x8: ++ return rewriteValueSW64_OpRsh8x8(v) ++ case OpSW64ADDV: ++ return rewriteValueSW64_OpSW64ADDV(v) ++ case OpSW64ADDVconst: ++ return rewriteValueSW64_OpSW64ADDVconst(v) ++ case OpSW64ADDWconst: ++ return rewriteValueSW64_OpSW64ADDWconst(v) ++ case OpSW64AND: ++ return rewriteValueSW64_OpSW64AND(v) ++ case OpSW64ANDconst: ++ return rewriteValueSW64_OpSW64ANDconst(v) ++ case OpSW64BIS: ++ return rewriteValueSW64_OpSW64BIS(v) ++ case OpSW64BISconst: ++ return rewriteValueSW64_OpSW64BISconst(v) ++ case OpSW64CMPEQ: ++ return rewriteValueSW64_OpSW64CMPEQ(v) ++ case OpSW64CMPLE: ++ return rewriteValueSW64_OpSW64CMPLE(v) ++ case OpSW64CMPLT: ++ return rewriteValueSW64_OpSW64CMPLT(v) ++ case OpSW64CMPULE: ++ return rewriteValueSW64_OpSW64CMPULE(v) ++ case OpSW64CMPULT: ++ return rewriteValueSW64_OpSW64CMPULT(v) ++ case OpSW64MOVBUload: ++ return rewriteValueSW64_OpSW64MOVBUload(v) ++ case OpSW64MOVBUreg: ++ return rewriteValueSW64_OpSW64MOVBUreg(v) ++ case OpSW64MOVBload: ++ return rewriteValueSW64_OpSW64MOVBload(v) ++ case OpSW64MOVBreg: ++ return rewriteValueSW64_OpSW64MOVBreg(v) ++ case OpSW64MOVBstore: ++ return rewriteValueSW64_OpSW64MOVBstore(v) ++ case OpSW64MOVBstorezero: ++ return rewriteValueSW64_OpSW64MOVBstorezero(v) ++ case OpSW64MOVDload: ++ return rewriteValueSW64_OpSW64MOVDload(v) ++ case OpSW64MOVDstore: ++ return rewriteValueSW64_OpSW64MOVDstore(v) ++ case OpSW64MOVFload: ++ return rewriteValueSW64_OpSW64MOVFload(v) ++ case OpSW64MOVFstore: ++ return rewriteValueSW64_OpSW64MOVFstore(v) ++ case OpSW64MOVHUload: ++ return rewriteValueSW64_OpSW64MOVHUload(v) ++ case OpSW64MOVHUreg: ++ return rewriteValueSW64_OpSW64MOVHUreg(v) ++ case OpSW64MOVHload: ++ return rewriteValueSW64_OpSW64MOVHload(v) ++ case OpSW64MOVHreg: ++ return rewriteValueSW64_OpSW64MOVHreg(v) ++ case OpSW64MOVHstore: ++ return rewriteValueSW64_OpSW64MOVHstore(v) ++ case OpSW64MOVHstorezero: ++ return rewriteValueSW64_OpSW64MOVHstorezero(v) ++ case OpSW64MOVVload: ++ return rewriteValueSW64_OpSW64MOVVload(v) ++ case OpSW64MOVVnop: ++ return rewriteValueSW64_OpSW64MOVVnop(v) ++ case OpSW64MOVVreg: ++ return rewriteValueSW64_OpSW64MOVVreg(v) ++ case OpSW64MOVVstore: ++ return rewriteValueSW64_OpSW64MOVVstore(v) ++ case OpSW64MOVVstorezero: ++ return rewriteValueSW64_OpSW64MOVVstorezero(v) ++ case OpSW64MOVWUload: ++ return rewriteValueSW64_OpSW64MOVWUload(v) ++ case OpSW64MOVWUreg: ++ return rewriteValueSW64_OpSW64MOVWUreg(v) ++ case OpSW64MOVWload: ++ return rewriteValueSW64_OpSW64MOVWload(v) ++ case OpSW64MOVWreg: ++ return rewriteValueSW64_OpSW64MOVWreg(v) ++ case OpSW64MOVWstore: ++ return rewriteValueSW64_OpSW64MOVWstore(v) ++ case OpSW64MOVWstorezero: ++ return rewriteValueSW64_OpSW64MOVWstorezero(v) ++ case OpSW64MULL: ++ return rewriteValueSW64_OpSW64MULL(v) ++ case OpSW64MULW: ++ return rewriteValueSW64_OpSW64MULW(v) ++ case OpSW64NEGV: ++ return rewriteValueSW64_OpSW64NEGV(v) ++ case OpSW64ORNOT: ++ return rewriteValueSW64_OpSW64ORNOT(v) ++ case OpSW64SEXTB: ++ return rewriteValueSW64_OpSW64SEXTB(v) ++ case OpSW64SEXTH: ++ return rewriteValueSW64_OpSW64SEXTH(v) ++ case OpSW64SLLconst: ++ return rewriteValueSW64_OpSW64SLLconst(v) ++ case OpSW64SRAconst: ++ return rewriteValueSW64_OpSW64SRAconst(v) ++ case OpSW64SRLconst: ++ return rewriteValueSW64_OpSW64SRLconst(v) ++ case OpSW64SUBV: ++ return rewriteValueSW64_OpSW64SUBV(v) ++ case OpSW64SUBVconst: ++ return rewriteValueSW64_OpSW64SUBVconst(v) ++ case OpSW64XOR: ++ return rewriteValueSW64_OpSW64XOR(v) ++ case OpSW64XORconst: ++ return rewriteValueSW64_OpSW64XORconst(v) ++ case OpSignExt16to32: ++ v.Op = OpSW64MOVHreg ++ return true ++ case OpSignExt16to64: ++ v.Op = OpSW64MOVHreg ++ return true ++ case OpSignExt32to64: ++ v.Op = OpSW64MOVWreg ++ return true ++ case OpSignExt8to16: ++ v.Op = OpSW64MOVBreg ++ return true ++ case OpSignExt8to32: ++ v.Op = OpSW64MOVBreg ++ return true ++ case OpSignExt8to64: ++ v.Op = OpSW64MOVBreg ++ return true ++ case OpSignmask: ++ return rewriteValueSW64_OpSignmask(v) ++ case OpSlicemask: ++ return rewriteValueSW64_OpSlicemask(v) ++ case OpSqrt: ++ v.Op = OpSW64FSQRTD ++ return true ++ case OpSqrt32: ++ v.Op = OpSW64FSQRTS ++ return true ++ case OpStaticCall: ++ v.Op = OpSW64CALLstatic ++ return true ++ case OpStore: ++ return rewriteValueSW64_OpStore(v) ++ case OpSub16: ++ v.Op = OpSW64SUBV ++ return true ++ case OpSub32: ++ v.Op = OpSW64SUBV ++ return true ++ case OpSub32F: ++ v.Op = OpSW64FSUBS ++ return true ++ case OpSub64: ++ v.Op = OpSW64SUBV ++ return true ++ case OpSub64F: ++ v.Op = OpSW64FSUBD ++ return true ++ case OpSub8: ++ v.Op = OpSW64SUBV ++ return true ++ case OpSubPtr: ++ v.Op = OpSW64SUBV ++ return true ++ case OpTailCall: ++ v.Op = OpSW64CALLtail ++ return true ++ case OpTrunc: ++ v.Op = OpSW64FCVTDL_Z ++ return true ++ case OpTrunc16to8: ++ v.Op = OpCopy ++ return true ++ case OpTrunc32to16: ++ v.Op = OpCopy ++ return true ++ case OpTrunc32to8: ++ v.Op = OpCopy ++ return true ++ case OpTrunc64to16: ++ v.Op = OpCopy ++ return true ++ case OpTrunc64to32: ++ v.Op = OpCopy ++ return true ++ case OpTrunc64to8: ++ v.Op = OpCopy ++ return true ++ case OpWB: ++ v.Op = OpSW64LoweredWB ++ return true ++ case OpXor16: ++ v.Op = OpSW64XOR ++ return true ++ case OpXor32: ++ v.Op = OpSW64XOR ++ return true ++ case OpXor64: ++ v.Op = OpSW64XOR ++ return true ++ case OpXor8: ++ v.Op = OpSW64XOR ++ return true ++ case OpZero: ++ return rewriteValueSW64_OpZero(v) ++ case OpZeroExt16to32: ++ v.Op = OpSW64MOVHUreg ++ return true ++ case OpZeroExt16to64: ++ v.Op = OpSW64MOVHUreg ++ return true ++ case OpZeroExt32to64: ++ v.Op = OpSW64MOVWUreg ++ return true ++ case OpZeroExt8to16: ++ v.Op = OpSW64MOVBUreg ++ return true ++ case OpZeroExt8to32: ++ v.Op = OpSW64MOVBUreg ++ return true ++ case OpZeroExt8to64: ++ v.Op = OpSW64MOVBUreg ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpAddr(v *Value) bool { ++ v_0 := v.Args[0] ++ // match: (Addr {sym} base) ++ // result: (SYMADDR {sym} base) ++ for { ++ sym := auxToSym(v.Aux) ++ base := v_0 ++ v.reset(OpSW64SYMADDR) ++ v.Aux = symToAux(sym) ++ v.AddArg(base) ++ return true ++ } ++} ++func rewriteValueSW64_OpAtomicCompareAndSwap32(v *Value) bool { ++ v_3 := v.Args[3] ++ v_2 := v.Args[2] ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (AtomicCompareAndSwap32 ptr old new mem) ++ // result: (LoweredAtomicCas32 ptr (SignExt32to64 old) new mem) ++ for { ++ ptr := v_0 ++ old := v_1 ++ new := v_2 ++ mem := v_3 ++ v.reset(OpSW64LoweredAtomicCas32) ++ v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) ++ v0.AddArg(old) ++ v.AddArg4(ptr, v0, new, mem) ++ return true ++ } ++} ++func rewriteValueSW64_OpAvg64u(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ // match: (Avg64u x y) ++ // result: (ADDV (SRLconst (SUBV x y) [1]) y) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64ADDV) ++ v0 := b.NewValue0(v.Pos, OpSW64SRLconst, t) ++ v0.AuxInt = int64ToAuxInt(1) ++ v1 := b.NewValue0(v.Pos, OpSW64SUBV, t) ++ v1.AddArg2(x, y) ++ v0.AddArg(v1) ++ v.AddArg2(v0, y) ++ return true ++ } ++} ++func rewriteValueSW64_OpCom16(v *Value) bool { ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Com16 x) ++ // result: (ORNOT (MOVVconst [0]) x) ++ for { ++ x := v_0 ++ v.reset(OpSW64ORNOT) ++ v0 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v0.AuxInt = int64ToAuxInt(0) ++ v.AddArg2(v0, x) ++ return true ++ } ++} ++func rewriteValueSW64_OpCom32(v *Value) bool { ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Com32 x) ++ // result: (ORNOT (MOVVconst [0]) x) ++ for { ++ x := v_0 ++ v.reset(OpSW64ORNOT) ++ v0 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v0.AuxInt = int64ToAuxInt(0) ++ v.AddArg2(v0, x) ++ return true ++ } ++} ++func rewriteValueSW64_OpCom64(v *Value) bool { ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Com64 x) ++ // result: (ORNOT (MOVVconst [0]) x) ++ for { ++ x := v_0 ++ v.reset(OpSW64ORNOT) ++ v0 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v0.AuxInt = int64ToAuxInt(0) ++ v.AddArg2(v0, x) ++ return true ++ } ++} ++func rewriteValueSW64_OpCom8(v *Value) bool { ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Com8 x) ++ // result: (ORNOT (MOVVconst [0]) x) ++ for { ++ x := v_0 ++ v.reset(OpSW64ORNOT) ++ v0 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v0.AuxInt = int64ToAuxInt(0) ++ v.AddArg2(v0, x) ++ return true ++ } ++} ++func rewriteValueSW64_OpConst16(v *Value) bool { ++ // match: (Const16 [val]) ++ // result: (MOVVconst [int64(val)]) ++ for { ++ val := auxIntToInt16(v.AuxInt) ++ v.reset(OpSW64MOVVconst) ++ v.AuxInt = int64ToAuxInt(int64(val)) ++ return true ++ } ++} ++func rewriteValueSW64_OpConst32(v *Value) bool { ++ // match: (Const32 [val]) ++ // result: (MOVVconst [int64(val)]) ++ for { ++ val := auxIntToInt32(v.AuxInt) ++ v.reset(OpSW64MOVVconst) ++ v.AuxInt = int64ToAuxInt(int64(val)) ++ return true ++ } ++} ++func rewriteValueSW64_OpConst32F(v *Value) bool { ++ // match: (Const32F [val]) ++ // result: (MOVFconst [float64(val)]) ++ for { ++ val := auxIntToFloat32(v.AuxInt) ++ v.reset(OpSW64MOVFconst) ++ v.AuxInt = float64ToAuxInt(float64(val)) ++ return true ++ } ++} ++func rewriteValueSW64_OpConst64(v *Value) bool { ++ // match: (Const64 [val]) ++ // result: (MOVVconst [int64(val)]) ++ for { ++ val := auxIntToInt64(v.AuxInt) ++ v.reset(OpSW64MOVVconst) ++ v.AuxInt = int64ToAuxInt(int64(val)) ++ return true ++ } ++} ++func rewriteValueSW64_OpConst64F(v *Value) bool { ++ // match: (Const64F [val]) ++ // result: (MOVDconst [float64(val)]) ++ for { ++ val := auxIntToFloat64(v.AuxInt) ++ v.reset(OpSW64MOVDconst) ++ v.AuxInt = float64ToAuxInt(float64(val)) ++ return true ++ } ++} ++func rewriteValueSW64_OpConst8(v *Value) bool { ++ // match: (Const8 [val]) ++ // result: (MOVVconst [int64(val)]) ++ for { ++ val := auxIntToInt8(v.AuxInt) ++ v.reset(OpSW64MOVVconst) ++ v.AuxInt = int64ToAuxInt(int64(val)) ++ return true ++ } ++} ++func rewriteValueSW64_OpConstBool(v *Value) bool { ++ // match: (ConstBool [t]) ++ // result: (MOVVconst [b2i(t)]) ++ for { ++ t := auxIntToBool(v.AuxInt) ++ v.reset(OpSW64MOVVconst) ++ v.AuxInt = int64ToAuxInt(b2i(t)) ++ return true ++ } ++} ++func rewriteValueSW64_OpConstNil(v *Value) bool { ++ // match: (ConstNil) ++ // result: (MOVVconst [0]) ++ for { ++ v.reset(OpSW64MOVVconst) ++ v.AuxInt = int64ToAuxInt(0) ++ return true ++ } ++} ++func rewriteValueSW64_OpCopysign(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ // match: (Copysign x y) ++ // result: (FCPYS y x) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64FCPYS) ++ v.AddArg2(y, x) ++ return true ++ } ++} ++func rewriteValueSW64_OpCtz32(v *Value) bool { ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Ctz32 x) ++ // result: (SUBV (CTTZ (ZeroExt32to64 x)) (MULLconst (CMPEQ (ZeroExt32to64 x) (MOVVconst [0]) ) [32])) ++ for { ++ t := v.Type ++ x := v_0 ++ v.reset(OpSW64SUBV) ++ v0 := b.NewValue0(v.Pos, OpSW64CTTZ, typ.UInt64) ++ v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) ++ v1.AddArg(x) ++ v0.AddArg(v1) ++ v2 := b.NewValue0(v.Pos, OpSW64MULLconst, t) ++ v2.AuxInt = int64ToAuxInt(32) ++ v3 := b.NewValue0(v.Pos, OpSW64CMPEQ, typ.Bool) ++ v4 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v4.AuxInt = int64ToAuxInt(0) ++ v3.AddArg2(v1, v4) ++ v2.AddArg(v3) ++ v.AddArg2(v0, v2) ++ return true ++ } ++} ++func rewriteValueSW64_OpCvt32Fto32(v *Value) bool { ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Cvt32Fto32 x) ++ // result: (FIMOVS (FCVTLW (FCVTDL_Z (FCVTSD x)))) ++ for { ++ x := v_0 ++ v.reset(OpSW64FIMOVS) ++ v0 := b.NewValue0(v.Pos, OpSW64FCVTLW, typ.Float32) ++ v1 := b.NewValue0(v.Pos, OpSW64FCVTDL_Z, typ.Float64) ++ v2 := b.NewValue0(v.Pos, OpSW64FCVTSD, typ.Float64) ++ v2.AddArg(x) ++ v1.AddArg(v2) ++ v0.AddArg(v1) ++ v.AddArg(v0) ++ return true ++ } ++} ++func rewriteValueSW64_OpCvt32Fto64(v *Value) bool { ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Cvt32Fto64 x) ++ // result: (FIMOVD (FCVTDL_Z (FCVTSD x))) ++ for { ++ x := v_0 ++ v.reset(OpSW64FIMOVD) ++ v0 := b.NewValue0(v.Pos, OpSW64FCVTDL_Z, typ.Float64) ++ v1 := b.NewValue0(v.Pos, OpSW64FCVTSD, typ.Float64) ++ v1.AddArg(x) ++ v0.AddArg(v1) ++ v.AddArg(v0) ++ return true ++ } ++} ++func rewriteValueSW64_OpCvt32to32F(v *Value) bool { ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Cvt32to32F x) ++ // result: (FCVTLS (IFMOVD x)) ++ for { ++ x := v_0 ++ v.reset(OpSW64FCVTLS) ++ v0 := b.NewValue0(v.Pos, OpSW64IFMOVD, typ.Float64) ++ v0.AddArg(x) ++ v.AddArg(v0) ++ return true ++ } ++} ++func rewriteValueSW64_OpCvt32to64F(v *Value) bool { ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Cvt32to64F x) ++ // result: (FCVTLD (IFMOVD (SignExt32to64 x))) ++ for { ++ x := v_0 ++ v.reset(OpSW64FCVTLD) ++ v0 := b.NewValue0(v.Pos, OpSW64IFMOVD, typ.Float64) ++ v1 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) ++ v1.AddArg(x) ++ v0.AddArg(v1) ++ v.AddArg(v0) ++ return true ++ } ++} ++func rewriteValueSW64_OpCvt64Fto32(v *Value) bool { ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Cvt64Fto32 x) ++ // result: (FIMOVS (FCVTLW (FCVTDL_Z x))) ++ for { ++ x := v_0 ++ v.reset(OpSW64FIMOVS) ++ v0 := b.NewValue0(v.Pos, OpSW64FCVTLW, typ.Float32) ++ v1 := b.NewValue0(v.Pos, OpSW64FCVTDL_Z, typ.Float64) ++ v1.AddArg(x) ++ v0.AddArg(v1) ++ v.AddArg(v0) ++ return true ++ } ++} ++func rewriteValueSW64_OpCvt64Fto64(v *Value) bool { ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Cvt64Fto64 x) ++ // result: (FIMOVD (FCVTDL_Z x)) ++ for { ++ x := v_0 ++ v.reset(OpSW64FIMOVD) ++ v0 := b.NewValue0(v.Pos, OpSW64FCVTDL_Z, typ.Float64) ++ v0.AddArg(x) ++ v.AddArg(v0) ++ return true ++ } ++} ++func rewriteValueSW64_OpDiv16(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Div16 x y) ++ // result: (Div64 (SignExt16to64 x) (SignExt16to64 y)) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpDiv64) ++ v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) ++ v0.AddArg(x) ++ v1 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) ++ v1.AddArg(y) ++ v.AddArg2(v0, v1) ++ return true ++ } ++} ++func rewriteValueSW64_OpDiv16u(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Div16u x y) ++ // result: (Div64u (ZeroExt16to64 x) (ZeroExt16to64 y)) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpDiv64u) ++ v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) ++ v0.AddArg(x) ++ v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) ++ v1.AddArg(y) ++ v.AddArg2(v0, v1) ++ return true ++ } ++} ++func rewriteValueSW64_OpDiv32(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Div32 x y) ++ // cond: buildcfg.GOSW64 <=3 ++ // result: (Div64 (SignExt32to64 x) (SignExt32to64 y)) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(buildcfg.GOSW64 <= 3) { ++ break ++ } ++ v.reset(OpDiv64) ++ v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) ++ v0.AddArg(x) ++ v1 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) ++ v1.AddArg(y) ++ v.AddArg2(v0, v1) ++ return true ++ } ++ // match: (Div32 x y) ++ // cond: buildcfg.GOSW64 >=4 ++ // result: (DIVW x y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(buildcfg.GOSW64 >= 4) { ++ break ++ } ++ v.reset(OpSW64DIVW) ++ v.AddArg2(x, y) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpDiv32u(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Div32u x y) ++ // cond: buildcfg.GOSW64 <=3 ++ // result: (Div64u (ZeroExt32to64 x) (ZeroExt32to64 y)) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(buildcfg.GOSW64 <= 3) { ++ break ++ } ++ v.reset(OpDiv64u) ++ v0 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) ++ v0.AddArg(x) ++ v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) ++ v1.AddArg(y) ++ v.AddArg2(v0, v1) ++ return true ++ } ++ // match: (Div32u x y) ++ // cond: buildcfg.GOSW64 >=4 ++ // result: (UDIVW x y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(buildcfg.GOSW64 >= 4) { ++ break ++ } ++ v.reset(OpSW64UDIVW) ++ v.AddArg2(x, y) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpDiv64(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Div64 x y) ++ // cond: buildcfg.GOSW64 <=3 ++ // result: (SUBV (XOR (Select0 (CALLudiv (SUBV (XOR x (Signmask x)) (Signmask x)) (SUBV (XOR y (Signmask y)) (Signmask y)))) (Signmask (XOR x y))) (Signmask (XOR x y))) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(buildcfg.GOSW64 <= 3) { ++ break ++ } ++ v.reset(OpSW64SUBV) ++ v0 := b.NewValue0(v.Pos, OpSW64XOR, typ.UInt64) ++ v1 := b.NewValue0(v.Pos, OpSelect0, typ.UInt64) ++ v2 := b.NewValue0(v.Pos, OpSW64CALLudiv, types.NewTuple(typ.UInt64, typ.UInt64)) ++ v3 := b.NewValue0(v.Pos, OpSW64SUBV, typ.UInt64) ++ v4 := b.NewValue0(v.Pos, OpSW64XOR, typ.UInt64) ++ v5 := b.NewValue0(v.Pos, OpSignmask, typ.Int32) ++ v5.AddArg(x) ++ v4.AddArg2(x, v5) ++ v3.AddArg2(v4, v5) ++ v6 := b.NewValue0(v.Pos, OpSW64SUBV, typ.UInt64) ++ v7 := b.NewValue0(v.Pos, OpSW64XOR, typ.UInt64) ++ v8 := b.NewValue0(v.Pos, OpSignmask, typ.Int32) ++ v8.AddArg(y) ++ v7.AddArg2(y, v8) ++ v6.AddArg2(v7, v8) ++ v2.AddArg2(v3, v6) ++ v1.AddArg(v2) ++ v9 := b.NewValue0(v.Pos, OpSignmask, typ.Int32) ++ v10 := b.NewValue0(v.Pos, OpSW64XOR, typ.UInt64) ++ v10.AddArg2(x, y) ++ v9.AddArg(v10) ++ v0.AddArg2(v1, v9) ++ v.AddArg2(v0, v9) ++ return true ++ } ++ // match: (Div64 [false] x y) ++ // cond: buildcfg.GOSW64 >=4 ++ // result: (DIVV x y) ++ for { ++ if auxIntToBool(v.AuxInt) != false { ++ break ++ } ++ x := v_0 ++ y := v_1 ++ if !(buildcfg.GOSW64 >= 4) { ++ break ++ } ++ v.reset(OpSW64DIVV) ++ v.AddArg2(x, y) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpDiv64u(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Div64u x y) ++ // cond: buildcfg.GOSW64 <=3 ++ // result: (Select0 (CALLudiv x y)) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(buildcfg.GOSW64 <= 3) { ++ break ++ } ++ v.reset(OpSelect0) ++ v.Type = typ.UInt64 ++ v0 := b.NewValue0(v.Pos, OpSW64CALLudiv, types.NewTuple(typ.UInt64, typ.UInt64)) ++ v0.AddArg2(x, y) ++ v.AddArg(v0) ++ return true ++ } ++ // match: (Div64u x y) ++ // cond: buildcfg.GOSW64 >=4 ++ // result: (UDIVV x y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(buildcfg.GOSW64 >= 4) { ++ break ++ } ++ v.reset(OpSW64UDIVV) ++ v.AddArg2(x, y) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpDiv8(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Div8 x y) ++ // result: (Div64 (SignExt8to64 x) (SignExt8to64 y)) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpDiv64) ++ v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) ++ v0.AddArg(x) ++ v1 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) ++ v1.AddArg(y) ++ v.AddArg2(v0, v1) ++ return true ++ } ++} ++func rewriteValueSW64_OpDiv8u(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Div8u x y) ++ // result: (Div64u (ZeroExt8to64 x) (ZeroExt8to64 y)) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpDiv64u) ++ v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) ++ v0.AddArg(x) ++ v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) ++ v1.AddArg(y) ++ v.AddArg2(v0, v1) ++ return true ++ } ++} ++func rewriteValueSW64_OpEq16(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Eq16 x y) ++ // result: (CMPEQ (ZeroExt16to64 x) (ZeroExt16to64 y)) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64CMPEQ) ++ v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) ++ v0.AddArg(x) ++ v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) ++ v1.AddArg(y) ++ v.AddArg2(v0, v1) ++ return true ++ } ++} ++func rewriteValueSW64_OpEq32(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Eq32 x y) ++ // result: (CMPEQ (ZeroExt32to64 x) (ZeroExt32to64 y)) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64CMPEQ) ++ v0 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) ++ v0.AddArg(x) ++ v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) ++ v1.AddArg(y) ++ v.AddArg2(v0, v1) ++ return true ++ } ++} ++func rewriteValueSW64_OpEq32F(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Eq32F x y) ++ // result: (FEqual (FCMPEQ x y)) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64FEqual) ++ v0 := b.NewValue0(v.Pos, OpSW64FCMPEQ, typ.Float64) ++ v0.AddArg2(x, y) ++ v.AddArg(v0) ++ return true ++ } ++} ++func rewriteValueSW64_OpEq64F(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Eq64F x y) ++ // result: (FEqual (FCMPEQ x y)) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64FEqual) ++ v0 := b.NewValue0(v.Pos, OpSW64FCMPEQ, typ.Float64) ++ v0.AddArg2(x, y) ++ v.AddArg(v0) ++ return true ++ } ++} ++func rewriteValueSW64_OpEq8(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Eq8 x y) ++ // result: (CMPEQ (ZeroExt8to64 x) (ZeroExt8to64 y)) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64CMPEQ) ++ v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) ++ v0.AddArg(x) ++ v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) ++ v1.AddArg(y) ++ v.AddArg2(v0, v1) ++ return true ++ } ++} ++func rewriteValueSW64_OpEqB(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (EqB x y) ++ // result: (XOR (MOVVconst [1]) (XOR x y) ) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64XOR) ++ v0 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v0.AuxInt = int64ToAuxInt(1) ++ v1 := b.NewValue0(v.Pos, OpSW64XOR, typ.Bool) ++ v1.AddArg2(x, y) ++ v.AddArg2(v0, v1) ++ return true ++ } ++} ++func rewriteValueSW64_OpHmul32(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Hmul32 x y) ++ // result: (SRAconst (MULL (SignExt32to64 x) (SignExt32to64 y)) [32]) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64SRAconst) ++ v.AuxInt = int64ToAuxInt(32) ++ v0 := b.NewValue0(v.Pos, OpSW64MULL, typ.Int64) ++ v1 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) ++ v1.AddArg(x) ++ v2 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) ++ v2.AddArg(y) ++ v0.AddArg2(v1, v2) ++ v.AddArg(v0) ++ return true ++ } ++} ++func rewriteValueSW64_OpHmul32u(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Hmul32u x y) ++ // result: (SRLconst (MULL (ZeroExt32to64 x) (ZeroExt32to64 y)) [32]) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64SRLconst) ++ v.AuxInt = int64ToAuxInt(32) ++ v0 := b.NewValue0(v.Pos, OpSW64MULL, typ.UInt64) ++ v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) ++ v1.AddArg(x) ++ v2 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) ++ v2.AddArg(y) ++ v0.AddArg2(v1, v2) ++ v.AddArg(v0) ++ return true ++ } ++} ++func rewriteValueSW64_OpHmul64(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Hmul64 x y) ++ // result: ( SUBV (SUBV (UMULH x y) (MULL (SRLconst x [63]) y)) (MULL (SRLconst y [63]) x) ) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64SUBV) ++ v.Type = typ.Int64 ++ v0 := b.NewValue0(v.Pos, OpSW64SUBV, typ.Int64) ++ v1 := b.NewValue0(v.Pos, OpSW64UMULH, typ.Int64) ++ v1.AddArg2(x, y) ++ v2 := b.NewValue0(v.Pos, OpSW64MULL, typ.Int64) ++ v3 := b.NewValue0(v.Pos, OpSW64SRLconst, typ.UInt64) ++ v3.AuxInt = int64ToAuxInt(63) ++ v3.AddArg(x) ++ v2.AddArg2(v3, y) ++ v0.AddArg2(v1, v2) ++ v4 := b.NewValue0(v.Pos, OpSW64MULL, typ.Int64) ++ v5 := b.NewValue0(v.Pos, OpSW64SRLconst, typ.UInt64) ++ v5.AuxInt = int64ToAuxInt(63) ++ v5.AddArg(y) ++ v4.AddArg2(v5, x) ++ v.AddArg2(v0, v4) ++ return true ++ } ++} ++func rewriteValueSW64_OpIsNonNil(v *Value) bool { ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (IsNonNil ptr) ++ // result: (CMPULT (MOVVconst [0]) ptr) ++ for { ++ ptr := v_0 ++ v.reset(OpSW64CMPULT) ++ v0 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v0.AuxInt = int64ToAuxInt(0) ++ v.AddArg2(v0, ptr) ++ return true ++ } ++} ++func rewriteValueSW64_OpLeq16(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Leq16 x y) ++ // result: (CMPLE (SignExt16to64 x) (SignExt16to64 y)) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64CMPLE) ++ v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) ++ v0.AddArg(x) ++ v1 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) ++ v1.AddArg(y) ++ v.AddArg2(v0, v1) ++ return true ++ } ++} ++func rewriteValueSW64_OpLeq16U(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Leq16U x y) ++ // result: (CMPULE (ZeroExt16to64 x) (ZeroExt16to64 y)) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64CMPULE) ++ v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) ++ v0.AddArg(x) ++ v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) ++ v1.AddArg(y) ++ v.AddArg2(v0, v1) ++ return true ++ } ++} ++func rewriteValueSW64_OpLeq32(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Leq32 x y) ++ // result: (CMPLE (SignExt32to64 x) (SignExt32to64 y)) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64CMPLE) ++ v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) ++ v0.AddArg(x) ++ v1 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) ++ v1.AddArg(y) ++ v.AddArg2(v0, v1) ++ return true ++ } ++} ++func rewriteValueSW64_OpLeq32F(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Leq32F x y) ++ // result: (FEqual (FCMPLE x y)) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64FEqual) ++ v0 := b.NewValue0(v.Pos, OpSW64FCMPLE, typ.Float64) ++ v0.AddArg2(x, y) ++ v.AddArg(v0) ++ return true ++ } ++} ++func rewriteValueSW64_OpLeq32U(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Leq32U x y) ++ // result: (CMPULE (ZeroExt32to64 x) (ZeroExt32to64 y)) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64CMPULE) ++ v0 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) ++ v0.AddArg(x) ++ v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) ++ v1.AddArg(y) ++ v.AddArg2(v0, v1) ++ return true ++ } ++} ++func rewriteValueSW64_OpLeq64F(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Leq64F x y) ++ // result: (FEqual (FCMPLE x y)) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64FEqual) ++ v0 := b.NewValue0(v.Pos, OpSW64FCMPLE, typ.Float64) ++ v0.AddArg2(x, y) ++ v.AddArg(v0) ++ return true ++ } ++} ++func rewriteValueSW64_OpLeq8(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Leq8 x y) ++ // result: (CMPLE (SignExt8to64 x) (SignExt8to64 y)) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64CMPLE) ++ v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) ++ v0.AddArg(x) ++ v1 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) ++ v1.AddArg(y) ++ v.AddArg2(v0, v1) ++ return true ++ } ++} ++func rewriteValueSW64_OpLeq8U(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Leq8U x y) ++ // result: (CMPULE (ZeroExt8to64 x) (ZeroExt8to64 y)) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64CMPULE) ++ v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) ++ v0.AddArg(x) ++ v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) ++ v1.AddArg(y) ++ v.AddArg2(v0, v1) ++ return true ++ } ++} ++func rewriteValueSW64_OpLess16(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Less16 x y) ++ // result: (CMPLT (SignExt16to64 x) (SignExt16to64 y)) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64CMPLT) ++ v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) ++ v0.AddArg(x) ++ v1 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) ++ v1.AddArg(y) ++ v.AddArg2(v0, v1) ++ return true ++ } ++} ++func rewriteValueSW64_OpLess16U(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Less16U x y) ++ // result: (CMPULT (ZeroExt16to64 x) (ZeroExt16to64 y)) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64CMPULT) ++ v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) ++ v0.AddArg(x) ++ v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) ++ v1.AddArg(y) ++ v.AddArg2(v0, v1) ++ return true ++ } ++} ++func rewriteValueSW64_OpLess32(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Less32 x y) ++ // result: (CMPLT (SignExt32to64 x) (SignExt32to64 y)) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64CMPLT) ++ v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) ++ v0.AddArg(x) ++ v1 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) ++ v1.AddArg(y) ++ v.AddArg2(v0, v1) ++ return true ++ } ++} ++func rewriteValueSW64_OpLess32F(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Less32F x y) ++ // result: (FEqual (FCMPLT x y)) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64FEqual) ++ v0 := b.NewValue0(v.Pos, OpSW64FCMPLT, typ.Float64) ++ v0.AddArg2(x, y) ++ v.AddArg(v0) ++ return true ++ } ++} ++func rewriteValueSW64_OpLess32U(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Less32U x y) ++ // result: (CMPULT (ZeroExt32to64 x) (ZeroExt32to64 y)) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64CMPULT) ++ v0 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) ++ v0.AddArg(x) ++ v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) ++ v1.AddArg(y) ++ v.AddArg2(v0, v1) ++ return true ++ } ++} ++func rewriteValueSW64_OpLess64F(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Less64F x y) ++ // result: (FEqual (FCMPLT x y)) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64FEqual) ++ v0 := b.NewValue0(v.Pos, OpSW64FCMPLT, typ.Float64) ++ v0.AddArg2(x, y) ++ v.AddArg(v0) ++ return true ++ } ++} ++func rewriteValueSW64_OpLess8(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Less8 x y) ++ // result: (CMPLT (SignExt8to64 x) (SignExt8to64 y)) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64CMPLT) ++ v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) ++ v0.AddArg(x) ++ v1 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) ++ v1.AddArg(y) ++ v.AddArg2(v0, v1) ++ return true ++ } ++} ++func rewriteValueSW64_OpLess8U(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Less8U x y) ++ // result: (CMPULT (ZeroExt8to64 x) (ZeroExt8to64 y)) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64CMPULT) ++ v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) ++ v0.AddArg(x) ++ v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) ++ v1.AddArg(y) ++ v.AddArg2(v0, v1) ++ return true ++ } ++} ++func rewriteValueSW64_OpLoad(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ // match: (Load ptr mem) ++ // cond: t.IsBoolean() ++ // result: (MOVBUload ptr mem) ++ for { ++ t := v.Type ++ ptr := v_0 ++ mem := v_1 ++ if !(t.IsBoolean()) { ++ break ++ } ++ v.reset(OpSW64MOVBUload) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ // match: (Load ptr mem) ++ // cond: (is8BitInt(t) && t.IsSigned()) ++ // result: (MOVBload ptr mem) ++ for { ++ t := v.Type ++ ptr := v_0 ++ mem := v_1 ++ if !(is8BitInt(t) && t.IsSigned()) { ++ break ++ } ++ v.reset(OpSW64MOVBload) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ // match: (Load ptr mem) ++ // cond: (is8BitInt(t) && !t.IsSigned()) ++ // result: (MOVBUload ptr mem) ++ for { ++ t := v.Type ++ ptr := v_0 ++ mem := v_1 ++ if !(is8BitInt(t) && !t.IsSigned()) { ++ break ++ } ++ v.reset(OpSW64MOVBUload) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ // match: (Load ptr mem) ++ // cond: (is16BitInt(t) && t.IsSigned()) ++ // result: (MOVHload ptr mem) ++ for { ++ t := v.Type ++ ptr := v_0 ++ mem := v_1 ++ if !(is16BitInt(t) && t.IsSigned()) { ++ break ++ } ++ v.reset(OpSW64MOVHload) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ // match: (Load ptr mem) ++ // cond: (is16BitInt(t) && !t.IsSigned()) ++ // result: (MOVHUload ptr mem) ++ for { ++ t := v.Type ++ ptr := v_0 ++ mem := v_1 ++ if !(is16BitInt(t) && !t.IsSigned()) { ++ break ++ } ++ v.reset(OpSW64MOVHUload) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ // match: (Load ptr mem) ++ // cond: (is32BitInt(t) && t.IsSigned()) ++ // result: (MOVWload ptr mem) ++ for { ++ t := v.Type ++ ptr := v_0 ++ mem := v_1 ++ if !(is32BitInt(t) && t.IsSigned()) { ++ break ++ } ++ v.reset(OpSW64MOVWload) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ // match: (Load ptr mem) ++ // cond: (is32BitInt(t) && !t.IsSigned()) ++ // result: (MOVWUload ptr mem) ++ for { ++ t := v.Type ++ ptr := v_0 ++ mem := v_1 ++ if !(is32BitInt(t) && !t.IsSigned()) { ++ break ++ } ++ v.reset(OpSW64MOVWUload) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ // match: (Load ptr mem) ++ // cond: (is64BitInt(t) || isPtr(t)) ++ // result: (MOVVload ptr mem) ++ for { ++ t := v.Type ++ ptr := v_0 ++ mem := v_1 ++ if !(is64BitInt(t) || isPtr(t)) { ++ break ++ } ++ v.reset(OpSW64MOVVload) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ // match: (Load ptr mem) ++ // cond: is32BitFloat(t) ++ // result: (MOVFload ptr mem) ++ for { ++ t := v.Type ++ ptr := v_0 ++ mem := v_1 ++ if !(is32BitFloat(t)) { ++ break ++ } ++ v.reset(OpSW64MOVFload) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ // match: (Load ptr mem) ++ // cond: is64BitFloat(t) ++ // result: (MOVDload ptr mem) ++ for { ++ t := v.Type ++ ptr := v_0 ++ mem := v_1 ++ if !(is64BitFloat(t)) { ++ break ++ } ++ v.reset(OpSW64MOVDload) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpLocalAddr(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (LocalAddr {sym} base mem) ++ // cond: t.Elem().HasPointers() ++ // result: (SYMADDR {sym} (SPanchored base mem)) ++ for { ++ t := v.Type ++ sym := auxToSym(v.Aux) ++ base := v_0 ++ mem := v_1 ++ if !(t.Elem().HasPointers()) { ++ break ++ } ++ v.reset(OpSW64SYMADDR) ++ v.Aux = symToAux(sym) ++ v0 := b.NewValue0(v.Pos, OpSPanchored, typ.Uintptr) ++ v0.AddArg2(base, mem) ++ v.AddArg(v0) ++ return true ++ } ++ // match: (LocalAddr {sym} base _) ++ // cond: !t.Elem().HasPointers() ++ // result: (SYMADDR {sym} base) ++ for { ++ t := v.Type ++ sym := auxToSym(v.Aux) ++ base := v_0 ++ if !(!t.Elem().HasPointers()) { ++ break ++ } ++ v.reset(OpSW64SYMADDR) ++ v.Aux = symToAux(sym) ++ v.AddArg(base) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpLsh16x16(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Lsh16x16 x y) ++ // result: (AND (NEGV (CMPULT (ZeroExt16to64 y) (MOVVconst [64]))) (SLL x (ZeroExt16to64 y))) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64AND) ++ v0 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v1 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v2 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) ++ v2.AddArg(y) ++ v3 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v3.AuxInt = int64ToAuxInt(64) ++ v1.AddArg2(v2, v3) ++ v0.AddArg(v1) ++ v4 := b.NewValue0(v.Pos, OpSW64SLL, t) ++ v4.AddArg2(x, v2) ++ v.AddArg2(v0, v4) ++ return true ++ } ++} ++func rewriteValueSW64_OpLsh16x32(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Lsh16x32 x y) ++ // result: (AND (NEGV (CMPULT (ZeroExt32to64 y) (MOVVconst [64]))) (SLL x (ZeroExt32to64 y))) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64AND) ++ v0 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v1 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v2 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) ++ v2.AddArg(y) ++ v3 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v3.AuxInt = int64ToAuxInt(64) ++ v1.AddArg2(v2, v3) ++ v0.AddArg(v1) ++ v4 := b.NewValue0(v.Pos, OpSW64SLL, t) ++ v4.AddArg2(x, v2) ++ v.AddArg2(v0, v4) ++ return true ++ } ++} ++func rewriteValueSW64_OpLsh16x64(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Lsh16x64 x (Const64 [c])) ++ // cond: uint64(c) < 16 ++ // result: (SLLconst (ZeroExt16to64 x) [c]) ++ for { ++ x := v_0 ++ if v_1.Op != OpConst64 { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(uint64(c) < 16) { ++ break ++ } ++ v.reset(OpSW64SLLconst) ++ v.AuxInt = int64ToAuxInt(c) ++ v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) ++ v0.AddArg(x) ++ v.AddArg(v0) ++ return true ++ } ++ // match: (Lsh16x64 x (MOVVconst [c])) ++ // cond: uint64(c) < 16 ++ // result: (SLLconst (ZeroExt16to64 x) [c]) ++ for { ++ x := v_0 ++ if v_1.Op != OpSW64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(uint64(c) < 16) { ++ break ++ } ++ v.reset(OpSW64SLLconst) ++ v.AuxInt = int64ToAuxInt(c) ++ v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) ++ v0.AddArg(x) ++ v.AddArg(v0) ++ return true ++ } ++ // match: (Lsh16x64 x y) ++ // result: (AND (NEGV (CMPULT y (MOVVconst [64]))) (SLL x y)) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64AND) ++ v0 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v1 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v2 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v2.AuxInt = int64ToAuxInt(64) ++ v1.AddArg2(y, v2) ++ v0.AddArg(v1) ++ v3 := b.NewValue0(v.Pos, OpSW64SLL, t) ++ v3.AddArg2(x, y) ++ v.AddArg2(v0, v3) ++ return true ++ } ++} ++func rewriteValueSW64_OpLsh16x8(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Lsh16x8 x y) ++ // result: (AND (NEGV (CMPULT (ZeroExt8to64 y) (MOVVconst [64]))) (SLL x (ZeroExt8to64 y))) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64AND) ++ v0 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v1 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v2 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) ++ v2.AddArg(y) ++ v3 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v3.AuxInt = int64ToAuxInt(64) ++ v1.AddArg2(v2, v3) ++ v0.AddArg(v1) ++ v4 := b.NewValue0(v.Pos, OpSW64SLL, t) ++ v4.AddArg2(x, v2) ++ v.AddArg2(v0, v4) ++ return true ++ } ++} ++func rewriteValueSW64_OpLsh32x16(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Lsh32x16 x y) ++ // result: (AND (NEGV (CMPULT (ZeroExt16to64 y) (MOVVconst [64]))) (SLL x (ZeroExt16to64 y))) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64AND) ++ v0 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v1 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v2 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) ++ v2.AddArg(y) ++ v3 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v3.AuxInt = int64ToAuxInt(64) ++ v1.AddArg2(v2, v3) ++ v0.AddArg(v1) ++ v4 := b.NewValue0(v.Pos, OpSW64SLL, t) ++ v4.AddArg2(x, v2) ++ v.AddArg2(v0, v4) ++ return true ++ } ++} ++func rewriteValueSW64_OpLsh32x32(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Lsh32x32 x y) ++ // result: (AND (NEGV (CMPULT (ZeroExt32to64 y) (MOVVconst [64]))) (SLL x (ZeroExt32to64 y))) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64AND) ++ v0 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v1 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v2 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) ++ v2.AddArg(y) ++ v3 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v3.AuxInt = int64ToAuxInt(64) ++ v1.AddArg2(v2, v3) ++ v0.AddArg(v1) ++ v4 := b.NewValue0(v.Pos, OpSW64SLL, t) ++ v4.AddArg2(x, v2) ++ v.AddArg2(v0, v4) ++ return true ++ } ++} ++func rewriteValueSW64_OpLsh32x64(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Lsh32x64 x (Const64 [c])) ++ // cond: uint64(c) < 32 ++ // result: (SLLconst (ZeroExt32to64 x) [c]) ++ for { ++ x := v_0 ++ if v_1.Op != OpConst64 { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(uint64(c) < 32) { ++ break ++ } ++ v.reset(OpSW64SLLconst) ++ v.AuxInt = int64ToAuxInt(c) ++ v0 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) ++ v0.AddArg(x) ++ v.AddArg(v0) ++ return true ++ } ++ // match: (Lsh32x64 x (MOVVconst [c])) ++ // cond: uint64(c) < 32 ++ // result: (SLLconst (ZeroExt32to64 x) [c]) ++ for { ++ x := v_0 ++ if v_1.Op != OpSW64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(uint64(c) < 32) { ++ break ++ } ++ v.reset(OpSW64SLLconst) ++ v.AuxInt = int64ToAuxInt(c) ++ v0 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) ++ v0.AddArg(x) ++ v.AddArg(v0) ++ return true ++ } ++ // match: (Lsh32x64 x y) ++ // result: (AND (NEGV (CMPULT y (MOVVconst [64]))) (SLL x y)) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64AND) ++ v0 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v1 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v2 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v2.AuxInt = int64ToAuxInt(64) ++ v1.AddArg2(y, v2) ++ v0.AddArg(v1) ++ v3 := b.NewValue0(v.Pos, OpSW64SLL, t) ++ v3.AddArg2(x, y) ++ v.AddArg2(v0, v3) ++ return true ++ } ++} ++func rewriteValueSW64_OpLsh32x8(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Lsh32x8 x y) ++ // result: (AND (NEGV (CMPULT (ZeroExt8to64 y) (MOVVconst [64]))) (SLL x (ZeroExt8to64 y))) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64AND) ++ v0 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v1 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v2 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) ++ v2.AddArg(y) ++ v3 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v3.AuxInt = int64ToAuxInt(64) ++ v1.AddArg2(v2, v3) ++ v0.AddArg(v1) ++ v4 := b.NewValue0(v.Pos, OpSW64SLL, t) ++ v4.AddArg2(x, v2) ++ v.AddArg2(v0, v4) ++ return true ++ } ++} ++func rewriteValueSW64_OpLsh64x16(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Lsh64x16 x y) ++ // result: (AND (NEGV (CMPULT (ZeroExt16to64 y) (MOVVconst [64]))) (SLL x (ZeroExt16to64 y))) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64AND) ++ v0 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v1 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v2 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) ++ v2.AddArg(y) ++ v3 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v3.AuxInt = int64ToAuxInt(64) ++ v1.AddArg2(v2, v3) ++ v0.AddArg(v1) ++ v4 := b.NewValue0(v.Pos, OpSW64SLL, t) ++ v4.AddArg2(x, v2) ++ v.AddArg2(v0, v4) ++ return true ++ } ++} ++func rewriteValueSW64_OpLsh64x32(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Lsh64x32 x y) ++ // result: (AND (NEGV (CMPULT (ZeroExt32to64 y) (MOVVconst [64]))) (SLL x (ZeroExt32to64 y))) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64AND) ++ v0 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v1 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v2 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) ++ v2.AddArg(y) ++ v3 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v3.AuxInt = int64ToAuxInt(64) ++ v1.AddArg2(v2, v3) ++ v0.AddArg(v1) ++ v4 := b.NewValue0(v.Pos, OpSW64SLL, t) ++ v4.AddArg2(x, v2) ++ v.AddArg2(v0, v4) ++ return true ++ } ++} ++func rewriteValueSW64_OpLsh64x64(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Lsh64x64 x (Const64 [c])) ++ // cond: uint64(c) < 64 ++ // result: (SLLconst x [c]) ++ for { ++ x := v_0 ++ if v_1.Op != OpConst64 { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(uint64(c) < 64) { ++ break ++ } ++ v.reset(OpSW64SLLconst) ++ v.AuxInt = int64ToAuxInt(c) ++ v.AddArg(x) ++ return true ++ } ++ // match: (Lsh64x64 x (MOVVconst [c])) ++ // cond: uint64(c) < 64 ++ // result: (SLLconst x [c]) ++ for { ++ x := v_0 ++ if v_1.Op != OpSW64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(uint64(c) < 64) { ++ break ++ } ++ v.reset(OpSW64SLLconst) ++ v.AuxInt = int64ToAuxInt(c) ++ v.AddArg(x) ++ return true ++ } ++ // match: (Lsh64x64 x y) ++ // result: (AND (NEGV (CMPULT y (MOVVconst [64]))) (SLL x y)) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64AND) ++ v0 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v1 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v2 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v2.AuxInt = int64ToAuxInt(64) ++ v1.AddArg2(y, v2) ++ v0.AddArg(v1) ++ v3 := b.NewValue0(v.Pos, OpSW64SLL, t) ++ v3.AddArg2(x, y) ++ v.AddArg2(v0, v3) ++ return true ++ } ++} ++func rewriteValueSW64_OpLsh64x8(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Lsh64x8 x y) ++ // result: (AND (NEGV (CMPULT (ZeroExt8to64 y) (MOVVconst [64]))) (SLL x (ZeroExt8to64 y))) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64AND) ++ v0 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v1 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v2 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) ++ v2.AddArg(y) ++ v3 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v3.AuxInt = int64ToAuxInt(64) ++ v1.AddArg2(v2, v3) ++ v0.AddArg(v1) ++ v4 := b.NewValue0(v.Pos, OpSW64SLL, t) ++ v4.AddArg2(x, v2) ++ v.AddArg2(v0, v4) ++ return true ++ } ++} ++func rewriteValueSW64_OpLsh8x16(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Lsh8x16 x y) ++ // result: (AND (NEGV (CMPULT (ZeroExt16to64 y) (MOVVconst [64]))) (SLL x (ZeroExt16to64 y))) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64AND) ++ v0 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v1 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v2 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) ++ v2.AddArg(y) ++ v3 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v3.AuxInt = int64ToAuxInt(64) ++ v1.AddArg2(v2, v3) ++ v0.AddArg(v1) ++ v4 := b.NewValue0(v.Pos, OpSW64SLL, t) ++ v4.AddArg2(x, v2) ++ v.AddArg2(v0, v4) ++ return true ++ } ++} ++func rewriteValueSW64_OpLsh8x32(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Lsh8x32 x y) ++ // result: (AND (NEGV (CMPULT (ZeroExt32to64 y) (MOVVconst [64]))) (SLL x (ZeroExt32to64 y))) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64AND) ++ v0 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v1 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v2 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) ++ v2.AddArg(y) ++ v3 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v3.AuxInt = int64ToAuxInt(64) ++ v1.AddArg2(v2, v3) ++ v0.AddArg(v1) ++ v4 := b.NewValue0(v.Pos, OpSW64SLL, t) ++ v4.AddArg2(x, v2) ++ v.AddArg2(v0, v4) ++ return true ++ } ++} ++func rewriteValueSW64_OpLsh8x64(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Lsh8x64 x (Const64 [c])) ++ // cond: uint64(c) < 8 ++ // result: (SLLconst (ZeroExt8to64 x) [c]) ++ for { ++ x := v_0 ++ if v_1.Op != OpConst64 { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(uint64(c) < 8) { ++ break ++ } ++ v.reset(OpSW64SLLconst) ++ v.AuxInt = int64ToAuxInt(c) ++ v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) ++ v0.AddArg(x) ++ v.AddArg(v0) ++ return true ++ } ++ // match: (Lsh8x64 x (MOVVconst [c])) ++ // cond: uint64(c) < 8 ++ // result: (SLLconst (ZeroExt8to64 x) [c]) ++ for { ++ x := v_0 ++ if v_1.Op != OpSW64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(uint64(c) < 8) { ++ break ++ } ++ v.reset(OpSW64SLLconst) ++ v.AuxInt = int64ToAuxInt(c) ++ v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) ++ v0.AddArg(x) ++ v.AddArg(v0) ++ return true ++ } ++ // match: (Lsh8x64 x y) ++ // result: (AND (NEGV (CMPULT y (MOVVconst [64]))) (SLL x y)) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64AND) ++ v0 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v1 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v2 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v2.AuxInt = int64ToAuxInt(64) ++ v1.AddArg2(y, v2) ++ v0.AddArg(v1) ++ v3 := b.NewValue0(v.Pos, OpSW64SLL, t) ++ v3.AddArg2(x, y) ++ v.AddArg2(v0, v3) ++ return true ++ } ++} ++func rewriteValueSW64_OpLsh8x8(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Lsh8x8 x y) ++ // result: (AND (NEGV (CMPULT (ZeroExt8to64 y) (MOVVconst [64]))) (SLL x (ZeroExt8to64 y))) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64AND) ++ v0 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v1 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v2 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) ++ v2.AddArg(y) ++ v3 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v3.AuxInt = int64ToAuxInt(64) ++ v1.AddArg2(v2, v3) ++ v0.AddArg(v1) ++ v4 := b.NewValue0(v.Pos, OpSW64SLL, t) ++ v4.AddArg2(x, v2) ++ v.AddArg2(v0, v4) ++ return true ++ } ++} ++func rewriteValueSW64_OpMod16(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Mod16 x y) ++ // result: (Mod64 (SignExt16to64 x) (SignExt16to64 y)) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpMod64) ++ v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) ++ v0.AddArg(x) ++ v1 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) ++ v1.AddArg(y) ++ v.AddArg2(v0, v1) ++ return true ++ } ++} ++func rewriteValueSW64_OpMod16u(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Mod16u x y) ++ // result: (Mod64u (ZeroExt16to64 x) (ZeroExt16to64 y)) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpMod64u) ++ v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) ++ v0.AddArg(x) ++ v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) ++ v1.AddArg(y) ++ v.AddArg2(v0, v1) ++ return true ++ } ++} ++func rewriteValueSW64_OpMod32(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Mod32 x y) ++ // result: (Mod64 (SignExt32to64 x) (SignExt32to64 y)) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpMod64) ++ v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) ++ v0.AddArg(x) ++ v1 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) ++ v1.AddArg(y) ++ v.AddArg2(v0, v1) ++ return true ++ } ++} ++func rewriteValueSW64_OpMod32u(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Mod32u x y) ++ // result: (Mod64u (ZeroExt32to64 x) (ZeroExt32to64 y)) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpMod64u) ++ v0 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) ++ v0.AddArg(x) ++ v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) ++ v1.AddArg(y) ++ v.AddArg2(v0, v1) ++ return true ++ } ++} ++func rewriteValueSW64_OpMod64(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Mod64 x y) ++ // result: (SUBV (XOR (Select1 (CALLudiv (SUBV (XOR x (Signmask x)) (Signmask x)) (SUBV (XOR y (Signmask y)) (Signmask y)))) (Signmask x)) (Signmask x)) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64SUBV) ++ v0 := b.NewValue0(v.Pos, OpSW64XOR, typ.UInt64) ++ v1 := b.NewValue0(v.Pos, OpSelect1, typ.UInt64) ++ v2 := b.NewValue0(v.Pos, OpSW64CALLudiv, types.NewTuple(typ.UInt64, typ.UInt64)) ++ v3 := b.NewValue0(v.Pos, OpSW64SUBV, typ.UInt64) ++ v4 := b.NewValue0(v.Pos, OpSW64XOR, typ.UInt64) ++ v5 := b.NewValue0(v.Pos, OpSignmask, typ.Int32) ++ v5.AddArg(x) ++ v4.AddArg2(x, v5) ++ v3.AddArg2(v4, v5) ++ v6 := b.NewValue0(v.Pos, OpSW64SUBV, typ.UInt64) ++ v7 := b.NewValue0(v.Pos, OpSW64XOR, typ.UInt64) ++ v8 := b.NewValue0(v.Pos, OpSignmask, typ.Int32) ++ v8.AddArg(y) ++ v7.AddArg2(y, v8) ++ v6.AddArg2(v7, v8) ++ v2.AddArg2(v3, v6) ++ v1.AddArg(v2) ++ v0.AddArg2(v1, v5) ++ v.AddArg2(v0, v5) ++ return true ++ } ++} ++func rewriteValueSW64_OpMod64u(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Mod64u x y) ++ // result: (Select1 (CALLudiv x y)) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpSelect1) ++ v.Type = typ.UInt64 ++ v0 := b.NewValue0(v.Pos, OpSW64CALLudiv, types.NewTuple(typ.UInt64, typ.UInt64)) ++ v0.AddArg2(x, y) ++ v.AddArg(v0) ++ return true ++ } ++} ++func rewriteValueSW64_OpMod8(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Mod8 x y) ++ // result: (Mod64 (SignExt8to64 x) (SignExt8to64 y)) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpMod64) ++ v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) ++ v0.AddArg(x) ++ v1 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) ++ v1.AddArg(y) ++ v.AddArg2(v0, v1) ++ return true ++ } ++} ++func rewriteValueSW64_OpMod8u(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Mod8u x y) ++ // result: (Mod64u (ZeroExt8to64 x) (ZeroExt8to64 y)) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpMod64u) ++ v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) ++ v0.AddArg(x) ++ v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) ++ v1.AddArg(y) ++ v.AddArg2(v0, v1) ++ return true ++ } ++} ++func rewriteValueSW64_OpMove(v *Value) bool { ++ v_2 := v.Args[2] ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ config := b.Func.Config ++ typ := &b.Func.Config.Types ++ // match: (Move [0] _ _ mem) ++ // result: mem ++ for { ++ if auxIntToInt64(v.AuxInt) != 0 { ++ break ++ } ++ mem := v_2 ++ v.copyOf(mem) ++ return true ++ } ++ // match: (Move [1] dst src mem) ++ // result: (MOVBstore dst (MOVBload src mem) mem) ++ for { ++ if auxIntToInt64(v.AuxInt) != 1 { ++ break ++ } ++ dst := v_0 ++ src := v_1 ++ mem := v_2 ++ v.reset(OpSW64MOVBstore) ++ v0 := b.NewValue0(v.Pos, OpSW64MOVBload, typ.Int8) ++ v0.AddArg2(src, mem) ++ v.AddArg3(dst, v0, mem) ++ return true ++ } ++ // match: (Move [2] {t} dst src mem) ++ // cond: t.Alignment()%2 == 0 ++ // result: (MOVHstore dst (MOVHload src mem) mem) ++ for { ++ if auxIntToInt64(v.AuxInt) != 2 { ++ break ++ } ++ t := auxToType(v.Aux) ++ dst := v_0 ++ src := v_1 ++ mem := v_2 ++ if !(t.Alignment()%2 == 0) { ++ break ++ } ++ v.reset(OpSW64MOVHstore) ++ v0 := b.NewValue0(v.Pos, OpSW64MOVHload, typ.Int16) ++ v0.AddArg2(src, mem) ++ v.AddArg3(dst, v0, mem) ++ return true ++ } ++ // match: (Move [2] dst src mem) ++ // result: (MOVBstore [1] dst (MOVBload [1] src mem) (MOVBstore dst (MOVBload src mem) mem)) ++ for { ++ if auxIntToInt64(v.AuxInt) != 2 { ++ break ++ } ++ dst := v_0 ++ src := v_1 ++ mem := v_2 ++ v.reset(OpSW64MOVBstore) ++ v.AuxInt = int32ToAuxInt(1) ++ v0 := b.NewValue0(v.Pos, OpSW64MOVBload, typ.Int8) ++ v0.AuxInt = int32ToAuxInt(1) ++ v0.AddArg2(src, mem) ++ v1 := b.NewValue0(v.Pos, OpSW64MOVBstore, types.TypeMem) ++ v2 := b.NewValue0(v.Pos, OpSW64MOVBload, typ.Int8) ++ v2.AddArg2(src, mem) ++ v1.AddArg3(dst, v2, mem) ++ v.AddArg3(dst, v0, v1) ++ return true ++ } ++ // match: (Move [4] {t} dst src mem) ++ // cond: t.Alignment()%4 == 0 ++ // result: (MOVWstore dst (MOVWload src mem) mem) ++ for { ++ if auxIntToInt64(v.AuxInt) != 4 { ++ break ++ } ++ t := auxToType(v.Aux) ++ dst := v_0 ++ src := v_1 ++ mem := v_2 ++ if !(t.Alignment()%4 == 0) { ++ break ++ } ++ v.reset(OpSW64MOVWstore) ++ v0 := b.NewValue0(v.Pos, OpSW64MOVWload, typ.Int32) ++ v0.AddArg2(src, mem) ++ v.AddArg3(dst, v0, mem) ++ return true ++ } ++ // match: (Move [4] {t} dst src mem) ++ // cond: t.Alignment()%2 == 0 ++ // result: (MOVHstore [2] dst (MOVHload [2] src mem) (MOVHstore dst (MOVHload src mem) mem)) ++ for { ++ if auxIntToInt64(v.AuxInt) != 4 { ++ break ++ } ++ t := auxToType(v.Aux) ++ dst := v_0 ++ src := v_1 ++ mem := v_2 ++ if !(t.Alignment()%2 == 0) { ++ break ++ } ++ v.reset(OpSW64MOVHstore) ++ v.AuxInt = int32ToAuxInt(2) ++ v0 := b.NewValue0(v.Pos, OpSW64MOVHload, typ.Int16) ++ v0.AuxInt = int32ToAuxInt(2) ++ v0.AddArg2(src, mem) ++ v1 := b.NewValue0(v.Pos, OpSW64MOVHstore, types.TypeMem) ++ v2 := b.NewValue0(v.Pos, OpSW64MOVHload, typ.Int16) ++ v2.AddArg2(src, mem) ++ v1.AddArg3(dst, v2, mem) ++ v.AddArg3(dst, v0, v1) ++ return true ++ } ++ // match: (Move [4] dst src mem) ++ // result: (MOVBstore [3] dst (MOVBload [3] src mem) (MOVBstore [2] dst (MOVBload [2] src mem) (MOVBstore [1] dst (MOVBload [1] src mem) (MOVBstore dst (MOVBload src mem) mem)))) ++ for { ++ if auxIntToInt64(v.AuxInt) != 4 { ++ break ++ } ++ dst := v_0 ++ src := v_1 ++ mem := v_2 ++ v.reset(OpSW64MOVBstore) ++ v.AuxInt = int32ToAuxInt(3) ++ v0 := b.NewValue0(v.Pos, OpSW64MOVBload, typ.Int8) ++ v0.AuxInt = int32ToAuxInt(3) ++ v0.AddArg2(src, mem) ++ v1 := b.NewValue0(v.Pos, OpSW64MOVBstore, types.TypeMem) ++ v1.AuxInt = int32ToAuxInt(2) ++ v2 := b.NewValue0(v.Pos, OpSW64MOVBload, typ.Int8) ++ v2.AuxInt = int32ToAuxInt(2) ++ v2.AddArg2(src, mem) ++ v3 := b.NewValue0(v.Pos, OpSW64MOVBstore, types.TypeMem) ++ v3.AuxInt = int32ToAuxInt(1) ++ v4 := b.NewValue0(v.Pos, OpSW64MOVBload, typ.Int8) ++ v4.AuxInt = int32ToAuxInt(1) ++ v4.AddArg2(src, mem) ++ v5 := b.NewValue0(v.Pos, OpSW64MOVBstore, types.TypeMem) ++ v6 := b.NewValue0(v.Pos, OpSW64MOVBload, typ.Int8) ++ v6.AddArg2(src, mem) ++ v5.AddArg3(dst, v6, mem) ++ v3.AddArg3(dst, v4, v5) ++ v1.AddArg3(dst, v2, v3) ++ v.AddArg3(dst, v0, v1) ++ return true ++ } ++ // match: (Move [8] {t} dst src mem) ++ // cond: t.Alignment()%8 == 0 ++ // result: (MOVVstore dst (MOVVload src mem) mem) ++ for { ++ if auxIntToInt64(v.AuxInt) != 8 { ++ break ++ } ++ t := auxToType(v.Aux) ++ dst := v_0 ++ src := v_1 ++ mem := v_2 ++ if !(t.Alignment()%8 == 0) { ++ break ++ } ++ v.reset(OpSW64MOVVstore) ++ v0 := b.NewValue0(v.Pos, OpSW64MOVVload, typ.UInt64) ++ v0.AddArg2(src, mem) ++ v.AddArg3(dst, v0, mem) ++ return true ++ } ++ // match: (Move [8] {t} dst src mem) ++ // cond: t.Alignment()%4 == 0 ++ // result: (MOVWstore [4] dst (MOVWload [4] src mem) (MOVWstore dst (MOVWload src mem) mem)) ++ for { ++ if auxIntToInt64(v.AuxInt) != 8 { ++ break ++ } ++ t := auxToType(v.Aux) ++ dst := v_0 ++ src := v_1 ++ mem := v_2 ++ if !(t.Alignment()%4 == 0) { ++ break ++ } ++ v.reset(OpSW64MOVWstore) ++ v.AuxInt = int32ToAuxInt(4) ++ v0 := b.NewValue0(v.Pos, OpSW64MOVWload, typ.Int32) ++ v0.AuxInt = int32ToAuxInt(4) ++ v0.AddArg2(src, mem) ++ v1 := b.NewValue0(v.Pos, OpSW64MOVWstore, types.TypeMem) ++ v2 := b.NewValue0(v.Pos, OpSW64MOVWload, typ.Int32) ++ v2.AddArg2(src, mem) ++ v1.AddArg3(dst, v2, mem) ++ v.AddArg3(dst, v0, v1) ++ return true ++ } ++ // match: (Move [8] {t} dst src mem) ++ // cond: t.Alignment()%2 == 0 ++ // result: (MOVHstore [6] dst (MOVHload [6] src mem) (MOVHstore [4] dst (MOVHload [4] src mem) (MOVHstore [2] dst (MOVHload [2] src mem) (MOVHstore dst (MOVHload src mem) mem)))) ++ for { ++ if auxIntToInt64(v.AuxInt) != 8 { ++ break ++ } ++ t := auxToType(v.Aux) ++ dst := v_0 ++ src := v_1 ++ mem := v_2 ++ if !(t.Alignment()%2 == 0) { ++ break ++ } ++ v.reset(OpSW64MOVHstore) ++ v.AuxInt = int32ToAuxInt(6) ++ v0 := b.NewValue0(v.Pos, OpSW64MOVHload, typ.Int16) ++ v0.AuxInt = int32ToAuxInt(6) ++ v0.AddArg2(src, mem) ++ v1 := b.NewValue0(v.Pos, OpSW64MOVHstore, types.TypeMem) ++ v1.AuxInt = int32ToAuxInt(4) ++ v2 := b.NewValue0(v.Pos, OpSW64MOVHload, typ.Int16) ++ v2.AuxInt = int32ToAuxInt(4) ++ v2.AddArg2(src, mem) ++ v3 := b.NewValue0(v.Pos, OpSW64MOVHstore, types.TypeMem) ++ v3.AuxInt = int32ToAuxInt(2) ++ v4 := b.NewValue0(v.Pos, OpSW64MOVHload, typ.Int16) ++ v4.AuxInt = int32ToAuxInt(2) ++ v4.AddArg2(src, mem) ++ v5 := b.NewValue0(v.Pos, OpSW64MOVHstore, types.TypeMem) ++ v6 := b.NewValue0(v.Pos, OpSW64MOVHload, typ.Int16) ++ v6.AddArg2(src, mem) ++ v5.AddArg3(dst, v6, mem) ++ v3.AddArg3(dst, v4, v5) ++ v1.AddArg3(dst, v2, v3) ++ v.AddArg3(dst, v0, v1) ++ return true ++ } ++ // match: (Move [3] dst src mem) ++ // result: (MOVBstore [2] dst (MOVBload [2] src mem) (MOVBstore [1] dst (MOVBload [1] src mem) (MOVBstore dst (MOVBload src mem) mem))) ++ for { ++ if auxIntToInt64(v.AuxInt) != 3 { ++ break ++ } ++ dst := v_0 ++ src := v_1 ++ mem := v_2 ++ v.reset(OpSW64MOVBstore) ++ v.AuxInt = int32ToAuxInt(2) ++ v0 := b.NewValue0(v.Pos, OpSW64MOVBload, typ.Int8) ++ v0.AuxInt = int32ToAuxInt(2) ++ v0.AddArg2(src, mem) ++ v1 := b.NewValue0(v.Pos, OpSW64MOVBstore, types.TypeMem) ++ v1.AuxInt = int32ToAuxInt(1) ++ v2 := b.NewValue0(v.Pos, OpSW64MOVBload, typ.Int8) ++ v2.AuxInt = int32ToAuxInt(1) ++ v2.AddArg2(src, mem) ++ v3 := b.NewValue0(v.Pos, OpSW64MOVBstore, types.TypeMem) ++ v4 := b.NewValue0(v.Pos, OpSW64MOVBload, typ.Int8) ++ v4.AddArg2(src, mem) ++ v3.AddArg3(dst, v4, mem) ++ v1.AddArg3(dst, v2, v3) ++ v.AddArg3(dst, v0, v1) ++ return true ++ } ++ // match: (Move [6] {t} dst src mem) ++ // cond: t.Alignment()%2 == 0 ++ // result: (MOVHstore [4] dst (MOVHload [4] src mem) (MOVHstore [2] dst (MOVHload [2] src mem) (MOVHstore dst (MOVHload src mem) mem))) ++ for { ++ if auxIntToInt64(v.AuxInt) != 6 { ++ break ++ } ++ t := auxToType(v.Aux) ++ dst := v_0 ++ src := v_1 ++ mem := v_2 ++ if !(t.Alignment()%2 == 0) { ++ break ++ } ++ v.reset(OpSW64MOVHstore) ++ v.AuxInt = int32ToAuxInt(4) ++ v0 := b.NewValue0(v.Pos, OpSW64MOVHload, typ.Int16) ++ v0.AuxInt = int32ToAuxInt(4) ++ v0.AddArg2(src, mem) ++ v1 := b.NewValue0(v.Pos, OpSW64MOVHstore, types.TypeMem) ++ v1.AuxInt = int32ToAuxInt(2) ++ v2 := b.NewValue0(v.Pos, OpSW64MOVHload, typ.Int16) ++ v2.AuxInt = int32ToAuxInt(2) ++ v2.AddArg2(src, mem) ++ v3 := b.NewValue0(v.Pos, OpSW64MOVHstore, types.TypeMem) ++ v4 := b.NewValue0(v.Pos, OpSW64MOVHload, typ.Int16) ++ v4.AddArg2(src, mem) ++ v3.AddArg3(dst, v4, mem) ++ v1.AddArg3(dst, v2, v3) ++ v.AddArg3(dst, v0, v1) ++ return true ++ } ++ // match: (Move [12] {t} dst src mem) ++ // cond: t.Alignment()%4 == 0 ++ // result: (MOVWstore [8] dst (MOVWload [8] src mem) (MOVWstore [4] dst (MOVWload [4] src mem) (MOVWstore dst (MOVWload src mem) mem))) ++ for { ++ if auxIntToInt64(v.AuxInt) != 12 { ++ break ++ } ++ t := auxToType(v.Aux) ++ dst := v_0 ++ src := v_1 ++ mem := v_2 ++ if !(t.Alignment()%4 == 0) { ++ break ++ } ++ v.reset(OpSW64MOVWstore) ++ v.AuxInt = int32ToAuxInt(8) ++ v0 := b.NewValue0(v.Pos, OpSW64MOVWload, typ.Int32) ++ v0.AuxInt = int32ToAuxInt(8) ++ v0.AddArg2(src, mem) ++ v1 := b.NewValue0(v.Pos, OpSW64MOVWstore, types.TypeMem) ++ v1.AuxInt = int32ToAuxInt(4) ++ v2 := b.NewValue0(v.Pos, OpSW64MOVWload, typ.Int32) ++ v2.AuxInt = int32ToAuxInt(4) ++ v2.AddArg2(src, mem) ++ v3 := b.NewValue0(v.Pos, OpSW64MOVWstore, types.TypeMem) ++ v4 := b.NewValue0(v.Pos, OpSW64MOVWload, typ.Int32) ++ v4.AddArg2(src, mem) ++ v3.AddArg3(dst, v4, mem) ++ v1.AddArg3(dst, v2, v3) ++ v.AddArg3(dst, v0, v1) ++ return true ++ } ++ // match: (Move [16] {t} dst src mem) ++ // cond: t.Alignment()%8 == 0 ++ // result: (MOVVstore [8] dst (MOVVload [8] src mem) (MOVVstore dst (MOVVload src mem) mem)) ++ for { ++ if auxIntToInt64(v.AuxInt) != 16 { ++ break ++ } ++ t := auxToType(v.Aux) ++ dst := v_0 ++ src := v_1 ++ mem := v_2 ++ if !(t.Alignment()%8 == 0) { ++ break ++ } ++ v.reset(OpSW64MOVVstore) ++ v.AuxInt = int32ToAuxInt(8) ++ v0 := b.NewValue0(v.Pos, OpSW64MOVVload, typ.UInt64) ++ v0.AuxInt = int32ToAuxInt(8) ++ v0.AddArg2(src, mem) ++ v1 := b.NewValue0(v.Pos, OpSW64MOVVstore, types.TypeMem) ++ v2 := b.NewValue0(v.Pos, OpSW64MOVVload, typ.UInt64) ++ v2.AddArg2(src, mem) ++ v1.AddArg3(dst, v2, mem) ++ v.AddArg3(dst, v0, v1) ++ return true ++ } ++ // match: (Move [24] {t} dst src mem) ++ // cond: t.Alignment()%8 == 0 ++ // result: (MOVVstore [16] dst (MOVVload [16] src mem) (MOVVstore [8] dst (MOVVload [8] src mem) (MOVVstore dst (MOVVload src mem) mem))) ++ for { ++ if auxIntToInt64(v.AuxInt) != 24 { ++ break ++ } ++ t := auxToType(v.Aux) ++ dst := v_0 ++ src := v_1 ++ mem := v_2 ++ if !(t.Alignment()%8 == 0) { ++ break ++ } ++ v.reset(OpSW64MOVVstore) ++ v.AuxInt = int32ToAuxInt(16) ++ v0 := b.NewValue0(v.Pos, OpSW64MOVVload, typ.UInt64) ++ v0.AuxInt = int32ToAuxInt(16) ++ v0.AddArg2(src, mem) ++ v1 := b.NewValue0(v.Pos, OpSW64MOVVstore, types.TypeMem) ++ v1.AuxInt = int32ToAuxInt(8) ++ v2 := b.NewValue0(v.Pos, OpSW64MOVVload, typ.UInt64) ++ v2.AuxInt = int32ToAuxInt(8) ++ v2.AddArg2(src, mem) ++ v3 := b.NewValue0(v.Pos, OpSW64MOVVstore, types.TypeMem) ++ v4 := b.NewValue0(v.Pos, OpSW64MOVVload, typ.UInt64) ++ v4.AddArg2(src, mem) ++ v3.AddArg3(dst, v4, mem) ++ v1.AddArg3(dst, v2, v3) ++ v.AddArg3(dst, v0, v1) ++ return true ++ } ++ // match: (Move [s] {t} dst src mem) ++ // cond: s > 24 && logLargeCopy(v, s) || t.Alignment()%8 != 0 ++ // result: (LoweredMove [t.Alignment()] dst src (ADDVconst src [s-moveSize(t.Alignment(), config)]) mem) ++ for { ++ s := auxIntToInt64(v.AuxInt) ++ t := auxToType(v.Aux) ++ dst := v_0 ++ src := v_1 ++ mem := v_2 ++ if !(s > 24 && logLargeCopy(v, s) || t.Alignment()%8 != 0) { ++ break ++ } ++ v.reset(OpSW64LoweredMove) ++ v.AuxInt = int64ToAuxInt(t.Alignment()) ++ v0 := b.NewValue0(v.Pos, OpSW64ADDVconst, src.Type) ++ v0.AuxInt = int64ToAuxInt(s - moveSize(t.Alignment(), config)) ++ v0.AddArg(src) ++ v.AddArg4(dst, src, v0, mem) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpNeq16(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Neq16 x y) ++ // result: (Not (CMPEQ (ZeroExt16to64 x) (ZeroExt16to64 y))) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpNot) ++ v0 := b.NewValue0(v.Pos, OpSW64CMPEQ, typ.Bool) ++ v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) ++ v1.AddArg(x) ++ v2 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) ++ v2.AddArg(y) ++ v0.AddArg2(v1, v2) ++ v.AddArg(v0) ++ return true ++ } ++} ++func rewriteValueSW64_OpNeq32(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Neq32 x y) ++ // result: (Not (CMPEQ (ZeroExt32to64 x) (ZeroExt32to64 y))) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpNot) ++ v0 := b.NewValue0(v.Pos, OpSW64CMPEQ, typ.Bool) ++ v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) ++ v1.AddArg(x) ++ v2 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) ++ v2.AddArg(y) ++ v0.AddArg2(v1, v2) ++ v.AddArg(v0) ++ return true ++ } ++} ++func rewriteValueSW64_OpNeq32F(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Neq32F x y) ++ // result: (FNotEqual (FCMPEQ x y)) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64FNotEqual) ++ v0 := b.NewValue0(v.Pos, OpSW64FCMPEQ, typ.Float64) ++ v0.AddArg2(x, y) ++ v.AddArg(v0) ++ return true ++ } ++} ++func rewriteValueSW64_OpNeq64(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Neq64 x y) ++ // result: (Not (CMPEQ x y)) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpNot) ++ v0 := b.NewValue0(v.Pos, OpSW64CMPEQ, typ.Bool) ++ v0.AddArg2(x, y) ++ v.AddArg(v0) ++ return true ++ } ++} ++func rewriteValueSW64_OpNeq64F(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Neq64F x y) ++ // result: (FNotEqual (FCMPEQ x y)) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64FNotEqual) ++ v0 := b.NewValue0(v.Pos, OpSW64FCMPEQ, typ.Float64) ++ v0.AddArg2(x, y) ++ v.AddArg(v0) ++ return true ++ } ++} ++func rewriteValueSW64_OpNeq8(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Neq8 x y) ++ // result: (Not (CMPEQ (ZeroExt8to64 x) (ZeroExt8to64 y))) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpNot) ++ v0 := b.NewValue0(v.Pos, OpSW64CMPEQ, typ.Bool) ++ v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) ++ v1.AddArg(x) ++ v2 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) ++ v2.AddArg(y) ++ v0.AddArg2(v1, v2) ++ v.AddArg(v0) ++ return true ++ } ++} ++func rewriteValueSW64_OpNeqPtr(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (NeqPtr x y) ++ // result: (Not (CMPEQ x y)) ++ for { ++ x := v_0 ++ y := v_1 ++ v.reset(OpNot) ++ v0 := b.NewValue0(v.Pos, OpSW64CMPEQ, typ.Bool) ++ v0.AddArg2(x, y) ++ v.AddArg(v0) ++ return true ++ } ++} ++func rewriteValueSW64_OpNot(v *Value) bool { ++ v_0 := v.Args[0] ++ // match: (Not x) ++ // result: (XORconst x [1]) ++ for { ++ x := v_0 ++ v.reset(OpSW64XORconst) ++ v.AuxInt = int64ToAuxInt(1) ++ v.AddArg(x) ++ return true ++ } ++} ++func rewriteValueSW64_OpOffPtr(v *Value) bool { ++ v_0 := v.Args[0] ++ // match: (OffPtr [off] ptr:(SP)) ++ // cond: is32Bit(off) ++ // result: (SYMADDR [int32(off)] ptr) ++ for { ++ off := auxIntToInt64(v.AuxInt) ++ ptr := v_0 ++ if ptr.Op != OpSP || !(is32Bit(off)) { ++ break ++ } ++ v.reset(OpSW64SYMADDR) ++ v.AuxInt = int32ToAuxInt(int32(off)) ++ v.AddArg(ptr) ++ return true ++ } ++ // match: (OffPtr [off] ptr) ++ // result: (ADDVconst [off] ptr) ++ for { ++ off := auxIntToInt64(v.AuxInt) ++ ptr := v_0 ++ v.reset(OpSW64ADDVconst) ++ v.AuxInt = int64ToAuxInt(off) ++ v.AddArg(ptr) ++ return true ++ } ++} ++func rewriteValueSW64_OpPanicBounds(v *Value) bool { ++ v_2 := v.Args[2] ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ // match: (PanicBounds [kind] x y mem) ++ // cond: boundsABI(kind) == 0 ++ // result: (LoweredPanicBoundsA [kind] x y mem) ++ for { ++ kind := auxIntToInt64(v.AuxInt) ++ x := v_0 ++ y := v_1 ++ mem := v_2 ++ if !(boundsABI(kind) == 0) { ++ break ++ } ++ v.reset(OpSW64LoweredPanicBoundsA) ++ v.AuxInt = int64ToAuxInt(kind) ++ v.AddArg3(x, y, mem) ++ return true ++ } ++ // match: (PanicBounds [kind] x y mem) ++ // cond: boundsABI(kind) == 1 ++ // result: (LoweredPanicBoundsB [kind] x y mem) ++ for { ++ kind := auxIntToInt64(v.AuxInt) ++ x := v_0 ++ y := v_1 ++ mem := v_2 ++ if !(boundsABI(kind) == 1) { ++ break ++ } ++ v.reset(OpSW64LoweredPanicBoundsB) ++ v.AuxInt = int64ToAuxInt(kind) ++ v.AddArg3(x, y, mem) ++ return true ++ } ++ // match: (PanicBounds [kind] x y mem) ++ // cond: boundsABI(kind) == 2 ++ // result: (LoweredPanicBoundsC [kind] x y mem) ++ for { ++ kind := auxIntToInt64(v.AuxInt) ++ x := v_0 ++ y := v_1 ++ mem := v_2 ++ if !(boundsABI(kind) == 2) { ++ break ++ } ++ v.reset(OpSW64LoweredPanicBoundsC) ++ v.AuxInt = int64ToAuxInt(kind) ++ v.AddArg3(x, y, mem) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpPopCount16(v *Value) bool { ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (PopCount16 x) ++ // result: (CTPOP (ZeroExt16to64 x)) ++ for { ++ x := v_0 ++ v.reset(OpSW64CTPOP) ++ v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) ++ v0.AddArg(x) ++ v.AddArg(v0) ++ return true ++ } ++} ++func rewriteValueSW64_OpPopCount32(v *Value) bool { ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (PopCount32 x) ++ // result: (CTPOP (ZeroExt32to64 x)) ++ for { ++ x := v_0 ++ v.reset(OpSW64CTPOP) ++ v0 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) ++ v0.AddArg(x) ++ v.AddArg(v0) ++ return true ++ } ++} ++func rewriteValueSW64_OpPopCount8(v *Value) bool { ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (PopCount8 x) ++ // result: (CTPOP (ZeroExt8to64 x)) ++ for { ++ x := v_0 ++ v.reset(OpSW64CTPOP) ++ v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) ++ v0.AddArg(x) ++ v.AddArg(v0) ++ return true ++ } ++} ++func rewriteValueSW64_OpRotateLeft16(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (RotateLeft16 x (MOVVconst [c])) ++ // result: (Or16 (Lsh16x64 x (MOVVconst [c&15])) (Rsh16Ux64 x (MOVVconst [-c&15]))) ++ for { ++ t := v.Type ++ x := v_0 ++ if v_1.Op != OpSW64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ v.reset(OpOr16) ++ v0 := b.NewValue0(v.Pos, OpLsh16x64, t) ++ v1 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v1.AuxInt = int64ToAuxInt(c & 15) ++ v0.AddArg2(x, v1) ++ v2 := b.NewValue0(v.Pos, OpRsh16Ux64, t) ++ v3 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v3.AuxInt = int64ToAuxInt(-c & 15) ++ v2.AddArg2(x, v3) ++ v.AddArg2(v0, v2) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpRotateLeft32(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (RotateLeft32 x (MOVVconst [c])) ++ // result: (Or32 (Lsh32x64 x (MOVVconst [c&31])) (Rsh32Ux64 x (MOVVconst [-c&31]))) ++ for { ++ t := v.Type ++ x := v_0 ++ if v_1.Op != OpSW64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ v.reset(OpOr32) ++ v0 := b.NewValue0(v.Pos, OpLsh32x64, t) ++ v1 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v1.AuxInt = int64ToAuxInt(c & 31) ++ v0.AddArg2(x, v1) ++ v2 := b.NewValue0(v.Pos, OpRsh32Ux64, t) ++ v3 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v3.AuxInt = int64ToAuxInt(-c & 31) ++ v2.AddArg2(x, v3) ++ v.AddArg2(v0, v2) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpRotateLeft64(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (RotateLeft64 x (MOVVconst [c])) ++ // result: (Or64 (Lsh64x64 x (MOVVconst [c&63])) (Rsh64Ux64 x (MOVVconst [-c&63]))) ++ for { ++ t := v.Type ++ x := v_0 ++ if v_1.Op != OpSW64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ v.reset(OpOr64) ++ v0 := b.NewValue0(v.Pos, OpLsh64x64, t) ++ v1 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v1.AuxInt = int64ToAuxInt(c & 63) ++ v0.AddArg2(x, v1) ++ v2 := b.NewValue0(v.Pos, OpRsh64Ux64, t) ++ v3 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v3.AuxInt = int64ToAuxInt(-c & 63) ++ v2.AddArg2(x, v3) ++ v.AddArg2(v0, v2) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpRotateLeft8(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (RotateLeft8 x (MOVVconst [c])) ++ // result: (Or8 (Lsh8x64 x (MOVVconst [c&7])) (Rsh8Ux64 x (MOVVconst [-c&7]))) ++ for { ++ t := v.Type ++ x := v_0 ++ if v_1.Op != OpSW64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ v.reset(OpOr8) ++ v0 := b.NewValue0(v.Pos, OpLsh8x64, t) ++ v1 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v1.AuxInt = int64ToAuxInt(c & 7) ++ v0.AddArg2(x, v1) ++ v2 := b.NewValue0(v.Pos, OpRsh8Ux64, t) ++ v3 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v3.AuxInt = int64ToAuxInt(-c & 7) ++ v2.AddArg2(x, v3) ++ v.AddArg2(v0, v2) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpRsh16Ux16(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Rsh16Ux16 x y) ++ // result: (AND (NEGV (CMPULT (ZeroExt16to64 y) (MOVVconst [64]))) (SRL (ZeroExt16to64 x) (ZeroExt16to64 y))) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64AND) ++ v0 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v1 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v2 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) ++ v2.AddArg(y) ++ v3 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v3.AuxInt = int64ToAuxInt(64) ++ v1.AddArg2(v2, v3) ++ v0.AddArg(v1) ++ v4 := b.NewValue0(v.Pos, OpSW64SRL, t) ++ v5 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) ++ v5.AddArg(x) ++ v4.AddArg2(v5, v2) ++ v.AddArg2(v0, v4) ++ return true ++ } ++} ++func rewriteValueSW64_OpRsh16Ux32(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Rsh16Ux32 x y) ++ // result: (AND (NEGV (CMPULT (ZeroExt32to64 y) (MOVVconst [64]))) (SRL (ZeroExt16to64 x) (ZeroExt32to64 y))) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64AND) ++ v0 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v1 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v2 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) ++ v2.AddArg(y) ++ v3 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v3.AuxInt = int64ToAuxInt(64) ++ v1.AddArg2(v2, v3) ++ v0.AddArg(v1) ++ v4 := b.NewValue0(v.Pos, OpSW64SRL, t) ++ v5 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) ++ v5.AddArg(x) ++ v4.AddArg2(v5, v2) ++ v.AddArg2(v0, v4) ++ return true ++ } ++} ++func rewriteValueSW64_OpRsh16Ux64(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Rsh16Ux64 x (Const64 [c])) ++ // cond: uint64(c) < 16 ++ // result: (SRLconst (ZeroExt16to64 x) [c]) ++ for { ++ x := v_0 ++ if v_1.Op != OpConst64 { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(uint64(c) < 16) { ++ break ++ } ++ v.reset(OpSW64SRLconst) ++ v.AuxInt = int64ToAuxInt(c) ++ v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) ++ v0.AddArg(x) ++ v.AddArg(v0) ++ return true ++ } ++ // match: (Rsh16Ux64 x (MOVVconst [c])) ++ // cond: uint64(c) < 16 ++ // result: (SRLconst (ZeroExt16to64 x) [c]) ++ for { ++ x := v_0 ++ if v_1.Op != OpSW64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(uint64(c) < 16) { ++ break ++ } ++ v.reset(OpSW64SRLconst) ++ v.AuxInt = int64ToAuxInt(c) ++ v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) ++ v0.AddArg(x) ++ v.AddArg(v0) ++ return true ++ } ++ // match: (Rsh16Ux64 x y) ++ // result: (AND (NEGV (CMPULT y (MOVVconst [64]))) (SRL (ZeroExt16to64 x) y)) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64AND) ++ v0 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v1 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v2 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v2.AuxInt = int64ToAuxInt(64) ++ v1.AddArg2(y, v2) ++ v0.AddArg(v1) ++ v3 := b.NewValue0(v.Pos, OpSW64SRL, t) ++ v4 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) ++ v4.AddArg(x) ++ v3.AddArg2(v4, y) ++ v.AddArg2(v0, v3) ++ return true ++ } ++} ++func rewriteValueSW64_OpRsh16Ux8(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Rsh16Ux8 x y) ++ // result: (AND (NEGV (CMPULT (ZeroExt8to64 y) (MOVVconst [64]))) (SRL (ZeroExt16to64 x) (ZeroExt8to64 y))) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64AND) ++ v0 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v1 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v2 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) ++ v2.AddArg(y) ++ v3 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v3.AuxInt = int64ToAuxInt(64) ++ v1.AddArg2(v2, v3) ++ v0.AddArg(v1) ++ v4 := b.NewValue0(v.Pos, OpSW64SRL, t) ++ v5 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) ++ v5.AddArg(x) ++ v4.AddArg2(v5, v2) ++ v.AddArg2(v0, v4) ++ return true ++ } ++} ++func rewriteValueSW64_OpRsh16x16(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Rsh16x16 x y) ++ // result: (SRA (SignExt16to64 x) (BIS (NEGV (CMPULT (MOVVconst [63]) (ZeroExt16to64 y))) (ZeroExt16to64 y))) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64SRA) ++ v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) ++ v0.AddArg(x) ++ v1 := b.NewValue0(v.Pos, OpSW64BIS, t) ++ v2 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v3 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v4 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v4.AuxInt = int64ToAuxInt(63) ++ v5 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) ++ v5.AddArg(y) ++ v3.AddArg2(v4, v5) ++ v2.AddArg(v3) ++ v1.AddArg2(v2, v5) ++ v.AddArg2(v0, v1) ++ return true ++ } ++} ++func rewriteValueSW64_OpRsh16x32(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Rsh16x32 x y) ++ // result: (SRA (SignExt16to64 x) (BIS (NEGV (CMPULT (MOVVconst [63]) (ZeroExt32to64 y))) (ZeroExt32to64 y))) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64SRA) ++ v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) ++ v0.AddArg(x) ++ v1 := b.NewValue0(v.Pos, OpSW64BIS, t) ++ v2 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v3 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v4 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v4.AuxInt = int64ToAuxInt(63) ++ v5 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) ++ v5.AddArg(y) ++ v3.AddArg2(v4, v5) ++ v2.AddArg(v3) ++ v1.AddArg2(v2, v5) ++ v.AddArg2(v0, v1) ++ return true ++ } ++} ++func rewriteValueSW64_OpRsh16x64(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Rsh16x64 x (Const64 [c])) ++ // cond: uint64(c) < 16 ++ // result: (SRAconst (SignExt16to64 x) [c]) ++ for { ++ x := v_0 ++ if v_1.Op != OpConst64 { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(uint64(c) < 16) { ++ break ++ } ++ v.reset(OpSW64SRAconst) ++ v.AuxInt = int64ToAuxInt(c) ++ v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) ++ v0.AddArg(x) ++ v.AddArg(v0) ++ return true ++ } ++ // match: (Rsh16x64 x (Const64 [c])) ++ // cond: uint64(c) >= 16 ++ // result: (SRAconst (SignExt16to64 x) [63]) ++ for { ++ x := v_0 ++ if v_1.Op != OpConst64 { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(uint64(c) >= 16) { ++ break ++ } ++ v.reset(OpSW64SRAconst) ++ v.AuxInt = int64ToAuxInt(63) ++ v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) ++ v0.AddArg(x) ++ v.AddArg(v0) ++ return true ++ } ++ // match: (Rsh16x64 x (MOVVconst [c])) ++ // cond: uint64(c) >= 16 ++ // result: (SRAconst (SignExt16to64 x) [63]) ++ for { ++ x := v_0 ++ if v_1.Op != OpSW64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(uint64(c) >= 16) { ++ break ++ } ++ v.reset(OpSW64SRAconst) ++ v.AuxInt = int64ToAuxInt(63) ++ v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) ++ v0.AddArg(x) ++ v.AddArg(v0) ++ return true ++ } ++ // match: (Rsh16x64 x (MOVVconst [c])) ++ // cond: uint64(c) < 16 ++ // result: (SRAconst (SignExt16to64 x) [c]) ++ for { ++ x := v_0 ++ if v_1.Op != OpSW64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(uint64(c) < 16) { ++ break ++ } ++ v.reset(OpSW64SRAconst) ++ v.AuxInt = int64ToAuxInt(c) ++ v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) ++ v0.AddArg(x) ++ v.AddArg(v0) ++ return true ++ } ++ // match: (Rsh16x64 x y) ++ // result: (SRA (SignExt16to64 x) (BIS (NEGV (CMPULT (MOVVconst [63]) y)) y)) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64SRA) ++ v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) ++ v0.AddArg(x) ++ v1 := b.NewValue0(v.Pos, OpSW64BIS, t) ++ v2 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v3 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v4 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v4.AuxInt = int64ToAuxInt(63) ++ v3.AddArg2(v4, y) ++ v2.AddArg(v3) ++ v1.AddArg2(v2, y) ++ v.AddArg2(v0, v1) ++ return true ++ } ++} ++func rewriteValueSW64_OpRsh16x8(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Rsh16x8 x y) ++ // result: (SRA (SignExt16to64 x) (BIS (NEGV (CMPULT (MOVVconst [63]) (ZeroExt8to64 y))) (ZeroExt8to64 y))) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64SRA) ++ v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) ++ v0.AddArg(x) ++ v1 := b.NewValue0(v.Pos, OpSW64BIS, t) ++ v2 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v3 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v4 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v4.AuxInt = int64ToAuxInt(63) ++ v5 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) ++ v5.AddArg(y) ++ v3.AddArg2(v4, v5) ++ v2.AddArg(v3) ++ v1.AddArg2(v2, v5) ++ v.AddArg2(v0, v1) ++ return true ++ } ++} ++func rewriteValueSW64_OpRsh32Ux16(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Rsh32Ux16 x y) ++ // result: (AND (NEGV (CMPULT (ZeroExt16to64 y) (MOVVconst [64]))) (SRL (ZeroExt32to64 x) (ZeroExt16to64 y))) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64AND) ++ v0 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v1 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v2 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) ++ v2.AddArg(y) ++ v3 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v3.AuxInt = int64ToAuxInt(64) ++ v1.AddArg2(v2, v3) ++ v0.AddArg(v1) ++ v4 := b.NewValue0(v.Pos, OpSW64SRL, t) ++ v5 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) ++ v5.AddArg(x) ++ v4.AddArg2(v5, v2) ++ v.AddArg2(v0, v4) ++ return true ++ } ++} ++func rewriteValueSW64_OpRsh32Ux32(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Rsh32Ux32 x y) ++ // result: (AND (NEGV (CMPULT (ZeroExt32to64 y) (MOVVconst [64]))) (SRL (ZeroExt32to64 x) (ZeroExt32to64 y))) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64AND) ++ v0 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v1 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v2 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) ++ v2.AddArg(y) ++ v3 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v3.AuxInt = int64ToAuxInt(64) ++ v1.AddArg2(v2, v3) ++ v0.AddArg(v1) ++ v4 := b.NewValue0(v.Pos, OpSW64SRL, t) ++ v5 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) ++ v5.AddArg(x) ++ v4.AddArg2(v5, v2) ++ v.AddArg2(v0, v4) ++ return true ++ } ++} ++func rewriteValueSW64_OpRsh32Ux64(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Rsh32Ux64 x (Const64 [c])) ++ // cond: uint64(c) < 32 ++ // result: (SRLconst (ZeroExt32to64 x) [c]) ++ for { ++ x := v_0 ++ if v_1.Op != OpConst64 { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(uint64(c) < 32) { ++ break ++ } ++ v.reset(OpSW64SRLconst) ++ v.AuxInt = int64ToAuxInt(c) ++ v0 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) ++ v0.AddArg(x) ++ v.AddArg(v0) ++ return true ++ } ++ // match: (Rsh32Ux64 x (MOVVconst [c])) ++ // cond: uint64(c) < 32 ++ // result: (SRLconst (ZeroExt32to64 x) [c]) ++ for { ++ x := v_0 ++ if v_1.Op != OpSW64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(uint64(c) < 32) { ++ break ++ } ++ v.reset(OpSW64SRLconst) ++ v.AuxInt = int64ToAuxInt(c) ++ v0 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) ++ v0.AddArg(x) ++ v.AddArg(v0) ++ return true ++ } ++ // match: (Rsh32Ux64 x y) ++ // result: (AND (NEGV (CMPULT y (MOVVconst [64]))) (SRL (ZeroExt32to64 x) y)) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64AND) ++ v0 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v1 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v2 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v2.AuxInt = int64ToAuxInt(64) ++ v1.AddArg2(y, v2) ++ v0.AddArg(v1) ++ v3 := b.NewValue0(v.Pos, OpSW64SRL, t) ++ v4 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) ++ v4.AddArg(x) ++ v3.AddArg2(v4, y) ++ v.AddArg2(v0, v3) ++ return true ++ } ++} ++func rewriteValueSW64_OpRsh32Ux8(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Rsh32Ux8 x y) ++ // result: (AND (NEGV (CMPULT (ZeroExt8to64 y) (MOVVconst [64]))) (SRL (ZeroExt32to64 x) (ZeroExt8to64 y))) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64AND) ++ v0 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v1 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v2 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) ++ v2.AddArg(y) ++ v3 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v3.AuxInt = int64ToAuxInt(64) ++ v1.AddArg2(v2, v3) ++ v0.AddArg(v1) ++ v4 := b.NewValue0(v.Pos, OpSW64SRL, t) ++ v5 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) ++ v5.AddArg(x) ++ v4.AddArg2(v5, v2) ++ v.AddArg2(v0, v4) ++ return true ++ } ++} ++func rewriteValueSW64_OpRsh32x16(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Rsh32x16 x y) ++ // result: (SRA (SignExt32to64 x) (BIS (NEGV (CMPULT (MOVVconst [63]) (ZeroExt16to64 y))) (ZeroExt16to64 y))) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64SRA) ++ v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) ++ v0.AddArg(x) ++ v1 := b.NewValue0(v.Pos, OpSW64BIS, t) ++ v2 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v3 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v4 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v4.AuxInt = int64ToAuxInt(63) ++ v5 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) ++ v5.AddArg(y) ++ v3.AddArg2(v4, v5) ++ v2.AddArg(v3) ++ v1.AddArg2(v2, v5) ++ v.AddArg2(v0, v1) ++ return true ++ } ++} ++func rewriteValueSW64_OpRsh32x32(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Rsh32x32 x y) ++ // result: (SRA (SignExt32to64 x) (BIS (NEGV (CMPULT (MOVVconst [63]) (ZeroExt32to64 y))) (ZeroExt32to64 y))) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64SRA) ++ v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) ++ v0.AddArg(x) ++ v1 := b.NewValue0(v.Pos, OpSW64BIS, t) ++ v2 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v3 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v4 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v4.AuxInt = int64ToAuxInt(63) ++ v5 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) ++ v5.AddArg(y) ++ v3.AddArg2(v4, v5) ++ v2.AddArg(v3) ++ v1.AddArg2(v2, v5) ++ v.AddArg2(v0, v1) ++ return true ++ } ++} ++func rewriteValueSW64_OpRsh32x64(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Rsh32x64 x (Const64 [c])) ++ // cond: uint64(c) < 32 ++ // result: (SRAconst (SignExt32to64 x) [c]) ++ for { ++ x := v_0 ++ if v_1.Op != OpConst64 { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(uint64(c) < 32) { ++ break ++ } ++ v.reset(OpSW64SRAconst) ++ v.AuxInt = int64ToAuxInt(c) ++ v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) ++ v0.AddArg(x) ++ v.AddArg(v0) ++ return true ++ } ++ // match: (Rsh32x64 x (Const64 [c])) ++ // cond: uint64(c) >= 32 ++ // result: (SRAconst (SignExt32to64 x) [63]) ++ for { ++ x := v_0 ++ if v_1.Op != OpConst64 { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(uint64(c) >= 32) { ++ break ++ } ++ v.reset(OpSW64SRAconst) ++ v.AuxInt = int64ToAuxInt(63) ++ v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) ++ v0.AddArg(x) ++ v.AddArg(v0) ++ return true ++ } ++ // match: (Rsh32x64 x (MOVVconst [c])) ++ // cond: uint64(c) >= 32 ++ // result: (SRAconst (SignExt32to64 x) [63]) ++ for { ++ x := v_0 ++ if v_1.Op != OpSW64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(uint64(c) >= 32) { ++ break ++ } ++ v.reset(OpSW64SRAconst) ++ v.AuxInt = int64ToAuxInt(63) ++ v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) ++ v0.AddArg(x) ++ v.AddArg(v0) ++ return true ++ } ++ // match: (Rsh32x64 x (MOVVconst [c])) ++ // cond: uint64(c) < 32 ++ // result: (SRAconst (SignExt32to64 x) [c]) ++ for { ++ x := v_0 ++ if v_1.Op != OpSW64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(uint64(c) < 32) { ++ break ++ } ++ v.reset(OpSW64SRAconst) ++ v.AuxInt = int64ToAuxInt(c) ++ v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) ++ v0.AddArg(x) ++ v.AddArg(v0) ++ return true ++ } ++ // match: (Rsh32x64 x y) ++ // result: (SRA (SignExt32to64 x) (BIS (NEGV (CMPULT (MOVVconst [63]) y)) y)) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64SRA) ++ v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) ++ v0.AddArg(x) ++ v1 := b.NewValue0(v.Pos, OpSW64BIS, t) ++ v2 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v3 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v4 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v4.AuxInt = int64ToAuxInt(63) ++ v3.AddArg2(v4, y) ++ v2.AddArg(v3) ++ v1.AddArg2(v2, y) ++ v.AddArg2(v0, v1) ++ return true ++ } ++} ++func rewriteValueSW64_OpRsh32x8(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Rsh32x8 x y) ++ // result: (SRA (SignExt32to64 x) (BIS (NEGV (CMPULT (MOVVconst [63]) (ZeroExt8to64 y))) (ZeroExt8to64 y))) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64SRA) ++ v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) ++ v0.AddArg(x) ++ v1 := b.NewValue0(v.Pos, OpSW64BIS, t) ++ v2 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v3 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v4 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v4.AuxInt = int64ToAuxInt(63) ++ v5 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) ++ v5.AddArg(y) ++ v3.AddArg2(v4, v5) ++ v2.AddArg(v3) ++ v1.AddArg2(v2, v5) ++ v.AddArg2(v0, v1) ++ return true ++ } ++} ++func rewriteValueSW64_OpRsh64Ux16(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Rsh64Ux16 x y) ++ // result: (AND (NEGV (CMPULT (ZeroExt16to64 y) (MOVVconst [64]))) (SRL x (ZeroExt16to64 y))) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64AND) ++ v0 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v1 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v2 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) ++ v2.AddArg(y) ++ v3 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v3.AuxInt = int64ToAuxInt(64) ++ v1.AddArg2(v2, v3) ++ v0.AddArg(v1) ++ v4 := b.NewValue0(v.Pos, OpSW64SRL, t) ++ v4.AddArg2(x, v2) ++ v.AddArg2(v0, v4) ++ return true ++ } ++} ++func rewriteValueSW64_OpRsh64Ux32(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Rsh64Ux32 x y) ++ // result: (AND (NEGV (CMPULT (ZeroExt32to64 y) (MOVVconst [64]))) (SRL x (ZeroExt32to64 y))) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64AND) ++ v0 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v1 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v2 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) ++ v2.AddArg(y) ++ v3 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v3.AuxInt = int64ToAuxInt(64) ++ v1.AddArg2(v2, v3) ++ v0.AddArg(v1) ++ v4 := b.NewValue0(v.Pos, OpSW64SRL, t) ++ v4.AddArg2(x, v2) ++ v.AddArg2(v0, v4) ++ return true ++ } ++} ++func rewriteValueSW64_OpRsh64Ux64(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Rsh64Ux64 x (Const64 [c])) ++ // cond: uint64(c) < 64 ++ // result: (SRLconst x [c]) ++ for { ++ x := v_0 ++ if v_1.Op != OpConst64 { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(uint64(c) < 64) { ++ break ++ } ++ v.reset(OpSW64SRLconst) ++ v.AuxInt = int64ToAuxInt(c) ++ v.AddArg(x) ++ return true ++ } ++ // match: (Rsh64Ux64 x (MOVVconst [c])) ++ // cond: uint64(c) < 64 ++ // result: (SRLconst x [c]) ++ for { ++ x := v_0 ++ if v_1.Op != OpSW64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(uint64(c) < 64) { ++ break ++ } ++ v.reset(OpSW64SRLconst) ++ v.AuxInt = int64ToAuxInt(c) ++ v.AddArg(x) ++ return true ++ } ++ // match: (Rsh64Ux64 x y) ++ // result: (AND (NEGV (CMPULT y (MOVVconst [64]))) (SRL x y)) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64AND) ++ v0 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v1 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v2 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v2.AuxInt = int64ToAuxInt(64) ++ v1.AddArg2(y, v2) ++ v0.AddArg(v1) ++ v3 := b.NewValue0(v.Pos, OpSW64SRL, t) ++ v3.AddArg2(x, y) ++ v.AddArg2(v0, v3) ++ return true ++ } ++} ++func rewriteValueSW64_OpRsh64Ux8(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Rsh64Ux8 x y) ++ // result: (AND (NEGV (CMPULT (ZeroExt8to64 y) (MOVVconst [64]))) (SRL x (ZeroExt8to64 y))) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64AND) ++ v0 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v1 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v2 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) ++ v2.AddArg(y) ++ v3 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v3.AuxInt = int64ToAuxInt(64) ++ v1.AddArg2(v2, v3) ++ v0.AddArg(v1) ++ v4 := b.NewValue0(v.Pos, OpSW64SRL, t) ++ v4.AddArg2(x, v2) ++ v.AddArg2(v0, v4) ++ return true ++ } ++} ++func rewriteValueSW64_OpRsh64x16(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Rsh64x16 x y) ++ // result: (SRA x (BIS (NEGV (CMPULT (MOVVconst [63]) (ZeroExt16to64 y))) (ZeroExt16to64 y))) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64SRA) ++ v0 := b.NewValue0(v.Pos, OpSW64BIS, t) ++ v1 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v2 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v3 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v3.AuxInt = int64ToAuxInt(63) ++ v4 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) ++ v4.AddArg(y) ++ v2.AddArg2(v3, v4) ++ v1.AddArg(v2) ++ v0.AddArg2(v1, v4) ++ v.AddArg2(x, v0) ++ return true ++ } ++} ++func rewriteValueSW64_OpRsh64x32(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Rsh64x32 x y) ++ // result: (SRA x (BIS (NEGV (CMPULT (MOVVconst [63]) (ZeroExt32to64 y))) (ZeroExt32to64 y))) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64SRA) ++ v0 := b.NewValue0(v.Pos, OpSW64BIS, t) ++ v1 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v2 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v3 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v3.AuxInt = int64ToAuxInt(63) ++ v4 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) ++ v4.AddArg(y) ++ v2.AddArg2(v3, v4) ++ v1.AddArg(v2) ++ v0.AddArg2(v1, v4) ++ v.AddArg2(x, v0) ++ return true ++ } ++} ++func rewriteValueSW64_OpRsh64x64(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Rsh64x64 x (Const64 [c])) ++ // cond: uint64(c) < 64 ++ // result: (SRAconst x [c]) ++ for { ++ x := v_0 ++ if v_1.Op != OpConst64 { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(uint64(c) < 64) { ++ break ++ } ++ v.reset(OpSW64SRAconst) ++ v.AuxInt = int64ToAuxInt(c) ++ v.AddArg(x) ++ return true ++ } ++ // match: (Rsh64x64 x (Const64 [c])) ++ // cond: uint64(c) >= 64 ++ // result: (SRAconst x [63]) ++ for { ++ x := v_0 ++ if v_1.Op != OpConst64 { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(uint64(c) >= 64) { ++ break ++ } ++ v.reset(OpSW64SRAconst) ++ v.AuxInt = int64ToAuxInt(63) ++ v.AddArg(x) ++ return true ++ } ++ // match: (Rsh64x64 x (MOVVconst [c])) ++ // cond: uint64(c) >= 64 ++ // result: (SRAconst x [63]) ++ for { ++ x := v_0 ++ if v_1.Op != OpSW64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(uint64(c) >= 64) { ++ break ++ } ++ v.reset(OpSW64SRAconst) ++ v.AuxInt = int64ToAuxInt(63) ++ v.AddArg(x) ++ return true ++ } ++ // match: (Rsh64x64 x (MOVVconst [c])) ++ // cond: uint64(c) < 64 ++ // result: (SRAconst x [c]) ++ for { ++ x := v_0 ++ if v_1.Op != OpSW64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(uint64(c) < 64) { ++ break ++ } ++ v.reset(OpSW64SRAconst) ++ v.AuxInt = int64ToAuxInt(c) ++ v.AddArg(x) ++ return true ++ } ++ // match: (Rsh64x64 x y) ++ // result: (SRA x (BIS (NEGV (CMPULT (MOVVconst [63]) y)) y)) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64SRA) ++ v0 := b.NewValue0(v.Pos, OpSW64BIS, t) ++ v1 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v2 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v3 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v3.AuxInt = int64ToAuxInt(63) ++ v2.AddArg2(v3, y) ++ v1.AddArg(v2) ++ v0.AddArg2(v1, y) ++ v.AddArg2(x, v0) ++ return true ++ } ++} ++func rewriteValueSW64_OpRsh64x8(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Rsh64x8 x y) ++ // result: (SRA x (BIS (NEGV (CMPULT (MOVVconst [63]) (ZeroExt8to64 y))) (ZeroExt8to64 y))) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64SRA) ++ v0 := b.NewValue0(v.Pos, OpSW64BIS, t) ++ v1 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v2 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v3 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v3.AuxInt = int64ToAuxInt(63) ++ v4 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) ++ v4.AddArg(y) ++ v2.AddArg2(v3, v4) ++ v1.AddArg(v2) ++ v0.AddArg2(v1, v4) ++ v.AddArg2(x, v0) ++ return true ++ } ++} ++func rewriteValueSW64_OpRsh8Ux16(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Rsh8Ux16 x y) ++ // result: (AND (NEGV (CMPULT (ZeroExt16to64 y) (MOVVconst [64]))) (SRL (ZeroExt8to64 x) (ZeroExt16to64 y))) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64AND) ++ v0 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v1 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v2 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) ++ v2.AddArg(y) ++ v3 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v3.AuxInt = int64ToAuxInt(64) ++ v1.AddArg2(v2, v3) ++ v0.AddArg(v1) ++ v4 := b.NewValue0(v.Pos, OpSW64SRL, t) ++ v5 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) ++ v5.AddArg(x) ++ v4.AddArg2(v5, v2) ++ v.AddArg2(v0, v4) ++ return true ++ } ++} ++func rewriteValueSW64_OpRsh8Ux32(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Rsh8Ux32 x y) ++ // result: (AND (NEGV (CMPULT (ZeroExt32to64 y) (MOVVconst [64]))) (SRL (ZeroExt8to64 x) (ZeroExt32to64 y))) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64AND) ++ v0 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v1 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v2 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) ++ v2.AddArg(y) ++ v3 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v3.AuxInt = int64ToAuxInt(64) ++ v1.AddArg2(v2, v3) ++ v0.AddArg(v1) ++ v4 := b.NewValue0(v.Pos, OpSW64SRL, t) ++ v5 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) ++ v5.AddArg(x) ++ v4.AddArg2(v5, v2) ++ v.AddArg2(v0, v4) ++ return true ++ } ++} ++func rewriteValueSW64_OpRsh8Ux64(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Rsh8Ux64 x (Const64 [c])) ++ // cond: uint64(c) < 8 ++ // result: (SRLconst (ZeroExt8to64 x) [c]) ++ for { ++ x := v_0 ++ if v_1.Op != OpConst64 { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(uint64(c) < 8) { ++ break ++ } ++ v.reset(OpSW64SRLconst) ++ v.AuxInt = int64ToAuxInt(c) ++ v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) ++ v0.AddArg(x) ++ v.AddArg(v0) ++ return true ++ } ++ // match: (Rsh8Ux64 x (MOVVconst [c])) ++ // cond: uint64(c) < 8 ++ // result: (SRLconst (ZeroExt8to64 x) [c]) ++ for { ++ x := v_0 ++ if v_1.Op != OpSW64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(uint64(c) < 8) { ++ break ++ } ++ v.reset(OpSW64SRLconst) ++ v.AuxInt = int64ToAuxInt(c) ++ v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) ++ v0.AddArg(x) ++ v.AddArg(v0) ++ return true ++ } ++ // match: (Rsh8Ux64 x y) ++ // result: (AND (NEGV (CMPULT y (MOVVconst [64]))) (SRL (ZeroExt8to64 x) y)) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64AND) ++ v0 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v1 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v2 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v2.AuxInt = int64ToAuxInt(64) ++ v1.AddArg2(y, v2) ++ v0.AddArg(v1) ++ v3 := b.NewValue0(v.Pos, OpSW64SRL, t) ++ v4 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) ++ v4.AddArg(x) ++ v3.AddArg2(v4, y) ++ v.AddArg2(v0, v3) ++ return true ++ } ++} ++func rewriteValueSW64_OpRsh8Ux8(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Rsh8Ux8 x y) ++ // result: (AND (NEGV (CMPULT (ZeroExt8to64 y) (MOVVconst [64]))) (SRL (ZeroExt8to64 x) (ZeroExt8to64 y))) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64AND) ++ v0 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v1 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v2 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) ++ v2.AddArg(y) ++ v3 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v3.AuxInt = int64ToAuxInt(64) ++ v1.AddArg2(v2, v3) ++ v0.AddArg(v1) ++ v4 := b.NewValue0(v.Pos, OpSW64SRL, t) ++ v5 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) ++ v5.AddArg(x) ++ v4.AddArg2(v5, v2) ++ v.AddArg2(v0, v4) ++ return true ++ } ++} ++func rewriteValueSW64_OpRsh8x16(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Rsh8x16 x y) ++ // result: (SRA (SignExt8to64 x) (BIS (NEGV (CMPULT (MOVVconst [63]) (ZeroExt16to64 y))) (ZeroExt16to64 y))) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64SRA) ++ v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) ++ v0.AddArg(x) ++ v1 := b.NewValue0(v.Pos, OpSW64BIS, t) ++ v2 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v3 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v4 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v4.AuxInt = int64ToAuxInt(63) ++ v5 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) ++ v5.AddArg(y) ++ v3.AddArg2(v4, v5) ++ v2.AddArg(v3) ++ v1.AddArg2(v2, v5) ++ v.AddArg2(v0, v1) ++ return true ++ } ++} ++func rewriteValueSW64_OpRsh8x32(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Rsh8x32 x y) ++ // result: (SRA (SignExt8to64 x) (BIS (NEGV (CMPULT (MOVVconst [63]) (ZeroExt32to64 y))) (ZeroExt32to64 y))) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64SRA) ++ v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) ++ v0.AddArg(x) ++ v1 := b.NewValue0(v.Pos, OpSW64BIS, t) ++ v2 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v3 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v4 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v4.AuxInt = int64ToAuxInt(63) ++ v5 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) ++ v5.AddArg(y) ++ v3.AddArg2(v4, v5) ++ v2.AddArg(v3) ++ v1.AddArg2(v2, v5) ++ v.AddArg2(v0, v1) ++ return true ++ } ++} ++func rewriteValueSW64_OpRsh8x64(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Rsh8x64 x (Const64 [c])) ++ // cond: uint64(c) < 8 ++ // result: (SRAconst (SignExt8to64 x) [c]) ++ for { ++ x := v_0 ++ if v_1.Op != OpConst64 { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(uint64(c) < 8) { ++ break ++ } ++ v.reset(OpSW64SRAconst) ++ v.AuxInt = int64ToAuxInt(c) ++ v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) ++ v0.AddArg(x) ++ v.AddArg(v0) ++ return true ++ } ++ // match: (Rsh8x64 x (Const64 [c])) ++ // cond: uint64(c) >= 8 ++ // result: (SRAconst (SignExt8to64 x) [63]) ++ for { ++ x := v_0 ++ if v_1.Op != OpConst64 { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(uint64(c) >= 8) { ++ break ++ } ++ v.reset(OpSW64SRAconst) ++ v.AuxInt = int64ToAuxInt(63) ++ v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) ++ v0.AddArg(x) ++ v.AddArg(v0) ++ return true ++ } ++ // match: (Rsh8x64 x (MOVVconst [c])) ++ // cond: uint64(c) >= 8 ++ // result: (SRAconst (SignExt8to64 x) [63]) ++ for { ++ x := v_0 ++ if v_1.Op != OpSW64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(uint64(c) >= 8) { ++ break ++ } ++ v.reset(OpSW64SRAconst) ++ v.AuxInt = int64ToAuxInt(63) ++ v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) ++ v0.AddArg(x) ++ v.AddArg(v0) ++ return true ++ } ++ // match: (Rsh8x64 x (MOVVconst [c])) ++ // cond: uint64(c) < 8 ++ // result: (SRAconst (SignExt8to64 x) [c]) ++ for { ++ x := v_0 ++ if v_1.Op != OpSW64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(uint64(c) < 8) { ++ break ++ } ++ v.reset(OpSW64SRAconst) ++ v.AuxInt = int64ToAuxInt(c) ++ v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) ++ v0.AddArg(x) ++ v.AddArg(v0) ++ return true ++ } ++ // match: (Rsh8x64 x y) ++ // result: (SRA (SignExt8to64 x) (BIS (NEGV (CMPULT (MOVVconst [63]) y)) y)) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64SRA) ++ v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) ++ v0.AddArg(x) ++ v1 := b.NewValue0(v.Pos, OpSW64BIS, t) ++ v2 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v3 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v4 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v4.AuxInt = int64ToAuxInt(63) ++ v3.AddArg2(v4, y) ++ v2.AddArg(v3) ++ v1.AddArg2(v2, y) ++ v.AddArg2(v0, v1) ++ return true ++ } ++} ++func rewriteValueSW64_OpRsh8x8(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (Rsh8x8 x y) ++ // result: (SRA (SignExt8to64 x) (BIS (NEGV (CMPULT (MOVVconst [63]) (ZeroExt8to64 y))) (ZeroExt8to64 y))) ++ for { ++ t := v.Type ++ x := v_0 ++ y := v_1 ++ v.reset(OpSW64SRA) ++ v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) ++ v0.AddArg(x) ++ v1 := b.NewValue0(v.Pos, OpSW64BIS, t) ++ v2 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v3 := b.NewValue0(v.Pos, OpSW64CMPULT, typ.Bool) ++ v4 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v4.AuxInt = int64ToAuxInt(63) ++ v5 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) ++ v5.AddArg(y) ++ v3.AddArg2(v4, v5) ++ v2.AddArg(v3) ++ v1.AddArg2(v2, v5) ++ v.AddArg2(v0, v1) ++ return true ++ } ++} ++func rewriteValueSW64_OpSW64ADDV(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ // match: (ADDV x (MOVVconst [c])) ++ // cond: is32Bit(c) && !t.IsPtr() ++ // result: (ADDVconst [c] x) ++ for { ++ for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { ++ x := v_0 ++ if v_1.Op != OpSW64MOVVconst { ++ continue ++ } ++ t := v_1.Type ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(is32Bit(c) && !t.IsPtr()) { ++ continue ++ } ++ v.reset(OpSW64ADDVconst) ++ v.AuxInt = int64ToAuxInt(c) ++ v.AddArg(x) ++ return true ++ } ++ break ++ } ++ // match: (ADDV x (NEGV y)) ++ // result: (SUBV x y) ++ for { ++ for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { ++ x := v_0 ++ if v_1.Op != OpSW64NEGV { ++ continue ++ } ++ y := v_1.Args[0] ++ v.reset(OpSW64SUBV) ++ v.AddArg2(x, y) ++ return true ++ } ++ break ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64ADDVconst(v *Value) bool { ++ v_0 := v.Args[0] ++ // match: (ADDVconst [0] x) ++ // result: x ++ for { ++ if auxIntToInt64(v.AuxInt) != 0 { ++ break ++ } ++ x := v_0 ++ v.copyOf(x) ++ return true ++ } ++ // match: (ADDVconst [c] (MOVVconst [d])) ++ // result: (MOVVconst [c+d]) ++ for { ++ c := auxIntToInt64(v.AuxInt) ++ if v_0.Op != OpSW64MOVVconst { ++ break ++ } ++ d := auxIntToInt64(v_0.AuxInt) ++ v.reset(OpSW64MOVVconst) ++ v.AuxInt = int64ToAuxInt(c + d) ++ return true ++ } ++ // match: (ADDVconst [c] (ADDVconst [d] x)) ++ // cond: is32Bit(c+d) ++ // result: (ADDVconst [c+d] x) ++ for { ++ c := auxIntToInt64(v.AuxInt) ++ if v_0.Op != OpSW64ADDVconst { ++ break ++ } ++ d := auxIntToInt64(v_0.AuxInt) ++ x := v_0.Args[0] ++ if !(is32Bit(c + d)) { ++ break ++ } ++ v.reset(OpSW64ADDVconst) ++ v.AuxInt = int64ToAuxInt(c + d) ++ v.AddArg(x) ++ return true ++ } ++ // match: (ADDVconst [c] (SUBVconst [d] x)) ++ // cond: is32Bit(c-d) ++ // result: (ADDVconst [c-d] x) ++ for { ++ c := auxIntToInt64(v.AuxInt) ++ if v_0.Op != OpSW64SUBVconst { ++ break ++ } ++ d := auxIntToInt64(v_0.AuxInt) ++ x := v_0.Args[0] ++ if !(is32Bit(c - d)) { ++ break ++ } ++ v.reset(OpSW64ADDVconst) ++ v.AuxInt = int64ToAuxInt(c - d) ++ v.AddArg(x) ++ return true ++ } ++ // match: (ADDVconst [off1] (SYMADDR [off2] {sym} ptr)) ++ // cond: is32Bit(off1+int64(off2)) ++ // result: (SYMADDR [int32(off1)+off2] {sym} ptr) ++ for { ++ off1 := auxIntToInt64(v.AuxInt) ++ if v_0.Op != OpSW64SYMADDR { ++ break ++ } ++ off2 := auxIntToInt32(v_0.AuxInt) ++ sym := auxToSym(v_0.Aux) ++ ptr := v_0.Args[0] ++ if !(is32Bit(off1 + int64(off2))) { ++ break ++ } ++ v.reset(OpSW64SYMADDR) ++ v.AuxInt = int32ToAuxInt(int32(off1) + off2) ++ v.Aux = symToAux(sym) ++ v.AddArg(ptr) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64ADDWconst(v *Value) bool { ++ v_0 := v.Args[0] ++ // match: (ADDWconst (MOVVconst [c]) [0]) ++ // result: (MOVVconst [int64(int32(c))]) ++ for { ++ if auxIntToInt32(v.AuxInt) != 0 || v_0.Op != OpSW64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_0.AuxInt) ++ v.reset(OpSW64MOVVconst) ++ v.AuxInt = int64ToAuxInt(int64(int32(c))) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64AND(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ // match: (AND x (MOVVconst [c])) ++ // cond: is32Bit(c) ++ // result: (ANDconst [c] x) ++ for { ++ for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { ++ x := v_0 ++ if v_1.Op != OpSW64MOVVconst { ++ continue ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(is32Bit(c)) { ++ continue ++ } ++ v.reset(OpSW64ANDconst) ++ v.AuxInt = int64ToAuxInt(c) ++ v.AddArg(x) ++ return true ++ } ++ break ++ } ++ // match: (AND x x) ++ // result: x ++ for { ++ x := v_0 ++ if x != v_1 { ++ break ++ } ++ v.copyOf(x) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64ANDconst(v *Value) bool { ++ v_0 := v.Args[0] ++ // match: (ANDconst (MOVVconst [c]) [255]) ++ // result: (MOVVconst [int64(uint8(c))]) ++ for { ++ if auxIntToInt64(v.AuxInt) != 255 || v_0.Op != OpSW64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_0.AuxInt) ++ v.reset(OpSW64MOVVconst) ++ v.AuxInt = int64ToAuxInt(int64(uint8(c))) ++ return true ++ } ++ // match: (ANDconst (MOVVconst [c]) [65535]) ++ // result: (MOVVconst [int64(uint16(c))]) ++ for { ++ if auxIntToInt64(v.AuxInt) != 65535 || v_0.Op != OpSW64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_0.AuxInt) ++ v.reset(OpSW64MOVVconst) ++ v.AuxInt = int64ToAuxInt(int64(uint16(c))) ++ return true ++ } ++ // match: (ANDconst (MOVVconst [c]) [0xffffffff]) ++ // result: (MOVVconst [int64(uint32(c))]) ++ for { ++ if auxIntToInt64(v.AuxInt) != 0xffffffff || v_0.Op != OpSW64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_0.AuxInt) ++ v.reset(OpSW64MOVVconst) ++ v.AuxInt = int64ToAuxInt(int64(uint32(c))) ++ return true ++ } ++ // match: (ANDconst [0] _) ++ // result: (MOVVconst [0]) ++ for { ++ if auxIntToInt64(v.AuxInt) != 0 { ++ break ++ } ++ v.reset(OpSW64MOVVconst) ++ v.AuxInt = int64ToAuxInt(0) ++ return true ++ } ++ // match: (ANDconst [-1] x) ++ // result: x ++ for { ++ if auxIntToInt64(v.AuxInt) != -1 { ++ break ++ } ++ x := v_0 ++ v.copyOf(x) ++ return true ++ } ++ // match: (ANDconst [c] (MOVVconst [d])) ++ // result: (MOVVconst [c&d]) ++ for { ++ c := auxIntToInt64(v.AuxInt) ++ if v_0.Op != OpSW64MOVVconst { ++ break ++ } ++ d := auxIntToInt64(v_0.AuxInt) ++ v.reset(OpSW64MOVVconst) ++ v.AuxInt = int64ToAuxInt(c & d) ++ return true ++ } ++ // match: (ANDconst [c] (ANDconst [d] x)) ++ // result: (ANDconst [c&d] x) ++ for { ++ c := auxIntToInt64(v.AuxInt) ++ if v_0.Op != OpSW64ANDconst { ++ break ++ } ++ d := auxIntToInt64(v_0.AuxInt) ++ x := v_0.Args[0] ++ v.reset(OpSW64ANDconst) ++ v.AuxInt = int64ToAuxInt(c & d) ++ v.AddArg(x) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64BIS(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ // match: (BIS x (MOVVconst [c])) ++ // cond: is32Bit(c) ++ // result: (BISconst [c] x) ++ for { ++ for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { ++ x := v_0 ++ if v_1.Op != OpSW64MOVVconst { ++ continue ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(is32Bit(c)) { ++ continue ++ } ++ v.reset(OpSW64BISconst) ++ v.AuxInt = int64ToAuxInt(c) ++ v.AddArg(x) ++ return true ++ } ++ break ++ } ++ // match: (BIS x x) ++ // result: x ++ for { ++ x := v_0 ++ if x != v_1 { ++ break ++ } ++ v.copyOf(x) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64BISconst(v *Value) bool { ++ v_0 := v.Args[0] ++ // match: (BISconst [0] x) ++ // result: x ++ for { ++ if auxIntToInt64(v.AuxInt) != 0 { ++ break ++ } ++ x := v_0 ++ v.copyOf(x) ++ return true ++ } ++ // match: (BISconst [-1] _) ++ // result: (MOVVconst [-1]) ++ for { ++ if auxIntToInt64(v.AuxInt) != -1 { ++ break ++ } ++ v.reset(OpSW64MOVVconst) ++ v.AuxInt = int64ToAuxInt(-1) ++ return true ++ } ++ // match: (BISconst [c] (MOVVconst [d])) ++ // result: (MOVVconst [c|d]) ++ for { ++ c := auxIntToInt64(v.AuxInt) ++ if v_0.Op != OpSW64MOVVconst { ++ break ++ } ++ d := auxIntToInt64(v_0.AuxInt) ++ v.reset(OpSW64MOVVconst) ++ v.AuxInt = int64ToAuxInt(c | d) ++ return true ++ } ++ // match: (BISconst [c] (BISconst [d] x)) ++ // cond: is32Bit(c|d) ++ // result: (BISconst [c|d] x) ++ for { ++ c := auxIntToInt64(v.AuxInt) ++ if v_0.Op != OpSW64BISconst { ++ break ++ } ++ d := auxIntToInt64(v_0.AuxInt) ++ x := v_0.Args[0] ++ if !(is32Bit(c | d)) { ++ break ++ } ++ v.reset(OpSW64BISconst) ++ v.AuxInt = int64ToAuxInt(c | d) ++ v.AddArg(x) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64CMPEQ(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ // match: (CMPEQ x (MOVVconst [c])) ++ // cond: is32Bit(c) ++ // result: (CMPEQconst [c] x) ++ for { ++ x := v_0 ++ if v_1.Op != OpSW64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(is32Bit(c)) { ++ break ++ } ++ v.reset(OpSW64CMPEQconst) ++ v.AuxInt = int64ToAuxInt(c) ++ v.AddArg(x) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64CMPLE(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ // match: (CMPLE x (MOVVconst [c])) ++ // cond: is32Bit(c) ++ // result: (CMPLEconst [c] x) ++ for { ++ x := v_0 ++ if v_1.Op != OpSW64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(is32Bit(c)) { ++ break ++ } ++ v.reset(OpSW64CMPLEconst) ++ v.AuxInt = int64ToAuxInt(c) ++ v.AddArg(x) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64CMPLT(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ // match: (CMPLT x (MOVVconst [c])) ++ // cond: is32Bit(c) ++ // result: (CMPLTconst [c] x) ++ for { ++ x := v_0 ++ if v_1.Op != OpSW64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(is32Bit(c)) { ++ break ++ } ++ v.reset(OpSW64CMPLTconst) ++ v.AuxInt = int64ToAuxInt(c) ++ v.AddArg(x) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64CMPULE(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ // match: (CMPULE x (MOVVconst [c])) ++ // cond: is32Bit(c) ++ // result: (CMPULEconst [c] x) ++ for { ++ x := v_0 ++ if v_1.Op != OpSW64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(is32Bit(c)) { ++ break ++ } ++ v.reset(OpSW64CMPULEconst) ++ v.AuxInt = int64ToAuxInt(c) ++ v.AddArg(x) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64CMPULT(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ // match: (CMPULT x (MOVVconst [c])) ++ // cond: is32Bit(c) ++ // result: (CMPULTconst [c] x) ++ for { ++ x := v_0 ++ if v_1.Op != OpSW64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(is32Bit(c)) { ++ break ++ } ++ v.reset(OpSW64CMPULTconst) ++ v.AuxInt = int64ToAuxInt(c) ++ v.AddArg(x) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64MOVBUload(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ config := b.Func.Config ++ // match: (MOVBUload [off1] {sym} (ADDVconst [off2] ptr) mem) ++ // cond: is16Bit(int64(off1)+off2) ++ // result: (MOVBUload [off1+int32(off2)] {sym} ptr mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ if v_0.Op != OpSW64ADDVconst { ++ break ++ } ++ off2 := auxIntToInt64(v_0.AuxInt) ++ ptr := v_0.Args[0] ++ mem := v_1 ++ if !(is16Bit(int64(off1) + off2)) { ++ break ++ } ++ v.reset(OpSW64MOVBUload) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(sym) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ // match: (MOVBUload [off1] {sym} (ADDVconst [off2] ptr) mem) ++ // cond: is32Bit(int64(off1)+off2) ++ // result: (MOVBUload [off1+int32(off2)] {sym} ptr mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ if v_0.Op != OpSW64ADDVconst { ++ break ++ } ++ off2 := auxIntToInt64(v_0.AuxInt) ++ ptr := v_0.Args[0] ++ mem := v_1 ++ if !(is32Bit(int64(off1) + off2)) { ++ break ++ } ++ v.reset(OpSW64MOVBUload) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(sym) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ // match: (MOVBUload [off1] {sym1} (SYMADDR [off2] {sym2} ptr) mem) ++ // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) ++ // result: (MOVBUload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym1 := auxToSym(v.Aux) ++ if v_0.Op != OpSW64SYMADDR { ++ break ++ } ++ off2 := auxIntToInt32(v_0.AuxInt) ++ sym2 := auxToSym(v_0.Aux) ++ ptr := v_0.Args[0] ++ mem := v_1 ++ if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) { ++ break ++ } ++ v.reset(OpSW64MOVBUload) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(mergeSym(sym1, sym2)) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64MOVBUreg(v *Value) bool { ++ v_0 := v.Args[0] ++ // match: (MOVBUreg x:(MOVBUload _ _)) ++ // result: (MOVVreg x) ++ for { ++ x := v_0 ++ if x.Op != OpSW64MOVBUload { ++ break ++ } ++ v.reset(OpSW64MOVVreg) ++ v.AddArg(x) ++ return true ++ } ++ // match: (MOVBUreg x:(MOVBUreg _)) ++ // result: (MOVVreg x) ++ for { ++ x := v_0 ++ if x.Op != OpSW64MOVBUreg { ++ break ++ } ++ v.reset(OpSW64MOVVreg) ++ v.AddArg(x) ++ return true ++ } ++ // match: (MOVBUreg (MOVVconst [c])) ++ // result: (MOVVconst [int64(uint8(c))]) ++ for { ++ if v_0.Op != OpSW64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_0.AuxInt) ++ v.reset(OpSW64MOVVconst) ++ v.AuxInt = int64ToAuxInt(int64(uint8(c))) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64MOVBload(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ config := b.Func.Config ++ // match: (MOVBload [off1] {sym} (ADDVconst [off2] ptr) mem) ++ // cond: is16Bit(int64(off1)+off2) ++ // result: (MOVBload [off1+int32(off2)] {sym} ptr mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ if v_0.Op != OpSW64ADDVconst { ++ break ++ } ++ off2 := auxIntToInt64(v_0.AuxInt) ++ ptr := v_0.Args[0] ++ mem := v_1 ++ if !(is16Bit(int64(off1) + off2)) { ++ break ++ } ++ v.reset(OpSW64MOVBload) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(sym) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ // match: (MOVBload [off1] {sym} (ADDVconst [off2] ptr) mem) ++ // cond: is32Bit(int64(off1)+off2) ++ // result: (MOVBload [off1+int32(off2)] {sym} ptr mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ if v_0.Op != OpSW64ADDVconst { ++ break ++ } ++ off2 := auxIntToInt64(v_0.AuxInt) ++ ptr := v_0.Args[0] ++ mem := v_1 ++ if !(is32Bit(int64(off1) + off2)) { ++ break ++ } ++ v.reset(OpSW64MOVBload) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(sym) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ // match: (MOVBload [off1] {sym1} (SYMADDR [off2] {sym2} ptr) mem) ++ // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) ++ // result: (MOVBload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym1 := auxToSym(v.Aux) ++ if v_0.Op != OpSW64SYMADDR { ++ break ++ } ++ off2 := auxIntToInt32(v_0.AuxInt) ++ sym2 := auxToSym(v_0.Aux) ++ ptr := v_0.Args[0] ++ mem := v_1 ++ if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) { ++ break ++ } ++ v.reset(OpSW64MOVBload) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(mergeSym(sym1, sym2)) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64MOVBreg(v *Value) bool { ++ v_0 := v.Args[0] ++ // match: (MOVBreg x:(MOVBreg _)) ++ // result: (MOVVreg x) ++ for { ++ x := v_0 ++ if x.Op != OpSW64MOVBreg { ++ break ++ } ++ v.reset(OpSW64MOVVreg) ++ v.AddArg(x) ++ return true ++ } ++ // match: (MOVBreg (MOVVconst [c])) ++ // result: (MOVVconst [int64(int8(c))]) ++ for { ++ if v_0.Op != OpSW64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_0.AuxInt) ++ v.reset(OpSW64MOVVconst) ++ v.AuxInt = int64ToAuxInt(int64(int8(c))) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64MOVBstore(v *Value) bool { ++ v_2 := v.Args[2] ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ config := b.Func.Config ++ // match: (MOVBstore [off1] {sym} (ADDVconst [off2] ptr) val mem) ++ // cond: is16Bit(int64(off1)+off2) ++ // result: (MOVBstore [off1+int32(off2)] {sym} ptr val mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ if v_0.Op != OpSW64ADDVconst { ++ break ++ } ++ off2 := auxIntToInt64(v_0.AuxInt) ++ ptr := v_0.Args[0] ++ val := v_1 ++ mem := v_2 ++ if !(is16Bit(int64(off1) + off2)) { ++ break ++ } ++ v.reset(OpSW64MOVBstore) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(sym) ++ v.AddArg3(ptr, val, mem) ++ return true ++ } ++ // match: (MOVBstore [off1] {sym} (ADDVconst [off2] ptr) val mem) ++ // cond: is32Bit(int64(off1)+off2) ++ // result: (MOVBstore [off1+int32(off2)] {sym} ptr val mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ if v_0.Op != OpSW64ADDVconst { ++ break ++ } ++ off2 := auxIntToInt64(v_0.AuxInt) ++ ptr := v_0.Args[0] ++ val := v_1 ++ mem := v_2 ++ if !(is32Bit(int64(off1) + off2)) { ++ break ++ } ++ v.reset(OpSW64MOVBstore) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(sym) ++ v.AddArg3(ptr, val, mem) ++ return true ++ } ++ // match: (MOVBstore [off1] {sym1} (SYMADDR [off2] {sym2} ptr) val mem) ++ // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) ++ // result: (MOVBstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym1 := auxToSym(v.Aux) ++ if v_0.Op != OpSW64SYMADDR { ++ break ++ } ++ off2 := auxIntToInt32(v_0.AuxInt) ++ sym2 := auxToSym(v_0.Aux) ++ ptr := v_0.Args[0] ++ val := v_1 ++ mem := v_2 ++ if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) { ++ break ++ } ++ v.reset(OpSW64MOVBstore) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(mergeSym(sym1, sym2)) ++ v.AddArg3(ptr, val, mem) ++ return true ++ } ++ // match: (MOVBstore [off] {sym} ptr (MOVVconst [0]) mem) ++ // result: (MOVBstorezero [off] {sym} ptr mem) ++ for { ++ off := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ ptr := v_0 ++ if v_1.Op != OpSW64MOVVconst || auxIntToInt64(v_1.AuxInt) != 0 { ++ break ++ } ++ mem := v_2 ++ v.reset(OpSW64MOVBstorezero) ++ v.AuxInt = int32ToAuxInt(off) ++ v.Aux = symToAux(sym) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ // match: (MOVBstore [off] {sym} ptr (MOVBreg x) mem) ++ // result: (MOVBstore [off] {sym} ptr x mem) ++ for { ++ off := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ ptr := v_0 ++ if v_1.Op != OpSW64MOVBreg { ++ break ++ } ++ x := v_1.Args[0] ++ mem := v_2 ++ v.reset(OpSW64MOVBstore) ++ v.AuxInt = int32ToAuxInt(off) ++ v.Aux = symToAux(sym) ++ v.AddArg3(ptr, x, mem) ++ return true ++ } ++ // match: (MOVBstore [off] {sym} ptr (MOVBUreg x) mem) ++ // result: (MOVBstore [off] {sym} ptr x mem) ++ for { ++ off := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ ptr := v_0 ++ if v_1.Op != OpSW64MOVBUreg { ++ break ++ } ++ x := v_1.Args[0] ++ mem := v_2 ++ v.reset(OpSW64MOVBstore) ++ v.AuxInt = int32ToAuxInt(off) ++ v.Aux = symToAux(sym) ++ v.AddArg3(ptr, x, mem) ++ return true ++ } ++ // match: (MOVBstore [off] {sym} ptr (MOVHreg x) mem) ++ // result: (MOVBstore [off] {sym} ptr x mem) ++ for { ++ off := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ ptr := v_0 ++ if v_1.Op != OpSW64MOVHreg { ++ break ++ } ++ x := v_1.Args[0] ++ mem := v_2 ++ v.reset(OpSW64MOVBstore) ++ v.AuxInt = int32ToAuxInt(off) ++ v.Aux = symToAux(sym) ++ v.AddArg3(ptr, x, mem) ++ return true ++ } ++ // match: (MOVBstore [off] {sym} ptr (MOVHUreg x) mem) ++ // result: (MOVBstore [off] {sym} ptr x mem) ++ for { ++ off := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ ptr := v_0 ++ if v_1.Op != OpSW64MOVHUreg { ++ break ++ } ++ x := v_1.Args[0] ++ mem := v_2 ++ v.reset(OpSW64MOVBstore) ++ v.AuxInt = int32ToAuxInt(off) ++ v.Aux = symToAux(sym) ++ v.AddArg3(ptr, x, mem) ++ return true ++ } ++ // match: (MOVBstore [off] {sym} ptr (MOVWreg x) mem) ++ // result: (MOVBstore [off] {sym} ptr x mem) ++ for { ++ off := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ ptr := v_0 ++ if v_1.Op != OpSW64MOVWreg { ++ break ++ } ++ x := v_1.Args[0] ++ mem := v_2 ++ v.reset(OpSW64MOVBstore) ++ v.AuxInt = int32ToAuxInt(off) ++ v.Aux = symToAux(sym) ++ v.AddArg3(ptr, x, mem) ++ return true ++ } ++ // match: (MOVBstore [off] {sym} ptr (MOVWUreg x) mem) ++ // result: (MOVBstore [off] {sym} ptr x mem) ++ for { ++ off := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ ptr := v_0 ++ if v_1.Op != OpSW64MOVWUreg { ++ break ++ } ++ x := v_1.Args[0] ++ mem := v_2 ++ v.reset(OpSW64MOVBstore) ++ v.AuxInt = int32ToAuxInt(off) ++ v.Aux = symToAux(sym) ++ v.AddArg3(ptr, x, mem) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64MOVBstorezero(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ config := b.Func.Config ++ // match: (MOVBstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) ++ // cond: is16Bit(int64(off1)+off2) ++ // result: (MOVBstorezero [off1+int32(off2)] {sym} ptr mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ if v_0.Op != OpSW64ADDVconst { ++ break ++ } ++ off2 := auxIntToInt64(v_0.AuxInt) ++ ptr := v_0.Args[0] ++ mem := v_1 ++ if !(is16Bit(int64(off1) + off2)) { ++ break ++ } ++ v.reset(OpSW64MOVBstorezero) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(sym) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ // match: (MOVBstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) ++ // cond: is32Bit(int64(off1)+off2) ++ // result: (MOVBstorezero [off1+int32(off2)] {sym} ptr mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ if v_0.Op != OpSW64ADDVconst { ++ break ++ } ++ off2 := auxIntToInt64(v_0.AuxInt) ++ ptr := v_0.Args[0] ++ mem := v_1 ++ if !(is32Bit(int64(off1) + off2)) { ++ break ++ } ++ v.reset(OpSW64MOVBstorezero) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(sym) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ // match: (MOVBstorezero [off1] {sym1} (SYMADDR [off2] {sym2} ptr) mem) ++ // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) ++ // result: (MOVBstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym1 := auxToSym(v.Aux) ++ if v_0.Op != OpSW64SYMADDR { ++ break ++ } ++ off2 := auxIntToInt32(v_0.AuxInt) ++ sym2 := auxToSym(v_0.Aux) ++ ptr := v_0.Args[0] ++ mem := v_1 ++ if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) { ++ break ++ } ++ v.reset(OpSW64MOVBstorezero) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(mergeSym(sym1, sym2)) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64MOVDload(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ config := b.Func.Config ++ // match: (MOVDload [off1] {sym} (ADDVconst [off2] ptr) mem) ++ // cond: is16Bit(int64(off1)+off2) ++ // result: (MOVDload [off1+int32(off2)] {sym} ptr mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ if v_0.Op != OpSW64ADDVconst { ++ break ++ } ++ off2 := auxIntToInt64(v_0.AuxInt) ++ ptr := v_0.Args[0] ++ mem := v_1 ++ if !(is16Bit(int64(off1) + off2)) { ++ break ++ } ++ v.reset(OpSW64MOVDload) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(sym) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ // match: (MOVDload [off1] {sym} (ADDVconst [off2] ptr) mem) ++ // cond: is32Bit(int64(off1)+off2) ++ // result: (MOVDload [off1+int32(off2)] {sym} ptr mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ if v_0.Op != OpSW64ADDVconst { ++ break ++ } ++ off2 := auxIntToInt64(v_0.AuxInt) ++ ptr := v_0.Args[0] ++ mem := v_1 ++ if !(is32Bit(int64(off1) + off2)) { ++ break ++ } ++ v.reset(OpSW64MOVDload) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(sym) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ // match: (MOVDload [off1] {sym1} (SYMADDR [off2] {sym2} ptr) mem) ++ // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) ++ // result: (MOVDload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym1 := auxToSym(v.Aux) ++ if v_0.Op != OpSW64SYMADDR { ++ break ++ } ++ off2 := auxIntToInt32(v_0.AuxInt) ++ sym2 := auxToSym(v_0.Aux) ++ ptr := v_0.Args[0] ++ mem := v_1 ++ if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) { ++ break ++ } ++ v.reset(OpSW64MOVDload) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(mergeSym(sym1, sym2)) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64MOVDstore(v *Value) bool { ++ v_2 := v.Args[2] ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ config := b.Func.Config ++ // match: (MOVDstore [off1] {sym} (ADDVconst [off2] ptr) val mem) ++ // cond: is16Bit(int64(off1)+off2) ++ // result: (MOVDstore [off1+int32(off2)] {sym} ptr val mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ if v_0.Op != OpSW64ADDVconst { ++ break ++ } ++ off2 := auxIntToInt64(v_0.AuxInt) ++ ptr := v_0.Args[0] ++ val := v_1 ++ mem := v_2 ++ if !(is16Bit(int64(off1) + off2)) { ++ break ++ } ++ v.reset(OpSW64MOVDstore) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(sym) ++ v.AddArg3(ptr, val, mem) ++ return true ++ } ++ // match: (MOVDstore [off1] {sym} (ADDVconst [off2] ptr) val mem) ++ // cond: is32Bit(int64(off1)+off2) ++ // result: (MOVDstore [off1+int32(off2)] {sym} ptr val mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ if v_0.Op != OpSW64ADDVconst { ++ break ++ } ++ off2 := auxIntToInt64(v_0.AuxInt) ++ ptr := v_0.Args[0] ++ val := v_1 ++ mem := v_2 ++ if !(is32Bit(int64(off1) + off2)) { ++ break ++ } ++ v.reset(OpSW64MOVDstore) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(sym) ++ v.AddArg3(ptr, val, mem) ++ return true ++ } ++ // match: (MOVDstore [off1] {sym1} (SYMADDR [off2] {sym2} ptr) val mem) ++ // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) ++ // result: (MOVDstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym1 := auxToSym(v.Aux) ++ if v_0.Op != OpSW64SYMADDR { ++ break ++ } ++ off2 := auxIntToInt32(v_0.AuxInt) ++ sym2 := auxToSym(v_0.Aux) ++ ptr := v_0.Args[0] ++ val := v_1 ++ mem := v_2 ++ if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) { ++ break ++ } ++ v.reset(OpSW64MOVDstore) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(mergeSym(sym1, sym2)) ++ v.AddArg3(ptr, val, mem) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64MOVFload(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ config := b.Func.Config ++ // match: (MOVFload [off1] {sym} (ADDVconst [off2] ptr) mem) ++ // cond: is16Bit(int64(off1)+off2) ++ // result: (MOVFload [off1+int32(off2)] {sym} ptr mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ if v_0.Op != OpSW64ADDVconst { ++ break ++ } ++ off2 := auxIntToInt64(v_0.AuxInt) ++ ptr := v_0.Args[0] ++ mem := v_1 ++ if !(is16Bit(int64(off1) + off2)) { ++ break ++ } ++ v.reset(OpSW64MOVFload) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(sym) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ // match: (MOVFload [off1] {sym} (ADDVconst [off2] ptr) mem) ++ // cond: is32Bit(int64(off1)+off2) ++ // result: (MOVFload [off1+int32(off2)] {sym} ptr mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ if v_0.Op != OpSW64ADDVconst { ++ break ++ } ++ off2 := auxIntToInt64(v_0.AuxInt) ++ ptr := v_0.Args[0] ++ mem := v_1 ++ if !(is32Bit(int64(off1) + off2)) { ++ break ++ } ++ v.reset(OpSW64MOVFload) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(sym) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ // match: (MOVFload [off1] {sym1} (SYMADDR [off2] {sym2} ptr) mem) ++ // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) ++ // result: (MOVFload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym1 := auxToSym(v.Aux) ++ if v_0.Op != OpSW64SYMADDR { ++ break ++ } ++ off2 := auxIntToInt32(v_0.AuxInt) ++ sym2 := auxToSym(v_0.Aux) ++ ptr := v_0.Args[0] ++ mem := v_1 ++ if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) { ++ break ++ } ++ v.reset(OpSW64MOVFload) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(mergeSym(sym1, sym2)) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64MOVFstore(v *Value) bool { ++ v_2 := v.Args[2] ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ config := b.Func.Config ++ // match: (MOVFstore [off1] {sym} (ADDVconst [off2] ptr) val mem) ++ // cond: is16Bit(int64(off1)+off2) ++ // result: (MOVFstore [off1+int32(off2)] {sym} ptr val mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ if v_0.Op != OpSW64ADDVconst { ++ break ++ } ++ off2 := auxIntToInt64(v_0.AuxInt) ++ ptr := v_0.Args[0] ++ val := v_1 ++ mem := v_2 ++ if !(is16Bit(int64(off1) + off2)) { ++ break ++ } ++ v.reset(OpSW64MOVFstore) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(sym) ++ v.AddArg3(ptr, val, mem) ++ return true ++ } ++ // match: (MOVFstore [off1] {sym} (ADDVconst [off2] ptr) val mem) ++ // cond: is32Bit(int64(off1)+off2) ++ // result: (MOVFstore [off1+int32(off2)] {sym} ptr val mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ if v_0.Op != OpSW64ADDVconst { ++ break ++ } ++ off2 := auxIntToInt64(v_0.AuxInt) ++ ptr := v_0.Args[0] ++ val := v_1 ++ mem := v_2 ++ if !(is32Bit(int64(off1) + off2)) { ++ break ++ } ++ v.reset(OpSW64MOVFstore) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(sym) ++ v.AddArg3(ptr, val, mem) ++ return true ++ } ++ // match: (MOVFstore [off1] {sym1} (SYMADDR [off2] {sym2} ptr) val mem) ++ // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) ++ // result: (MOVFstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym1 := auxToSym(v.Aux) ++ if v_0.Op != OpSW64SYMADDR { ++ break ++ } ++ off2 := auxIntToInt32(v_0.AuxInt) ++ sym2 := auxToSym(v_0.Aux) ++ ptr := v_0.Args[0] ++ val := v_1 ++ mem := v_2 ++ if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) { ++ break ++ } ++ v.reset(OpSW64MOVFstore) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(mergeSym(sym1, sym2)) ++ v.AddArg3(ptr, val, mem) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64MOVHUload(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ config := b.Func.Config ++ // match: (MOVHUload [off1] {sym} (ADDVconst [off2] ptr) mem) ++ // cond: is16Bit(int64(off1)+off2) ++ // result: (MOVHUload [off1+int32(off2)] {sym} ptr mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ if v_0.Op != OpSW64ADDVconst { ++ break ++ } ++ off2 := auxIntToInt64(v_0.AuxInt) ++ ptr := v_0.Args[0] ++ mem := v_1 ++ if !(is16Bit(int64(off1) + off2)) { ++ break ++ } ++ v.reset(OpSW64MOVHUload) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(sym) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ // match: (MOVHUload [off1] {sym} (ADDVconst [off2] ptr) mem) ++ // cond: is32Bit(int64(off1)+off2) ++ // result: (MOVHUload [off1+int32(off2)] {sym} ptr mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ if v_0.Op != OpSW64ADDVconst { ++ break ++ } ++ off2 := auxIntToInt64(v_0.AuxInt) ++ ptr := v_0.Args[0] ++ mem := v_1 ++ if !(is32Bit(int64(off1) + off2)) { ++ break ++ } ++ v.reset(OpSW64MOVHUload) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(sym) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ // match: (MOVHUload [off1] {sym1} (SYMADDR [off2] {sym2} ptr) mem) ++ // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) ++ // result: (MOVHUload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym1 := auxToSym(v.Aux) ++ if v_0.Op != OpSW64SYMADDR { ++ break ++ } ++ off2 := auxIntToInt32(v_0.AuxInt) ++ sym2 := auxToSym(v_0.Aux) ++ ptr := v_0.Args[0] ++ mem := v_1 ++ if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) { ++ break ++ } ++ v.reset(OpSW64MOVHUload) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(mergeSym(sym1, sym2)) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64MOVHUreg(v *Value) bool { ++ v_0 := v.Args[0] ++ // match: (MOVHUreg x:(MOVBUload _ _)) ++ // result: (MOVVreg x) ++ for { ++ x := v_0 ++ if x.Op != OpSW64MOVBUload { ++ break ++ } ++ v.reset(OpSW64MOVVreg) ++ v.AddArg(x) ++ return true ++ } ++ // match: (MOVHUreg x:(MOVHUload _ _)) ++ // result: (MOVVreg x) ++ for { ++ x := v_0 ++ if x.Op != OpSW64MOVHUload { ++ break ++ } ++ v.reset(OpSW64MOVVreg) ++ v.AddArg(x) ++ return true ++ } ++ // match: (MOVHUreg x:(MOVBUreg _)) ++ // result: (MOVVreg x) ++ for { ++ x := v_0 ++ if x.Op != OpSW64MOVBUreg { ++ break ++ } ++ v.reset(OpSW64MOVVreg) ++ v.AddArg(x) ++ return true ++ } ++ // match: (MOVHUreg x:(MOVHUreg _)) ++ // result: (MOVVreg x) ++ for { ++ x := v_0 ++ if x.Op != OpSW64MOVHUreg { ++ break ++ } ++ v.reset(OpSW64MOVVreg) ++ v.AddArg(x) ++ return true ++ } ++ // match: (MOVHUreg (MOVVconst [c])) ++ // result: (MOVVconst [int64(uint16(c))]) ++ for { ++ if v_0.Op != OpSW64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_0.AuxInt) ++ v.reset(OpSW64MOVVconst) ++ v.AuxInt = int64ToAuxInt(int64(uint16(c))) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64MOVHload(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ config := b.Func.Config ++ // match: (MOVHload [off1] {sym} (ADDVconst [off2] ptr) mem) ++ // cond: is16Bit(int64(off1)+off2) ++ // result: (MOVHload [off1+int32(off2)] {sym} ptr mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ if v_0.Op != OpSW64ADDVconst { ++ break ++ } ++ off2 := auxIntToInt64(v_0.AuxInt) ++ ptr := v_0.Args[0] ++ mem := v_1 ++ if !(is16Bit(int64(off1) + off2)) { ++ break ++ } ++ v.reset(OpSW64MOVHload) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(sym) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ // match: (MOVHload [off1] {sym} (ADDVconst [off2] ptr) mem) ++ // cond: is32Bit(int64(off1)+off2) ++ // result: (MOVHload [off1+int32(off2)] {sym} ptr mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ if v_0.Op != OpSW64ADDVconst { ++ break ++ } ++ off2 := auxIntToInt64(v_0.AuxInt) ++ ptr := v_0.Args[0] ++ mem := v_1 ++ if !(is32Bit(int64(off1) + off2)) { ++ break ++ } ++ v.reset(OpSW64MOVHload) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(sym) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ // match: (MOVHload [off1] {sym1} (SYMADDR [off2] {sym2} ptr) mem) ++ // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) ++ // result: (MOVHload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym1 := auxToSym(v.Aux) ++ if v_0.Op != OpSW64SYMADDR { ++ break ++ } ++ off2 := auxIntToInt32(v_0.AuxInt) ++ sym2 := auxToSym(v_0.Aux) ++ ptr := v_0.Args[0] ++ mem := v_1 ++ if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) { ++ break ++ } ++ v.reset(OpSW64MOVHload) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(mergeSym(sym1, sym2)) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64MOVHreg(v *Value) bool { ++ v_0 := v.Args[0] ++ // match: (MOVHreg x:(MOVBreg _)) ++ // result: (MOVVreg x) ++ for { ++ x := v_0 ++ if x.Op != OpSW64MOVBreg { ++ break ++ } ++ v.reset(OpSW64MOVVreg) ++ v.AddArg(x) ++ return true ++ } ++ // match: (MOVHreg x:(MOVHreg _)) ++ // result: (MOVVreg x) ++ for { ++ x := v_0 ++ if x.Op != OpSW64MOVHreg { ++ break ++ } ++ v.reset(OpSW64MOVVreg) ++ v.AddArg(x) ++ return true ++ } ++ // match: (MOVHreg (MOVVconst [c])) ++ // result: (MOVVconst [int64(int16(c))]) ++ for { ++ if v_0.Op != OpSW64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_0.AuxInt) ++ v.reset(OpSW64MOVVconst) ++ v.AuxInt = int64ToAuxInt(int64(int16(c))) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64MOVHstore(v *Value) bool { ++ v_2 := v.Args[2] ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ config := b.Func.Config ++ // match: (MOVHstore [off1] {sym} (ADDVconst [off2] ptr) val mem) ++ // cond: is16Bit(int64(off1)+off2) ++ // result: (MOVHstore [off1+int32(off2)] {sym} ptr val mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ if v_0.Op != OpSW64ADDVconst { ++ break ++ } ++ off2 := auxIntToInt64(v_0.AuxInt) ++ ptr := v_0.Args[0] ++ val := v_1 ++ mem := v_2 ++ if !(is16Bit(int64(off1) + off2)) { ++ break ++ } ++ v.reset(OpSW64MOVHstore) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(sym) ++ v.AddArg3(ptr, val, mem) ++ return true ++ } ++ // match: (MOVHstore [off1] {sym} (ADDVconst [off2] ptr) val mem) ++ // cond: is32Bit(int64(off1)+off2) ++ // result: (MOVHstore [off1+int32(off2)] {sym} ptr val mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ if v_0.Op != OpSW64ADDVconst { ++ break ++ } ++ off2 := auxIntToInt64(v_0.AuxInt) ++ ptr := v_0.Args[0] ++ val := v_1 ++ mem := v_2 ++ if !(is32Bit(int64(off1) + off2)) { ++ break ++ } ++ v.reset(OpSW64MOVHstore) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(sym) ++ v.AddArg3(ptr, val, mem) ++ return true ++ } ++ // match: (MOVHstore [off1] {sym1} (SYMADDR [off2] {sym2} ptr) val mem) ++ // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) ++ // result: (MOVHstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym1 := auxToSym(v.Aux) ++ if v_0.Op != OpSW64SYMADDR { ++ break ++ } ++ off2 := auxIntToInt32(v_0.AuxInt) ++ sym2 := auxToSym(v_0.Aux) ++ ptr := v_0.Args[0] ++ val := v_1 ++ mem := v_2 ++ if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) { ++ break ++ } ++ v.reset(OpSW64MOVHstore) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(mergeSym(sym1, sym2)) ++ v.AddArg3(ptr, val, mem) ++ return true ++ } ++ // match: (MOVHstore [off] {sym} ptr (MOVVconst [0]) mem) ++ // result: (MOVHstorezero [off] {sym} ptr mem) ++ for { ++ off := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ ptr := v_0 ++ if v_1.Op != OpSW64MOVVconst || auxIntToInt64(v_1.AuxInt) != 0 { ++ break ++ } ++ mem := v_2 ++ v.reset(OpSW64MOVHstorezero) ++ v.AuxInt = int32ToAuxInt(off) ++ v.Aux = symToAux(sym) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ // match: (MOVHstore [off] {sym} ptr (MOVHreg x) mem) ++ // result: (MOVHstore [off] {sym} ptr x mem) ++ for { ++ off := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ ptr := v_0 ++ if v_1.Op != OpSW64MOVHreg { ++ break ++ } ++ x := v_1.Args[0] ++ mem := v_2 ++ v.reset(OpSW64MOVHstore) ++ v.AuxInt = int32ToAuxInt(off) ++ v.Aux = symToAux(sym) ++ v.AddArg3(ptr, x, mem) ++ return true ++ } ++ // match: (MOVHstore [off] {sym} ptr (MOVHUreg x) mem) ++ // result: (MOVHstore [off] {sym} ptr x mem) ++ for { ++ off := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ ptr := v_0 ++ if v_1.Op != OpSW64MOVHUreg { ++ break ++ } ++ x := v_1.Args[0] ++ mem := v_2 ++ v.reset(OpSW64MOVHstore) ++ v.AuxInt = int32ToAuxInt(off) ++ v.Aux = symToAux(sym) ++ v.AddArg3(ptr, x, mem) ++ return true ++ } ++ // match: (MOVHstore [off] {sym} ptr (MOVWreg x) mem) ++ // result: (MOVHstore [off] {sym} ptr x mem) ++ for { ++ off := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ ptr := v_0 ++ if v_1.Op != OpSW64MOVWreg { ++ break ++ } ++ x := v_1.Args[0] ++ mem := v_2 ++ v.reset(OpSW64MOVHstore) ++ v.AuxInt = int32ToAuxInt(off) ++ v.Aux = symToAux(sym) ++ v.AddArg3(ptr, x, mem) ++ return true ++ } ++ // match: (MOVHstore [off] {sym} ptr (MOVWUreg x) mem) ++ // result: (MOVHstore [off] {sym} ptr x mem) ++ for { ++ off := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ ptr := v_0 ++ if v_1.Op != OpSW64MOVWUreg { ++ break ++ } ++ x := v_1.Args[0] ++ mem := v_2 ++ v.reset(OpSW64MOVHstore) ++ v.AuxInt = int32ToAuxInt(off) ++ v.Aux = symToAux(sym) ++ v.AddArg3(ptr, x, mem) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64MOVHstorezero(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ config := b.Func.Config ++ // match: (MOVHstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) ++ // cond: is16Bit(int64(off1)+off2) ++ // result: (MOVHstorezero [off1+int32(off2)] {sym} ptr mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ if v_0.Op != OpSW64ADDVconst { ++ break ++ } ++ off2 := auxIntToInt64(v_0.AuxInt) ++ ptr := v_0.Args[0] ++ mem := v_1 ++ if !(is16Bit(int64(off1) + off2)) { ++ break ++ } ++ v.reset(OpSW64MOVHstorezero) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(sym) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ // match: (MOVHstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) ++ // cond: is32Bit(int64(off1)+off2) ++ // result: (MOVHstorezero [off1+int32(off2)] {sym} ptr mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ if v_0.Op != OpSW64ADDVconst { ++ break ++ } ++ off2 := auxIntToInt64(v_0.AuxInt) ++ ptr := v_0.Args[0] ++ mem := v_1 ++ if !(is32Bit(int64(off1) + off2)) { ++ break ++ } ++ v.reset(OpSW64MOVHstorezero) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(sym) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ // match: (MOVHstorezero [off1] {sym1} (SYMADDR [off2] {sym2} ptr) mem) ++ // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) ++ // result: (MOVHstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym1 := auxToSym(v.Aux) ++ if v_0.Op != OpSW64SYMADDR { ++ break ++ } ++ off2 := auxIntToInt32(v_0.AuxInt) ++ sym2 := auxToSym(v_0.Aux) ++ ptr := v_0.Args[0] ++ mem := v_1 ++ if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) { ++ break ++ } ++ v.reset(OpSW64MOVHstorezero) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(mergeSym(sym1, sym2)) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64MOVVload(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ config := b.Func.Config ++ // match: (MOVVload [off1] {sym} (ADDVconst [off2] ptr) mem) ++ // cond: is16Bit(int64(off1)+off2) ++ // result: (MOVVload [off1+int32(off2)] {sym} ptr mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ if v_0.Op != OpSW64ADDVconst { ++ break ++ } ++ off2 := auxIntToInt64(v_0.AuxInt) ++ ptr := v_0.Args[0] ++ mem := v_1 ++ if !(is16Bit(int64(off1) + off2)) { ++ break ++ } ++ v.reset(OpSW64MOVVload) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(sym) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ // match: (MOVVload [off1] {sym} (ADDVconst [off2] ptr) mem) ++ // cond: is32Bit(int64(off1)+off2) ++ // result: (MOVVload [off1+int32(off2)] {sym} ptr mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ if v_0.Op != OpSW64ADDVconst { ++ break ++ } ++ off2 := auxIntToInt64(v_0.AuxInt) ++ ptr := v_0.Args[0] ++ mem := v_1 ++ if !(is32Bit(int64(off1) + off2)) { ++ break ++ } ++ v.reset(OpSW64MOVVload) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(sym) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ // match: (MOVVload [off1] {sym1} (SYMADDR [off2] {sym2} ptr) mem) ++ // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) ++ // result: (MOVVload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym1 := auxToSym(v.Aux) ++ if v_0.Op != OpSW64SYMADDR { ++ break ++ } ++ off2 := auxIntToInt32(v_0.AuxInt) ++ sym2 := auxToSym(v_0.Aux) ++ ptr := v_0.Args[0] ++ mem := v_1 ++ if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) { ++ break ++ } ++ v.reset(OpSW64MOVVload) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(mergeSym(sym1, sym2)) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64MOVVnop(v *Value) bool { ++ v_0 := v.Args[0] ++ // match: (MOVVnop (MOVVconst [c])) ++ // result: (MOVVconst [c]) ++ for { ++ if v_0.Op != OpSW64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_0.AuxInt) ++ v.reset(OpSW64MOVVconst) ++ v.AuxInt = int64ToAuxInt(c) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64MOVVreg(v *Value) bool { ++ v_0 := v.Args[0] ++ // match: (MOVVreg x) ++ // cond: x.Uses == 1 ++ // result: (MOVVnop x) ++ for { ++ x := v_0 ++ if !(x.Uses == 1) { ++ break ++ } ++ v.reset(OpSW64MOVVnop) ++ v.AddArg(x) ++ return true ++ } ++ // match: (MOVVreg (MOVVconst [c])) ++ // result: (MOVVconst [c]) ++ for { ++ if v_0.Op != OpSW64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_0.AuxInt) ++ v.reset(OpSW64MOVVconst) ++ v.AuxInt = int64ToAuxInt(c) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64MOVVstore(v *Value) bool { ++ v_2 := v.Args[2] ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ config := b.Func.Config ++ // match: (MOVVstore [off1] {sym} (ADDVconst [off2] ptr) val mem) ++ // cond: is16Bit(int64(off1)+off2) ++ // result: (MOVVstore [off1+int32(off2)] {sym} ptr val mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ if v_0.Op != OpSW64ADDVconst { ++ break ++ } ++ off2 := auxIntToInt64(v_0.AuxInt) ++ ptr := v_0.Args[0] ++ val := v_1 ++ mem := v_2 ++ if !(is16Bit(int64(off1) + off2)) { ++ break ++ } ++ v.reset(OpSW64MOVVstore) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(sym) ++ v.AddArg3(ptr, val, mem) ++ return true ++ } ++ // match: (MOVVstore [off1] {sym} (ADDVconst [off2] ptr) val mem) ++ // cond: is32Bit(int64(off1)+off2) ++ // result: (MOVVstore [off1+int32(off2)] {sym} ptr val mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ if v_0.Op != OpSW64ADDVconst { ++ break ++ } ++ off2 := auxIntToInt64(v_0.AuxInt) ++ ptr := v_0.Args[0] ++ val := v_1 ++ mem := v_2 ++ if !(is32Bit(int64(off1) + off2)) { ++ break ++ } ++ v.reset(OpSW64MOVVstore) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(sym) ++ v.AddArg3(ptr, val, mem) ++ return true ++ } ++ // match: (MOVVstore [off1] {sym1} (SYMADDR [off2] {sym2} ptr) val mem) ++ // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) ++ // result: (MOVVstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym1 := auxToSym(v.Aux) ++ if v_0.Op != OpSW64SYMADDR { ++ break ++ } ++ off2 := auxIntToInt32(v_0.AuxInt) ++ sym2 := auxToSym(v_0.Aux) ++ ptr := v_0.Args[0] ++ val := v_1 ++ mem := v_2 ++ if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) { ++ break ++ } ++ v.reset(OpSW64MOVVstore) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(mergeSym(sym1, sym2)) ++ v.AddArg3(ptr, val, mem) ++ return true ++ } ++ // match: (MOVVstore [off] {sym} ptr (MOVVconst [0]) mem) ++ // result: (MOVVstorezero [off] {sym} ptr mem) ++ for { ++ off := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ ptr := v_0 ++ if v_1.Op != OpSW64MOVVconst || auxIntToInt64(v_1.AuxInt) != 0 { ++ break ++ } ++ mem := v_2 ++ v.reset(OpSW64MOVVstorezero) ++ v.AuxInt = int32ToAuxInt(off) ++ v.Aux = symToAux(sym) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64MOVVstorezero(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ config := b.Func.Config ++ // match: (MOVVstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) ++ // cond: is16Bit(int64(off1)+off2) ++ // result: (MOVVstorezero [off1+int32(off2)] {sym} ptr mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ if v_0.Op != OpSW64ADDVconst { ++ break ++ } ++ off2 := auxIntToInt64(v_0.AuxInt) ++ ptr := v_0.Args[0] ++ mem := v_1 ++ if !(is16Bit(int64(off1) + off2)) { ++ break ++ } ++ v.reset(OpSW64MOVVstorezero) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(sym) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ // match: (MOVVstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) ++ // cond: is32Bit(int64(off1)+off2) ++ // result: (MOVVstorezero [off1+int32(off2)] {sym} ptr mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ if v_0.Op != OpSW64ADDVconst { ++ break ++ } ++ off2 := auxIntToInt64(v_0.AuxInt) ++ ptr := v_0.Args[0] ++ mem := v_1 ++ if !(is32Bit(int64(off1) + off2)) { ++ break ++ } ++ v.reset(OpSW64MOVVstorezero) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(sym) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ // match: (MOVVstorezero [off1] {sym1} (SYMADDR [off2] {sym2} ptr) mem) ++ // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) ++ // result: (MOVVstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym1 := auxToSym(v.Aux) ++ if v_0.Op != OpSW64SYMADDR { ++ break ++ } ++ off2 := auxIntToInt32(v_0.AuxInt) ++ sym2 := auxToSym(v_0.Aux) ++ ptr := v_0.Args[0] ++ mem := v_1 ++ if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) { ++ break ++ } ++ v.reset(OpSW64MOVVstorezero) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(mergeSym(sym1, sym2)) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64MOVWUload(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ config := b.Func.Config ++ // match: (MOVWUload [off1] {sym} (ADDVconst [off2] ptr) mem) ++ // cond: is16Bit(int64(off1)+off2) ++ // result: (MOVWUload [off1+int32(off2)] {sym} ptr mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ if v_0.Op != OpSW64ADDVconst { ++ break ++ } ++ off2 := auxIntToInt64(v_0.AuxInt) ++ ptr := v_0.Args[0] ++ mem := v_1 ++ if !(is16Bit(int64(off1) + off2)) { ++ break ++ } ++ v.reset(OpSW64MOVWUload) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(sym) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ // match: (MOVWUload [off1] {sym} (ADDVconst [off2] ptr) mem) ++ // cond: is32Bit(int64(off1)+off2) ++ // result: (MOVWUload [off1+int32(off2)] {sym} ptr mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ if v_0.Op != OpSW64ADDVconst { ++ break ++ } ++ off2 := auxIntToInt64(v_0.AuxInt) ++ ptr := v_0.Args[0] ++ mem := v_1 ++ if !(is32Bit(int64(off1) + off2)) { ++ break ++ } ++ v.reset(OpSW64MOVWUload) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(sym) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ // match: (MOVWUload [off1] {sym1} (SYMADDR [off2] {sym2} ptr) mem) ++ // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) ++ // result: (MOVWUload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym1 := auxToSym(v.Aux) ++ if v_0.Op != OpSW64SYMADDR { ++ break ++ } ++ off2 := auxIntToInt32(v_0.AuxInt) ++ sym2 := auxToSym(v_0.Aux) ++ ptr := v_0.Args[0] ++ mem := v_1 ++ if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) { ++ break ++ } ++ v.reset(OpSW64MOVWUload) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(mergeSym(sym1, sym2)) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64MOVWUreg(v *Value) bool { ++ v_0 := v.Args[0] ++ // match: (MOVWUreg x:(MOVBUload _ _)) ++ // result: (MOVVreg x) ++ for { ++ x := v_0 ++ if x.Op != OpSW64MOVBUload { ++ break ++ } ++ v.reset(OpSW64MOVVreg) ++ v.AddArg(x) ++ return true ++ } ++ // match: (MOVWUreg x:(MOVHUload _ _)) ++ // result: (MOVVreg x) ++ for { ++ x := v_0 ++ if x.Op != OpSW64MOVHUload { ++ break ++ } ++ v.reset(OpSW64MOVVreg) ++ v.AddArg(x) ++ return true ++ } ++ // match: (MOVWUreg x:(MOVBUreg _)) ++ // result: (MOVVreg x) ++ for { ++ x := v_0 ++ if x.Op != OpSW64MOVBUreg { ++ break ++ } ++ v.reset(OpSW64MOVVreg) ++ v.AddArg(x) ++ return true ++ } ++ // match: (MOVWUreg x:(MOVHUreg _)) ++ // result: (MOVVreg x) ++ for { ++ x := v_0 ++ if x.Op != OpSW64MOVHUreg { ++ break ++ } ++ v.reset(OpSW64MOVVreg) ++ v.AddArg(x) ++ return true ++ } ++ // match: (MOVWUreg x:(MOVWUreg _)) ++ // result: (MOVVreg x) ++ for { ++ x := v_0 ++ if x.Op != OpSW64MOVWUreg { ++ break ++ } ++ v.reset(OpSW64MOVVreg) ++ v.AddArg(x) ++ return true ++ } ++ // match: (MOVWUreg (MOVVconst [c])) ++ // result: (MOVVconst [int64(uint32(c))]) ++ for { ++ if v_0.Op != OpSW64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_0.AuxInt) ++ v.reset(OpSW64MOVVconst) ++ v.AuxInt = int64ToAuxInt(int64(uint32(c))) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64MOVWload(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ config := b.Func.Config ++ // match: (MOVWload [off1] {sym} (ADDVconst [off2] ptr) mem) ++ // cond: is16Bit(int64(off1)+off2) ++ // result: (MOVWload [off1+int32(off2)] {sym} ptr mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ if v_0.Op != OpSW64ADDVconst { ++ break ++ } ++ off2 := auxIntToInt64(v_0.AuxInt) ++ ptr := v_0.Args[0] ++ mem := v_1 ++ if !(is16Bit(int64(off1) + off2)) { ++ break ++ } ++ v.reset(OpSW64MOVWload) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(sym) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ // match: (MOVWload [off1] {sym} (ADDVconst [off2] ptr) mem) ++ // cond: is32Bit(int64(off1)+off2) ++ // result: (MOVWload [off1+int32(off2)] {sym} ptr mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ if v_0.Op != OpSW64ADDVconst { ++ break ++ } ++ off2 := auxIntToInt64(v_0.AuxInt) ++ ptr := v_0.Args[0] ++ mem := v_1 ++ if !(is32Bit(int64(off1) + off2)) { ++ break ++ } ++ v.reset(OpSW64MOVWload) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(sym) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ // match: (MOVWload [off1] {sym1} (SYMADDR [off2] {sym2} ptr) mem) ++ // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) ++ // result: (MOVWload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym1 := auxToSym(v.Aux) ++ if v_0.Op != OpSW64SYMADDR { ++ break ++ } ++ off2 := auxIntToInt32(v_0.AuxInt) ++ sym2 := auxToSym(v_0.Aux) ++ ptr := v_0.Args[0] ++ mem := v_1 ++ if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) { ++ break ++ } ++ v.reset(OpSW64MOVWload) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(mergeSym(sym1, sym2)) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64MOVWreg(v *Value) bool { ++ v_0 := v.Args[0] ++ // match: (MOVWreg x:(MOVWload _ _)) ++ // result: (MOVVreg x) ++ for { ++ x := v_0 ++ if x.Op != OpSW64MOVWload { ++ break ++ } ++ v.reset(OpSW64MOVVreg) ++ v.AddArg(x) ++ return true ++ } ++ // match: (MOVWreg x:(MOVBreg _)) ++ // result: (MOVVreg x) ++ for { ++ x := v_0 ++ if x.Op != OpSW64MOVBreg { ++ break ++ } ++ v.reset(OpSW64MOVVreg) ++ v.AddArg(x) ++ return true ++ } ++ // match: (MOVWreg x:(MOVHreg _)) ++ // result: (MOVVreg x) ++ for { ++ x := v_0 ++ if x.Op != OpSW64MOVHreg { ++ break ++ } ++ v.reset(OpSW64MOVVreg) ++ v.AddArg(x) ++ return true ++ } ++ // match: (MOVWreg x:(MOVWreg _)) ++ // result: (MOVVreg x) ++ for { ++ x := v_0 ++ if x.Op != OpSW64MOVWreg { ++ break ++ } ++ v.reset(OpSW64MOVVreg) ++ v.AddArg(x) ++ return true ++ } ++ // match: (MOVWreg (MOVVconst [c])) ++ // result: (MOVVconst [int64(int32(c))]) ++ for { ++ if v_0.Op != OpSW64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_0.AuxInt) ++ v.reset(OpSW64MOVVconst) ++ v.AuxInt = int64ToAuxInt(int64(int32(c))) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64MOVWstore(v *Value) bool { ++ v_2 := v.Args[2] ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ config := b.Func.Config ++ // match: (MOVWstore [off1] {sym} (ADDVconst [off2] ptr) val mem) ++ // cond: is16Bit(int64(off1)+off2) ++ // result: (MOVWstore [off1+int32(off2)] {sym} ptr val mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ if v_0.Op != OpSW64ADDVconst { ++ break ++ } ++ off2 := auxIntToInt64(v_0.AuxInt) ++ ptr := v_0.Args[0] ++ val := v_1 ++ mem := v_2 ++ if !(is16Bit(int64(off1) + off2)) { ++ break ++ } ++ v.reset(OpSW64MOVWstore) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(sym) ++ v.AddArg3(ptr, val, mem) ++ return true ++ } ++ // match: (MOVWstore [off1] {sym} (ADDVconst [off2] ptr) val mem) ++ // cond: is32Bit(int64(off1)+off2) ++ // result: (MOVWstore [off1+int32(off2)] {sym} ptr val mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ if v_0.Op != OpSW64ADDVconst { ++ break ++ } ++ off2 := auxIntToInt64(v_0.AuxInt) ++ ptr := v_0.Args[0] ++ val := v_1 ++ mem := v_2 ++ if !(is32Bit(int64(off1) + off2)) { ++ break ++ } ++ v.reset(OpSW64MOVWstore) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(sym) ++ v.AddArg3(ptr, val, mem) ++ return true ++ } ++ // match: (MOVWstore [off1] {sym1} (SYMADDR [off2] {sym2} ptr) val mem) ++ // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) ++ // result: (MOVWstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym1 := auxToSym(v.Aux) ++ if v_0.Op != OpSW64SYMADDR { ++ break ++ } ++ off2 := auxIntToInt32(v_0.AuxInt) ++ sym2 := auxToSym(v_0.Aux) ++ ptr := v_0.Args[0] ++ val := v_1 ++ mem := v_2 ++ if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) { ++ break ++ } ++ v.reset(OpSW64MOVWstore) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(mergeSym(sym1, sym2)) ++ v.AddArg3(ptr, val, mem) ++ return true ++ } ++ // match: (MOVWstore [off] {sym} ptr (MOVVconst [0]) mem) ++ // result: (MOVWstorezero [off] {sym} ptr mem) ++ for { ++ off := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ ptr := v_0 ++ if v_1.Op != OpSW64MOVVconst || auxIntToInt64(v_1.AuxInt) != 0 { ++ break ++ } ++ mem := v_2 ++ v.reset(OpSW64MOVWstorezero) ++ v.AuxInt = int32ToAuxInt(off) ++ v.Aux = symToAux(sym) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ // match: (MOVWstore [off] {sym} ptr (MOVWreg x) mem) ++ // result: (MOVWstore [off] {sym} ptr x mem) ++ for { ++ off := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ ptr := v_0 ++ if v_1.Op != OpSW64MOVWreg { ++ break ++ } ++ x := v_1.Args[0] ++ mem := v_2 ++ v.reset(OpSW64MOVWstore) ++ v.AuxInt = int32ToAuxInt(off) ++ v.Aux = symToAux(sym) ++ v.AddArg3(ptr, x, mem) ++ return true ++ } ++ // match: (MOVWstore [off] {sym} ptr (MOVWUreg x) mem) ++ // result: (MOVWstore [off] {sym} ptr x mem) ++ for { ++ off := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ ptr := v_0 ++ if v_1.Op != OpSW64MOVWUreg { ++ break ++ } ++ x := v_1.Args[0] ++ mem := v_2 ++ v.reset(OpSW64MOVWstore) ++ v.AuxInt = int32ToAuxInt(off) ++ v.Aux = symToAux(sym) ++ v.AddArg3(ptr, x, mem) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64MOVWstorezero(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ config := b.Func.Config ++ // match: (MOVWstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) ++ // cond: is16Bit(int64(off1)+off2) ++ // result: (MOVWstorezero [off1+int32(off2)] {sym} ptr mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ if v_0.Op != OpSW64ADDVconst { ++ break ++ } ++ off2 := auxIntToInt64(v_0.AuxInt) ++ ptr := v_0.Args[0] ++ mem := v_1 ++ if !(is16Bit(int64(off1) + off2)) { ++ break ++ } ++ v.reset(OpSW64MOVWstorezero) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(sym) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ // match: (MOVWstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) ++ // cond: is32Bit(int64(off1)+off2) ++ // result: (MOVWstorezero [off1+int32(off2)] {sym} ptr mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym := auxToSym(v.Aux) ++ if v_0.Op != OpSW64ADDVconst { ++ break ++ } ++ off2 := auxIntToInt64(v_0.AuxInt) ++ ptr := v_0.Args[0] ++ mem := v_1 ++ if !(is32Bit(int64(off1) + off2)) { ++ break ++ } ++ v.reset(OpSW64MOVWstorezero) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(sym) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ // match: (MOVWstorezero [off1] {sym1} (SYMADDR [off2] {sym2} ptr) mem) ++ // cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared) ++ // result: (MOVWstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem) ++ for { ++ off1 := auxIntToInt32(v.AuxInt) ++ sym1 := auxToSym(v.Aux) ++ if v_0.Op != OpSW64SYMADDR { ++ break ++ } ++ off2 := auxIntToInt32(v_0.AuxInt) ++ sym2 := auxToSym(v_0.Aux) ++ ptr := v_0.Args[0] ++ mem := v_1 ++ if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) { ++ break ++ } ++ v.reset(OpSW64MOVWstorezero) ++ v.AuxInt = int32ToAuxInt(off1 + int32(off2)) ++ v.Aux = symToAux(mergeSym(sym1, sym2)) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64MULL(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ // match: (MULL x (MOVVconst [c])) ++ // result: (MULLconst [c] x) ++ for { ++ for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { ++ x := v_0 ++ if v_1.Op != OpSW64MOVVconst { ++ continue ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ v.reset(OpSW64MULLconst) ++ v.AuxInt = int64ToAuxInt(c) ++ v.AddArg(x) ++ return true ++ } ++ break ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64MULW(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ // match: (MULW x (MOVVconst [c])) ++ // cond: is32Bit(c) ++ // result: (MULWconst [c] x) ++ for { ++ for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { ++ x := v_0 ++ if v_1.Op != OpSW64MOVVconst { ++ continue ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(is32Bit(c)) { ++ continue ++ } ++ v.reset(OpSW64MULWconst) ++ v.AuxInt = int64ToAuxInt(c) ++ v.AddArg(x) ++ return true ++ } ++ break ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64NEGV(v *Value) bool { ++ v_0 := v.Args[0] ++ // match: (NEGV (MOVVconst [c])) ++ // result: (MOVVconst [-c]) ++ for { ++ if v_0.Op != OpSW64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_0.AuxInt) ++ v.reset(OpSW64MOVVconst) ++ v.AuxInt = int64ToAuxInt(-c) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64ORNOT(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ // match: (ORNOT x (MOVVconst [c])) ++ // cond: is32Bit(c) ++ // result: (ORNOTconst [c] x) ++ for { ++ x := v_0 ++ if v_1.Op != OpSW64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(is32Bit(c)) { ++ break ++ } ++ v.reset(OpSW64ORNOTconst) ++ v.AuxInt = int64ToAuxInt(c) ++ v.AddArg(x) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64SEXTB(v *Value) bool { ++ v_0 := v.Args[0] ++ // match: (SEXTB (MOVVconst [c])) ++ // result: (MOVVconst [int64(int8(c))]) ++ for { ++ if v_0.Op != OpSW64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_0.AuxInt) ++ v.reset(OpSW64MOVVconst) ++ v.AuxInt = int64ToAuxInt(int64(int8(c))) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64SEXTH(v *Value) bool { ++ v_0 := v.Args[0] ++ // match: (SEXTH (MOVVconst [c])) ++ // result: (MOVVconst [int64(int16(c))]) ++ for { ++ if v_0.Op != OpSW64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_0.AuxInt) ++ v.reset(OpSW64MOVVconst) ++ v.AuxInt = int64ToAuxInt(int64(int16(c))) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64SLLconst(v *Value) bool { ++ v_0 := v.Args[0] ++ // match: (SLLconst [c] (MOVVconst [d])) ++ // result: (MOVVconst [int64(d)<>uint64(c)]) ++ for { ++ c := auxIntToInt64(v.AuxInt) ++ if v_0.Op != OpSW64MOVVconst { ++ break ++ } ++ d := auxIntToInt64(v_0.AuxInt) ++ v.reset(OpSW64MOVVconst) ++ v.AuxInt = int64ToAuxInt(int64(d) >> uint64(c)) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64SRLconst(v *Value) bool { ++ v_0 := v.Args[0] ++ // match: (SRLconst [c] (MOVVconst [d])) ++ // result: (MOVVconst [int64(uint64(d)>>uint64(c))]) ++ for { ++ c := auxIntToInt64(v.AuxInt) ++ if v_0.Op != OpSW64MOVVconst { ++ break ++ } ++ d := auxIntToInt64(v_0.AuxInt) ++ v.reset(OpSW64MOVVconst) ++ v.AuxInt = int64ToAuxInt(int64(uint64(d) >> uint64(c))) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64SUBV(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ // match: (SUBV x (MOVVconst [c])) ++ // cond: is32Bit(c) ++ // result: (SUBVconst [c] x) ++ for { ++ x := v_0 ++ if v_1.Op != OpSW64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(is32Bit(c)) { ++ break ++ } ++ v.reset(OpSW64SUBVconst) ++ v.AuxInt = int64ToAuxInt(c) ++ v.AddArg(x) ++ return true ++ } ++ // match: (SUBV x x) ++ // result: (MOVVconst [0]) ++ for { ++ x := v_0 ++ if x != v_1 { ++ break ++ } ++ v.reset(OpSW64MOVVconst) ++ v.AuxInt = int64ToAuxInt(0) ++ return true ++ } ++ // match: (SUBV (MOVVconst [0]) x) ++ // result: (NEGV x) ++ for { ++ if v_0.Op != OpSW64MOVVconst || auxIntToInt64(v_0.AuxInt) != 0 { ++ break ++ } ++ x := v_1 ++ v.reset(OpSW64NEGV) ++ v.AddArg(x) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64SUBVconst(v *Value) bool { ++ v_0 := v.Args[0] ++ // match: (SUBVconst [0] x) ++ // result: x ++ for { ++ if auxIntToInt64(v.AuxInt) != 0 { ++ break ++ } ++ x := v_0 ++ v.copyOf(x) ++ return true ++ } ++ // match: (SUBVconst [c] (MOVVconst [d])) ++ // result: (MOVVconst [d-c]) ++ for { ++ c := auxIntToInt64(v.AuxInt) ++ if v_0.Op != OpSW64MOVVconst { ++ break ++ } ++ d := auxIntToInt64(v_0.AuxInt) ++ v.reset(OpSW64MOVVconst) ++ v.AuxInt = int64ToAuxInt(d - c) ++ return true ++ } ++ // match: (SUBVconst [c] (SUBVconst [d] x)) ++ // cond: is32Bit(-c-d) ++ // result: (ADDVconst [-c-d] x) ++ for { ++ c := auxIntToInt64(v.AuxInt) ++ if v_0.Op != OpSW64SUBVconst { ++ break ++ } ++ d := auxIntToInt64(v_0.AuxInt) ++ x := v_0.Args[0] ++ if !(is32Bit(-c - d)) { ++ break ++ } ++ v.reset(OpSW64ADDVconst) ++ v.AuxInt = int64ToAuxInt(-c - d) ++ v.AddArg(x) ++ return true ++ } ++ // match: (SUBVconst [c] (ADDVconst [d] x)) ++ // cond: is32Bit(-c+d) ++ // result: (ADDVconst [-c+d] x) ++ for { ++ c := auxIntToInt64(v.AuxInt) ++ if v_0.Op != OpSW64ADDVconst { ++ break ++ } ++ d := auxIntToInt64(v_0.AuxInt) ++ x := v_0.Args[0] ++ if !(is32Bit(-c + d)) { ++ break ++ } ++ v.reset(OpSW64ADDVconst) ++ v.AuxInt = int64ToAuxInt(-c + d) ++ v.AddArg(x) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64XOR(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ // match: (XOR x (MOVVconst [c])) ++ // cond: is32Bit(c) ++ // result: (XORconst [c] x) ++ for { ++ for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 { ++ x := v_0 ++ if v_1.Op != OpSW64MOVVconst { ++ continue ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(is32Bit(c)) { ++ continue ++ } ++ v.reset(OpSW64XORconst) ++ v.AuxInt = int64ToAuxInt(c) ++ v.AddArg(x) ++ return true ++ } ++ break ++ } ++ // match: (XOR x x) ++ // result: (MOVVconst [0]) ++ for { ++ x := v_0 ++ if x != v_1 { ++ break ++ } ++ v.reset(OpSW64MOVVconst) ++ v.AuxInt = int64ToAuxInt(0) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSW64XORconst(v *Value) bool { ++ v_0 := v.Args[0] ++ // match: (XORconst [0] x) ++ // result: x ++ for { ++ if auxIntToInt64(v.AuxInt) != 0 { ++ break ++ } ++ x := v_0 ++ v.copyOf(x) ++ return true ++ } ++ // match: (XORconst [c] (MOVVconst [d])) ++ // result: (MOVVconst [c^d]) ++ for { ++ c := auxIntToInt64(v.AuxInt) ++ if v_0.Op != OpSW64MOVVconst { ++ break ++ } ++ d := auxIntToInt64(v_0.AuxInt) ++ v.reset(OpSW64MOVVconst) ++ v.AuxInt = int64ToAuxInt(c ^ d) ++ return true ++ } ++ // match: (XORconst [c] (XORconst [d] x)) ++ // cond: is32Bit(c^d) ++ // result: (XORconst [c^d] x) ++ for { ++ c := auxIntToInt64(v.AuxInt) ++ if v_0.Op != OpSW64XORconst { ++ break ++ } ++ d := auxIntToInt64(v_0.AuxInt) ++ x := v_0.Args[0] ++ if !(is32Bit(c ^ d)) { ++ break ++ } ++ v.reset(OpSW64XORconst) ++ v.AuxInt = int64ToAuxInt(c ^ d) ++ v.AddArg(x) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpSignmask(v *Value) bool { ++ v_0 := v.Args[0] ++ // match: (Signmask x) ++ // result: (SRAconst x [63]) ++ for { ++ x := v_0 ++ v.reset(OpSW64SRAconst) ++ v.AuxInt = int64ToAuxInt(63) ++ v.AddArg(x) ++ return true ++ } ++} ++func rewriteValueSW64_OpSlicemask(v *Value) bool { ++ v_0 := v.Args[0] ++ b := v.Block ++ // match: (Slicemask x) ++ // result: (SRAconst (NEGV x) [63]) ++ for { ++ t := v.Type ++ x := v_0 ++ v.reset(OpSW64SRAconst) ++ v.AuxInt = int64ToAuxInt(63) ++ v0 := b.NewValue0(v.Pos, OpSW64NEGV, t) ++ v0.AddArg(x) ++ v.AddArg(v0) ++ return true ++ } ++} ++func rewriteValueSW64_OpStore(v *Value) bool { ++ v_2 := v.Args[2] ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ // match: (Store {t} ptr val mem) ++ // cond: t.Size() == 1 ++ // result: (MOVBstore ptr val mem) ++ for { ++ t := auxToType(v.Aux) ++ ptr := v_0 ++ val := v_1 ++ mem := v_2 ++ if !(t.Size() == 1) { ++ break ++ } ++ v.reset(OpSW64MOVBstore) ++ v.AddArg3(ptr, val, mem) ++ return true ++ } ++ // match: (Store {t} ptr val mem) ++ // cond: t.Size() == 2 ++ // result: (MOVHstore ptr val mem) ++ for { ++ t := auxToType(v.Aux) ++ ptr := v_0 ++ val := v_1 ++ mem := v_2 ++ if !(t.Size() == 2) { ++ break ++ } ++ v.reset(OpSW64MOVHstore) ++ v.AddArg3(ptr, val, mem) ++ return true ++ } ++ // match: (Store {t} ptr val mem) ++ // cond: t.Size() == 4 && !is32BitFloat(val.Type) ++ // result: (MOVWstore ptr val mem) ++ for { ++ t := auxToType(v.Aux) ++ ptr := v_0 ++ val := v_1 ++ mem := v_2 ++ if !(t.Size() == 4 && !is32BitFloat(val.Type)) { ++ break ++ } ++ v.reset(OpSW64MOVWstore) ++ v.AddArg3(ptr, val, mem) ++ return true ++ } ++ // match: (Store {t} ptr val mem) ++ // cond: t.Size() == 8 && !is64BitFloat(val.Type) ++ // result: (MOVVstore ptr val mem) ++ for { ++ t := auxToType(v.Aux) ++ ptr := v_0 ++ val := v_1 ++ mem := v_2 ++ if !(t.Size() == 8 && !is64BitFloat(val.Type)) { ++ break ++ } ++ v.reset(OpSW64MOVVstore) ++ v.AddArg3(ptr, val, mem) ++ return true ++ } ++ // match: (Store {t} ptr val mem) ++ // cond: t.Size() == 4 && is32BitFloat(val.Type) ++ // result: (MOVFstore ptr val mem) ++ for { ++ t := auxToType(v.Aux) ++ ptr := v_0 ++ val := v_1 ++ mem := v_2 ++ if !(t.Size() == 4 && is32BitFloat(val.Type)) { ++ break ++ } ++ v.reset(OpSW64MOVFstore) ++ v.AddArg3(ptr, val, mem) ++ return true ++ } ++ // match: (Store {t} ptr val mem) ++ // cond: t.Size() == 8 && is64BitFloat(val.Type) ++ // result: (MOVDstore ptr val mem) ++ for { ++ t := auxToType(v.Aux) ++ ptr := v_0 ++ val := v_1 ++ mem := v_2 ++ if !(t.Size() == 8 && is64BitFloat(val.Type)) { ++ break ++ } ++ v.reset(OpSW64MOVDstore) ++ v.AddArg3(ptr, val, mem) ++ return true ++ } ++ return false ++} ++func rewriteValueSW64_OpZero(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ b := v.Block ++ config := b.Func.Config ++ typ := &b.Func.Config.Types ++ // match: (Zero [0] _ mem) ++ // result: mem ++ for { ++ if auxIntToInt64(v.AuxInt) != 0 { ++ break ++ } ++ mem := v_1 ++ v.copyOf(mem) ++ return true ++ } ++ // match: (Zero [1] ptr mem) ++ // result: (MOVBstore ptr (MOVVconst [0]) mem) ++ for { ++ if auxIntToInt64(v.AuxInt) != 1 { ++ break ++ } ++ ptr := v_0 ++ mem := v_1 ++ v.reset(OpSW64MOVBstore) ++ v0 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v0.AuxInt = int64ToAuxInt(0) ++ v.AddArg3(ptr, v0, mem) ++ return true ++ } ++ // match: (Zero [2] {t} ptr mem) ++ // cond: t.Alignment()%2 == 0 ++ // result: (MOVHstore ptr (MOVVconst [0]) mem) ++ for { ++ if auxIntToInt64(v.AuxInt) != 2 { ++ break ++ } ++ t := auxToType(v.Aux) ++ ptr := v_0 ++ mem := v_1 ++ if !(t.Alignment()%2 == 0) { ++ break ++ } ++ v.reset(OpSW64MOVHstore) ++ v0 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v0.AuxInt = int64ToAuxInt(0) ++ v.AddArg3(ptr, v0, mem) ++ return true ++ } ++ // match: (Zero [2] ptr mem) ++ // result: (MOVBstore [1] ptr (MOVVconst [0]) (MOVBstore [0] ptr (MOVVconst [0]) mem)) ++ for { ++ if auxIntToInt64(v.AuxInt) != 2 { ++ break ++ } ++ ptr := v_0 ++ mem := v_1 ++ v.reset(OpSW64MOVBstore) ++ v.AuxInt = int32ToAuxInt(1) ++ v0 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v0.AuxInt = int64ToAuxInt(0) ++ v1 := b.NewValue0(v.Pos, OpSW64MOVBstore, types.TypeMem) ++ v1.AuxInt = int32ToAuxInt(0) ++ v1.AddArg3(ptr, v0, mem) ++ v.AddArg3(ptr, v0, v1) ++ return true ++ } ++ // match: (Zero [4] {t} ptr mem) ++ // cond: t.Alignment()%4 == 0 ++ // result: (MOVWstore ptr (MOVVconst [0]) mem) ++ for { ++ if auxIntToInt64(v.AuxInt) != 4 { ++ break ++ } ++ t := auxToType(v.Aux) ++ ptr := v_0 ++ mem := v_1 ++ if !(t.Alignment()%4 == 0) { ++ break ++ } ++ v.reset(OpSW64MOVWstore) ++ v0 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v0.AuxInt = int64ToAuxInt(0) ++ v.AddArg3(ptr, v0, mem) ++ return true ++ } ++ // match: (Zero [4] {t} ptr mem) ++ // cond: t.Alignment()%2 == 0 ++ // result: (MOVHstore [2] ptr (MOVVconst [0]) (MOVHstore [0] ptr (MOVVconst [0]) mem)) ++ for { ++ if auxIntToInt64(v.AuxInt) != 4 { ++ break ++ } ++ t := auxToType(v.Aux) ++ ptr := v_0 ++ mem := v_1 ++ if !(t.Alignment()%2 == 0) { ++ break ++ } ++ v.reset(OpSW64MOVHstore) ++ v.AuxInt = int32ToAuxInt(2) ++ v0 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v0.AuxInt = int64ToAuxInt(0) ++ v1 := b.NewValue0(v.Pos, OpSW64MOVHstore, types.TypeMem) ++ v1.AuxInt = int32ToAuxInt(0) ++ v1.AddArg3(ptr, v0, mem) ++ v.AddArg3(ptr, v0, v1) ++ return true ++ } ++ // match: (Zero [4] ptr mem) ++ // result: (MOVBstore [3] ptr (MOVVconst [0]) (MOVBstore [2] ptr (MOVVconst [0]) (MOVBstore [1] ptr (MOVVconst [0]) (MOVBstore [0] ptr (MOVVconst [0]) mem)))) ++ for { ++ if auxIntToInt64(v.AuxInt) != 4 { ++ break ++ } ++ ptr := v_0 ++ mem := v_1 ++ v.reset(OpSW64MOVBstore) ++ v.AuxInt = int32ToAuxInt(3) ++ v0 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v0.AuxInt = int64ToAuxInt(0) ++ v1 := b.NewValue0(v.Pos, OpSW64MOVBstore, types.TypeMem) ++ v1.AuxInt = int32ToAuxInt(2) ++ v2 := b.NewValue0(v.Pos, OpSW64MOVBstore, types.TypeMem) ++ v2.AuxInt = int32ToAuxInt(1) ++ v3 := b.NewValue0(v.Pos, OpSW64MOVBstore, types.TypeMem) ++ v3.AuxInt = int32ToAuxInt(0) ++ v3.AddArg3(ptr, v0, mem) ++ v2.AddArg3(ptr, v0, v3) ++ v1.AddArg3(ptr, v0, v2) ++ v.AddArg3(ptr, v0, v1) ++ return true ++ } ++ // match: (Zero [8] {t} ptr mem) ++ // cond: t.Alignment()%8 == 0 ++ // result: (MOVVstore ptr (MOVVconst [0]) mem) ++ for { ++ if auxIntToInt64(v.AuxInt) != 8 { ++ break ++ } ++ t := auxToType(v.Aux) ++ ptr := v_0 ++ mem := v_1 ++ if !(t.Alignment()%8 == 0) { ++ break ++ } ++ v.reset(OpSW64MOVVstore) ++ v0 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v0.AuxInt = int64ToAuxInt(0) ++ v.AddArg3(ptr, v0, mem) ++ return true ++ } ++ // match: (Zero [8] {t} ptr mem) ++ // cond: t.Alignment()%4 == 0 ++ // result: (MOVWstore [4] ptr (MOVVconst [0]) (MOVWstore [0] ptr (MOVVconst [0]) mem)) ++ for { ++ if auxIntToInt64(v.AuxInt) != 8 { ++ break ++ } ++ t := auxToType(v.Aux) ++ ptr := v_0 ++ mem := v_1 ++ if !(t.Alignment()%4 == 0) { ++ break ++ } ++ v.reset(OpSW64MOVWstore) ++ v.AuxInt = int32ToAuxInt(4) ++ v0 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v0.AuxInt = int64ToAuxInt(0) ++ v1 := b.NewValue0(v.Pos, OpSW64MOVWstore, types.TypeMem) ++ v1.AuxInt = int32ToAuxInt(0) ++ v1.AddArg3(ptr, v0, mem) ++ v.AddArg3(ptr, v0, v1) ++ return true ++ } ++ // match: (Zero [8] {t} ptr mem) ++ // cond: t.Alignment()%2 == 0 ++ // result: (MOVHstore [6] ptr (MOVVconst [0]) (MOVHstore [4] ptr (MOVVconst [0]) (MOVHstore [2] ptr (MOVVconst [0]) (MOVHstore [0] ptr (MOVVconst [0]) mem)))) ++ for { ++ if auxIntToInt64(v.AuxInt) != 8 { ++ break ++ } ++ t := auxToType(v.Aux) ++ ptr := v_0 ++ mem := v_1 ++ if !(t.Alignment()%2 == 0) { ++ break ++ } ++ v.reset(OpSW64MOVHstore) ++ v.AuxInt = int32ToAuxInt(6) ++ v0 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v0.AuxInt = int64ToAuxInt(0) ++ v1 := b.NewValue0(v.Pos, OpSW64MOVHstore, types.TypeMem) ++ v1.AuxInt = int32ToAuxInt(4) ++ v2 := b.NewValue0(v.Pos, OpSW64MOVHstore, types.TypeMem) ++ v2.AuxInt = int32ToAuxInt(2) ++ v3 := b.NewValue0(v.Pos, OpSW64MOVHstore, types.TypeMem) ++ v3.AuxInt = int32ToAuxInt(0) ++ v3.AddArg3(ptr, v0, mem) ++ v2.AddArg3(ptr, v0, v3) ++ v1.AddArg3(ptr, v0, v2) ++ v.AddArg3(ptr, v0, v1) ++ return true ++ } ++ // match: (Zero [3] ptr mem) ++ // result: (MOVBstore [2] ptr (MOVVconst [0]) (MOVBstore [1] ptr (MOVVconst [0]) (MOVBstore [0] ptr (MOVVconst [0]) mem))) ++ for { ++ if auxIntToInt64(v.AuxInt) != 3 { ++ break ++ } ++ ptr := v_0 ++ mem := v_1 ++ v.reset(OpSW64MOVBstore) ++ v.AuxInt = int32ToAuxInt(2) ++ v0 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v0.AuxInt = int64ToAuxInt(0) ++ v1 := b.NewValue0(v.Pos, OpSW64MOVBstore, types.TypeMem) ++ v1.AuxInt = int32ToAuxInt(1) ++ v2 := b.NewValue0(v.Pos, OpSW64MOVBstore, types.TypeMem) ++ v2.AuxInt = int32ToAuxInt(0) ++ v2.AddArg3(ptr, v0, mem) ++ v1.AddArg3(ptr, v0, v2) ++ v.AddArg3(ptr, v0, v1) ++ return true ++ } ++ // match: (Zero [6] {t} ptr mem) ++ // cond: t.Alignment()%2 == 0 ++ // result: (MOVHstore [4] ptr (MOVVconst [0]) (MOVHstore [2] ptr (MOVVconst [0]) (MOVHstore [0] ptr (MOVVconst [0]) mem))) ++ for { ++ if auxIntToInt64(v.AuxInt) != 6 { ++ break ++ } ++ t := auxToType(v.Aux) ++ ptr := v_0 ++ mem := v_1 ++ if !(t.Alignment()%2 == 0) { ++ break ++ } ++ v.reset(OpSW64MOVHstore) ++ v.AuxInt = int32ToAuxInt(4) ++ v0 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v0.AuxInt = int64ToAuxInt(0) ++ v1 := b.NewValue0(v.Pos, OpSW64MOVHstore, types.TypeMem) ++ v1.AuxInt = int32ToAuxInt(2) ++ v2 := b.NewValue0(v.Pos, OpSW64MOVHstore, types.TypeMem) ++ v2.AuxInt = int32ToAuxInt(0) ++ v2.AddArg3(ptr, v0, mem) ++ v1.AddArg3(ptr, v0, v2) ++ v.AddArg3(ptr, v0, v1) ++ return true ++ } ++ // match: (Zero [12] {t} ptr mem) ++ // cond: t.Alignment()%4 == 0 ++ // result: (MOVWstore [8] ptr (MOVVconst [0]) (MOVWstore [4] ptr (MOVVconst [0]) (MOVWstore [0] ptr (MOVVconst [0]) mem))) ++ for { ++ if auxIntToInt64(v.AuxInt) != 12 { ++ break ++ } ++ t := auxToType(v.Aux) ++ ptr := v_0 ++ mem := v_1 ++ if !(t.Alignment()%4 == 0) { ++ break ++ } ++ v.reset(OpSW64MOVWstore) ++ v.AuxInt = int32ToAuxInt(8) ++ v0 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v0.AuxInt = int64ToAuxInt(0) ++ v1 := b.NewValue0(v.Pos, OpSW64MOVWstore, types.TypeMem) ++ v1.AuxInt = int32ToAuxInt(4) ++ v2 := b.NewValue0(v.Pos, OpSW64MOVWstore, types.TypeMem) ++ v2.AuxInt = int32ToAuxInt(0) ++ v2.AddArg3(ptr, v0, mem) ++ v1.AddArg3(ptr, v0, v2) ++ v.AddArg3(ptr, v0, v1) ++ return true ++ } ++ // match: (Zero [16] {t} ptr mem) ++ // cond: t.Alignment()%8 == 0 ++ // result: (MOVVstore [8] ptr (MOVVconst [0]) (MOVVstore [0] ptr (MOVVconst [0]) mem)) ++ for { ++ if auxIntToInt64(v.AuxInt) != 16 { ++ break ++ } ++ t := auxToType(v.Aux) ++ ptr := v_0 ++ mem := v_1 ++ if !(t.Alignment()%8 == 0) { ++ break ++ } ++ v.reset(OpSW64MOVVstore) ++ v.AuxInt = int32ToAuxInt(8) ++ v0 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v0.AuxInt = int64ToAuxInt(0) ++ v1 := b.NewValue0(v.Pos, OpSW64MOVVstore, types.TypeMem) ++ v1.AuxInt = int32ToAuxInt(0) ++ v1.AddArg3(ptr, v0, mem) ++ v.AddArg3(ptr, v0, v1) ++ return true ++ } ++ // match: (Zero [24] {t} ptr mem) ++ // cond: (t.Alignment()%8 == 0 || buildcfg.GOSW64 >=4) ++ // result: (MOVVstore [16] ptr (MOVVconst [0]) (MOVVstore [8] ptr (MOVVconst [0]) (MOVVstore [0] ptr (MOVVconst [0]) mem))) ++ for { ++ if auxIntToInt64(v.AuxInt) != 24 { ++ break ++ } ++ t := auxToType(v.Aux) ++ ptr := v_0 ++ mem := v_1 ++ if !(t.Alignment()%8 == 0 || buildcfg.GOSW64 >= 4) { ++ break ++ } ++ v.reset(OpSW64MOVVstore) ++ v.AuxInt = int32ToAuxInt(16) ++ v0 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v0.AuxInt = int64ToAuxInt(0) ++ v1 := b.NewValue0(v.Pos, OpSW64MOVVstore, types.TypeMem) ++ v1.AuxInt = int32ToAuxInt(8) ++ v2 := b.NewValue0(v.Pos, OpSW64MOVVstore, types.TypeMem) ++ v2.AuxInt = int32ToAuxInt(0) ++ v2.AddArg3(ptr, v0, mem) ++ v1.AddArg3(ptr, v0, v2) ++ v.AddArg3(ptr, v0, v1) ++ return true ++ } ++ // match: (Zero [32] {t} ptr mem) ++ // cond: (t.Alignment()%8 == 0 || buildcfg.GOSW64 >=4) ++ // result: (MOVVstore [24] ptr (MOVVconst [0]) (MOVVstore [16] ptr (MOVVconst [0]) (MOVVstore [8] ptr (MOVVconst [0]) (MOVVstore [0] ptr (MOVVconst [0]) mem)))) ++ for { ++ if auxIntToInt64(v.AuxInt) != 32 { ++ break ++ } ++ t := auxToType(v.Aux) ++ ptr := v_0 ++ mem := v_1 ++ if !(t.Alignment()%8 == 0 || buildcfg.GOSW64 >= 4) { ++ break ++ } ++ v.reset(OpSW64MOVVstore) ++ v.AuxInt = int32ToAuxInt(24) ++ v0 := b.NewValue0(v.Pos, OpSW64MOVVconst, typ.UInt64) ++ v0.AuxInt = int64ToAuxInt(0) ++ v1 := b.NewValue0(v.Pos, OpSW64MOVVstore, types.TypeMem) ++ v1.AuxInt = int32ToAuxInt(16) ++ v2 := b.NewValue0(v.Pos, OpSW64MOVVstore, types.TypeMem) ++ v2.AuxInt = int32ToAuxInt(8) ++ v3 := b.NewValue0(v.Pos, OpSW64MOVVstore, types.TypeMem) ++ v3.AuxInt = int32ToAuxInt(0) ++ v3.AddArg3(ptr, v0, mem) ++ v2.AddArg3(ptr, v0, v3) ++ v1.AddArg3(ptr, v0, v2) ++ v.AddArg3(ptr, v0, v1) ++ return true ++ } ++ // match: (Zero [s] {t} ptr mem) ++ // cond: s%8 == 0 && s > 24 && s <= 8*128 && t.Alignment()%8 == 0 && !config.noDuffDevice ++ // result: (DUFFZERO [8 * (128 - int64(s/8))] ptr mem) ++ for { ++ s := auxIntToInt64(v.AuxInt) ++ t := auxToType(v.Aux) ++ ptr := v_0 ++ mem := v_1 ++ if !(s%8 == 0 && s > 24 && s <= 8*128 && t.Alignment()%8 == 0 && !config.noDuffDevice) { ++ break ++ } ++ v.reset(OpSW64DUFFZERO) ++ v.AuxInt = int64ToAuxInt(8 * (128 - int64(s/8))) ++ v.AddArg2(ptr, mem) ++ return true ++ } ++ // match: (Zero [s] {t} ptr mem) ++ // cond: (s > 8*128 || config.noDuffDevice) || t.Alignment()%8 != 0 ++ // result: (LoweredZero [t.Alignment()] ptr (ADDVconst ptr [s-moveSize(t.Alignment(), config)]) mem) ++ for { ++ s := auxIntToInt64(v.AuxInt) ++ t := auxToType(v.Aux) ++ ptr := v_0 ++ mem := v_1 ++ if !((s > 8*128 || config.noDuffDevice) || t.Alignment()%8 != 0) { ++ break ++ } ++ v.reset(OpSW64LoweredZero) ++ v.AuxInt = int64ToAuxInt(t.Alignment()) ++ v0 := b.NewValue0(v.Pos, OpSW64ADDVconst, ptr.Type) ++ v0.AuxInt = int64ToAuxInt(s - moveSize(t.Alignment(), config)) ++ v0.AddArg(ptr) ++ v.AddArg3(ptr, v0, mem) ++ return true ++ } ++ return false ++} ++func rewriteBlockSW64(b *Block) bool { ++ typ := &b.Func.Config.Types ++ switch b.Kind { ++ case BlockSW64EQ: ++ // match: (EQ (XORconst cmp:(CMPEQ _ _) [1]) yes no) ++ // result: (NE cmp yes no) ++ for b.Controls[0].Op == OpSW64XORconst { ++ v_0 := b.Controls[0] ++ if auxIntToInt64(v_0.AuxInt) != 1 { ++ break ++ } ++ cmp := v_0.Args[0] ++ if cmp.Op != OpSW64CMPEQ { ++ break ++ } ++ b.resetWithControl(BlockSW64NE, cmp) ++ return true ++ } ++ // match: (EQ (XORconst cmp:(CMPEQconst _) [1]) yes no) ++ // result: (NE cmp yes no) ++ for b.Controls[0].Op == OpSW64XORconst { ++ v_0 := b.Controls[0] ++ if auxIntToInt64(v_0.AuxInt) != 1 { ++ break ++ } ++ cmp := v_0.Args[0] ++ if cmp.Op != OpSW64CMPEQconst { ++ break ++ } ++ b.resetWithControl(BlockSW64NE, cmp) ++ return true ++ } ++ // match: (EQ (CMPEQconst x [0]) yes no) ++ // result: (NE x yes no) ++ for b.Controls[0].Op == OpSW64CMPEQconst { ++ v_0 := b.Controls[0] ++ if auxIntToInt64(v_0.AuxInt) != 0 { ++ break ++ } ++ x := v_0.Args[0] ++ b.resetWithControl(BlockSW64NE, x) ++ return true ++ } ++ // match: (EQ (CMPLTconst x [0]) yes no) ++ // result: (GE x yes no) ++ for b.Controls[0].Op == OpSW64CMPLTconst { ++ v_0 := b.Controls[0] ++ if auxIntToInt64(v_0.AuxInt) != 0 { ++ break ++ } ++ x := v_0.Args[0] ++ b.resetWithControl(BlockSW64GE, x) ++ return true ++ } ++ // match: (EQ (CMPLEconst x [0]) yes no) ++ // result: (GT x yes no) ++ for b.Controls[0].Op == OpSW64CMPLEconst { ++ v_0 := b.Controls[0] ++ if auxIntToInt64(v_0.AuxInt) != 0 { ++ break ++ } ++ x := v_0.Args[0] ++ b.resetWithControl(BlockSW64GT, x) ++ return true ++ } ++ // match: (EQ (CMPLTconst x [1]) yes no) ++ // result: (GT x yes no) ++ for b.Controls[0].Op == OpSW64CMPLTconst { ++ v_0 := b.Controls[0] ++ if auxIntToInt64(v_0.AuxInt) != 1 { ++ break ++ } ++ x := v_0.Args[0] ++ b.resetWithControl(BlockSW64GT, x) ++ return true ++ } ++ // match: (EQ (CMPULTconst x [1]) yes no) ++ // result: (NE x yes no) ++ for b.Controls[0].Op == OpSW64CMPULTconst { ++ v_0 := b.Controls[0] ++ if auxIntToInt64(v_0.AuxInt) != 1 { ++ break ++ } ++ x := v_0.Args[0] ++ b.resetWithControl(BlockSW64NE, x) ++ return true ++ } ++ // match: (EQ (CMPULEconst x [0]) yes no) ++ // result: (NE x yes no) ++ for b.Controls[0].Op == OpSW64CMPULEconst { ++ v_0 := b.Controls[0] ++ if auxIntToInt64(v_0.AuxInt) != 0 { ++ break ++ } ++ x := v_0.Args[0] ++ b.resetWithControl(BlockSW64NE, x) ++ return true ++ } ++ // match: (EQ (CMPEQ x (MOVVconst [0])) yes no) ++ // result: (NE x yes no) ++ for b.Controls[0].Op == OpSW64CMPEQ { ++ v_0 := b.Controls[0] ++ _ = v_0.Args[1] ++ x := v_0.Args[0] ++ v_0_1 := v_0.Args[1] ++ if v_0_1.Op != OpSW64MOVVconst || auxIntToInt64(v_0_1.AuxInt) != 0 { ++ break ++ } ++ b.resetWithControl(BlockSW64NE, x) ++ return true ++ } ++ // match: (EQ (CMPLT x (MOVVconst [0])) yes no) ++ // result: (GE x yes no) ++ for b.Controls[0].Op == OpSW64CMPLT { ++ v_0 := b.Controls[0] ++ _ = v_0.Args[1] ++ x := v_0.Args[0] ++ v_0_1 := v_0.Args[1] ++ if v_0_1.Op != OpSW64MOVVconst || auxIntToInt64(v_0_1.AuxInt) != 0 { ++ break ++ } ++ b.resetWithControl(BlockSW64GE, x) ++ return true ++ } ++ // match: (EQ (CMPLT x (MOVVconst [1])) yes no) ++ // result: (GT x yes no) ++ for b.Controls[0].Op == OpSW64CMPLT { ++ v_0 := b.Controls[0] ++ _ = v_0.Args[1] ++ x := v_0.Args[0] ++ v_0_1 := v_0.Args[1] ++ if v_0_1.Op != OpSW64MOVVconst || auxIntToInt64(v_0_1.AuxInt) != 1 { ++ break ++ } ++ b.resetWithControl(BlockSW64GT, x) ++ return true ++ } ++ // match: (EQ (CMPLE x (MOVVconst [0])) yes no) ++ // result: (GT x yes no) ++ for b.Controls[0].Op == OpSW64CMPLE { ++ v_0 := b.Controls[0] ++ _ = v_0.Args[1] ++ x := v_0.Args[0] ++ v_0_1 := v_0.Args[1] ++ if v_0_1.Op != OpSW64MOVVconst || auxIntToInt64(v_0_1.AuxInt) != 0 { ++ break ++ } ++ b.resetWithControl(BlockSW64GT, x) ++ return true ++ } ++ // match: (EQ (CMPULT x (MOVVconst [1])) yes no) ++ // result: (NE x yes no) ++ for b.Controls[0].Op == OpSW64CMPULT { ++ v_0 := b.Controls[0] ++ _ = v_0.Args[1] ++ x := v_0.Args[0] ++ v_0_1 := v_0.Args[1] ++ if v_0_1.Op != OpSW64MOVVconst || auxIntToInt64(v_0_1.AuxInt) != 1 { ++ break ++ } ++ b.resetWithControl(BlockSW64NE, x) ++ return true ++ } ++ // match: (EQ (CMPULE x (MOVVconst [0])) yes no) ++ // result: (NE x yes no) ++ for b.Controls[0].Op == OpSW64CMPULE { ++ v_0 := b.Controls[0] ++ _ = v_0.Args[1] ++ x := v_0.Args[0] ++ v_0_1 := v_0.Args[1] ++ if v_0_1.Op != OpSW64MOVVconst || auxIntToInt64(v_0_1.AuxInt) != 0 { ++ break ++ } ++ b.resetWithControl(BlockSW64NE, x) ++ return true ++ } ++ // match: (EQ (CMPEQ (MOVVconst [0]) x) yes no) ++ // result: (NE x yes no) ++ for b.Controls[0].Op == OpSW64CMPEQ { ++ v_0 := b.Controls[0] ++ x := v_0.Args[1] ++ v_0_0 := v_0.Args[0] ++ if v_0_0.Op != OpSW64MOVVconst || auxIntToInt64(v_0_0.AuxInt) != 0 { ++ break ++ } ++ b.resetWithControl(BlockSW64NE, x) ++ return true ++ } ++ // match: (EQ (CMPLT (MOVVconst [0]) x) yes no) ++ // result: (LE x yes no) ++ for b.Controls[0].Op == OpSW64CMPLT { ++ v_0 := b.Controls[0] ++ x := v_0.Args[1] ++ v_0_0 := v_0.Args[0] ++ if v_0_0.Op != OpSW64MOVVconst || auxIntToInt64(v_0_0.AuxInt) != 0 { ++ break ++ } ++ b.resetWithControl(BlockSW64LE, x) ++ return true ++ } ++ // match: (EQ (CMPLE (MOVVconst [0]) x) yes no) ++ // result: (LT x yes no) ++ for b.Controls[0].Op == OpSW64CMPLE { ++ v_0 := b.Controls[0] ++ x := v_0.Args[1] ++ v_0_0 := v_0.Args[0] ++ if v_0_0.Op != OpSW64MOVVconst || auxIntToInt64(v_0_0.AuxInt) != 0 { ++ break ++ } ++ b.resetWithControl(BlockSW64LT, x) ++ return true ++ } ++ // match: (EQ (CMPLE (MOVVconst [1]) x) yes no) ++ // result: (LE x yes no) ++ for b.Controls[0].Op == OpSW64CMPLE { ++ v_0 := b.Controls[0] ++ x := v_0.Args[1] ++ v_0_0 := v_0.Args[0] ++ if v_0_0.Op != OpSW64MOVVconst || auxIntToInt64(v_0_0.AuxInt) != 1 { ++ break ++ } ++ b.resetWithControl(BlockSW64LE, x) ++ return true ++ } ++ // match: (EQ (CMPULT (MOVVconst [0]) x) yes no) ++ // result: (EQ x yes no) ++ for b.Controls[0].Op == OpSW64CMPULT { ++ v_0 := b.Controls[0] ++ x := v_0.Args[1] ++ v_0_0 := v_0.Args[0] ++ if v_0_0.Op != OpSW64MOVVconst || auxIntToInt64(v_0_0.AuxInt) != 0 { ++ break ++ } ++ b.resetWithControl(BlockSW64EQ, x) ++ return true ++ } ++ // match: (EQ (CMPULE (MOVVconst [1]) x) yes no) ++ // result: (EQ x yes no) ++ for b.Controls[0].Op == OpSW64CMPULE { ++ v_0 := b.Controls[0] ++ x := v_0.Args[1] ++ v_0_0 := v_0.Args[0] ++ if v_0_0.Op != OpSW64MOVVconst || auxIntToInt64(v_0_0.AuxInt) != 1 { ++ break ++ } ++ b.resetWithControl(BlockSW64EQ, x) ++ return true ++ } ++ // match: (EQ (FNotEqual cmp) yes no) ++ // result: (FNE cmp yes no) ++ for b.Controls[0].Op == OpSW64FNotEqual { ++ v_0 := b.Controls[0] ++ cmp := v_0.Args[0] ++ b.resetWithControl(BlockSW64FNE, cmp) ++ return true ++ } ++ // match: (EQ (FEqual cmp) yes no) ++ // result: (FEQ cmp yes no) ++ for b.Controls[0].Op == OpSW64FEqual { ++ v_0 := b.Controls[0] ++ cmp := v_0.Args[0] ++ b.resetWithControl(BlockSW64FEQ, cmp) ++ return true ++ } ++ case BlockIf: ++ // match: (If cond yes no) ++ // result: (LBS cond yes no) ++ for { ++ cond := b.Controls[0] ++ b.resetWithControl(BlockSW64LBS, cond) ++ return true ++ } ++ case BlockJumpTable: ++ // match: (JumpTable idx) ++ // result: (JUMPTABLE {makeJumpTableSym(b)} idx (SYMADDR {makeJumpTableSym(b)} (SB))) ++ for { ++ idx := b.Controls[0] ++ v0 := b.NewValue0(b.Pos, OpSW64SYMADDR, typ.Uintptr) ++ v0.Aux = symToAux(makeJumpTableSym(b)) ++ v1 := b.NewValue0(b.Pos, OpSB, typ.Uintptr) ++ v0.AddArg(v1) ++ b.resetWithControl2(BlockSW64JUMPTABLE, idx, v0) ++ b.Aux = symToAux(makeJumpTableSym(b)) ++ return true ++ } ++ case BlockSW64LBS: ++ // match: (LBS (CMPEQ x y) yes no) ++ // result: (NE (CMPEQ x y) yes no) ++ for b.Controls[0].Op == OpSW64CMPEQ { ++ v_0 := b.Controls[0] ++ y := v_0.Args[1] ++ x := v_0.Args[0] ++ v0 := b.NewValue0(v_0.Pos, OpSW64CMPEQ, typ.Bool) ++ v0.AddArg2(x, y) ++ b.resetWithControl(BlockSW64NE, v0) ++ return true ++ } ++ // match: (LBS (XORconst (CMPEQ x y) [1]) yes no) ++ // result: (EQ (CMPEQ x y) yes no) ++ for b.Controls[0].Op == OpSW64XORconst { ++ v_0 := b.Controls[0] ++ if auxIntToInt64(v_0.AuxInt) != 1 { ++ break ++ } ++ v_0_0 := v_0.Args[0] ++ if v_0_0.Op != OpSW64CMPEQ { ++ break ++ } ++ y := v_0_0.Args[1] ++ x := v_0_0.Args[0] ++ v0 := b.NewValue0(v_0.Pos, OpSW64CMPEQ, typ.Bool) ++ v0.AddArg2(x, y) ++ b.resetWithControl(BlockSW64EQ, v0) ++ return true ++ } ++ // match: (LBS (CMPLT x y) yes no) ++ // result: (NE (CMPLT x y) yes no) ++ for b.Controls[0].Op == OpSW64CMPLT { ++ v_0 := b.Controls[0] ++ y := v_0.Args[1] ++ x := v_0.Args[0] ++ v0 := b.NewValue0(v_0.Pos, OpSW64CMPLT, typ.Bool) ++ v0.AddArg2(x, y) ++ b.resetWithControl(BlockSW64NE, v0) ++ return true ++ } ++ // match: (LBS (CMPULT x y) yes no) ++ // result: (NE (CMPULT x y) yes no) ++ for b.Controls[0].Op == OpSW64CMPULT { ++ v_0 := b.Controls[0] ++ y := v_0.Args[1] ++ x := v_0.Args[0] ++ v0 := b.NewValue0(v_0.Pos, OpSW64CMPULT, typ.Bool) ++ v0.AddArg2(x, y) ++ b.resetWithControl(BlockSW64NE, v0) ++ return true ++ } ++ // match: (LBS (CMPLE x y) yes no) ++ // result: (NE (CMPLE x y) yes no) ++ for b.Controls[0].Op == OpSW64CMPLE { ++ v_0 := b.Controls[0] ++ y := v_0.Args[1] ++ x := v_0.Args[0] ++ v0 := b.NewValue0(v_0.Pos, OpSW64CMPLE, typ.Bool) ++ v0.AddArg2(x, y) ++ b.resetWithControl(BlockSW64NE, v0) ++ return true ++ } ++ // match: (LBS (CMPULE x y) yes no) ++ // result: (NE (CMPULE x y) yes no) ++ for b.Controls[0].Op == OpSW64CMPULE { ++ v_0 := b.Controls[0] ++ y := v_0.Args[1] ++ x := v_0.Args[0] ++ v0 := b.NewValue0(v_0.Pos, OpSW64CMPULE, typ.Bool) ++ v0.AddArg2(x, y) ++ b.resetWithControl(BlockSW64NE, v0) ++ return true ++ } ++ // match: (LBS (FEqual cc) yes no) ++ // result: (FNE cc yes no) ++ for b.Controls[0].Op == OpSW64FEqual { ++ v_0 := b.Controls[0] ++ cc := v_0.Args[0] ++ b.resetWithControl(BlockSW64FNE, cc) ++ return true ++ } ++ // match: (LBS (FNotEqual cc) yes no) ++ // result: (FEQ cc yes no) ++ for b.Controls[0].Op == OpSW64FNotEqual { ++ v_0 := b.Controls[0] ++ cc := v_0.Args[0] ++ b.resetWithControl(BlockSW64FEQ, cc) ++ return true ++ } ++ case BlockSW64NE: ++ // match: (NE (XORconst cmp:(CMPEQ _ _) [1]) yes no) ++ // result: (EQ cmp yes no) ++ for b.Controls[0].Op == OpSW64XORconst { ++ v_0 := b.Controls[0] ++ if auxIntToInt64(v_0.AuxInt) != 1 { ++ break ++ } ++ cmp := v_0.Args[0] ++ if cmp.Op != OpSW64CMPEQ { ++ break ++ } ++ b.resetWithControl(BlockSW64EQ, cmp) ++ return true ++ } ++ // match: (NE (XORconst cmp:(CMPEQconst _) [1]) yes no) ++ // result: (EQ cmp yes no) ++ for b.Controls[0].Op == OpSW64XORconst { ++ v_0 := b.Controls[0] ++ if auxIntToInt64(v_0.AuxInt) != 1 { ++ break ++ } ++ cmp := v_0.Args[0] ++ if cmp.Op != OpSW64CMPEQconst { ++ break ++ } ++ b.resetWithControl(BlockSW64EQ, cmp) ++ return true ++ } ++ // match: (NE (CMPEQconst x [0]) yes no) ++ // result: (EQ x yes no) ++ for b.Controls[0].Op == OpSW64CMPEQconst { ++ v_0 := b.Controls[0] ++ if auxIntToInt64(v_0.AuxInt) != 0 { ++ break ++ } ++ x := v_0.Args[0] ++ b.resetWithControl(BlockSW64EQ, x) ++ return true ++ } ++ // match: (NE (CMPLTconst x [0]) yes no) ++ // result: (LT x yes no) ++ for b.Controls[0].Op == OpSW64CMPLTconst { ++ v_0 := b.Controls[0] ++ if auxIntToInt64(v_0.AuxInt) != 0 { ++ break ++ } ++ x := v_0.Args[0] ++ b.resetWithControl(BlockSW64LT, x) ++ return true ++ } ++ // match: (NE (CMPLEconst x [0]) yes no) ++ // result: (LE x yes no) ++ for b.Controls[0].Op == OpSW64CMPLEconst { ++ v_0 := b.Controls[0] ++ if auxIntToInt64(v_0.AuxInt) != 0 { ++ break ++ } ++ x := v_0.Args[0] ++ b.resetWithControl(BlockSW64LE, x) ++ return true ++ } ++ // match: (NE (CMPLTconst x [1]) yes no) ++ // result: (LE x yes no) ++ for b.Controls[0].Op == OpSW64CMPLTconst { ++ v_0 := b.Controls[0] ++ if auxIntToInt64(v_0.AuxInt) != 1 { ++ break ++ } ++ x := v_0.Args[0] ++ b.resetWithControl(BlockSW64LE, x) ++ return true ++ } ++ // match: (NE (CMPULTconst x [1]) yes no) ++ // result: (EQ x yes no) ++ for b.Controls[0].Op == OpSW64CMPULTconst { ++ v_0 := b.Controls[0] ++ if auxIntToInt64(v_0.AuxInt) != 1 { ++ break ++ } ++ x := v_0.Args[0] ++ b.resetWithControl(BlockSW64EQ, x) ++ return true ++ } ++ // match: (NE (CMPULEconst x [0]) yes no) ++ // result: (EQ x yes no) ++ for b.Controls[0].Op == OpSW64CMPULEconst { ++ v_0 := b.Controls[0] ++ if auxIntToInt64(v_0.AuxInt) != 0 { ++ break ++ } ++ x := v_0.Args[0] ++ b.resetWithControl(BlockSW64EQ, x) ++ return true ++ } ++ // match: (NE (CMPEQ x (MOVVconst [0])) yes no) ++ // result: (EQ x yes no) ++ for b.Controls[0].Op == OpSW64CMPEQ { ++ v_0 := b.Controls[0] ++ _ = v_0.Args[1] ++ x := v_0.Args[0] ++ v_0_1 := v_0.Args[1] ++ if v_0_1.Op != OpSW64MOVVconst || auxIntToInt64(v_0_1.AuxInt) != 0 { ++ break ++ } ++ b.resetWithControl(BlockSW64EQ, x) ++ return true ++ } ++ // match: (NE (CMPLT x (MOVVconst [0])) yes no) ++ // result: (LT x yes no) ++ for b.Controls[0].Op == OpSW64CMPLT { ++ v_0 := b.Controls[0] ++ _ = v_0.Args[1] ++ x := v_0.Args[0] ++ v_0_1 := v_0.Args[1] ++ if v_0_1.Op != OpSW64MOVVconst || auxIntToInt64(v_0_1.AuxInt) != 0 { ++ break ++ } ++ b.resetWithControl(BlockSW64LT, x) ++ return true ++ } ++ // match: (NE (CMPLT x (MOVVconst [1])) yes no) ++ // result: (LE x yes no) ++ for b.Controls[0].Op == OpSW64CMPLT { ++ v_0 := b.Controls[0] ++ _ = v_0.Args[1] ++ x := v_0.Args[0] ++ v_0_1 := v_0.Args[1] ++ if v_0_1.Op != OpSW64MOVVconst || auxIntToInt64(v_0_1.AuxInt) != 1 { ++ break ++ } ++ b.resetWithControl(BlockSW64LE, x) ++ return true ++ } ++ // match: (NE (CMPLE x (MOVVconst [0])) yes no) ++ // result: (LE x yes no) ++ for b.Controls[0].Op == OpSW64CMPLE { ++ v_0 := b.Controls[0] ++ _ = v_0.Args[1] ++ x := v_0.Args[0] ++ v_0_1 := v_0.Args[1] ++ if v_0_1.Op != OpSW64MOVVconst || auxIntToInt64(v_0_1.AuxInt) != 0 { ++ break ++ } ++ b.resetWithControl(BlockSW64LE, x) ++ return true ++ } ++ // match: (NE (CMPULT x (MOVVconst [1])) yes no) ++ // result: (EQ x yes no) ++ for b.Controls[0].Op == OpSW64CMPULT { ++ v_0 := b.Controls[0] ++ _ = v_0.Args[1] ++ x := v_0.Args[0] ++ v_0_1 := v_0.Args[1] ++ if v_0_1.Op != OpSW64MOVVconst || auxIntToInt64(v_0_1.AuxInt) != 1 { ++ break ++ } ++ b.resetWithControl(BlockSW64EQ, x) ++ return true ++ } ++ // match: (NE (CMPULE x (MOVVconst [0])) yes no) ++ // result: (EQ x yes no) ++ for b.Controls[0].Op == OpSW64CMPULE { ++ v_0 := b.Controls[0] ++ _ = v_0.Args[1] ++ x := v_0.Args[0] ++ v_0_1 := v_0.Args[1] ++ if v_0_1.Op != OpSW64MOVVconst || auxIntToInt64(v_0_1.AuxInt) != 0 { ++ break ++ } ++ b.resetWithControl(BlockSW64EQ, x) ++ return true ++ } ++ // match: (NE (CMPEQ (MOVVconst [0]) x) yes no) ++ // result: (EQ x yes no) ++ for b.Controls[0].Op == OpSW64CMPEQ { ++ v_0 := b.Controls[0] ++ x := v_0.Args[1] ++ v_0_0 := v_0.Args[0] ++ if v_0_0.Op != OpSW64MOVVconst || auxIntToInt64(v_0_0.AuxInt) != 0 { ++ break ++ } ++ b.resetWithControl(BlockSW64EQ, x) ++ return true ++ } ++ // match: (NE (CMPLT (MOVVconst [0]) x) yes no) ++ // result: (GT x yes no) ++ for b.Controls[0].Op == OpSW64CMPLT { ++ v_0 := b.Controls[0] ++ x := v_0.Args[1] ++ v_0_0 := v_0.Args[0] ++ if v_0_0.Op != OpSW64MOVVconst || auxIntToInt64(v_0_0.AuxInt) != 0 { ++ break ++ } ++ b.resetWithControl(BlockSW64GT, x) ++ return true ++ } ++ // match: (NE (CMPLE (MOVVconst [0]) x) yes no) ++ // result: (GE x yes no) ++ for b.Controls[0].Op == OpSW64CMPLE { ++ v_0 := b.Controls[0] ++ x := v_0.Args[1] ++ v_0_0 := v_0.Args[0] ++ if v_0_0.Op != OpSW64MOVVconst || auxIntToInt64(v_0_0.AuxInt) != 0 { ++ break ++ } ++ b.resetWithControl(BlockSW64GE, x) ++ return true ++ } ++ // match: (NE (CMPLE (MOVVconst [1]) x) yes no) ++ // result: (GT x yes no) ++ for b.Controls[0].Op == OpSW64CMPLE { ++ v_0 := b.Controls[0] ++ x := v_0.Args[1] ++ v_0_0 := v_0.Args[0] ++ if v_0_0.Op != OpSW64MOVVconst || auxIntToInt64(v_0_0.AuxInt) != 1 { ++ break ++ } ++ b.resetWithControl(BlockSW64GT, x) ++ return true ++ } ++ // match: (NE (CMPULT (MOVVconst [0]) x) yes no) ++ // result: (NE x yes no) ++ for b.Controls[0].Op == OpSW64CMPULT { ++ v_0 := b.Controls[0] ++ x := v_0.Args[1] ++ v_0_0 := v_0.Args[0] ++ if v_0_0.Op != OpSW64MOVVconst || auxIntToInt64(v_0_0.AuxInt) != 0 { ++ break ++ } ++ b.resetWithControl(BlockSW64NE, x) ++ return true ++ } ++ // match: (NE (CMPULE (MOVVconst [1]) x) yes no) ++ // result: (NE x yes no) ++ for b.Controls[0].Op == OpSW64CMPULE { ++ v_0 := b.Controls[0] ++ x := v_0.Args[1] ++ v_0_0 := v_0.Args[0] ++ if v_0_0.Op != OpSW64MOVVconst || auxIntToInt64(v_0_0.AuxInt) != 1 { ++ break ++ } ++ b.resetWithControl(BlockSW64NE, x) ++ return true ++ } ++ // match: (NE (FNotEqual cmp) yes no) ++ // result: (FEQ cmp yes no) ++ for b.Controls[0].Op == OpSW64FNotEqual { ++ v_0 := b.Controls[0] ++ cmp := v_0.Args[0] ++ b.resetWithControl(BlockSW64FEQ, cmp) ++ return true ++ } ++ // match: (NE (FEqual cmp) yes no) ++ // result: (FNE cmp yes no) ++ for b.Controls[0].Op == OpSW64FEqual { ++ v_0 := b.Controls[0] ++ cmp := v_0.Args[0] ++ b.resetWithControl(BlockSW64FNE, cmp) ++ return true ++ } ++ } ++ return false ++} +diff --git a/src/cmd/compile/internal/ssa/schedule.go b/src/cmd/compile/internal/ssa/schedule.go +index bce0108dcb..124e333c15 100644 +--- a/src/cmd/compile/internal/ssa/schedule.go ++++ b/src/cmd/compile/internal/ssa/schedule.go +@@ -92,7 +92,7 @@ func (op Op) isLoweredGetClosurePtr() bool { + switch op { + case OpAMD64LoweredGetClosurePtr, OpPPC64LoweredGetClosurePtr, OpARMLoweredGetClosurePtr, OpARM64LoweredGetClosurePtr, + Op386LoweredGetClosurePtr, OpMIPS64LoweredGetClosurePtr, OpLOONG64LoweredGetClosurePtr, OpS390XLoweredGetClosurePtr, OpMIPSLoweredGetClosurePtr, +- OpRISCV64LoweredGetClosurePtr, OpWasmLoweredGetClosurePtr: ++ OpRISCV64LoweredGetClosurePtr, OpWasmLoweredGetClosurePtr, OpSW64LoweredGetClosurePtr: + return true + } + return false +diff --git a/src/cmd/compile/internal/ssagen/intrinsics.go b/src/cmd/compile/internal/ssagen/intrinsics.go +index e4da86db51..8de6eb4c2d 100644 +--- a/src/cmd/compile/internal/ssagen/intrinsics.go ++++ b/src/cmd/compile/internal/ssagen/intrinsics.go +@@ -225,21 +225,21 @@ func initIntrinsics(cfg *intrinsicBuildConfig) { + s.vars[memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v) + return s.newValue1(ssa.OpSelect0, types.Types[types.TUINT32], v) + }, +- sys.AMD64, sys.ARM64, sys.Loong64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X) ++ sys.AMD64, sys.ARM64, sys.Loong64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X, sys.SW64) + addF("internal/runtime/atomic", "Load8", + func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { + v := s.newValue2(ssa.OpAtomicLoad8, types.NewTuple(types.Types[types.TUINT8], types.TypeMem), args[0], s.mem()) + s.vars[memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v) + return s.newValue1(ssa.OpSelect0, types.Types[types.TUINT8], v) + }, +- sys.AMD64, sys.ARM64, sys.Loong64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X) ++ sys.AMD64, sys.ARM64, sys.Loong64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X, sys.SW64) + addF("internal/runtime/atomic", "Load64", + func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { + v := s.newValue2(ssa.OpAtomicLoad64, types.NewTuple(types.Types[types.TUINT64], types.TypeMem), args[0], s.mem()) + s.vars[memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v) + return s.newValue1(ssa.OpSelect0, types.Types[types.TUINT64], v) + }, +- sys.AMD64, sys.ARM64, sys.Loong64, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X) ++ sys.AMD64, sys.ARM64, sys.Loong64, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X, sys.SW64) + addF("internal/runtime/atomic", "LoadAcq", + func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { + v := s.newValue2(ssa.OpAtomicLoadAcq32, types.NewTuple(types.Types[types.TUINT32], types.TypeMem), args[0], s.mem()) +@@ -260,32 +260,32 @@ func initIntrinsics(cfg *intrinsicBuildConfig) { + s.vars[memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v) + return s.newValue1(ssa.OpSelect0, s.f.Config.Types.BytePtr, v) + }, +- sys.AMD64, sys.ARM64, sys.Loong64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X) ++ sys.AMD64, sys.ARM64, sys.Loong64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X, sys.SW64) + + addF("internal/runtime/atomic", "Store", + func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { + s.vars[memVar] = s.newValue3(ssa.OpAtomicStore32, types.TypeMem, args[0], args[1], s.mem()) + return nil + }, +- sys.AMD64, sys.ARM64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X) ++ sys.AMD64, sys.ARM64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X, sys.SW64) + addF("internal/runtime/atomic", "Store8", + func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { + s.vars[memVar] = s.newValue3(ssa.OpAtomicStore8, types.TypeMem, args[0], args[1], s.mem()) + return nil + }, +- sys.AMD64, sys.ARM64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X) ++ sys.AMD64, sys.ARM64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X, sys.SW64) + addF("internal/runtime/atomic", "Store64", + func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { + s.vars[memVar] = s.newValue3(ssa.OpAtomicStore64, types.TypeMem, args[0], args[1], s.mem()) + return nil + }, +- sys.AMD64, sys.ARM64, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X) ++ sys.AMD64, sys.ARM64, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X, sys.SW64) + addF("internal/runtime/atomic", "StorepNoWB", + func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { + s.vars[memVar] = s.newValue3(ssa.OpAtomicStorePtrNoWB, types.TypeMem, args[0], args[1], s.mem()) + return nil + }, +- sys.AMD64, sys.ARM64, sys.Loong64, sys.MIPS, sys.MIPS64, sys.RISCV64, sys.S390X) ++ sys.AMD64, sys.ARM64, sys.Loong64, sys.MIPS, sys.MIPS64, sys.RISCV64, sys.S390X, sys.SW64) + addF("internal/runtime/atomic", "StoreRel", + func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { + s.vars[memVar] = s.newValue3(ssa.OpAtomicStoreRel32, types.TypeMem, args[0], args[1], s.mem()) +@@ -368,14 +368,14 @@ func initIntrinsics(cfg *intrinsicBuildConfig) { + s.vars[memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v) + return s.newValue1(ssa.OpSelect0, types.Types[types.TUINT32], v) + }, +- sys.AMD64, sys.Loong64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X) ++ sys.AMD64, sys.Loong64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X, sys.SW64) + addF("internal/runtime/atomic", "Xchg64", + func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { + v := s.newValue3(ssa.OpAtomicExchange64, types.NewTuple(types.Types[types.TUINT64], types.TypeMem), args[0], args[1], s.mem()) + s.vars[memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v) + return s.newValue1(ssa.OpSelect0, types.Types[types.TUINT64], v) + }, +- sys.AMD64, sys.Loong64, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X) ++ sys.AMD64, sys.Loong64, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X, sys.SW64) + + makeAtomicGuardedIntrinsicARM64common := func(op0, op1 ssa.Op, typ types.Kind, emit atomicOpEmitter, needReturn bool) intrinsicBuilder { + +@@ -481,14 +481,14 @@ func initIntrinsics(cfg *intrinsicBuildConfig) { + s.vars[memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v) + return s.newValue1(ssa.OpSelect0, types.Types[types.TUINT32], v) + }, +- sys.AMD64, sys.Loong64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X) ++ sys.AMD64, sys.Loong64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X, sys.SW64) + addF("internal/runtime/atomic", "Xadd64", + func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { + v := s.newValue3(ssa.OpAtomicAdd64, types.NewTuple(types.Types[types.TUINT64], types.TypeMem), args[0], args[1], s.mem()) + s.vars[memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v) + return s.newValue1(ssa.OpSelect0, types.Types[types.TUINT64], v) + }, +- sys.AMD64, sys.Loong64, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X) ++ sys.AMD64, sys.Loong64, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X, sys.SW64) + + addF("internal/runtime/atomic", "Xadd", + makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicAdd32, ssa.OpAtomicAdd32Variant, types.TUINT32, atomicEmitterARM64), +@@ -503,14 +503,14 @@ func initIntrinsics(cfg *intrinsicBuildConfig) { + s.vars[memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v) + return s.newValue1(ssa.OpSelect0, types.Types[types.TBOOL], v) + }, +- sys.AMD64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X) ++ sys.AMD64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X, sys.SW64) + addF("internal/runtime/atomic", "Cas64", + func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { + v := s.newValue4(ssa.OpAtomicCompareAndSwap64, types.NewTuple(types.Types[types.TBOOL], types.TypeMem), args[0], args[1], args[2], s.mem()) + s.vars[memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v) + return s.newValue1(ssa.OpSelect0, types.Types[types.TBOOL], v) + }, +- sys.AMD64, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X) ++ sys.AMD64, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X, sys.SW64) + addF("internal/runtime/atomic", "CasRel", + func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { + v := s.newValue4(ssa.OpAtomicCompareAndSwap32, types.NewTuple(types.Types[types.TBOOL], types.TypeMem), args[0], args[1], args[2], s.mem()) +@@ -724,7 +724,7 @@ func initIntrinsics(cfg *intrinsicBuildConfig) { + func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { + return s.newValue1(ssa.OpSqrt, types.Types[types.TFLOAT64], args[0]) + }, +- sys.I386, sys.AMD64, sys.ARM, sys.ARM64, sys.Loong64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X, sys.Wasm) ++ sys.I386, sys.AMD64, sys.ARM, sys.ARM64, sys.Loong64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X, sys.Wasm, sys.SW64) + addF("math", "Trunc", + func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { + return s.newValue1(ssa.OpTrunc, types.Types[types.TFLOAT64], args[0]) +@@ -754,12 +754,12 @@ func initIntrinsics(cfg *intrinsicBuildConfig) { + func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { + return s.newValue1(ssa.OpAbs, types.Types[types.TFLOAT64], args[0]) + }, +- sys.ARM64, sys.ARM, sys.Loong64, sys.PPC64, sys.RISCV64, sys.Wasm, sys.MIPS, sys.MIPS64) ++ sys.ARM64, sys.ARM, sys.Loong64, sys.PPC64, sys.RISCV64, sys.Wasm, sys.MIPS, sys.MIPS64, sys.SW64) + addF("math", "Copysign", + func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { + return s.newValue2(ssa.OpCopysign, types.Types[types.TFLOAT64], args[0], args[1]) + }, +- sys.Loong64, sys.PPC64, sys.RISCV64, sys.Wasm) ++ sys.Loong64, sys.PPC64, sys.RISCV64, sys.Wasm, sys.SW64) + addF("math", "FMA", + func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { + return s.newValue3(ssa.OpFMA, types.Types[types.TFLOAT64], args[0], args[1], args[2]) +@@ -886,7 +886,7 @@ func initIntrinsics(cfg *intrinsicBuildConfig) { + func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { + return s.newValue1(ssa.OpCtz64, types.Types[types.TINT], args[0]) + }, +- sys.AMD64, sys.ARM64, sys.ARM, sys.Loong64, sys.S390X, sys.MIPS, sys.PPC64, sys.Wasm) ++ sys.AMD64, sys.ARM64, sys.ARM, sys.Loong64, sys.S390X, sys.MIPS, sys.PPC64, sys.Wasm, sys.SW64) + addF("math/bits", "TrailingZeros64", + func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { + lo := s.newValue1(ssa.OpInt64Lo, types.Types[types.TUINT32], args[0]) +@@ -898,7 +898,7 @@ func initIntrinsics(cfg *intrinsicBuildConfig) { + func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { + return s.newValue1(ssa.OpCtz32, types.Types[types.TINT], args[0]) + }, +- sys.AMD64, sys.I386, sys.ARM64, sys.ARM, sys.Loong64, sys.S390X, sys.MIPS, sys.PPC64, sys.Wasm) ++ sys.AMD64, sys.I386, sys.ARM64, sys.ARM, sys.Loong64, sys.S390X, sys.MIPS, sys.PPC64, sys.Wasm, sys.SW64) + addF("math/bits", "TrailingZeros16", + func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { + x := s.newValue1(ssa.OpZeroExt16to32, types.Types[types.TUINT32], args[0]) +@@ -919,7 +919,7 @@ func initIntrinsics(cfg *intrinsicBuildConfig) { + y := s.newValue2(ssa.OpOr64, types.Types[types.TUINT64], x, c) + return s.newValue1(ssa.OpCtz64, types.Types[types.TINT], y) + }, +- sys.Loong64, sys.S390X, sys.PPC64) ++ sys.Loong64, sys.S390X, sys.PPC64, sys.SW64) + addF("math/bits", "TrailingZeros8", + func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { + x := s.newValue1(ssa.OpZeroExt8to32, types.Types[types.TUINT32], args[0]) +@@ -940,7 +940,7 @@ func initIntrinsics(cfg *intrinsicBuildConfig) { + y := s.newValue2(ssa.OpOr64, types.Types[types.TUINT64], x, c) + return s.newValue1(ssa.OpCtz64, types.Types[types.TINT], y) + }, +- sys.Loong64, sys.S390X) ++ sys.Loong64, sys.S390X, sys.SW64) + alias("math/bits", "ReverseBytes64", "internal/runtime/sys", "Bswap64", all...) + alias("math/bits", "ReverseBytes32", "internal/runtime/sys", "Bswap32", all...) + addF("math/bits", "ReverseBytes16", +@@ -1137,7 +1137,7 @@ func initIntrinsics(cfg *intrinsicBuildConfig) { + func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { + return s.newValue1(ssa.OpPopCount64, types.Types[types.TINT], args[0]) + }, +- sys.PPC64, sys.ARM64, sys.S390X, sys.Wasm) ++ sys.PPC64, sys.ARM64, sys.S390X, sys.Wasm, sys.SW64) + addF("math/bits", "OnesCount32", + makeOnesCountAMD64(ssa.OpPopCount32), + sys.AMD64) +@@ -1148,7 +1148,7 @@ func initIntrinsics(cfg *intrinsicBuildConfig) { + func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { + return s.newValue1(ssa.OpPopCount32, types.Types[types.TINT], args[0]) + }, +- sys.PPC64, sys.ARM64, sys.S390X, sys.Wasm) ++ sys.PPC64, sys.ARM64, sys.S390X, sys.Wasm, sys.SW64) + addF("math/bits", "OnesCount16", + makeOnesCountAMD64(ssa.OpPopCount16), + sys.AMD64) +@@ -1159,12 +1159,12 @@ func initIntrinsics(cfg *intrinsicBuildConfig) { + func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { + return s.newValue1(ssa.OpPopCount16, types.Types[types.TINT], args[0]) + }, +- sys.ARM64, sys.S390X, sys.PPC64, sys.Wasm) ++ sys.ARM64, sys.S390X, sys.PPC64, sys.Wasm, sys.SW64) + addF("math/bits", "OnesCount8", + func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { + return s.newValue1(ssa.OpPopCount8, types.Types[types.TINT], args[0]) + }, +- sys.S390X, sys.PPC64, sys.Wasm) ++ sys.S390X, sys.PPC64, sys.Wasm, sys.SW64) + addF("math/bits", "OnesCount", + makeOnesCountAMD64(ssa.OpPopCount64), + sys.AMD64) +diff --git a/src/cmd/compile/internal/ssagen/intrinsics_test.go b/src/cmd/compile/internal/ssagen/intrinsics_test.go +index 2e29a45c0b..3eadd93c6b 100644 +--- a/src/cmd/compile/internal/ssagen/intrinsics_test.go ++++ b/src/cmd/compile/internal/ssagen/intrinsics_test.go +@@ -1300,6 +1300,93 @@ var wantIntrinsics = map[testIntrinsicKey]struct{}{ + {"wasm", "math/bits", "TrailingZeros8"}: struct{}{}, + {"wasm", "runtime", "KeepAlive"}: struct{}{}, + {"wasm", "runtime", "slicebytetostringtmp"}: struct{}{}, ++ {"sw64", "internal/runtime/atomic", "Cas"}: struct{}{}, ++ {"sw64", "internal/runtime/atomic", "Cas64"}: struct{}{}, ++ {"sw64", "internal/runtime/atomic", "Casint32"}: struct{}{}, ++ {"sw64", "internal/runtime/atomic", "Casint64"}: struct{}{}, ++ {"sw64", "internal/runtime/atomic", "Casp1"}: struct{}{}, ++ {"sw64", "internal/runtime/atomic", "CasRel"}: struct{}{}, ++ {"sw64", "internal/runtime/atomic", "Casuintptr"}: struct{}{}, ++ {"sw64", "internal/runtime/atomic", "Load"}: struct{}{}, ++ {"sw64", "internal/runtime/atomic", "Load8"}: struct{}{}, ++ {"sw64", "internal/runtime/atomic", "Load64"}: struct{}{}, ++ {"sw64", "internal/runtime/atomic", "Loadint32"}: struct{}{}, ++ {"sw64", "internal/runtime/atomic", "Loadint64"}: struct{}{}, ++ {"sw64", "internal/runtime/atomic", "Loadp"}: struct{}{}, ++ {"sw64", "internal/runtime/atomic", "Loaduint"}: struct{}{}, ++ {"sw64", "internal/runtime/atomic", "Loaduintptr"}: struct{}{}, ++ {"sw64", "internal/runtime/atomic", "LoadAcq"}: struct{}{}, ++ {"sw64", "internal/runtime/atomic", "LoadAcq64"}: struct{}{}, ++ {"sw64", "internal/runtime/atomic", "LoadAcquintptr"}: struct{}{}, ++ {"sw64", "internal/runtime/atomic", "Store"}: struct{}{}, ++ {"sw64", "internal/runtime/atomic", "Store8"}: struct{}{}, ++ {"sw64", "internal/runtime/atomic", "Store64"}: struct{}{}, ++ {"sw64", "internal/runtime/atomic", "Storeint32"}: struct{}{}, ++ {"sw64", "internal/runtime/atomic", "Storeint64"}: struct{}{}, ++ {"sw64", "internal/runtime/atomic", "Storeuintptr"}: struct{}{}, ++ {"sw64", "internal/runtime/atomic", "StorepNoWB"}: struct{}{}, ++ {"sw64", "internal/runtime/atomic", "StoreRel"}: struct{}{}, ++ {"sw64", "internal/runtime/atomic", "StoreRel64"}: struct{}{}, ++ {"sw64", "internal/runtime/atomic", "StoreReluintptr"}: struct{}{}, ++ {"sw64", "internal/runtime/atomic", "Xadd"}: struct{}{}, ++ {"sw64", "internal/runtime/atomic", "Xadd64"}: struct{}{}, ++ {"sw64", "internal/runtime/atomic", "Xaddint32"}: struct{}{}, ++ {"sw64", "internal/runtime/atomic", "Xaddint64"}: struct{}{}, ++ {"sw64", "internal/runtime/atomic", "Xadduintptr"}: struct{}{}, ++ {"sw64", "internal/runtime/atomic", "Xchg"}: struct{}{}, ++ {"sw64", "internal/runtime/atomic", "Xchg64"}: struct{}{}, ++ {"sw64", "internal/runtime/atomic", "Xchgint32"}: struct{}{}, ++ {"sw64", "internal/runtime/atomic", "Xchgint64"}: struct{}{}, ++ {"sw64", "internal/runtime/atomic", "Xchguintptr"}: struct{}{}, ++ {"sw64", "internal/runtime/sys", "GetCallerSP"}: struct{}{}, ++ {"sw64", "internal/runtime/sys", "GetCallerPC"}: struct{}{}, ++ {"sw64", "internal/runtime/sys", "GetClosurePtr"}: struct{}{}, ++ {"sw64", "internal/runtime/sys", "OnesCount64"}: struct{}{}, ++ {"sw64", "internal/runtime/sys", "TrailingZeros8"}: struct{}{}, ++ {"sw64", "internal/runtime/sys", "TrailingZeros32"}: struct{}{}, ++ {"sw64", "internal/runtime/sys", "TrailingZeros64"}: struct{}{}, ++ {"sw64", "math", "Abs"}: struct{}{}, ++ {"sw64", "math", "Copysign"}: struct{}{}, ++ {"sw64", "math", "sqrt"}: struct{}{}, ++ {"sw64", "math/bits", "OnesCount8"}: struct{}{}, ++ {"sw64", "math/bits", "OnesCount16"}: struct{}{}, ++ {"sw64", "math/bits", "OnesCount32"}: struct{}{}, ++ {"sw64", "math/bits", "OnesCount64"}: struct{}{}, ++ {"sw64", "math/bits", "TrailingZeros16"}: struct{}{}, ++ {"sw64", "math/bits", "TrailingZeros32"}: struct{}{}, ++ {"sw64", "math/bits", "TrailingZeros64"}: struct{}{}, ++ {"sw64", "math/bits", "TrailingZeros8"}: struct{}{}, ++ {"sw64", "runtime", "KeepAlive"}: struct{}{}, ++ {"sw64", "runtime", "slicebytetostringtmp"}: struct{}{}, ++ {"sw64", "sync/atomic", "AddInt32"}: struct{}{}, ++ {"sw64", "sync/atomic", "AddInt64"}: struct{}{}, ++ {"sw64", "sync/atomic", "AddUint32"}: struct{}{}, ++ {"sw64", "sync/atomic", "AddUint64"}: struct{}{}, ++ {"sw64", "sync/atomic", "AddUintptr"}: struct{}{}, ++ {"sw64", "sync/atomic", "CompareAndSwapInt32"}: struct{}{}, ++ {"sw64", "sync/atomic", "CompareAndSwapInt64"}: struct{}{}, ++ {"sw64", "sync/atomic", "CompareAndSwapUint32"}: struct{}{}, ++ {"sw64", "sync/atomic", "CompareAndSwapUint64"}: struct{}{}, ++ {"sw64", "sync/atomic", "CompareAndSwapUintptr"}: struct{}{}, ++ {"sw64", "sync/atomic", "LoadInt32"}: struct{}{}, ++ {"sw64", "sync/atomic", "LoadInt64"}: struct{}{}, ++ {"sw64", "sync/atomic", "LoadPointer"}: struct{}{}, ++ {"sw64", "sync/atomic", "LoadUint32"}: struct{}{}, ++ {"sw64", "sync/atomic", "LoadUint64"}: struct{}{}, ++ {"sw64", "sync/atomic", "LoadUintptr"}: struct{}{}, ++ {"sw64", "sync/atomic", "StoreInt32"}: struct{}{}, ++ {"sw64", "sync/atomic", "StoreInt64"}: struct{}{}, ++ {"sw64", "sync/atomic", "StoreUint32"}: struct{}{}, ++ {"sw64", "sync/atomic", "StoreUint64"}: struct{}{}, ++ {"sw64", "sync/atomic", "StoreUintptr"}: struct{}{}, ++ {"sw64", "sync/atomic", "SwapInt32"}: struct{}{}, ++ {"sw64", "sync/atomic", "SwapInt64"}: struct{}{}, ++ {"sw64", "sync/atomic", "SwapUint32"}: struct{}{}, ++ {"sw64", "sync/atomic", "SwapUint64"}: struct{}{}, ++ {"sw64", "sync/atomic", "SwapUintptr"}: struct{}{}, ++ {"sw64", "sync", "runtime_LoadAcquintptr"}: struct{}{}, ++ {"sw64", "sync", "runtime_StoreReluintptr"}: struct{}{}, ++ + } + + func TestIntrinsics(t *testing.T) { +diff --git a/src/cmd/compile/internal/ssagen/ssa.go b/src/cmd/compile/internal/ssagen/ssa.go +index edd1ffb0c9..38e2d60b0c 100644 +--- a/src/cmd/compile/internal/ssagen/ssa.go ++++ b/src/cmd/compile/internal/ssagen/ssa.go +@@ -7201,7 +7201,7 @@ func (s *State) Call(v *ssa.Value) *obj.Prog { + switch Arch.LinkArch.Family { + case sys.AMD64, sys.I386, sys.PPC64, sys.RISCV64, sys.S390X, sys.Wasm: + p.To.Type = obj.TYPE_REG +- case sys.ARM, sys.ARM64, sys.Loong64, sys.MIPS, sys.MIPS64: ++ case sys.ARM, sys.ARM64, sys.Loong64, sys.MIPS, sys.MIPS64, sys.SW64: + p.To.Type = obj.TYPE_MEM + default: + base.Fatalf("unknown indirect call family") +diff --git a/src/cmd/compile/internal/sw64/galign.go b/src/cmd/compile/internal/sw64/galign.go +new file mode 100644 +index 0000000000..853a5c45f9 +--- /dev/null ++++ b/src/cmd/compile/internal/sw64/galign.go +@@ -0,0 +1,28 @@ ++// 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 sw64 ++ ++import ( ++ "cmd/compile/internal/ssa" ++ "cmd/compile/internal/ssagen" ++ "cmd/internal/obj/sw64" ++) ++ ++func Init(arch *ssagen.ArchInfo) { ++ arch.LinkArch = &sw64.LinkSW64 ++ arch.REGSP = sw64.REGSP ++ arch.MAXWIDTH = 1 << 50 ++ ++ arch.ZeroRange = zerorange ++ //arch.ZeroAuto = zeroAuto //zxw new change ++ arch.Ginsnop = ginsnop ++ //arch.Ginsnopdefer = ginsnop //zxw new add ++ ++ arch.SSAMarkMoves = func(s *ssagen.State, b *ssa.Block) {} ++ arch.SSAGenValue = ssaGenValue ++ arch.SSAGenBlock = ssaGenBlock ++ arch.LoadRegResult = loadRegResult ++ arch.SpillArgReg = spillArgReg ++} +diff --git a/src/cmd/compile/internal/sw64/ggen.go b/src/cmd/compile/internal/sw64/ggen.go +new file mode 100644 +index 0000000000..d659601797 +--- /dev/null ++++ b/src/cmd/compile/internal/sw64/ggen.go +@@ -0,0 +1,33 @@ ++// 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 sw64 ++ ++import ( ++ "cmd/compile/internal/objw" ++ "cmd/compile/internal/types" ++ "cmd/internal/obj" ++ "cmd/internal/obj/sw64" ++) ++ ++func zerorange(pp *objw.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog { ++ base := p.Ctxt.Arch.FixedFrameSize + off ++ for i := int64(0); i < cnt; i += int64(types.PtrSize) { ++ // STL ZERO, FixedFrameSize+off+i(SP) ++ p = pp.Append(p, sw64.ASTL, obj.TYPE_REG, sw64.REGZERO, 0, obj.TYPE_MEM, sw64.REGSP, base+i) ++ } ++ ++ return p ++} ++ ++//zxw new change ++func ginsnop(pp *objw.Progs) *obj.Prog { ++ p := pp.Prog(sw64.ALDI) ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = sw64.REG_R31 ++ ++ p.To.Type = obj.TYPE_CONST ++ p.To.Offset = 0 ++ return p ++} +diff --git a/src/cmd/compile/internal/sw64/ssa.go b/src/cmd/compile/internal/sw64/ssa.go +new file mode 100644 +index 0000000000..33a59f4e6a +--- /dev/null ++++ b/src/cmd/compile/internal/sw64/ssa.go +@@ -0,0 +1,1140 @@ ++// 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 sw64 ++ ++import ( ++ "cmd/compile/internal/base" ++ "cmd/compile/internal/ir" ++ "cmd/compile/internal/logopt" ++ "cmd/compile/internal/objw" ++ "cmd/compile/internal/ssa" ++ "cmd/compile/internal/ssagen" ++ "cmd/compile/internal/types" ++ "cmd/internal/obj" ++ "cmd/internal/obj/sw64" ++ "math" ++) ++ ++// isFPreg returns whether r is an FP register ++func isFPreg(r int16) bool { ++ return sw64.REG_F0 <= r && r <= sw64.REG_F31 ++} ++ ++func loadByType(t *types.Type, r int16) obj.As { ++ if sw64.IsFReg(int(r)) { ++ if t.Size() == 4 { ++ return sw64.AFLDS ++ } ++ if t.Size() == 8 { ++ return sw64.AFLDD ++ } ++ panic("bad load type") ++ } ++ switch t.Size() { ++ case 1: ++ return sw64.ALDBU ++ case 2: ++ return sw64.ALDHU ++ case 4: ++ return sw64.ALDW ++ case 8: ++ return sw64.ALDL ++ } ++ panic("bad load type") ++} ++ ++func storeByType(t *types.Type, r int16) obj.As { ++ if sw64.IsFReg(int(r)) { ++ if t.Size() == 4 { ++ return sw64.AFSTS ++ } ++ if t.Size() == 8 { ++ return sw64.AFSTD ++ } ++ panic("bad store type") ++ } ++ ++ switch t.Size() { ++ case 1: ++ return sw64.ASTB ++ case 2: ++ return sw64.ASTH ++ case 4: ++ return sw64.ASTW ++ case 8: ++ return sw64.ASTL ++ } ++ panic("bad store type") ++} ++ ++func ssaGenValue(s *ssagen.State, v *ssa.Value) { ++ switch v.Op { ++ case ssa.OpLoadReg: ++ r := v.Reg() ++ p := s.Prog(loadByType(v.Type, r)) ++ ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = r ++ ++ ssagen.AddrAuto(&p.To, v.Args[0]) ++ case ssa.OpStoreReg: ++ r := v.Args[0].Reg() ++ p := s.Prog(storeByType(v.Type, r)) ++ ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = r ++ ++ ssagen.AddrAuto(&p.To, v) ++ case ssa.OpArgIntReg, ssa.OpArgFloatReg: ++ // The assembler needs to wrap the entry safepoint/stack growth code with spill/unspill ++ // The loop only runs once. ++ for _, a := range v.Block.Func.RegArgs { ++ // Pass the spill/unspill information along to the assembler, offset by size of ++ // the saved LR slot. ++ addr := ssagen.SpillSlotAddr(a, sw64.REGSP, base.Ctxt.Arch.FixedFrameSize) ++ s.FuncInfo().AddSpill( ++ obj.RegSpill{Reg: a.Reg, Addr: addr, Unspill: loadByType(a.Type, a.Reg), Spill: storeByType(a.Type, a.Reg)}) ++ } ++ v.Block.Func.RegArgs = nil ++ ssagen.CheckArgReg(v) ++ case ssa.OpSW64CALLstatic: ++ s.Call(v) ++ case ssa.OpSW64CALLclosure, ssa.OpSW64CALLinter: ++ _, ok := v.Aux.(*obj.LSym) ++ if !ok && v.Args[0].Reg() != sw64.REG_R27 { ++ // TODO(snyh): remove this if we can restrict ACALL use R27 in ssa ++ p := s.Prog(sw64.ALDI) ++ p.From = obj.Addr{Type: obj.TYPE_REG, Reg: sw64.REG_R27} ++ p.To = obj.Addr{Type: obj.TYPE_ADDR, Reg: v.Args[0].Reg()} ++ } ++ s.Call(v) ++ case ssa.OpSW64CALLtail: ++ s.TailCall(v) ++ case ssa.OpSW64LoweredWB: ++ p := s.Prog(obj.ACALL) ++ p.To.Type = obj.TYPE_MEM ++ p.To.Name = obj.NAME_EXTERN ++ // AuxInt encodes how many buffer entries we need. ++ p.To.Sym = ir.Syms.GCWriteBarrier[v.AuxInt-1] ++ case ssa.OpSW64MOVVnop: ++ // nothing to do ++ case ssa.OpSW64FCVTSD, ++ ssa.OpSW64FCVTDS, ++ ssa.OpSW64IFMOVD, ++ ssa.OpSW64IFMOVS, ++ ssa.OpSW64FIMOVD, ++ ssa.OpSW64FIMOVS, ++ ssa.OpSW64FCVTDL, ++ ssa.OpSW64FCVTLS, ++ ssa.OpSW64FCVTLD, ++ ssa.OpSW64FCVTLW, ++ ssa.OpSW64FCVTWL, ++ ssa.OpSW64FSQRTS, ++ ssa.OpSW64FSQRTD, ++ ssa.OpSW64CTLZ, ++ ssa.OpSW64CTTZ, ++ ssa.OpSW64CTPOP, ++ ssa.OpSW64SEXTB, ++ ssa.OpSW64SEXTH, ++ ssa.OpSW64FCVTDL_Z, ++ ssa.OpSW64FCVTDL_P, ++ ssa.OpSW64FCVTDL_G, ++ ssa.OpSW64FCVTDL_N, ++ ssa.OpSW64MOVBreg, ++ ssa.OpSW64MOVBUreg, ++ ssa.OpSW64MOVHreg, ++ ssa.OpSW64MOVHUreg, ++ ssa.OpSW64MOVWreg, ++ ssa.OpSW64MOVWUreg, ++ ssa.OpSW64MOVVreg: ++ p := s.Prog(v.Op.Asm()) ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = v.Args[0].Reg() ++ p.To.Type = obj.TYPE_REG ++ p.To.Reg = v.Reg() ++ case ssa.OpSW64SEXTBconst, ++ ssa.OpSW64SEXTHconst: ++ p := s.Prog(v.Op.Asm()) ++ p.From.Type = obj.TYPE_CONST ++ p.From.Offset = v.AuxInt ++ p.To.Type = obj.TYPE_REG ++ p.To.Reg = v.Reg() ++ case ssa.OpSW64FADDS, ++ ssa.OpSW64FADDD, ++ ssa.OpSW64FSUBD, ++ ssa.OpSW64FSUBS, ++ ssa.OpSW64FMULS, ++ ssa.OpSW64FMULD, ++ ssa.OpSW64FDIVS, ++ ssa.OpSW64FDIVD, ++ ssa.OpSW64FCPYS, ++ ssa.OpSW64ADDV, ++ ssa.OpSW64ADDW, ++ ssa.OpSW64S4ADDV, ++ ssa.OpSW64S8ADDV, ++ ssa.OpSW64SUBV, ++ ssa.OpSW64S4SUBV, ++ ssa.OpSW64S8SUBV, ++ ssa.OpSW64MULW, ++ ssa.OpSW64MULL, ++ ssa.OpSW64UMULH, ++ ssa.OpSW64AND, ++ ssa.OpSW64BIS, ++ ssa.OpSW64XOR, ++ ssa.OpSW64ORNOT, ++ ssa.OpSW64SLL, ++ ssa.OpSW64SRL, ++ ssa.OpSW64SRA: ++ p := s.Prog(v.Op.Asm()) ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = v.Args[0].Reg() ++ p.AddRestSource(obj.Addr{ ++ Type: obj.TYPE_REG, ++ Reg: v.Args[1].Reg(), ++ }) ++ p.To.Type = obj.TYPE_REG ++ p.To.Reg = v.Reg() ++ ++ case ssa.OpSW64DIVV, ++ ssa.OpSW64UDIVV, ++ ssa.OpSW64DIVW, ++ ssa.OpSW64UDIVW: ++ // z := sdiv intXX, x , y ++ // will fault on division with -1, fix it ++ //x := v.Args[1].Reg() ++ ++ var j *obj.Prog ++ if v.Op == ssa.OpSW64DIVV || v.Op == ssa.OpSW64DIVW { ++ if ssa.DivisionNeedsFixUp(v) { ++ var c *obj.Prog ++ l := s.Prog(sw64.ALDI) ++ l.From.Type = obj.TYPE_REG ++ l.From.Reg = sw64.REGTMP ++ l.To.Type = obj.TYPE_CONST ++ l.To.Offset = -1 ++ ++ c = s.Prog(sw64.ACMPEQ) ++ j = s.Prog(sw64.ABNE) ++ ++ c.From.Type = obj.TYPE_REG ++ c.From.Reg = sw64.REGTMP ++ c.To.Type = obj.TYPE_REG ++ c.To.Reg = sw64.REGTMP ++ c.AddRestSource(obj.Addr{ ++ Type: obj.TYPE_REG, ++ Reg: v.Args[1].Reg(), ++ }) ++ ++ j.From.Type = obj.TYPE_REG ++ j.From.Reg = sw64.REGTMP ++ j.To.Type = obj.TYPE_BRANCH ++ } ++ } ++ ++ var j2 *obj.Prog ++ var n *obj.Prog ++ ++ p := s.Prog(v.Op.Asm()) ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = v.Args[0].Reg() ++ p.AddRestSource(obj.Addr{ ++ Type: obj.TYPE_REG, ++ Reg: v.Args[1].Reg(), ++ }) ++ p.To.Type = obj.TYPE_REG ++ p.To.Reg = v.Reg() ++ ++ if j != nil { ++ j2 = s.Prog(sw64.ABR) ++ j2.From.Type = obj.TYPE_REG ++ j2.From.Reg = sw64.REG_R31 ++ j2.To.Type = obj.TYPE_BRANCH ++ ++ if v.Op == ssa.OpSW64DIVV || v.Op == ssa.OpSW64DIVW { ++ // n / -1 = -n ++ n = s.Prog(sw64.ASUBL) ++ n.From.Type = obj.TYPE_REG ++ n.From.Reg = sw64.REG_R31 ++ n.AddRestSource(obj.Addr{ ++ Type: obj.TYPE_REG, ++ Reg: v.Args[0].Reg(), ++ }) ++ ++ n.To.Type = obj.TYPE_REG ++ n.To.Reg = v.Reg() ++ } ++ // j3 = s.Prog(sw64.ABR) ++ // j3.From.Type = obj.TYPE_REG ++ // j3.From.Reg = sw64.REG_R31 ++ // j3.To.Type = obj.TYPE_BRANCH ++ ++ // if n != nil { ++ j.To.SetTarget(n) ++ j2.To.SetTarget(s.Pc()) ++ // } ++ } ++ ++ // if j2 != nil { ++ //j3.To.SetTarget(s.Pc()) ++ // } ++ ++ case ssa.OpSW64FABS: ++ p := s.Prog(v.Op.Asm()) ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = sw64.REG_F31 ++ p.AddRestSource(obj.Addr{ ++ Type: obj.TYPE_REG, ++ Reg: v.Args[0].Reg(), ++ }) ++ p.To.Type = obj.TYPE_REG ++ p.To.Reg = v.Reg() ++ ++ case ssa.OpSW64CALLudiv: ++ p := s.Prog(obj.ACALL) ++ p.To.Type = obj.TYPE_MEM ++ p.To.Name = obj.NAME_EXTERN ++ p.To.Sym = ir.Syms.Udiv ++ case ssa.OpSW64ADDVconst, ++ ssa.OpSW64ADDWconst, ++ ssa.OpSW64SUBVconst, ++ ssa.OpSW64MULWconst, ++ ssa.OpSW64MULLconst, ++ ssa.OpSW64UMULHconst, ++ ssa.OpSW64DIVVconst, ++ ssa.OpSW64ANDconst, ++ ssa.OpSW64BISconst, ++ ssa.OpSW64XORconst, ++ ssa.OpSW64ORNOTconst, ++ ssa.OpSW64SLLconst, ++ ssa.OpSW64SRLconst, ++ ssa.OpSW64SRAconst, ++ ssa.OpSW64CMPLEconst, ++ ssa.OpSW64CMPLTconst, ++ ssa.OpSW64CMPEQconst, ++ ssa.OpSW64CMPULEconst, ++ ssa.OpSW64CMPULTconst, ++ ssa.OpSW64ZAPNOTconst: ++ p := s.Prog(v.Op.Asm()) ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = v.Args[0].Reg() ++ ib := obj.Addr{ ++ Type: obj.TYPE_CONST, ++ Offset: v.AuxInt, ++ } ++ p.AddRestSource(ib) ++ p.To.Type = obj.TYPE_REG ++ p.To.Reg = v.Reg() ++ case ssa.OpSW64NEGV: ++ // SUB from REGZERO ++ p := s.Prog(v.Op.Asm()) ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = sw64.REGZERO ++ p.AddRestSource(obj.Addr{ ++ Type: obj.TYPE_REG, ++ Reg: v.Args[0].Reg(), ++ }) ++ p.To.Type = obj.TYPE_REG ++ p.To.Reg = v.Reg() ++ case ssa.OpSW64NEGF, ++ ssa.OpSW64NEGD: ++ //FCPYSN Fx,Fx,Fy ++ p := s.Prog(v.Op.Asm()) ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = v.Args[0].Reg() ++ p.AddRestSource(obj.Addr{ ++ Type: obj.TYPE_REG, ++ Reg: v.Args[0].Reg(), ++ }) ++ p.To.Type = obj.TYPE_REG ++ p.To.Reg = v.Reg() ++ case ssa.OpSW64MOVBstorezero, ++ ssa.OpSW64MOVHstorezero, ++ ssa.OpSW64MOVWstorezero, ++ ssa.OpSW64MOVVstorezero: ++ p := s.Prog(v.Op.Asm()) ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = sw64.REGZERO ++ p.To.Type = obj.TYPE_MEM ++ p.To.Reg = v.Args[0].Reg() ++ ssagen.AddAux(&p.To, v) ++ case ssa.OpSW64MOVBstore, ++ ssa.OpSW64MOVHstore, ++ ssa.OpSW64MOVWstore, ++ ssa.OpSW64MOVVstore, ++ ssa.OpSW64MOVFstore, ++ ssa.OpSW64MOVDstore: ++ p := s.Prog(v.Op.Asm()) ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = v.Args[1].Reg() ++ p.To.Type = obj.TYPE_MEM ++ p.To.Reg = v.Args[0].Reg() ++ ssagen.AddAux(&p.To, v) ++ case ssa.OpSW64MOVBload, ++ ssa.OpSW64MOVBUload, ++ ssa.OpSW64MOVHload, ++ ssa.OpSW64MOVHUload, ++ ssa.OpSW64MOVWload, ++ ssa.OpSW64MOVWUload, ++ ssa.OpSW64MOVVload, ++ ssa.OpSW64MOVFload, ++ ssa.OpSW64MOVDload: ++ p := s.Prog(v.Op.Asm()) ++ p.To.Type = obj.TYPE_MEM ++ p.To.Reg = v.Args[0].Reg() ++ ssagen.AddAux(&p.To, v) ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = v.Reg() ++ ++ case ssa.OpSW64SYMADDR: ++ // arg0 + auxInt + aux.(*gc.Sym), arg0=SP/SB ++ p := s.Prog(sw64.ASYMADDR) ++ p.To.Type = obj.TYPE_ADDR ++ p.To.Reg = v.Args[0].Reg() ++ var wantreg string ++ // LDL R, $sym+off(base) ++ // the assembler expands it as the following: ++ // - base is SP: add constant offset to SP ++ // when constant is large, tmp registe may be used ++ // - base is SB: load external address with relocation ++ switch v.Aux.(type) { ++ default: ++ v.Fatalf("aux is of unknown type %T", v.Aux) ++ case *obj.LSym: ++ wantreg = "SB" ++ ssagen.AddAux(&p.To, v) ++ case *ir.Name: ++ // TODO: can ir change Node interface ? ++ p.As = sw64.ALDI ++ wantreg = "SP" ++ ssagen.AddAux(&p.To, v) ++ case nil: ++ p.As = sw64.ALDI ++ // No sym, just LDL R, $off(SP) ++ wantreg = "SP" ++ p.To.Offset = v.AuxInt ++ } ++ if reg := v.Args[0].RegName(); reg != wantreg { ++ v.Fatalf("bad reg %s for symbol type %T, want %s", reg, v.Aux, wantreg) ++ } ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = v.Reg() ++ ++ case ssa.OpCopy, ssa.OpSW64MOVVconvert: ++ if v.Type.IsMemory() { ++ return ++ } ++ x := int(v.Args[0].Reg()) ++ y := int(v.Reg()) ++ if x == y { ++ return ++ } ++ var as obj.As ++ switch { ++ case sw64.IsFReg(x) && sw64.IsRReg(y) && v.Type.Size() == 4: ++ as = sw64.AFIMOVS ++ case sw64.IsFReg(x) && sw64.IsRReg(y) && v.Type.Size() == 8: ++ as = sw64.AFIMOVD ++ case sw64.IsRReg(x) && sw64.IsFReg(y) && v.Type.Size() == 4: ++ as = sw64.AIFMOVS ++ case sw64.IsRReg(x) && sw64.IsFReg(y) && v.Type.Size() == 8: ++ as = sw64.AIFMOVD ++ case sw64.IsRReg(x) && sw64.IsRReg(y): ++ as = sw64.ALDI ++ x, y = y, x ++ case sw64.IsFReg(x) && sw64.IsFReg(y): ++ as = sw64.AFCPYS ++ default: ++ v.Fatalf("not implement OpCopy with %v and %v. %s\n", ++ x&63, y&63, ++ v.LongString()) ++ } ++ p := s.Prog(as) ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = int16(x) ++ if as == sw64.AFCPYS { ++ p.AddRestSource(obj.Addr{ ++ Type: obj.TYPE_REG, ++ Reg: int16(x), ++ }) ++ } ++ p.To.Type = obj.TYPE_REG ++ p.To.Reg = int16(y) ++ case ssa.OpSW64MOVFconst, ++ ssa.OpSW64MOVDconst: ++ p := s.Prog(v.Op.Asm()) ++ p.To.Type = obj.TYPE_FCONST ++ p.To.Val = math.Float64frombits(uint64(v.AuxInt)) ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = v.Reg() ++ case ssa.OpSW64CMPEQ, ssa.OpSW64CMPLE, ssa.OpSW64CMPLT, ++ ssa.OpSW64CMPULE, ssa.OpSW64CMPULT, ssa.OpSW64FCMPUN, ++ ssa.OpSW64FCMPEQ, ssa.OpSW64FCMPLE, ssa.OpSW64FCMPLT: ++ p := s.Prog(v.Op.Asm()) ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = v.Args[0].Reg() ++ p.AddRestSource(obj.Addr{ ++ Type: obj.TYPE_REG, ++ Reg: v.Args[1].Reg(), ++ }) ++ p.To.Type = obj.TYPE_REG ++ p.To.Reg = v.Reg() ++ case ssa.OpSW64MOVVconst: ++ r := v.Reg() ++ p := s.Prog(v.Op.Asm()) ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = r ++ p.To.Type = obj.TYPE_CONST ++ p.To.Offset = v.AuxInt ++ if isFPreg(r) { ++ // cannot move into FP registers, use TMP as intermediate ++ p.From.Reg = sw64.REGTMP ++ p = s.Prog(sw64.AIFMOVD) ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = sw64.REGTMP ++ p.To.Type = obj.TYPE_REG ++ p.To.Reg = r ++ } ++ ++ case ssa.OpSW64LoweredNilCheck: ++ // Issue a load which will fault if arg is nil. ++ p := s.Prog(sw64.ALDBU) ++ p.To.Type = obj.TYPE_MEM ++ p.To.Reg = v.Args[0].Reg() ++ ssagen.AddAux(&p.To, v) ++ ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = sw64.REGTMP ++ if logopt.Enabled() { ++ logopt.LogOpt(v.Pos, "nilcheck", "genssa", v.Block.Func.Name) ++ } ++ ++ if base.Debug.Nil != 0 && v.Pos.Line() > 1 { // v.Pos.Line()==1 in generated wrappers ++ base.WarnfAt(v.Pos, "generated nil check") ++ } ++ case ssa.OpSW64DUFFZERO: ++ // runtime.duffzero expects start address - 8 in R1 ++ ++ //SUBL arg0.REG, $8, R1 ++ p := s.Prog(sw64.ASUBL) ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = v.Args[0].Reg() ++ p.AddRestSource(obj.Addr{ ++ Type: obj.TYPE_CONST, ++ Offset: 8, ++ }) ++ p.To.Type = obj.TYPE_REG ++ p.To.Reg = sw64.REG_R1 ++ // DUFFZERO runtime.duffzero+v.AuxInt(SB) ++ p = s.Prog(obj.ADUFFZERO) ++ p.To.Type = obj.TYPE_MEM ++ p.To.Name = obj.NAME_EXTERN ++ p.To.Sym = ir.Syms.Duffzero ++ p.To.Offset = v.AuxInt ++ case ssa.OpSW64LoweredZero: ++ //SUBL R1, $sz ,R1 ++ //STx R31,sz(R1) ++ //ADDL R1, $sz, R1 ++ //CMPULT R1, Rarg1, REGTMP ++ //BNE REGTMP, -3(PC) ++ var sz int64 ++ var mov obj.As ++ switch { ++ case v.AuxInt%8 == 0: ++ sz = 8 ++ mov = sw64.ASTL ++ case v.AuxInt%4 == 0: ++ sz = 4 ++ mov = sw64.ASTW ++ case v.AuxInt%2 == 0: ++ sz = 2 ++ mov = sw64.ASTH ++ default: ++ sz = 1 ++ mov = sw64.ASTB ++ } ++ //SUBL R1, $sz ,R1 ++ p := s.Prog(sw64.ASUBL) ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = sw64.REG_R1 ++ p.AddRestSource(obj.Addr{ ++ Type: obj.TYPE_CONST, ++ Offset: sz, ++ }) ++ p.To.Type = obj.TYPE_REG ++ p.To.Reg = sw64.REG_R1 ++ //STx R31, sz(R1) ++ p2 := s.Prog(mov) ++ p2.From.Type = obj.TYPE_REG ++ p2.From.Reg = sw64.REGZERO ++ p2.To.Type = obj.TYPE_MEM ++ p2.To.Reg = sw64.REG_R1 ++ p2.To.Offset = sz ++ //ADDL R1, $sz, R1 ++ p3 := s.Prog(sw64.AADDL) ++ p3.From.Type = obj.TYPE_REG ++ p3.From.Reg = sw64.REG_R1 ++ p3.AddRestSource(obj.Addr{ ++ Type: obj.TYPE_CONST, ++ Offset: sz, ++ }) ++ p3.To.Type = obj.TYPE_REG ++ p3.To.Reg = sw64.REG_R1 ++ //CMPULT R1, Rarg1, REGTMP ++ p4 := s.Prog(sw64.ACMPULT) ++ p4.From.Type = obj.TYPE_REG ++ p4.From.Reg = sw64.REG_R1 ++ p4.AddRestSource(obj.Addr{ ++ Type: obj.TYPE_REG, ++ Reg: v.Args[1].Reg(), ++ }) ++ p4.To.Type = obj.TYPE_REG ++ p4.To.Reg = sw64.REGTMP ++ //BNE RGETMP, -3(PC) ++ p5 := s.Prog(sw64.ABNE) ++ p5.From.Type = obj.TYPE_REG ++ p5.From.Reg = sw64.REGTMP ++ p5.To.Type = obj.TYPE_BRANCH ++ p5.To.SetTarget(p2) ++ case ssa.OpSW64LoweredMove: ++ //SUBL R1, $8, R1 ++ //LDx Rtmp, 8(R1) ++ //STx Rtmp, (R2) ++ //ADDL R1, $8, R1 ++ //ADDL R2, $8, R2 ++ //CMPULT R1, Rarg2, Rtmp ++ //BNE Rtmp, -5(PC) ++ var sz int64 ++ var ldx obj.As ++ var stx obj.As ++ switch { ++ case v.AuxInt%8 == 0: ++ sz = 8 ++ ldx = sw64.ALDL ++ stx = sw64.ASTL ++ case v.AuxInt%4 == 0: ++ sz = 4 ++ ldx = sw64.ALDW ++ stx = sw64.ASTW ++ case v.AuxInt%2 == 0: ++ sz = 2 ++ ldx = sw64.ALDHU ++ stx = sw64.ASTH ++ default: ++ sz = 1 ++ ldx = sw64.ALDBU ++ stx = sw64.ASTB ++ } ++ //SUBL R1, $sz, R1 ++ p := s.Prog(sw64.ASUBL) ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = sw64.REG_R1 ++ p.AddRestSource(obj.Addr{ ++ Type: obj.TYPE_CONST, ++ Offset: sz, ++ }) ++ p.To.Type = obj.TYPE_REG ++ p.To.Reg = sw64.REG_R1 ++ //LDL Rtmp, sz(R1) ++ p2 := s.Prog(ldx) ++ p2.From.Type = obj.TYPE_REG ++ p2.From.Reg = sw64.REGTMP ++ p2.To.Offset = sz ++ p2.To.Type = obj.TYPE_MEM ++ p2.To.Reg = sw64.REG_R1 ++ //STL Rtmp, (R2) ++ p3 := s.Prog(stx) ++ p3.From.Type = obj.TYPE_REG ++ p3.From.Reg = sw64.REGTMP ++ p3.To.Type = obj.TYPE_MEM ++ p3.To.Reg = sw64.REG_R2 ++ //ADDL R1, $sz, R1 ++ p4 := s.Prog(sw64.AADDL) ++ p4.From.Type = obj.TYPE_REG ++ p4.From.Reg = sw64.REG_R1 ++ p4.AddRestSource(obj.Addr{ ++ Type: obj.TYPE_CONST, ++ Offset: sz, ++ }) ++ p4.To.Type = obj.TYPE_REG ++ p4.To.Reg = sw64.REG_R1 ++ //ADDL R2, $sz, R2 ++ p5 := s.Prog(sw64.AADDL) ++ p5.From.Type = obj.TYPE_REG ++ p5.From.Reg = sw64.REG_R2 ++ p5.AddRestSource(obj.Addr{ ++ Type: obj.TYPE_CONST, ++ Offset: sz, ++ }) ++ p5.To.Type = obj.TYPE_REG ++ p5.To.Reg = sw64.REG_R2 ++ //CMPULT R1, Rarg2, Rtmp ++ p6 := s.Prog(sw64.ACMPULT) ++ p6.From.Type = obj.TYPE_REG ++ p6.From.Reg = sw64.REG_R1 ++ p6.AddRestSource(obj.Addr{ ++ Type: obj.TYPE_REG, ++ Reg: v.Args[2].Reg(), ++ }) ++ p6.To.Type = obj.TYPE_REG ++ p6.To.Reg = sw64.REGTMP ++ //BNE Rtmp, -5(PC) ++ p7 := s.Prog(sw64.ABNE) ++ p7.From.Type = obj.TYPE_REG ++ p7.From.Reg = sw64.REGTMP ++ p7.To.Type = obj.TYPE_BRANCH ++ p7.To.SetTarget(p2) ++ case ssa.OpSW64LoweredGetClosurePtr: ++ // Closure pointer is R27 (sw64.REGCTXT). ++ ssagen.CheckLoweredGetClosurePtr(v) ++ case ssa.OpSW64LoweredGetCallerSP: ++ // caller's SP is FixedFrameSize below the address of the first arg ++ p := s.Prog(sw64.ALDI) ++ p.To.Type = obj.TYPE_ADDR ++ p.To.Offset = -base.Ctxt.Arch.FixedFrameSize ++ p.To.Name = obj.NAME_PARAM ++ ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = v.Reg() ++ case ssa.OpSW64LoweredGetCallerPC: ++ p := s.Prog(obj.AGETCALLERPC) ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = v.Reg() ++ case ssa.OpSW64FEqual, ++ ssa.OpSW64FNotEqual: ++ as := sw64.ACMPULT ++ if v.Op == ssa.OpSW64FNotEqual { ++ as = sw64.ACMPEQ ++ } ++ p := s.Prog(sw64.AFIMOVD) ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = v.Args[0].Reg() ++ p.To.Type = obj.TYPE_REG ++ p.To.Reg = v.Reg() ++ p1 := s.Prog(as) ++ p1.From.Type = obj.TYPE_REG ++ p1.From.Reg = sw64.REGZERO ++ p1.AddRestSource(obj.Addr{ ++ Type: obj.TYPE_REG, ++ Reg: v.Reg(), ++ }) ++ p1.To.Type = obj.TYPE_REG ++ p1.To.Reg = v.Reg() ++ ++ case ssa.OpSW64LoweredPanicBoundsA, ssa.OpSW64LoweredPanicBoundsB, ssa.OpSW64LoweredPanicBoundsC: ++ p := s.Prog(obj.ACALL) ++ p.To.Type = obj.TYPE_MEM ++ p.To.Name = obj.NAME_EXTERN ++ p.To.Sym = ssagen.BoundsCheckFunc[v.AuxInt] ++ s.UseArgs(16) // space used in callee args area by assembly stubs ++ ++ //zxw new add ++ case ssa.OpSW64LoweredAtomicLoad8, ssa.OpSW64LoweredAtomicLoad32, ssa.OpSW64LoweredAtomicLoad64: ++ as := sw64.ALDL ++ switch v.Op { ++ case ssa.OpSW64LoweredAtomicLoad8: ++ as = sw64.ALDBU ++ case ssa.OpSW64LoweredAtomicLoad32: ++ as = sw64.ALDW ++ } ++ s.Prog(sw64.AMEMB) ++ p := s.Prog(as) ++ p.To.Type = obj.TYPE_MEM ++ p.To.Reg = v.Args[0].Reg() ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = v.Reg0() ++ s.Prog(sw64.AMEMB) ++ case ssa.OpSW64LoweredAtomicStore8, ssa.OpSW64LoweredAtomicStore32, ssa.OpSW64LoweredAtomicStore64: ++ as := sw64.ASTL ++ switch v.Op { ++ case ssa.OpSW64LoweredAtomicStore8: ++ as = sw64.ASTB ++ case ssa.OpSW64LoweredAtomicStore32: ++ as = sw64.ASTW ++ } ++ s.Prog(sw64.AMEMB) ++ p := s.Prog(as) ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = v.Args[1].Reg() ++ p.To.Type = obj.TYPE_MEM ++ p.To.Reg = v.Args[0].Reg() ++ s.Prog(sw64.AMEMB) ++ case ssa.OpSW64LoweredAtomicAdd32, ssa.OpSW64LoweredAtomicAdd64: ++ // MEMB ++ // LLDx Rout, (Rarg0) ++ // LDI Rtmp, 1 ++ // WR_F Rtmp ++ // ADDL Rarg1, Rout, Rtmp ++ // LSTx Rtmp, (Rarg0) ++ // RD_F Rtmp ++ // BEQ Rtmp, -6(PC) ++ // ADDL Rarg1, Rout, Rout ++ // MEMB ++ var sz int64 ++ sz = 1 ++ lldx := sw64.ALLDL ++ lstx := sw64.ALSTL ++ if v.Op == ssa.OpSW64LoweredAtomicAdd32 { ++ lldx = sw64.ALLDW ++ lstx = sw64.ALSTW ++ } ++ s.Prog(sw64.AMEMB) ++ // LLDx Rout, (Rarg0) ++ p := s.Prog(lldx) ++ p.To.Type = obj.TYPE_MEM ++ p.To.Reg = v.Args[0].Reg() ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = v.Reg0() ++ // LDI Rtmp, 1 ++ p1 := s.Prog(sw64.ALDI) ++ p1.From.Type = obj.TYPE_REG ++ p1.From.Reg = sw64.REGTMP ++ p1.To.Type = obj.TYPE_CONST ++ p1.To.Offset = sz ++ // WR_F Rtmp ++ p2 := s.Prog(sw64.AWR_F) ++ p2.From.Type = obj.TYPE_REG ++ p2.From.Reg = sw64.REGTMP ++ // ADDL Rarg1, Rout, Rtmp ++ p3 := s.Prog(sw64.AADDL) ++ p3.From.Type = obj.TYPE_REG ++ p3.From.Reg = v.Args[1].Reg() ++ p3.AddRestSource(obj.Addr{ ++ Type: obj.TYPE_REG, ++ Reg: v.Reg0(), ++ }) ++ p3.To.Type = obj.TYPE_REG ++ p3.To.Reg = sw64.REGTMP ++ // LSTx Rtmp, (Rarg0) ++ p4 := s.Prog(lstx) ++ p4.From.Type = obj.TYPE_REG ++ p4.From.Reg = sw64.REGTMP ++ p4.To.Type = obj.TYPE_MEM ++ p4.To.Reg = v.Args[0].Reg() ++ // RD_F Rtmp ++ p5 := s.Prog(sw64.ARD_F) ++ p5.From.Type = obj.TYPE_REG ++ p5.From.Reg = sw64.REGTMP ++ // BEQ Rtmp, -6(PC) ++ p6 := s.Prog(sw64.ABEQ) ++ p6.From.Type = obj.TYPE_REG ++ p6.From.Reg = sw64.REGTMP ++ p6.To.Type = obj.TYPE_BRANCH ++ p6.To.SetTarget(p) ++ // ADDL Rarg1, Rout, Rout ++ p7 := s.Prog(sw64.AADDL) ++ p7.From.Type = obj.TYPE_REG ++ p7.From.Reg = v.Args[1].Reg() ++ p7.AddRestSource(obj.Addr{ ++ Type: obj.TYPE_REG, ++ Reg: v.Reg0(), ++ }) ++ p7.To.Type = obj.TYPE_REG ++ p7.To.Reg = v.Reg0() ++ s.Prog(sw64.AMEMB) ++ case ssa.OpSW64LoweredAtomicExchange32, ssa.OpSW64LoweredAtomicExchange64: ++ // MEMB ++ // LLDx Rout, (Rarg0) ++ // LDI Rtmp, 1 ++ // WR_F Rtmp ++ // BIS Rarg1, R31, Rtmp ++ // LSTx Rtmp, (Rarg0) ++ // RD_F Rtmp ++ // BEQ Rtmp, -6(PC) ++ // MEMB ++ var sz int64 ++ sz = 1 ++ lldx := sw64.ALLDL ++ lstx := sw64.ALSTL ++ if v.Op == ssa.OpSW64LoweredAtomicExchange32 { ++ lldx = sw64.ALLDW ++ lstx = sw64.ALSTW ++ } ++ s.Prog(sw64.AMEMB) ++ // LLDx Rout, (Rarg0) ++ p := s.Prog(lldx) ++ p.To.Type = obj.TYPE_MEM ++ p.To.Reg = v.Args[0].Reg() ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = v.Reg0() ++ // LDI Rtmp, 1 ++ p1 := s.Prog(sw64.ALDI) ++ p1.From.Type = obj.TYPE_REG ++ p1.From.Reg = sw64.REGTMP ++ p1.To.Type = obj.TYPE_CONST ++ p1.To.Offset = sz ++ // WR_F Rtmp ++ p2 := s.Prog(sw64.AWR_F) ++ p2.From.Type = obj.TYPE_REG ++ p2.From.Reg = sw64.REGTMP ++ // BIS Rarg1, R31, Rtmp ++ p3 := s.Prog(sw64.ABIS) ++ p3.From.Type = obj.TYPE_REG ++ p3.From.Reg = v.Args[1].Reg() ++ p3.AddRestSource(obj.Addr{ ++ Type: obj.TYPE_REG, ++ Reg: sw64.REGZERO, ++ }) ++ p3.To.Type = obj.TYPE_REG ++ p3.To.Reg = sw64.REGTMP ++ // LSTx Rtmp, (Rarg0) ++ p4 := s.Prog(lstx) ++ p4.From.Type = obj.TYPE_REG ++ p4.From.Reg = sw64.REGTMP ++ p4.To.Type = obj.TYPE_MEM ++ p4.To.Reg = v.Args[0].Reg() ++ // RD_F Rtmp ++ p5 := s.Prog(sw64.ARD_F) ++ p5.From.Type = obj.TYPE_REG ++ p5.From.Reg = sw64.REGTMP ++ // BEQ Rtmp, -6(PC) ++ p6 := s.Prog(sw64.ABEQ) ++ p6.From.Type = obj.TYPE_REG ++ p6.From.Reg = sw64.REGTMP ++ p6.To.Type = obj.TYPE_BRANCH ++ p6.To.SetTarget(p) ++ s.Prog(sw64.AMEMB) ++ case ssa.OpSW64LoweredAtomicCas32, ssa.OpSW64LoweredAtomicCas64: ++ // MEMB ++ // LLDx Rout, (Rarg0) ++ // CMPEQ Rout, Rarg1, Rout ++ // WR_F Rout ++ // BIS Rarg2, R31, Rtmp ++ // LSTx Rtmp, (Rarg0) ++ // RD_F Rtmp ++ // BEQ Rout, 2(PC) ++ // BEQ Rtmp, -7(PC) ++ // MEMB ++ lldx := sw64.ALLDL ++ lstx := sw64.ALSTL ++ if v.Op == ssa.OpSW64LoweredAtomicCas32 { ++ lldx = sw64.ALLDW ++ lstx = sw64.ALSTW ++ } ++ s.Prog(sw64.AMEMB) ++ // LLDx Rout, (Rarg0) ++ p := s.Prog(lldx) ++ p.To.Type = obj.TYPE_MEM ++ p.To.Reg = v.Args[0].Reg() ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = v.Reg0() ++ // CMPEQ Rout, Rarg1, Rout ++ p1 := s.Prog(sw64.ACMPEQ) ++ p1.From.Type = obj.TYPE_REG ++ p1.From.Reg = v.Reg0() ++ p1.AddRestSource(obj.Addr{ ++ Type: obj.TYPE_REG, ++ Reg: v.Args[1].Reg(), ++ }) ++ p1.To.Type = obj.TYPE_REG ++ p1.To.Reg = v.Reg0() ++ // WR_F Rout ++ p2 := s.Prog(sw64.AWR_F) ++ p2.From.Type = obj.TYPE_REG ++ p2.From.Reg = v.Reg0() ++ // BIS Rarg2, R31, Rtmp ++ p3 := s.Prog(sw64.ABIS) ++ p3.From.Type = obj.TYPE_REG ++ p3.From.Reg = v.Args[2].Reg() ++ p3.AddRestSource(obj.Addr{ ++ Type: obj.TYPE_REG, ++ Reg: sw64.REGZERO, ++ }) ++ p3.To.Type = obj.TYPE_REG ++ p3.To.Reg = sw64.REGTMP ++ // LSTx Rtmp, (Rarg0) ++ p4 := s.Prog(lstx) ++ p4.From.Type = obj.TYPE_REG ++ p4.From.Reg = sw64.REGTMP ++ p4.To.Type = obj.TYPE_MEM ++ p4.To.Reg = v.Args[0].Reg() ++ // RD_F Rtmp ++ p5 := s.Prog(sw64.ARD_F) ++ p5.From.Type = obj.TYPE_REG ++ p5.From.Reg = sw64.REGTMP ++ // BEQ Rout, 2(PC) ++ p6 := s.Prog(sw64.ABEQ) ++ p6.From.Type = obj.TYPE_REG ++ p6.From.Reg = v.Reg0() ++ p6.To.Type = obj.TYPE_BRANCH ++ // BEQ Rtmp, -7(PC) ++ p7 := s.Prog(sw64.ABEQ) ++ p7.From.Type = obj.TYPE_REG ++ p7.From.Reg = sw64.REGTMP ++ p7.To.Type = obj.TYPE_BRANCH ++ p7.To.SetTarget(p) ++ p8 := s.Prog(sw64.AMEMB) ++ p6.To.SetTarget(p8) ++ ++ default: ++ v.Fatalf("genValue not implemented: %s", v.LongString()) ++ } ++} ++ ++var blockJump = map[ssa.BlockKind]struct { ++ asm, invasm obj.As ++}{ ++ ssa.BlockSW64NE: {sw64.ABNE, sw64.ABEQ}, ++ ssa.BlockSW64EQ: {sw64.ABEQ, sw64.ABNE}, ++ ssa.BlockSW64LT: {sw64.ABLT, sw64.ABGE}, ++ ssa.BlockSW64LE: {sw64.ABLE, sw64.ABGT}, ++ ssa.BlockSW64GT: {sw64.ABGT, sw64.ABLE}, ++ ssa.BlockSW64GE: {sw64.ABGE, sw64.ABLT}, ++ ssa.BlockSW64FNE: {sw64.AFBNE, sw64.AFBEQ}, ++ ssa.BlockSW64FEQ: {sw64.AFBEQ, sw64.AFBNE}, ++ ssa.BlockSW64FLT: {sw64.AFBLT, sw64.AFBGE}, ++ ssa.BlockSW64FLE: {sw64.AFBLE, sw64.AFBGT}, ++ ssa.BlockSW64FGT: {sw64.AFBGT, sw64.AFBLE}, ++ ssa.BlockSW64FGE: {sw64.AFBGE, sw64.AFBLT}, ++ ssa.BlockSW64LBC: {sw64.ABLBC, sw64.ABLBS}, ++ ssa.BlockSW64LBS: {sw64.ABLBS, sw64.ABLBC}, ++} ++ ++func ssaGenBlock(s *ssagen.State, b, next *ssa.Block) { ++ switch b.Kind { ++ case ssa.BlockPlain: ++ if b.Succs[0].Block() != next { ++ p := s.Prog(obj.AJMP) ++ p.To.Type = obj.TYPE_BRANCH ++ s.Branches = append(s.Branches, ssagen.Branch{P: p, B: b.Succs[0].Block()}) ++ } ++ ++ case ssa.BlockDefer: ++ // defer returns in R0: ++ // 0 if we should continue executing ++ // 1 if we should jump to deferreturn call ++ // ++ // see also runtime/asm_sw64.s:return0 ++ p := s.Prog(sw64.ABNE) ++ p.From = obj.Addr{ ++ Type: obj.TYPE_REG, ++ Reg: sw64.REG_R0, ++ } ++ p.To.Type = obj.TYPE_BRANCH ++ s.Branches = append(s.Branches, ssagen.Branch{P: p, B: b.Succs[1].Block()}) ++ ++ if b.Succs[0].Block() != next { ++ p := s.Prog(obj.AJMP) ++ p.To.Type = obj.TYPE_BRANCH ++ s.Branches = append(s.Branches, ssagen.Branch{P: p, B: b.Succs[0].Block()}) ++ } ++ ++ case ssa.BlockExit, ssa.BlockRetJmp: ++ //s.Prog(obj.AUNDEF) // tell plive.go that we never reach here ++ ++ case ssa.BlockRet: ++ s.Prog(obj.ARET) ++ ++ case ssa.BlockSW64NE, ++ ssa.BlockSW64EQ, ++ ssa.BlockSW64LT, ++ ssa.BlockSW64LE, ++ ssa.BlockSW64GT, ++ ssa.BlockSW64GE, ++ ssa.BlockSW64FNE, ++ ssa.BlockSW64FEQ, ++ ssa.BlockSW64FLT, ++ ssa.BlockSW64FLE, ++ ssa.BlockSW64FGT, ++ ssa.BlockSW64FGE, ++ ssa.BlockSW64LBC, ++ ssa.BlockSW64LBS: ++ jmp := blockJump[b.Kind] ++ var p *obj.Prog ++ switch next { ++ case b.Succs[0].Block(): ++ p = s.Prog(jmp.invasm) ++ p.To.Type = obj.TYPE_BRANCH ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = b.Controls[0].Reg() //zxw new change ++ s.Branches = append(s.Branches, ssagen.Branch{P: p, B: b.Succs[1].Block()}) ++ case b.Succs[1].Block(): ++ p = s.Prog(jmp.asm) ++ p.To.Type = obj.TYPE_BRANCH ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = b.Controls[0].Reg() ++ s.Branches = append(s.Branches, ssagen.Branch{P: p, B: b.Succs[0].Block()}) ++ default: ++ //zxw change ++ if b.Likely != ssa.BranchUnlikely { ++ p = s.Prog(jmp.asm) ++ p.To.Type = obj.TYPE_BRANCH ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = b.Controls[0].Reg() ++ s.Branches = append(s.Branches, ssagen.Branch{P: p, B: b.Succs[0].Block()}) ++ q := s.Prog(obj.AJMP) ++ q.To.Type = obj.TYPE_BRANCH ++ s.Branches = append(s.Branches, ssagen.Branch{P: q, B: b.Succs[1].Block()}) ++ } else { ++ p = s.Prog(jmp.invasm) ++ p.To.Type = obj.TYPE_BRANCH ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = b.Controls[0].Reg() ++ s.Branches = append(s.Branches, ssagen.Branch{P: p, B: b.Succs[1].Block()}) ++ q := s.Prog(obj.AJMP) ++ q.To.Type = obj.TYPE_BRANCH ++ s.Branches = append(s.Branches, ssagen.Branch{P: q, B: b.Succs[0].Block()}) ++ } ++ } ++ ++ case ssa.BlockSW64JUMPTABLE: ++ // S8ADDL IDX, TABLE, Rtmp ++ // LDL Rtmp, (Rtmp) ++ // JMP ZERO, (Rtmp) ++ p := s.Prog(sw64.AS8ADDL) ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = b.Controls[0].Reg() ++ p.AddRestSource(obj.Addr{ ++ Type: obj.TYPE_REG, ++ Reg: b.Controls[1].Reg(), ++ }) ++ p.To.Type = obj.TYPE_REG ++ p.To.Reg = sw64.REGTMP ++ ++ p2 := s.Prog(sw64.ALDL) ++ p2.From.Type = obj.TYPE_REG ++ p2.From.Reg = sw64.REGTMP ++ p2.To.Type = obj.TYPE_MEM ++ p2.To.Reg = sw64.REGTMP ++ p2.To.Offset = 0 ++ ++ p3 := s.Prog(sw64.AJMP) ++ p3.From.Reg = sw64.REGZERO ++ p3.From.Type = obj.TYPE_REG ++ p3.To.Type = obj.TYPE_MEM ++ p3.To.Reg = sw64.REGTMP ++ p3.To.Offset = 0 ++ ++ // Save jump tables for later resolution of the target blocks. ++ s.JumpTables = append(s.JumpTables, b) ++ ++ default: ++ b.Fatalf("branch not implemented: %s", b.LongString()) ++ } ++} ++ ++func loadRegResult(s *ssagen.State, f *ssa.Func, t *types.Type, reg int16, n *ir.Name, off int64) *obj.Prog { ++ p := s.Prog(loadByType(t, reg)) ++// p.From.Type = obj.TYPE_MEM ++// p.From.Name = obj.NAME_AUTO ++// p.From.Sym = n.Linksym() ++// p.From.Offset = n.FrameOffset() + off ++// p.To.Type = obj.TYPE_REG ++// p.To.Reg = reg ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = reg ++ p.To.Type = obj.TYPE_MEM ++ p.To.Name = obj.NAME_AUTO ++ p.To.Sym = n.Linksym() ++ p.To.Offset = n.FrameOffset() + off ++ return p ++} ++ ++func spillArgReg(pp *objw.Progs, p *obj.Prog, f *ssa.Func, t *types.Type, reg int16, n *ir.Name, off int64) *obj.Prog { ++ p = pp.Append(p, storeByType(t, reg), obj.TYPE_REG, reg, 0, obj.TYPE_MEM, 0, n.FrameOffset()+off) ++ p.To.Name = obj.NAME_PARAM ++ p.To.Sym = n.Linksym() ++ p.Pos = p.Pos.WithNotStmt() ++ return p ++} +diff --git a/src/cmd/compile/internal/test/inl_test.go b/src/cmd/compile/internal/test/inl_test.go +index 9a1a8bb105..4d37c8b1c5 100644 +--- a/src/cmd/compile/internal/test/inl_test.go ++++ b/src/cmd/compile/internal/test/inl_test.go +@@ -241,7 +241,7 @@ func TestIntendedInlining(t *testing.T) { + want["runtime"] = append(want["runtime"], "(*bmap).keys") + want["runtime"] = append(want["runtime"], "(*bmap).overflow") + } +- if runtime.GOARCH != "386" && runtime.GOARCH != "loong64" && runtime.GOARCH != "mips64" && runtime.GOARCH != "mips64le" && runtime.GOARCH != "riscv64" { ++ if runtime.GOARCH != "386" && runtime.GOARCH != "loong64" && runtime.GOARCH != "mips64" && runtime.GOARCH != "mips64le" && runtime.GOARCH != "riscv64" && runtime.GOARCH != "sw64" { + // nextFreeFast calls sys.TrailingZeros64, which on 386 is implemented in asm and is not inlinable. + // We currently don't have midstack inlining so nextFreeFast is also not inlinable on 386. + // On loong64, mips64x and riscv64, TrailingZeros64 is not intrinsified and causes nextFreeFast +diff --git a/src/cmd/compile/internal/types2/gccgosizes.go b/src/cmd/compile/internal/types2/gccgosizes.go +index 460200126c..3ce6207732 100644 +--- a/src/cmd/compile/internal/types2/gccgosizes.go ++++ b/src/cmd/compile/internal/types2/gccgosizes.go +@@ -38,4 +38,5 @@ var gccgoArchSizes = map[string]*StdSizes{ + "sparc": {4, 8}, + "sparc64": {8, 8}, + "wasm": {8, 8}, ++ "sw64": {8, 8}, + } +diff --git a/src/cmd/compile/internal/types2/sizes.go b/src/cmd/compile/internal/types2/sizes.go +index 7b1c00b40a..d5f633da1a 100644 +--- a/src/cmd/compile/internal/types2/sizes.go ++++ b/src/cmd/compile/internal/types2/sizes.go +@@ -244,6 +244,7 @@ var gcArchSizes = map[string]*gcSizes{ + "s390x": {8, 8}, + "sparc64": {8, 8}, + "wasm": {8, 8}, ++ "sw64": {8, 8}, + // When adding more architectures here, + // update the doc string of SizesFor below. + } +@@ -253,7 +254,7 @@ var gcArchSizes = map[string]*gcSizes{ + // + // Supported architectures for compiler "gc": + // "386", "amd64", "amd64p32", "arm", "arm64", "loong64", "mips", "mipsle", +-// "mips64", "mips64le", "ppc64", "ppc64le", "riscv64", "s390x", "sparc64", "wasm". ++// "mips64", "mips64le", "ppc64", "ppc64le", "riscv64", "s390x", "sparc64", "wasm", "sw64". + func SizesFor(compiler, arch string) Sizes { + switch compiler { + case "gc": +diff --git a/src/cmd/compile/main.go b/src/cmd/compile/main.go +index 7d38bea7fa..1c59d4c686 100644 +--- a/src/cmd/compile/main.go ++++ b/src/cmd/compile/main.go +@@ -17,6 +17,7 @@ import ( + "cmd/compile/internal/riscv64" + "cmd/compile/internal/s390x" + "cmd/compile/internal/ssagen" ++ "cmd/compile/internal/sw64" + "cmd/compile/internal/wasm" + "cmd/compile/internal/x86" + "fmt" +@@ -40,6 +41,7 @@ var archInits = map[string]func(*ssagen.ArchInfo){ + "riscv64": riscv64.Init, + "s390x": s390x.Init, + "wasm": wasm.Init, ++ "sw64": sw64.Init, + } + + func main() { diff --git a/0001-cmd-link-internal-add-support-for-internal-linking-o.patch b/0001-cmd-link-internal-add-support-for-internal-linking-o.patch new file mode 100644 index 0000000000000000000000000000000000000000..8f49bc5378a4e86ad82b6008e3e5688252365a39 --- /dev/null +++ b/0001-cmd-link-internal-add-support-for-internal-linking-o.patch @@ -0,0 +1,457 @@ +From 2730907e506ac1fdcc25fbb263df89a03c12b309 Mon Sep 17 00:00:00 2001 +From: limeidan +Date: Mon, 9 Oct 2023 17:31:14 +0800 +Subject: [PATCH 01/44] cmd/link/internal: add support for internal linking on + loong64 + +Change-Id: Ic0d36f27481ac707d04aaf7001f26061e510dd8f +--- + src/cmd/link/internal/loadelf/ldelf.go | 24 ++ + src/cmd/link/internal/loong64/asm.go | 356 ++++++++++++++++++++++++- + 2 files changed, 375 insertions(+), 5 deletions(-) + +diff --git a/src/cmd/link/internal/loadelf/ldelf.go b/src/cmd/link/internal/loadelf/ldelf.go +index e0363b5535..be14cc3bb2 100644 +--- a/src/cmd/link/internal/loadelf/ldelf.go ++++ b/src/cmd/link/internal/loadelf/ldelf.go +@@ -602,6 +602,11 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, f *bio.Reader, + // See https://sourceware.org/bugzilla/show_bug.cgi?id=21809 + continue + } ++ ++ if arch.Family == sys.Loong64 && (strings.HasPrefix(elfsym.name, ".L") || elfsym.name == "L0\001") { ++ // Symbols generated by the relax feature of gcc and binutils on loong64. ++ continue ++ } + } + + if strings.HasPrefix(elfsym.name, ".Linfo_string") { +@@ -682,6 +687,12 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, f *bio.Reader, + l.SetAttrOnList(s, true) + textp = append(textp, s) + for ss := l.SubSym(s); ss != 0; ss = l.SubSym(ss) { ++ if arch.Family == sys.Loong64 && (strings.HasPrefix(l.SymName(ss), ".L") || l.SymName(ss) == "L0\001") { ++ // Symbols generated by the relax feature of gcc and binutils on loong64. ++ // We ignore them here because there are too many symbols of this type, ++ // resulting in insufficient space in findfunctable. ++ continue ++ } + if l.AttrOnList(ss) { + return errorf("symbol %s listed multiple times", + l.SymName(ss)) +@@ -1018,7 +1029,14 @@ func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, uint8, error) { + MIPS64 | uint32(elf.R_MIPS_PC32)<<16: + return 4, 4, nil + ++ // These are informational annotations to assist linker optimizations. ++ case LOONG64 | uint32(elf.R_LARCH_ALIGN)<<16, ++ LOONG64 | uint32(elf.R_LARCH_RELAX)<<16: ++ return 0, 0, nil ++ + case LOONG64 | uint32(elf.R_LARCH_ADD8)<<16, ++ LOONG64 | uint32(elf.R_LARCH_ADD6)<<16, ++ LOONG64 | uint32(elf.R_LARCH_SUB6)<<16, + LOONG64 | uint32(elf.R_LARCH_SUB8)<<16: + return 1, 1, nil + +@@ -1032,7 +1050,13 @@ func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, uint8, error) { + LOONG64 | uint32(elf.R_LARCH_ADD32)<<16, + LOONG64 | uint32(elf.R_LARCH_SUB24)<<16, + LOONG64 | uint32(elf.R_LARCH_SUB32)<<16, ++ LOONG64 | uint32(elf.R_LARCH_B16)<<16, ++ LOONG64 | uint32(elf.R_LARCH_B21)<<16, + LOONG64 | uint32(elf.R_LARCH_B26)<<16, ++ LOONG64 | uint32(elf.R_LARCH_PCALA_HI20)<<16, ++ LOONG64 | uint32(elf.R_LARCH_PCALA_LO12)<<16, ++ LOONG64 | uint32(elf.R_LARCH_GOT_PC_HI20)<<16, ++ LOONG64 | uint32(elf.R_LARCH_GOT_PC_LO12)<<16, + LOONG64 | uint32(elf.R_LARCH_32_PCREL)<<16: + return 4, 4, nil + +diff --git a/src/cmd/link/internal/loong64/asm.go b/src/cmd/link/internal/loong64/asm.go +index 2e69594f92..3a83f1a5ad 100644 +--- a/src/cmd/link/internal/loong64/asm.go ++++ b/src/cmd/link/internal/loong64/asm.go +@@ -58,10 +58,328 @@ func gentext(ctxt *ld.Link, ldr *loader.Loader) { + } + + func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym, r loader.Reloc, rIdx int) bool { +- log.Fatalf("adddynrel not implemented") ++ targ := r.Sym() ++ var targType sym.SymKind ++ if targ != 0 { ++ targType = ldr.SymType(targ) ++ } ++ ++ switch r.Type() { ++ default: ++ if r.Type() >= objabi.ElfRelocOffset { ++ ldr.Errorf(s, "adddynrel: unexpected reloction type %d (%s)", r.Type(), sym.RelocName(target.Arch, r.Type())) ++ return false ++ } ++ ++ case objabi.ElfRelocOffset + objabi.RelocType(elf.R_LARCH_64): ++ if targType == sym.SDYNIMPORT { ++ ldr.Errorf(s, "unexpected R_LARCH_64 relocation for dynamic symbol %s", ldr.SymName(targ)) ++ } ++ su := ldr.MakeSymbolUpdater(s) ++ su.SetRelocType(rIdx, objabi.R_ADDR) ++ if target.IsPIE() && target.IsInternal() { ++ // For internal linking PIE, this R_ADDR relocation cannot ++ // be resolved statically. We need to generate a dynamic ++ // relocation. Let the code below handle it. ++ break ++ } ++ return true ++ ++ case objabi.ElfRelocOffset + objabi.RelocType(elf.R_LARCH_B26): ++ if targType == sym.SDYNIMPORT { ++ addpltsym(target, ldr, syms, targ) ++ su := ldr.MakeSymbolUpdater(s) ++ su.SetRelocSym(rIdx, syms.PLT) ++ su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymPlt(targ))) ++ } ++ if targType == 0 || targType == sym.SXREF { ++ ldr.Errorf(s, "unknown symbol %s in callloong64", ldr.SymName(targ)) ++ } ++ su := ldr.MakeSymbolUpdater(s) ++ su.SetRelocType(rIdx, objabi.R_CALLLOONG64) ++ return true ++ ++ case objabi.ElfRelocOffset + objabi.RelocType(elf.R_LARCH_GOT_PC_HI20), ++ objabi.ElfRelocOffset + objabi.RelocType(elf.R_LARCH_GOT_PC_LO12): ++ if targType != sym.SDYNIMPORT { ++ // TODO: turn LDR of GOT entry into ADR of symbol itself ++ } ++ ++ ld.AddGotSym(target, ldr, syms, targ, uint32(elf.R_LARCH_64)) ++ su := ldr.MakeSymbolUpdater(s) ++ if r.Type() == objabi.ElfRelocOffset+objabi.RelocType(elf.R_LARCH_GOT_PC_HI20) { ++ su.SetRelocType(rIdx, objabi.R_LOONG64_ADDR_HI) ++ } else { ++ su.SetRelocType(rIdx, objabi.R_LOONG64_ADDR_LO) ++ } ++ su.SetRelocSym(rIdx, syms.GOT) ++ su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymGot(targ))) ++ return true ++ ++ case objabi.ElfRelocOffset + objabi.RelocType(elf.R_LARCH_PCALA_HI20), ++ objabi.ElfRelocOffset + objabi.RelocType(elf.R_LARCH_PCALA_LO12): ++ if targType == sym.SDYNIMPORT { ++ ldr.Errorf(s, "unexpected relocation for dynamic symbol %s", ldr.SymName(targ)) ++ } ++ if targType == 0 || targType == sym.SXREF { ++ ldr.Errorf(s, "unknown symbol %s", ldr.SymName(targ)) ++ } ++ ++ su := ldr.MakeSymbolUpdater(s) ++ if r.Type() == objabi.ElfRelocOffset+objabi.RelocType(elf.R_LARCH_PCALA_HI20) { ++ su.SetRelocType(rIdx, objabi.R_LOONG64_ADDR_HI) ++ } else { ++ su.SetRelocType(rIdx, objabi.R_LOONG64_ADDR_LO) ++ } ++ return true ++ ++ case objabi.ElfRelocOffset + objabi.RelocType(elf.R_LARCH_ADD64), ++ objabi.ElfRelocOffset + objabi.RelocType(elf.R_LARCH_SUB64): ++ su := ldr.MakeSymbolUpdater(s) ++ if r.Type() == objabi.ElfRelocOffset+objabi.RelocType(elf.R_LARCH_ADD64) { ++ su.SetRelocType(rIdx, objabi.R_LOONG64_ADD64) ++ } else { ++ su.SetRelocType(rIdx, objabi.R_LOONG64_SUB64) ++ } ++ return true ++ ++ case objabi.ElfRelocOffset + objabi.RelocType(elf.R_LARCH_B16), ++ objabi.ElfRelocOffset + objabi.RelocType(elf.R_LARCH_B21): ++ if targType == sym.SDYNIMPORT { ++ addpltsym(target, ldr, syms, targ) ++ su := ldr.MakeSymbolUpdater(s) ++ su.SetRelocSym(rIdx, syms.PLT) ++ su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymPlt(targ))) ++ } ++ if targType == 0 || targType == sym.SXREF { ++ ldr.Errorf(s, "unknown symbol %s in R_JMPxxLOONG64", ldr.SymName(targ)) ++ } ++ su := ldr.MakeSymbolUpdater(s) ++ if r.Type() == objabi.ElfRelocOffset+objabi.RelocType(elf.R_LARCH_B16) { ++ su.SetRelocType(rIdx, objabi.R_JMP16LOONG64) ++ } else { ++ su.SetRelocType(rIdx, objabi.R_JMP21LOONG64) ++ } ++ return true ++ } ++ ++ relocs := ldr.Relocs(s) ++ r = relocs.At(rIdx) ++ ++ switch r.Type() { ++ case objabi.R_CALLLOONG64: ++ if targType != sym.SDYNIMPORT { ++ return true ++ } ++ if target.IsExternal() { ++ return true ++ } ++ ++ // Internal linking. ++ if r.Add() != 0 { ++ ldr.Errorf(s, "PLT call with no-zero addend (%v)", r.Add()) ++ } ++ ++ // Build a PLT entry and change the relocation target to that entry. ++ addpltsym(target, ldr, syms, targ) ++ su := ldr.MakeSymbolUpdater(s) ++ su.SetRelocSym(rIdx, syms.PLT) ++ su.SetRelocAdd(rIdx, int64(ldr.SymPlt(targ))) ++ return true ++ ++ case objabi.R_ADDR: ++ if ldr.SymType(s) == sym.STEXT && target.IsElf() { ++ // The code is asking for the address of an external ++ // function. We provide it with the address of the ++ // correspondent GOT symbol. ++ ld.AddGotSym(target, ldr, syms, targ, uint32(elf.R_LARCH_64)) ++ su := ldr.MakeSymbolUpdater(s) ++ su.SetRelocSym(rIdx, syms.GOT) ++ su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymGot(targ))) ++ return true ++ } ++ ++ // Process dynamic relocations for the data sections. ++ if target.IsPIE() && target.IsInternal() { ++ // When internally linking, generate dynamic relocations ++ // for all typical R_ADDR relocations. The exception ++ // are those R_ADDR that are created as part of generating ++ // the dynamic relocations and must be resolved statically. ++ // ++ // There are three phases relevant to understanding this: ++ // ++ // dodata() // we are here ++ // address() // symbol address assignment ++ // reloc() // resolution of static R_ADDR relocs ++ // ++ // At this point symbol addresses have not been ++ // assigned yet (as the final size of the .rela section ++ // will affect the addresses), and so we cannot write ++ // the Elf64_Rela.r_offset now. Instead we delay it ++ // until after the 'address' phase of the linker is ++ // complete. We do this via Addaddrplus, which creates ++ // a new R_ADDR relocation which will be resolved in ++ // the 'reloc' phase. ++ // ++ // These synthetic static R_ADDR relocs must be skipped ++ // now, or else we will be caught in an infinite loop ++ // of generating synthetic relocs for our synthetic ++ // relocs. ++ // ++ // Furthermore, the rela sections contain dynamic ++ // relocations with R_ADDR relocations on ++ // Elf64_Rela.r_offset. This field should contain the ++ // symbol offset as determined by reloc(), not the ++ // final dynamically linked address as a dynamic ++ // relocation would provide. ++ switch ldr.SymName(s) { ++ case ".dynsym", ".rela", ".rela.plt", ".got.plt", ".dynamic": ++ return false ++ } ++ } else { ++ // Either internally linking a static executable, ++ // in which case we can resolve these relocations ++ // statically in the 'reloc' phase, or externally ++ // linking, in which case the relocation will be ++ // prepared in the 'reloc' phase and passed to the ++ // external linker in the 'asmb' phase. ++ if ldr.SymType(s) != sym.SDATA && ldr.SymType(s) != sym.SRODATA { ++ break ++ } ++ } ++ ++ if target.IsElf() { ++ // Generate R_LARCH_RELATIVE relocations for best ++ // efficiency in the dynamic linker. ++ // ++ // As noted above, symbol addresses have not been ++ // assigned yet, so we can't generate the final reloc ++ // entry yet. We ultimately want: ++ // ++ // r_offset = s + r.Off ++ // r_info = R_LARCH_RELATIVE ++ // r_addend = targ + r.Add ++ // ++ // The dynamic linker will set *offset = base address + ++ // addend. ++ // ++ // AddAddrPlus is used for r_offset and r_addend to ++ // generate new R_ADDR relocations that will update ++ // these fields in the 'reloc' phase. ++ rela := ldr.MakeSymbolUpdater(syms.Rela) ++ rela.AddAddrPlus(target.Arch, s, int64(r.Off())) ++ if r.Siz() == 8 { ++ rela.AddUint64(target.Arch, elf.R_INFO(0, uint32(elf.R_LARCH_RELATIVE))) ++ } else { ++ ldr.Errorf(s, "unexpected relocation for dynamic symbol %s", ldr.SymName(targ)) ++ } ++ rela.AddAddrPlus(target.Arch, targ, int64(r.Add())) ++ return true ++ } ++ ++ case objabi.R_LOONG64_GOT_HI, ++ objabi.R_LOONG64_GOT_LO: ++ ld.AddGotSym(target, ldr, syms, targ, uint32(elf.R_LARCH_64)) ++ su := ldr.MakeSymbolUpdater(s) ++ if r.Type() == objabi.R_LOONG64_GOT_HI { ++ su.SetRelocType(rIdx, objabi.R_LOONG64_ADDR_HI) ++ } else { ++ su.SetRelocType(rIdx, objabi.R_LOONG64_ADDR_LO) ++ } ++ su.SetRelocSym(rIdx, syms.GOT) ++ su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymGot(targ))) ++ return true ++ } + return false + } + ++func elfsetupplt(ctxt *ld.Link, ldr *loader.Loader, plt, gotplt *loader.SymbolBuilder, dynamic loader.Sym) { ++ if plt.Size() == 0 { ++ // pcalau12i $r14, imm ++ plt.AddSymRef(ctxt.Arch, gotplt.Sym(), 0, objabi.R_LOONG64_ADDR_HI, 4) ++ plt.SetUint32(ctxt.Arch, plt.Size()-4, 0x1a00000e) ++ ++ // sub.d $r13, $r13, $r15 ++ plt.AddUint32(ctxt.Arch, 0x0011bdad) ++ ++ // ld.d $r15, $r14, imm ++ plt.AddSymRef(ctxt.Arch, gotplt.Sym(), 0, objabi.R_LOONG64_ADDR_LO, 4) ++ plt.SetUint32(ctxt.Arch, plt.Size()-4, 0x28c001cf) ++ ++ // addi.d $r13, $r13, -40 ++ plt.AddUint32(ctxt.Arch, 0x02ff61ad) ++ ++ // addi.d $r12, $r14, imm ++ plt.AddSymRef(ctxt.Arch, gotplt.Sym(), 0, objabi.R_LOONG64_ADDR_LO, 4) ++ plt.SetUint32(ctxt.Arch, plt.Size()-4, 0x2c001cc) ++ ++ // srli.d $r13, $r13, 1 ++ plt.AddUint32(ctxt.Arch, 0x004505ad) ++ ++ // ld.d $r12, $r12, 8 ++ plt.AddUint32(ctxt.Arch, 0x28c0218c) ++ ++ // jirl $r0, $r15, 0 ++ plt.AddUint32(ctxt.Arch, 0x4c0001e0) ++ ++ // check gotplt.size == 0 ++ if gotplt.Size() != 0 { ++ ctxt.Errorf(gotplt.Sym(), "got.plt is not empty at the very beginning") ++ } ++ ++ gotplt.AddUint64(ctxt.Arch, 0) ++ gotplt.AddUint64(ctxt.Arch, 0) ++ } ++} ++ ++func addpltsym(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym) { ++ if ldr.SymPlt(s) >= 0 { ++ return ++ } ++ ++ ld.Adddynsym(ldr, target, syms, s) ++ ++ if target.IsElf() { ++ plt := ldr.MakeSymbolUpdater(syms.PLT) ++ gotplt := ldr.MakeSymbolUpdater(syms.GOTPLT) ++ rela := ldr.MakeSymbolUpdater(syms.RelaPLT) ++ if plt.Size() == 0 { ++ panic("plt is not set up") ++ } ++ ++ // pcalau12i $r15, imm ++ plt.AddAddrPlus4(target.Arch, gotplt.Sym(), gotplt.Size()) ++ plt.SetUint32(target.Arch, plt.Size()-4, 0x1a00000f) ++ relocs := plt.Relocs() ++ plt.SetRelocType(relocs.Count()-1, objabi.R_LOONG64_ADDR_HI) ++ ++ // ld.d $r15, $r15, imm ++ plt.AddAddrPlus4(target.Arch, gotplt.Sym(), gotplt.Size()) ++ plt.SetUint32(target.Arch, plt.Size()-4, 0x28c001ef) ++ relocs = plt.Relocs() ++ plt.SetRelocType(relocs.Count()-1, objabi.R_LOONG64_ADDR_LO) ++ ++ // pcaddu12i $r13, 0 ++ plt.AddUint32(target.Arch, 0x1c00000d) ++ ++ // jirl r0, r15, 0 ++ plt.AddUint32(target.Arch, 0x4c0001e0) ++ ++ // add to got.plt: pointer to plt[0] ++ gotplt.AddAddrPlus(target.Arch, plt.Sym(), 0) ++ ++ // rela ++ rela.AddAddrPlus(target.Arch, gotplt.Sym(), gotplt.Size()-8) ++ sDynid := ldr.SymDynid(s) ++ rela.AddUint64(target.Arch, elf.R_INFO(uint32(sDynid), uint32(elf.R_LARCH_JUMP_SLOT))) ++ rela.AddUint64(target.Arch, 0) ++ ++ ldr.SetPlt(s, int32(plt.Size()-16)) ++ } else { ++ ldr.Errorf(s, "addpltsym: unsupport binary format") ++ } ++} ++ + func elfreloc1(ctxt *ld.Link, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym, r loader.ExtReloc, ri int, sectoff int64) bool { + // loong64 ELF relocation (endian neutral) + // offset uint64 +@@ -134,10 +452,6 @@ func elfreloc1(ctxt *ld.Link, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym, + return true + } + +-func elfsetupplt(ctxt *ld.Link, ldr *loader.Loader, plt, gotplt *loader.SymbolBuilder, dynamic loader.Sym) { +- return +-} +- + func machoreloc1(*sys.Arch, *ld.OutBuf, *loader.Loader, loader.Sym, loader.ExtReloc, int64) bool { + return false + } +@@ -197,6 +511,38 @@ func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loade + pc := ldr.SymValue(s) + int64(r.Off()) + t := ldr.SymAddr(rs) + r.Add() - pc + return int64(val&0xfc000000 | (((t >> 2) & 0xffff) << 10) | (((t >> 2) & 0x3ff0000) >> 16)), noExtReloc, isOk ++ ++ case objabi.R_JMP16LOONG64, ++ objabi.R_JMP21LOONG64: ++ pc := ldr.SymValue(s) + int64(r.Off()) ++ t := ldr.SymAddr(rs) + r.Add() - pc ++ if r.Type() == objabi.R_JMP16LOONG64 { ++ return int64(val&0xfc0003ff | (((t >> 2) & 0xffff) << 10)), noExtReloc, isOk ++ } ++ return int64(val&0xfc0003e0 | (((t >> 2) & 0xffff) << 10) | (((t >> 2) & 0x1f0000) >> 16)), noExtReloc, isOk ++ ++ case objabi.R_LOONG64_TLS_IE_HI, ++ objabi.R_LOONG64_TLS_IE_LO: ++ if target.IsPIE() && target.IsElf() { ++ if !target.IsLinux() { ++ ldr.Errorf(s, "TLS reloc on unsupported OS %v", target.HeadType) ++ } ++ t := ldr.SymAddr(rs) + r.Add() ++ if r.Type() == objabi.R_LOONG64_TLS_IE_HI { ++ // pcalau12i -> lu12i.w ++ return (0x14000000 | (val & 0x1f) | ((t >> 12) << 5)), noExtReloc, isOk ++ } ++ // ld.d -> ori ++ return (0x03800000 | (val & 0x3ff) | ((t & 0xfff) << 10)), noExtReloc, isOk ++ } else { ++ log.Fatalf("cannot handle R_LOONG64_TLS_IE_x (sym %s) when linking internally", ldr.SymName(rs)) ++ } ++ ++ case objabi.R_LOONG64_ADD64, objabi.R_LOONG64_SUB64: ++ if r.Type() == objabi.R_LOONG64_ADD64 { ++ return int64(val + ldr.SymAddr(rs) + r.Add()), noExtReloc, isOk ++ } ++ return int64(val - (ldr.SymAddr(rs) + r.Add())), noExtReloc, isOk + } + + return val, 0, false +-- +2.38.1 + diff --git a/0002-cmd-dist-internal-platform-enable-internal-linking-f.patch b/0002-cmd-dist-internal-platform-enable-internal-linking-f.patch new file mode 100644 index 0000000000000000000000000000000000000000..8f2e4c171a8fe6328bc2ecfa7c3888b65e22339b --- /dev/null +++ b/0002-cmd-dist-internal-platform-enable-internal-linking-f.patch @@ -0,0 +1,83 @@ +From d404dccc7f089ddbd81b95c3d97f19acc6cb0329 Mon Sep 17 00:00:00 2001 +From: limeidan +Date: Mon, 9 Oct 2023 17:32:03 +0800 +Subject: [PATCH 02/44] cmd/dist, internal/platform: enable internal linking + feature and test on loong64 + +Change-Id: Ifea676e9eb44281465832fc4050f6286e50f4543 +--- + src/cmd/dist/build.go | 4 +++- + src/cmd/dist/test.go | 4 ++-- + src/internal/platform/supported.go | 6 ++++-- + 3 files changed, 9 insertions(+), 5 deletions(-) + +diff --git a/src/cmd/dist/build.go b/src/cmd/dist/build.go +index 1f467647f5..b71d6c393e 100644 +--- a/src/cmd/dist/build.go ++++ b/src/cmd/dist/build.go +@@ -624,10 +624,12 @@ func setup() { + func mustLinkExternal(goos, goarch string, cgoEnabled bool) bool { + if cgoEnabled { + switch goarch { +- case "loong64", "mips", "mipsle", "mips64", "mips64le": ++ case "mips", "mipsle", "mips64", "mips64le": + // Internally linking cgo is incomplete on some architectures. + // https://golang.org/issue/14449 + return true ++ case "loong64": ++ return false + case "arm64": + if goos == "windows" { + // windows/arm64 internal linking is not implemented. +diff --git a/src/cmd/dist/test.go b/src/cmd/dist/test.go +index 0c992118f4..9728ef29cb 100644 +--- a/src/cmd/dist/test.go ++++ b/src/cmd/dist/test.go +@@ -1164,7 +1164,7 @@ func (t *tester) internalLink() bool { + // Internally linking cgo is incomplete on some architectures. + // https://golang.org/issue/10373 + // https://golang.org/issue/14449 +- if goarch == "loong64" || goarch == "mips64" || goarch == "mips64le" || goarch == "mips" || goarch == "mipsle" || goarch == "riscv64" { ++ if goarch == "mips64" || goarch == "mips64le" || goarch == "mips" || goarch == "mipsle" || goarch == "riscv64" { + return false + } + if goos == "aix" { +@@ -1185,7 +1185,7 @@ func (t *tester) internalLinkPIE() bool { + } + switch goos + "-" + goarch { + case "darwin-amd64", "darwin-arm64", +- "linux-amd64", "linux-arm64", "linux-ppc64le", ++ "linux-amd64", "linux-arm64", "linux-loong64", "linux-ppc64le", + "android-arm64", + "windows-amd64", "windows-386", "windows-arm": + return true +diff --git a/src/internal/platform/supported.go b/src/internal/platform/supported.go +index e864c37d68..79ed6d4b1c 100644 +--- a/src/internal/platform/supported.go ++++ b/src/internal/platform/supported.go +@@ -85,10 +85,12 @@ func FuzzInstrumented(goos, goarch string) bool { + func MustLinkExternal(goos, goarch string, withCgo bool) bool { + if withCgo { + switch goarch { +- case "loong64", "mips", "mipsle", "mips64", "mips64le": ++ case "mips", "mipsle", "mips64", "mips64le": + // Internally linking cgo is incomplete on some architectures. + // https://go.dev/issue/14449 + return true ++ case "loong64": ++ return false + case "arm64": + if goos == "windows" { + // windows/arm64 internal linking is not implemented. +@@ -225,7 +227,7 @@ func InternalLinkPIESupported(goos, goarch string) bool { + switch goos + "/" + goarch { + case "android/arm64", + "darwin/amd64", "darwin/arm64", +- "linux/amd64", "linux/arm64", "linux/ppc64le", ++ "linux/amd64", "linux/arm64", "linux/loong64", "linux/ppc64le", + "windows/386", "windows/amd64", "windows/arm", "windows/arm64": + return true + } +-- +2.38.1 + diff --git a/0002-cmd-internal-obj-Add-sw64-port.patch b/0002-cmd-internal-obj-Add-sw64-port.patch new file mode 100644 index 0000000000000000000000000000000000000000..3acdb5bd0602972c96eadb72098dd33fb99882b0 --- /dev/null +++ b/0002-cmd-internal-obj-Add-sw64-port.patch @@ -0,0 +1,4446 @@ +diff --git a/src/cmd/internal/obj/link.go b/src/cmd/internal/obj/link.go +index 1b2d344eaf..33f072059c 100644 +--- a/src/cmd/internal/obj/link.go ++++ b/src/cmd/internal/obj/link.go +@@ -446,6 +446,7 @@ const ( + ABaseRISCV + ABaseS390X + ABaseWasm ++ ABaseSW64 + + AllowedOpCodes = 1 << 11 // The number of opcodes available for any given architecture. + AMask = AllowedOpCodes - 1 // AND with this to use the opcode as an array index. +@@ -1228,6 +1229,19 @@ func (fi *FuncInfo) UnspillRegisterArgs(last *Prog, pa ProgAlloc) *Prog { + return last + } + ++// TODO: delete this function after converting the format of sw64 LDx ++func (fi *FuncInfo) UnspillRegisterArgsSW64(last *Prog, pa ProgAlloc) *Prog { ++ for _, ra := range fi.spills { ++ unspill := Appendp(last, pa) ++ unspill.As = ra.Unspill ++ unspill.From.Type = TYPE_REG ++ unspill.From.Reg = ra.Reg ++ unspill.To = ra.Addr ++ last = unspill ++ } ++ return last ++} ++ + // LinkArch is the definition of a single architecture. + type LinkArch struct { + *sys.Arch +diff --git a/src/cmd/internal/obj/stringer_sw64.go b/src/cmd/internal/obj/stringer_sw64.go +new file mode 100644 +index 0000000000..faa4e3db9a +--- /dev/null ++++ b/src/cmd/internal/obj/stringer_sw64.go +@@ -0,0 +1,104 @@ ++// 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 ignore ++// +build ignore ++ ++// This is a mini version of the stringer tool customized for the Anames table ++// in the architecture support for obj. ++// This version just generates the slice of strings, not the String method. ++ ++package main ++ ++import ( ++ "bufio" ++ "flag" ++ "fmt" ++ "log" ++ "os" ++ "regexp" ++ "strings" ++) ++ ++var ( ++ input = flag.String("i", "", "input file name") ++ output = flag.String("o", "", "output file name") ++ pkg = flag.String("p", "", "package name") ++) ++ ++var Are = regexp.MustCompile(`^\tA([A-Z0-9_]+)`) ++ ++func main() { ++ flag.Parse() ++ if *input == "" || *output == "" || *pkg == "" { ++ flag.Usage() ++ os.Exit(2) ++ } ++ in, err := os.Open(*input) ++ if err != nil { ++ log.Fatal(err) ++ } ++ fd, err := os.Create(*output) ++ if err != nil { ++ log.Fatal(err) ++ } ++ out := bufio.NewWriter(fd) ++ defer out.Flush() ++ var on = false ++ s := bufio.NewScanner(in) ++ first := true ++ for s.Scan() { ++ line := s.Text() ++ if !on { ++ // First relevant line contains "= obj.ABase". ++ // If we find it, delete the = so we don't stop immediately. ++ const prefix = "= obj.ABase" ++ index := strings.Index(line, prefix) ++ if index < 0 { ++ continue ++ } ++ // It's on. Start with the header. ++ fmt.Fprintf(out, header, *input, *output, *pkg, *pkg) ++ on = true ++ line = line[:index] ++ } ++ // Strip comments so their text won't defeat our heuristic. ++ index := strings.Index(line, "//") ++ if index > 0 { ++ line = line[:index] ++ } ++ index = strings.Index(line, "/*") ++ if index > 0 { ++ line = line[:index] ++ } ++ // Termination condition: Any line with an = changes the sequence, ++ // so stop there, and stop at a closing brace. ++ if strings.HasPrefix(line, "}") || strings.ContainsRune(line, '=') { ++ break ++ } ++ sub := Are.FindStringSubmatch(line) ++ if len(sub) < 2 { ++ continue ++ } ++ if first { ++ fmt.Fprintf(out, "\tobj.A_ARCHSPECIFIC: %q,\n", sub[1]) ++ first = false ++ } else { ++ fmt.Fprintf(out, "\t%q,\n", sub[1]) ++ } ++ } ++ fmt.Fprintln(out, "}") ++ if s.Err() != nil { ++ log.Fatal(err) ++ } ++} ++ ++const header = `// Code generated by stringer -i %s -o %s -p %s; DO NOT EDIT. ++ ++package %s ++ ++import "cmd/internal/obj" ++ ++var Anames = []string{ ++` +diff --git a/src/cmd/internal/obj/sw64/a.out.go b/src/cmd/internal/obj/sw64/a.out.go +new file mode 100644 +index 0000000000..718b6b597c +--- /dev/null ++++ b/src/cmd/internal/obj/sw64/a.out.go +@@ -0,0 +1,502 @@ ++// cmd/9c/9.out.h from Vita Nuova. ++// ++// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. ++// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) ++// Portions Copyright © 1997-1999 Vita Nuova Limited ++// Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com) ++// Portions Copyright © 2004,2006 Bruce Ellis ++// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) ++// Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others ++// Portions Copyright © 2009 The Go Authors. All rights reserved. ++// ++// Permission is hereby granted, free of charge, to any person obtaining a copy ++// of this software and associated documentation files (the "Software"), to deal ++// in the Software without restriction, including without limitation the rights ++// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++// copies of the Software, and to permit persons to whom the Software is ++// furnished to do so, subject to the following conditions: ++// ++// The above copyright notice and this permission notice shall be included in ++// all copies or substantial portions of the Software. ++// ++// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ++// THE SOFTWARE. ++ ++package sw64 ++ ++import ( ++ "cmd/internal/obj" ++) ++ ++//go:generate go run ../stringer_sw64.go -i $GOFILE -o anames.go -p sw64 ++ ++/* ++ * sw64 ++ */ ++const ( ++ NREG = 32 /* number of general registers */ ++ NFREG = 32 /* number of floating point registers */ ++ NVREG = 32 /* number of SIMD registers */ ++ NINST = 253 + 114 /* number of instructions */ ++) ++ ++const ( ++ REG_R0 = obj.RBaseSW64 + iota ++ REG_R1 ++ REG_R2 ++ REG_R3 ++ REG_R4 ++ REG_R5 ++ REG_R6 ++ REG_R7 ++ REG_R8 ++ REG_R9 ++ REG_R10 ++ REG_R11 ++ REG_R12 ++ REG_R13 ++ REG_R14 ++ REG_R15 ++ REG_R16 ++ REG_R17 ++ REG_R18 ++ REG_R19 ++ REG_R20 ++ REG_R21 ++ REG_R22 ++ REG_R23 ++ REG_R24 ++ REG_R25 ++ REG_R26 ++ REG_R27 ++ REG_R28 ++ REG_R29 ++ REG_R30 ++ REG_R31 ++ ++ REG_F0 ++ REG_F1 ++ REG_F2 ++ REG_F3 ++ REG_F4 ++ REG_F5 ++ REG_F6 ++ REG_F7 ++ REG_F8 ++ REG_F9 ++ REG_F10 ++ REG_F11 ++ REG_F12 ++ REG_F13 ++ REG_F14 ++ REG_F15 ++ REG_F16 ++ REG_F17 ++ REG_F18 ++ REG_F19 ++ REG_F20 ++ REG_F21 ++ REG_F22 ++ REG_F23 ++ REG_F24 ++ REG_F25 ++ REG_F26 ++ REG_F27 ++ REG_F28 ++ REG_F29 ++ REG_F30 ++ REG_F31 ++ ++ // SIMD ++ REG_V0 ++ REG_V1 ++ REG_V2 ++ REG_V3 ++ REG_V4 ++ REG_V5 ++ REG_V6 ++ REG_V7 ++ REG_V8 ++ REG_V9 ++ REG_V10 ++ REG_V11 ++ REG_V12 ++ REG_V13 ++ REG_V14 ++ REG_V15 ++ REG_V16 ++ REG_V17 ++ REG_V18 ++ REG_V19 ++ REG_V20 ++ REG_V21 ++ REG_V22 ++ REG_V23 ++ REG_V24 ++ REG_V25 ++ REG_V26 ++ REG_V27 ++ REG_V28 ++ REG_V29 ++ REG_V30 ++ REG_V31 ++ ++ REGG = REG_R15 // fp ++ REGLINK = REG_R26 // ra ++ REGCTXT = REG_R25 // t12/pv ++ REGTMP = REG_R28 // at ++ REGSB = REG_R29 // gp ++ REGSP = REG_R30 // sp ++ REGZERO = REG_R31 // zero ++ ++) ++ ++var SW64DWARFRegisters = map[int16]int16{} ++ ++func init() { ++ // f assigns dwarfregisters[from:to] = (base):(to-from+base) ++ f := func(from, to, base int16) { ++ for r := int16(from); r <= to; r++ { ++ SW64DWARFRegisters[r] = (r - from) + base ++ } ++ } ++ f(REG_R0, REG_R31, 0) ++ f(REG_F0, REG_F31, 32) // For 32-bit SW64, compiler only uses even numbered registers -- see cmd/compile/internal/ssa/gen/SW64Ops.go ++} ++ ++const ( ++ BIG = 32766 ++) ++ ++const ( ++ C_NONE = iota ++ C_RREG // integer register ++ C_FREG // float-point register ++ C_VREG // SIMD externtion register ++ C_REG // any register ++ C_SUCON // integer constant not greater than 0xff ++ C_MCON // integer constant [-0x8000,0x7fff] ++ C_LCON // integer constant without restriction ++ C_FCON // float-point constant without restriction ++ C_LEXT // external symbol ++ C_ADDR // all symbol ++ C_SAUTO // (a.NAME == NAME_PARAM || a.NAME == NAME_AUTO) && offset is [-0x7fff, 0x7fff] ++ C_LAUTO // a.NAME == NAME_PARAM || a.NAME == NAME_AUTO ++ C_ZOREG // a.NAME == NAME_NONE && offset is 0 ++ C_SOREG // (a.NAME == NAME_NONE) && offset is [-0x7fff, 0x7fff] ++ C_LOREG // a.NAME == NAME_NONE ++ C_SBRA // a.NAME == NAME_NONE && offset is 0 ++ C_GOTADDR // The GOT slot for a symbol in -dynlink mode ++ C_GOK ++ C_TLS_LE ++ C_TLS_IE ++ C_NCLASS /* must be the last */ ++) ++ ++const ( ++ ASYS_CALL = obj.ABaseSW64 + obj.A_ARCHSPECIFIC + iota ++ ASYS_CALL_B ++ AEXCB ++ //控制指令, JMP,RET,CALL定义为obj.AJMP,obj.ARET,obj.CALL ++ ABR ++ ALBR ++ ABSR ++ ABEQ ++ ABNE ++ ABLT ++ ABLE ++ ABGT ++ ABGE ++ ABLBC ++ ABLBS ++ AFBEQ ++ AFBNE ++ AFBLT ++ AFBLE ++ AFBGT ++ AFBGE ++ ++ //Load/Store ++ AMOVB ++ AMOVBU ++ AMOVH ++ AMOVHU ++ AMOVW ++ AMOVWU ++ AMOVV ++ AMOVF ++ AMOVD ++ ALDBU //存储装载指令 ++ ALDHU ++ ALDW ++ ALDL ++ ALDL_U ++ ASTB ++ ASTH ++ ASTW ++ ASTL ++ ASTL_U ++ AFLDS ++ AFLDD ++ AFSTS ++ AFSTD ++ ++ // Load/Store with addend ++ ALDBUA ++ ALDHUA ++ ALDWA ++ ALDLA ++ AFLDSA ++ AFLDDA ++ ASTBA ++ ASTHA ++ ASTWA ++ ASTLA ++ AFSTSA ++ AFSTDA ++ ++ //装入立即数 ++ ALDI ++ ALDF //装入浮点立即数 ++ ALDIH ++ // 整数算数运算 ++ AADDW ++ ASUBW ++ AS4ADDW ++ AS4SUBW ++ AS8ADDW ++ AS8SUBW ++ AADDL ++ ASUBL ++ AS4ADDL ++ AS4SUBL ++ AS8ADDL ++ AS8SUBL ++ AMULW ++ AMULL ++ AUMULH ++ ACTPOP ++ ACTLZ ++ ACTTZ ++ AZAP ++ AZAPNOT ++ ASEXTB ++ ASEXTH ++ ADIVW ++ AUDIVW ++ AREMW ++ AUREMW ++ ADIVL ++ AUDIVL ++ AREML ++ AUREML ++ AADDPI ++ AADDPIS ++ ASBT ++ ACBT ++ ++ //浮点数运算 ++ AFADDS ++ AFADDD ++ AFSUBS ++ AFSUBD ++ AFMULS ++ AFMULD ++ AFMAS ++ AFMAD ++ AFMSS ++ AFMSD ++ AFNMAS ++ AFNMAD ++ AFNMSS ++ AFNMSD ++ AFSELEQ ++ AFSELNE ++ AFSELLT ++ AFSELLE ++ AFSELGT ++ AFSELGE ++ AFDIVS ++ AFDIVD ++ AFCPYS ++ AFCVTSD ++ AFCVTDS ++ AFCVTDL ++ AFCVTLS ++ AFCVTLD ++ AFCVTLW ++ AFCVTWL ++ AFSQRTS ++ AFSQRTD ++ AFCVTDL_Z ++ AFCVTDL_P ++ AFCVTDL_G ++ AFCVTDL_N ++ AFCMPLE ++ AFCMPLT ++ AFCMPEQ ++ AFCMPUN ++ AFCPYSN ++ AFCPYSE ++ AIFMOVS ++ AIFMOVD ++ AFIMOVS ++ AFIMOVD ++ ARFPCR ++ AWFPCR ++ ASETFPEC0 ++ ASETFPEC1 ++ ASETFPEC2 ++ ASETFPEC3 ++ //杂项指令 ++ AMEMB ++ AIMEMB ++ ARTC ++ ARCID ++ AHALT ++ ARD_F ++ AWR_F ++ ARTID ++ ALLDW ++ ALLDL ++ ALDW_INC ++ ALDL_INC ++ ALDW_DEC ++ ALDL_DEC ++ ALDW_SET ++ ALDL_SET ++ ALSTW ++ ALSTL ++ ALDW_NC ++ ALDL_NC ++ ALDD_NC ++ ASTW_NC ++ ASTL_NC ++ ASTD_NC ++ ACMPEQ ++ ACMPLT ++ ACMPLE ++ ACMPULT ++ ACMPULE ++ AAND ++ ABIC ++ ABIS ++ AORNOT ++ AXOR ++ AEQV ++ AINSLB ++ AINSLH ++ AINSLW ++ AINSLL ++ AINSHB ++ AINSHH ++ AINSHW ++ AINSHL ++ ASLL ++ ASRL ++ ASRA ++ AEXTLB ++ AEXTLH ++ AEXTLW ++ AEXTLL ++ AEXTHB ++ AEXTHH ++ AEXTHW ++ AEXTHL ++ AMASKLB ++ AMASKLH ++ AMASKLW ++ AMASKLL ++ AMASKHB ++ AMASKHH ++ AMASKHW ++ AMASKHL ++ ACMPGEB ++ ASELEQ ++ ASELGE ++ ASELGT ++ ASELLE ++ ASELLT ++ ASELNE ++ ASELLBC ++ ASELLBS ++ APRI_ST ++ APRI_LD ++ ASYMADDR ++ AWORD ++ ANOOP ++ ALDGP ++ ++ // CRC32 ++ ACRC32L ++ ACRC32W ++ ACRC32H ++ ACRC32B ++ ACRC32CL ++ ACRC32CW ++ ACRC32CH ++ ACRC32CB ++ ++ // SIMD ++ AVLDD ++ AVLDS ++ AVSTD ++ AVSTS ++ AVAND ++ AVXOR ++ AVOR ++ AVORNOT ++ AVBIC ++ AVADDW ++ AVADDL ++ AVSUBW ++ AVSUBL ++ AVCMPUEQB ++ AVCMPUGTB ++ AVCPYB ++ AVCPYH ++ AVCTPOP ++ AVCTLZ ++ AVMAXB ++ AVMAXH ++ AVMAXW ++ AVMAXL ++ AVUMAXB ++ AVUMAXH ++ AVUMAXW ++ AVUMAXL ++ AVMINB ++ AVMINH ++ AVMINW ++ AVMINL ++ AVUMINB ++ AVUMINH ++ AVUMINW ++ AVUMINL ++ ALAST ++ ++ // aliases ++ AJMP = obj.AJMP ++ ACALL = obj.ACALL ++ ARET = obj.ARET ++) ++ ++const ( ++ /* mark flags */ ++ FOLL = 1 << 0 ++ LABEL = 1 << 1 ++ LEAF = 1 << 2 ++ SYNC = 1 << 3 ++ BRANCH = 1 << 4 ++ LOAD = 1 << 5 ++ FCMP = 1 << 6 ++ NOSCHED = 1 << 7 ++ CHANGED = 1 << 9 ++ ++ NSCHED = 20 ++) +diff --git a/src/cmd/internal/obj/sw64/anames.go b/src/cmd/internal/obj/sw64/anames.go +new file mode 100644 +index 0000000000..6d87a05e70 +--- /dev/null ++++ b/src/cmd/internal/obj/sw64/anames.go +@@ -0,0 +1,273 @@ ++// Code generated by stringer -i a.out.go -o anames.go -p sw64; DO NOT EDIT. ++ ++package sw64 ++ ++import "cmd/internal/obj" ++ ++var Anames = []string{ ++ obj.A_ARCHSPECIFIC: "SYS_CALL", ++ "SYS_CALL_B", ++ "EXCB", ++ "BR", ++ "LBR", ++ "BSR", ++ "BEQ", ++ "BNE", ++ "BLT", ++ "BLE", ++ "BGT", ++ "BGE", ++ "BLBC", ++ "BLBS", ++ "FBEQ", ++ "FBNE", ++ "FBLT", ++ "FBLE", ++ "FBGT", ++ "FBGE", ++ "MOVB", ++ "MOVBU", ++ "MOVH", ++ "MOVHU", ++ "MOVW", ++ "MOVWU", ++ "MOVV", ++ "MOVF", ++ "MOVD", ++ "LDBU", ++ "LDHU", ++ "LDW", ++ "LDL", ++ "LDL_U", ++ "STB", ++ "STH", ++ "STW", ++ "STL", ++ "STL_U", ++ "FLDS", ++ "FLDD", ++ "FSTS", ++ "FSTD", ++ "LDBUA", ++ "LDHUA", ++ "LDWA", ++ "LDLA", ++ "FLDSA", ++ "FLDDA", ++ "STBA", ++ "STHA", ++ "STWA", ++ "STLA", ++ "FSTSA", ++ "FSTDA", ++ "LDI", ++ "LDF", ++ "LDIH", ++ "ADDW", ++ "SUBW", ++ "S4ADDW", ++ "S4SUBW", ++ "S8ADDW", ++ "S8SUBW", ++ "ADDL", ++ "SUBL", ++ "S4ADDL", ++ "S4SUBL", ++ "S8ADDL", ++ "S8SUBL", ++ "MULW", ++ "MULL", ++ "UMULH", ++ "CTPOP", ++ "CTLZ", ++ "CTTZ", ++ "ZAP", ++ "ZAPNOT", ++ "SEXTB", ++ "SEXTH", ++ "DIVW", ++ "UDIVW", ++ "REMW", ++ "UREMW", ++ "DIVL", ++ "UDIVL", ++ "REML", ++ "UREML", ++ "ADDPI", ++ "ADDPIS", ++ "SBT", ++ "CBT", ++ "FADDS", ++ "FADDD", ++ "FSUBS", ++ "FSUBD", ++ "FMULS", ++ "FMULD", ++ "FMAS", ++ "FMAD", ++ "FMSS", ++ "FMSD", ++ "FNMAS", ++ "FNMAD", ++ "FNMSS", ++ "FNMSD", ++ "FSELEQ", ++ "FSELNE", ++ "FSELLT", ++ "FSELLE", ++ "FSELGT", ++ "FSELGE", ++ "FDIVS", ++ "FDIVD", ++ "FCPYS", ++ "FCVTSD", ++ "FCVTDS", ++ "FCVTDL", ++ "FCVTLS", ++ "FCVTLD", ++ "FCVTLW", ++ "FCVTWL", ++ "FSQRTS", ++ "FSQRTD", ++ "FCVTDL_Z", ++ "FCVTDL_P", ++ "FCVTDL_G", ++ "FCVTDL_N", ++ "FCMPLE", ++ "FCMPLT", ++ "FCMPEQ", ++ "FCMPUN", ++ "FCPYSN", ++ "FCPYSE", ++ "IFMOVS", ++ "IFMOVD", ++ "FIMOVS", ++ "FIMOVD", ++ "RFPCR", ++ "WFPCR", ++ "SETFPEC0", ++ "SETFPEC1", ++ "SETFPEC2", ++ "SETFPEC3", ++ "MEMB", ++ "IMEMB", ++ "RTC", ++ "RCID", ++ "HALT", ++ "RD_F", ++ "WR_F", ++ "RTID", ++ "LLDW", ++ "LLDL", ++ "LDW_INC", ++ "LDL_INC", ++ "LDW_DEC", ++ "LDL_DEC", ++ "LDW_SET", ++ "LDL_SET", ++ "LSTW", ++ "LSTL", ++ "LDW_NC", ++ "LDL_NC", ++ "LDD_NC", ++ "STW_NC", ++ "STL_NC", ++ "STD_NC", ++ "CMPEQ", ++ "CMPLT", ++ "CMPLE", ++ "CMPULT", ++ "CMPULE", ++ "AND", ++ "BIC", ++ "BIS", ++ "ORNOT", ++ "XOR", ++ "EQV", ++ "INSLB", ++ "INSLH", ++ "INSLW", ++ "INSLL", ++ "INSHB", ++ "INSHH", ++ "INSHW", ++ "INSHL", ++ "SLL", ++ "SRL", ++ "SRA", ++ "EXTLB", ++ "EXTLH", ++ "EXTLW", ++ "EXTLL", ++ "EXTHB", ++ "EXTHH", ++ "EXTHW", ++ "EXTHL", ++ "MASKLB", ++ "MASKLH", ++ "MASKLW", ++ "MASKLL", ++ "MASKHB", ++ "MASKHH", ++ "MASKHW", ++ "MASKHL", ++ "CMPGEB", ++ "SELEQ", ++ "SELGE", ++ "SELGT", ++ "SELLE", ++ "SELLT", ++ "SELNE", ++ "SELLBC", ++ "SELLBS", ++ "PRI_ST", ++ "PRI_LD", ++ "SYMADDR", ++ "WORD", ++ "NOOP", ++ "LDGP", ++ "CRC32L", ++ "CRC32W", ++ "CRC32H", ++ "CRC32B", ++ "CRC32CL", ++ "CRC32CW", ++ "CRC32CH", ++ "CRC32CB", ++ "VLDD", ++ "VLDS", ++ "VSTD", ++ "VSTS", ++ "VAND", ++ "VXOR", ++ "VOR", ++ "VORNOT", ++ "VBIC", ++ "VADDW", ++ "VADDL", ++ "VSUBW", ++ "VSUBL", ++ "VCMPUEQB", ++ "VCMPUGTB", ++ "VCPYB", ++ "VCPYH", ++ "VCTPOP", ++ "VCTLZ", ++ "VMAXB", ++ "VMAXH", ++ "VMAXW", ++ "VMAXL", ++ "VUMAXB", ++ "VUMAXH", ++ "VUMAXW", ++ "VUMAXL", ++ "VMINB", ++ "VMINH", ++ "VMINW", ++ "VMINL", ++ "VUMINB", ++ "VUMINH", ++ "VUMINW", ++ "VUMINL", ++ "LAST", ++} +diff --git a/src/cmd/internal/obj/sw64/anames77.go b/src/cmd/internal/obj/sw64/anames77.go +new file mode 100644 +index 0000000000..9486c07a08 +--- /dev/null ++++ b/src/cmd/internal/obj/sw64/anames77.go +@@ -0,0 +1,30 @@ ++// 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 sw64 ++ ++var cnames77 = []string{ ++ "NONE", ++ "RREG", ++ "FREG", ++ "VREG", ++ "REG", ++ "SUCON", ++ "MCON", ++ "LCON", ++ "FCON", ++ "LEXT", ++ "ADDR", ++ "SAUTO", ++ "LAUTO", ++ "ZOREG", ++ "SOREG", ++ "LOREG", ++ "SBRA", ++ "GOTADDR", ++ "GOK", ++ "C_TLS_LE", ++ "C_TLS_IE", ++ "NCLASS", ++} +diff --git a/src/cmd/internal/obj/sw64/asm77.go b/src/cmd/internal/obj/sw64/asm77.go +new file mode 100644 +index 0000000000..e3bc9e8e51 +--- /dev/null ++++ b/src/cmd/internal/obj/sw64/asm77.go +@@ -0,0 +1,2177 @@ ++// cmd/9l/optab.c, cmd/9l/asmout.c from Vita Nuova. ++// ++// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. ++// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) ++// Portions Copyright © 1997-1999 Vita Nuova Limited ++// Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com) ++// Portions Copyright © 2004,2006 Bruce Ellis ++// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) ++// Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others ++// Portions Copyright © 2009 The Go Authors. All rights reserved. ++// ++// Permission is hereby granted, free of charge, to any person obtaining a copy ++// of this software and associated documentation files (the "Software"), to deal ++// in the Software without restriction, including without limitation the rights ++// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++// copies of the Software, and to permit persons to whom the Software is ++// furnished to do so, subject to the following conditions: ++// ++// The above copyright notice and this permission notice shall be included in ++// all copies or substantial portions of the Software. ++// ++// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ++// THE SOFTWARE. ++ ++package sw64 ++ ++import ( ++ "cmd/internal/obj" ++ "cmd/internal/objabi" ++ "fmt" ++ "internal/buildcfg" ++ "log" ++ "math" ++ "sort" ++) ++ ++// ctxt77 holds state while assembling a single function. ++// Each function gets a fresh ctxt77. ++// This allows for multiple functions to be safely concurrently assembled. ++type ctxt77 struct { ++ ctxt *obj.Link ++ newprog obj.ProgAlloc ++ cursym *obj.LSym ++ autosize int32 ++ instoffset int64 ++ pc int64 ++} ++ ++const ( ++ funcAlign = 16 ++) ++ ++type Optab struct { ++ as obj.As ++ a1 uint8 ++ a2 uint8 ++ a3 uint8 ++ a4 uint8 ++ type_ int8 ++ size int8 ++ param int16 ++ flag uint8 ++} ++ ++const ( ++ // Optab.flag ++ NOTUSETMP = 1 << iota // p expands to multiple instructions, but does NOT use REGTMP ++) ++ ++var optab = []Optab{ ++ {obj.ANOP, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0}, ++ {obj.AFUNCDATA, C_SUCON, C_NONE, C_NONE, C_LEXT, 0, 0, 0, 0}, ++ {obj.APCDATA, C_SUCON, C_NONE, C_NONE, C_LCON, 0, 0, 0, 0}, ++ {obj.ARET, C_RREG, C_NONE, C_NONE, C_SOREG, 2, 4, 0, 0}, ++ //zxw add ++ {obj.ARET, C_NONE, C_NONE, C_NONE, C_LEXT, 24, 12, REG_R29, NOTUSETMP}, ++ {AMEMB, C_NONE, C_NONE, C_NONE, C_NONE, 4, 4, 0, 0}, ++ // {ARTC, C_RREG, C_NONE, C_NONE, C_NONE, 4, 4, 0, 0}, ++ {ARD_F, C_RREG, C_NONE, C_NONE, C_NONE, 4, 4, 0, 0}, ++ {ASYS_CALL, C_SUCON, C_NONE, C_NONE, C_NONE, 1, 4, 0, 0}, ++ {AEXCB, C_RREG, C_NONE, C_NONE, C_SAUTO, 2, 4, 0, 0}, ++ ++ {ARFPCR, C_FREG, C_NONE, C_NONE, C_NONE, 6, 4, 0, 0}, ++ {ASETFPEC0, C_NONE, C_NONE, C_NONE, C_NONE, 6, 4, 0, 0}, ++ ++ {AADDW, C_RREG, C_RREG, C_NONE, C_RREG, 6, 4, 0, 0}, ++ {AADDW, C_RREG, C_SUCON, C_NONE, C_RREG, 7, 4, 0, 0}, ++ {AADDW, C_RREG, C_MCON, C_NONE, C_RREG, 14, 8, 0, 0}, ++ {AADDW, C_RREG, C_LCON, C_NONE, C_RREG, 16, 16, 0, 0}, ++ {AADDW, C_RREG, C_NONE, C_NONE, C_RREG, 6, 4, 0, 0}, ++ ++ {ACTPOP, C_RREG, C_RREG, C_NONE, C_RREG, 6, 4, 0, 0}, ++ {AIFMOVS, C_RREG, C_NONE, C_NONE, C_FREG, 6, 4, 0, 0}, ++ {AFIMOVS, C_FREG, C_NONE, C_NONE, C_RREG, 6, 4, 0, 0}, ++ {AFADDS, C_FREG, C_FREG, C_NONE, C_FREG, 6, 4, 0, 0}, ++ {AFSQRTS, C_RREG, C_FREG, C_NONE, C_FREG, 6, 4, 0, 0}, ++ ++ {ALDBU, C_RREG, C_NONE, C_NONE, C_SAUTO, 2, 4, REG_R30, 0}, ++ {ALDBU, C_RREG, C_NONE, C_NONE, C_LAUTO, 17, 20, REG_R30, 0}, ++ {ALDBU, C_RREG, C_NONE, C_NONE, C_SOREG, 2, 4, 0, 0}, ++ {ALDBU, C_RREG, C_NONE, C_NONE, C_LOREG, 17, 20, 0, 0}, ++ {ALDBU, C_RREG, C_NONE, C_NONE, C_LEXT, 12, 8, REG_R29, NOTUSETMP}, ++ {ALDBU, C_RREG, C_NONE, C_NONE, C_TLS_LE, 22, 12, 0, NOTUSETMP}, ++ {ALDBU, C_RREG, C_NONE, C_NONE, C_TLS_IE, 23, 16, 0, 0}, ++ {ASTB, C_RREG, C_NONE, C_NONE, C_SAUTO, 2, 4, REG_R30, 0}, ++ {ASTB, C_RREG, C_NONE, C_NONE, C_LAUTO, 17, 20, REG_R30, 0}, ++ {ASTB, C_RREG, C_NONE, C_NONE, C_SOREG, 2, 4, 0, 0}, ++ {ASTB, C_RREG, C_NONE, C_NONE, C_LOREG, 17, 20, 0, 0}, ++ {ASTB, C_RREG, C_NONE, C_NONE, C_LEXT, 13, 8, REG_R29, 0}, ++ {ASTB, C_RREG, C_NONE, C_NONE, C_TLS_LE, 22, 12, 0, NOTUSETMP}, ++ {ASTB, C_RREG, C_NONE, C_NONE, C_TLS_IE, 23, 16, 0, 0}, ++ ++ {AFLDD, C_FREG, C_NONE, C_NONE, C_SAUTO, 2, 4, REG_R30, 0}, ++ {AFLDD, C_FREG, C_NONE, C_NONE, C_LAUTO, 17, 20, REG_R30, 0}, ++ {AFLDD, C_FREG, C_NONE, C_NONE, C_SOREG, 2, 4, 0, 0}, ++ {AFLDD, C_FREG, C_NONE, C_NONE, C_LOREG, 17, 20, 0, 0}, ++ {AFLDD, C_FREG, C_NONE, C_NONE, C_LEXT, 15, 12, REG_R29, 0}, ++ ++ {AFSTD, C_FREG, C_NONE, C_NONE, C_SAUTO, 2, 4, REG_R30, 0}, ++ {AFSTD, C_FREG, C_NONE, C_NONE, C_LAUTO, 17, 20, REG_R30, 0}, ++ {AFSTD, C_FREG, C_NONE, C_NONE, C_SOREG, 2, 4, 0, 0}, ++ {AFSTD, C_FREG, C_NONE, C_NONE, C_LOREG, 17, 20, 0, 0}, ++ {AFSTD, C_FREG, C_NONE, C_NONE, C_LEXT, 13, 8, REG_R29, 0}, ++ ++ {ALDI, C_RREG, C_NONE, C_NONE, C_MCON, 2, 4, 0, 0}, ++ {ALDI, C_RREG, C_NONE, C_NONE, C_SAUTO, 2, 4, REG_R30, 0}, ++ {ALDI, C_RREG, C_NONE, C_NONE, C_LAUTO, 17, 20, REG_R30, 0}, ++ {ALDI, C_RREG, C_NONE, C_NONE, C_RREG, 2, 4, 0, 0}, ++ {ALDI, C_RREG, C_NONE, C_NONE, C_SOREG, 2, 4, 0, 0}, ++ {ALDI, C_RREG, C_NONE, C_NONE, C_LOREG, 17, 20, 0, 0}, ++ {AADDPI, C_LEXT, C_NONE, C_NONE, C_RREG, 27, 4, 0, 0}, ++ ++ {ASYMADDR, C_RREG, C_NONE, C_NONE, C_LEXT, 12, 8, REG_R29, NOTUSETMP}, ++ {ALLDW, C_RREG, C_NONE, C_NONE, C_SOREG, 5, 4, 0, 0}, ++ {ABR, C_RREG, C_NONE, C_NONE, C_SBRA, 3, 4, 0, 0}, ++ {ABR, C_RREG, C_NONE, C_NONE, C_LEXT, 10, 4, REG_R29, 0}, ++ {AFBGE, C_FREG, C_NONE, C_NONE, C_SBRA, 3, 4, 0, 0}, ++ {AFBGE, C_FREG, C_NONE, C_NONE, C_LEXT, 10, 4, REG_R29, 0}, ++ {obj.AJMP, C_RREG, C_NONE, C_NONE, C_LEXT, 9, 12, REG_R29, NOTUSETMP}, ++ {obj.AJMP, C_RREG, C_NONE, C_NONE, C_SOREG, 21, 4, 0, 0}, ++ ++ {AFMAS, C_FREG, C_FREG, C_FREG, C_FREG, 8, 4, 0, 0}, ++ {ASELEQ, C_RREG, C_RREG, C_RREG, C_RREG, 8, 4, 0, 0}, ++ ++ {AMOVD, C_GOTADDR, C_NONE, C_NONE, C_RREG, 25, 8, 0, 0}, ++ {ASYMADDR, C_RREG, C_NONE, C_NONE, C_GOTADDR, 26, 8, 0, 0}, ++ ++ {AVADDW, C_VREG, C_VREG, C_NONE, C_VREG, 30, 4, 0, 0}, ++ {AVADDW, C_VREG, C_NONE, C_NONE, C_VREG, 30, 4, 0, 0}, ++ {AVAND, C_VREG, C_VREG, C_NONE, C_VREG, 31, 4, 0, 0}, ++ {AVAND, C_VREG, C_NONE, C_NONE, C_VREG, 31, 4, 0, 0}, ++ {AVLDD, C_VREG, C_NONE, C_NONE, C_SOREG, 32, 4, 0, 0}, ++ //{AVLDD, C_SOREG, C_NONE, C_NONE, C_VREG, 32, 4, 0, 0}, ++ {AVSTD, C_VREG, C_NONE, C_NONE, C_SOREG, 32, 4, 0, 0}, ++ {AVCPYB, C_FREG, C_NONE, C_NONE, C_VREG, 33, 4, 0, 0}, ++ {AVCTPOP, C_VREG, C_NONE, C_NONE, C_VREG, 34, 4, 0, 0}, ++ ++ {AMOVB, C_RREG, C_NONE, C_NONE, C_RREG, 35, 4, 0, 0}, ++ {AMOVBU, C_RREG, C_NONE, C_NONE, C_RREG, 36, 4, 0, 0}, ++ ++ {ALDGP, C_RREG, C_NONE, C_NONE, C_RREG, 20, 16, 0, 0}, ++ {ANOOP, C_NONE, C_NONE, C_NONE, C_NONE, 11, 4, 0, 0}, ++ {obj.AUNDEF, C_NONE, C_NONE, C_NONE, C_NONE, 18, 4, 0, 0}, ++ {AWORD, C_LCON, C_NONE, C_NONE, C_NONE, 19, 4, 0, 0}, ++ {obj.AXXX, C_NONE, C_NONE, C_NONE, C_NONE, 0, 4, 0, 0}, ++} ++ ++var oprange [ALAST & obj.AMask][]Optab ++ ++var xcmp [C_NCLASS][C_NCLASS]bool ++ ++func span77(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { ++ if ctxt.Retpoline { ++ ctxt.Diag("-spectre=ret not supported on sw64") ++ ctxt.Retpoline = false // don't keep printing ++ } ++ p := cursym.Func().Text ++ if p == nil || p.Link == nil { // handle external functions and ELF section symbols ++ return ++ } ++ ++ c := ctxt77{ctxt: ctxt, newprog: newprog, cursym: cursym, autosize: int32(p.To.Offset + ctxt.Arch.FixedFrameSize)} ++ ++ if oprange[AADDL&obj.AMask] == nil { ++ c.ctxt.Diag("sw64 ops not initialized, call sw64.buildop first") ++ ++ } ++ ++ pc := int64(0) ++ p.Pc = pc ++ ++ var m int ++ var o *Optab ++ for p = p.Link; p != nil; p = p.Link { ++ p.Pc = pc ++ o = c.oplook(p) ++ m = int(o.size) ++ if m == 0 { ++ if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA { ++ c.ctxt.Diag("zero-width instruction\n%v", p) ++ } ++ continue ++ } ++ ++ if (p.As == ALSTW || p.As == ALSTL) && p.Pc&0x7 != 0 { ++ m += 4 ++ } ++ pc += int64(m) ++ } ++ ++ c.cursym.Size = pc ++ ++ /* ++ * if any procedure is large enough to ++ * generate a large SBRA branch, then ++ * generate extra passes putting branches ++ * around jmps to fix. this is rare. ++ */ ++ /* bflag := 1 ++ ++ var otxt int64 ++ var q *obj.Prog ++ for bflag != 0 { ++ bflag = 0 ++ pc = 0 ++ for p = c.cursym.Func().Text.Link; p != nil; p = p.Link { ++ p.Pc = pc ++ o = c.oplook(p) ++ // very large conditional branches ++ if (o.type_ == 3 || o.type_ == 10) && p.To.Target() != nil { ++ otxt = p.To.Target().Pc - pc ++ if otxt < -(1<<17)+10 || otxt >= (1<<17)-10 { ++ q = c.newprog() ++ q.Link = p.Link ++ p.Link = q ++ q.As = ABR ++ q.To.Type = obj.TYPE_BRANCH ++ q.To.SetTarget(p.To.Target()) ++ p.To.SetTarget(q) ++ q = c.newprog() ++ q.Link = p.Link ++ p.Link = q ++ q.As = ABR ++ q.To.Type = obj.TYPE_BRANCH ++ q.To.SetTarget(q.Link.Link) ++ c.addnop(p.Link) ++ c.addnop(p) ++ bflag = 1 ++ } ++ } ++ m = int(o.size) ++ if m == 0 { ++ if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA { ++ c.ctxt.Diag("zero-width instruction\n%v", p) ++ } ++ continue ++ } ++ ++ pc += int64(m) ++ } ++ ++ c.cursym.Size = pc ++ } ++ ++ pc += -pc & (funcAlign - 1) ++ c.cursym.Size = pc ++ */ ++ /* ++ * lay out the code, emitting code and data relocations. ++ */ ++ c.cursym.Grow(c.cursym.Size) ++ bp := c.cursym.P ++ var i int32 ++ var out [5]uint32 ++ for p := c.cursym.Func().Text.Link; p != nil; p = p.Link { ++ c.pc = p.Pc ++ o = c.oplook(p) ++ if int(o.size) > 4*len(out) { ++ log.Fatalf("out array in span77 is too small, need at least %d for %v", o.size/4, p) ++ } ++ c.asmout(p, o, out[:]) ++ n := o.size ++ if (p.As == ALSTW || p.As == ALSTL) && p.Pc&0x7 != 0 { ++ n += 4 ++ } ++ for i = 0; i < int32(n/4); i++ { ++ c.ctxt.Arch.ByteOrder.PutUint32(bp, out[i]) ++ bp = bp[4:] ++ } ++ } ++ ++ // Mark nonpreemptible instruction sequences. ++ // We use REGTMP as a scratch register during call injection, ++ // so instruction sequences that use REGTMP are unsafe to ++ // preempt asynchronously. ++ obj.MarkUnsafePoints(c.ctxt, c.cursym.Func().Text, c.newprog, c.isUnsafePoint, c.isRestartable) ++ ++ // Now that we know byte offsets, we can generate jump table entries. ++ for _, jt := range cursym.Func().JumpTables { ++ for i, p := range jt.Targets { ++ // The ith jumptable entry points to the p.Pc'th ++ // byte in the function symbol s. ++ jt.Sym.WriteAddr(ctxt, int64(i)*8, 8, cursym, p.Pc) ++ } ++ } ++ ++ verifyLock(c) ++} ++ ++// isUnsafePoint returns whether p is an unsafe point. ++func (c *ctxt77) isUnsafePoint(p *obj.Prog) bool { ++ // If p explicitly uses REGTMP, it's unsafe to preempt, because the ++ // preemption sequence clobbers REGTMP. ++ return p.From.Reg == REGTMP || p.To.Reg == REGTMP || p.Reg == REGTMP ++} ++ ++// isRestartable returns whether p is a multi-instruction sequence that, ++// if preempted, can be restarted. ++func (c *ctxt77) isRestartable(p *obj.Prog) bool { ++ if c.isUnsafePoint(p) { ++ return false ++ } ++ // If p is a multi-instruction sequence with uses REGTMP inserted by ++ // the assembler in order to materialize a large constant/offset, we ++ // can restart p (at the start of the instruction sequence), recompute ++ // the content of REGTMP, upon async preemption. Currently, all cases ++ // of assembler-inserted REGTMP fall into this category. ++ // If p doesn't use REGTMP, it can be simply preempted, so we don't ++ // mark it. ++ o := c.oplook(p) ++ return o.size > 4 && o.flag&NOTUSETMP == 0 ++} ++ ++func verifyLock(c ctxt77) { ++ for p := c.cursym.Func().Text.Link; p != nil; p = p.Link { ++ // 判断锁装入指令与写锁标志指令是否成对出现 ++ if p.As == ALLDW || p.As == ALLDL { ++ for q := p; q != nil; q = q.Link { ++ if q.As != AWR_F { ++ if q.As == ALSTW || q.As == ALSTL { ++ c.ctxt.Diag("missing WR_F after %s\n", p.As) ++ return ++ } else { ++ if (q.Pc + 4) == c.cursym.Size { ++ c.ctxt.Diag("Atomic operation is not logical!\n") ++ return ++ } ++ continue ++ } ++ } else { ++ break ++ } ++ } ++ } ++ if p.As == ALSTW || p.As == ALSTL { ++ // 判断锁存储指令与读锁标志指令是否成对出现 ++ if p.Link.As != ARD_F { ++ c.ctxt.Diag("missing RD_F after %s\n", p.As) ++ return ++ } ++ } ++ } ++ ++} ++ ++func IsReg(r int) bool { ++ return REG_R0 <= r && r <= REG_V31 ++} ++func IsFReg(r int) bool { ++ return REG_F0 <= r && r <= REG_F31 ++} ++func IsRReg(r int) bool { ++ return REG_R0 <= r && r <= REG_R31 ++} ++func IsVReg(r int) bool { ++ return REG_V0 <= r && r <= REG_V31 ++} ++func isint16(v int64) bool { ++ return int64(int16(v)) == v ++} ++func isuint8(v uint64) bool { ++ return uint64(uint8(v)) == v ++} ++ ++func isint32(v int64) bool { ++ return int64(int32(v)) == v ++} ++ ++func isuint32(v uint64) bool { ++ return uint64(uint32(v)) == v ++} ++ ++func (c *ctxt77) aclass(a *obj.Addr) int { ++ if a.Sym != nil { // use relocation ++ if a.Sym.Type == objabi.STLSBSS { ++ if c.ctxt.Flag_shared { ++ return C_TLS_IE ++ } else { ++ return C_TLS_LE ++ } ++ } ++ } ++ switch a.Type { ++ case obj.TYPE_NONE: ++ return C_NONE ++ ++ case obj.TYPE_REG: ++ if IsRReg(int(a.Reg)) { ++ return C_RREG ++ } ++ ++ if IsFReg(int(a.Reg)) { ++ return C_FREG ++ } ++ ++ if IsVReg(int(a.Reg)) { ++ return C_VREG ++ } ++ ++ case obj.TYPE_CONST: ++ if isuint8(uint64(a.Offset)) { ++ return C_SUCON ++ } ++ if isint16(a.Offset) { ++ return C_MCON ++ } ++ return C_LCON ++ ++ case obj.TYPE_FCONST: ++ return C_FCON ++ ++ case obj.TYPE_MEM, ++ obj.TYPE_ADDR: ++ switch a.Name { ++ case obj.NAME_GOTREF: ++ return C_GOTADDR ++ case obj.NAME_EXTERN, obj.NAME_STATIC: ++ if a.Sym.Type == objabi.STLSBSS { ++ c.ctxt.Diag("taking address of TLS variable is not supported") ++ } ++ return C_LEXT ++ case obj.NAME_PARAM, obj.NAME_AUTO: ++ if isint16(a.Offset) { ++ return C_SAUTO ++ } ++ if a.Offset > math.MaxInt16 || -a.Offset > math.MaxInt16 { ++ return C_LAUTO ++ } ++ case obj.NAME_NONE: ++ if isint16(a.Offset) { ++ return C_SOREG ++ } ++ if a.Offset > math.MaxInt16 || -a.Offset > math.MaxInt16 { ++ return C_LOREG ++ } ++ } ++ return C_ADDR ++ ++ case obj.TYPE_BRANCH: ++ switch a.Name { ++ case obj.NAME_EXTERN, obj.NAME_STATIC: ++ return C_LEXT ++ } ++ return C_SBRA ++ case obj.TYPE_INDIR: ++ switch a.Name { ++ case obj.NAME_EXTERN, obj.NAME_STATIC: ++ return C_LEXT ++ } ++ } ++ return C_GOK ++} ++ ++func prasm(p *obj.Prog) { ++ fmt.Printf("%v\n", p) ++} ++ ++func (c *ctxt77) oplook(p *obj.Prog) *Optab { ++ if oprange[AADDL&obj.AMask] == nil { ++ c.ctxt.Diag("sw64 ops not initialized, call sw64.buildop first") ++ } ++ a1 := int(p.Optab) ++ if a1 != 0 { ++ return &optab[a1-1] ++ } ++ a1 = int(p.From.Class) ++ if a1 == 0 { ++ a1 = c.aclass(&p.From) + 1 ++ p.From.Class = int8(a1) ++ } ++ ++ a1-- ++ ++ a3 := C_NONE ++ if len(p.RestArgs) == 2 { ++ a3 = int(p.RestArgs[1].Addr.Class) ++ if a3 == 0 { ++ a3 = c.aclass(&p.RestArgs[1].Addr) + 1 ++ p.GetFrom3().Class = int8(a3) ++ } ++ a3-- ++ ++ } ++ ++ a2 := C_NONE ++ if p.Reg != 0 { ++ a2 = C_RREG ++ if IsFReg(int(p.Reg)) { ++ a2 = C_FREG ++ } ++ if IsVReg(int(p.Reg)) { ++ a2 = C_VREG ++ } ++ } ++ if (p.Reg == 0) && (len(p.RestArgs) != 0) { ++ a2 = int(p.RestArgs[0].Addr.Class) ++ if a2 == 0 { ++ a2 = c.aclass(&p.RestArgs[0].Addr) + 1 ++ p.RestArgs[0].Addr.Class = int8(a2) ++ } ++ a2-- ++ } ++ a4 := int(p.To.Class) ++ if a4 == 0 { ++ a4 = c.aclass(&p.To) + 1 ++ p.To.Class = int8(a4) ++ } ++ ++ a4-- ++ ++ ops := oprange[p.As&obj.AMask] ++ c1 := &xcmp[a1] ++ c2 := &xcmp[a2] ++ c3 := &xcmp[a3] ++ c4 := &xcmp[a4] ++ for i := range ops { ++ op := &ops[i] ++ if c1[op.a1] && c2[op.a2] && c3[op.a3] && c4[op.a4] { ++ p.Optab = uint16(cap(optab) - cap(ops) + i + 1) ++ return op ++ } ++ } ++ ++ c.ctxt.Diag("illegal combination %v %v %v %v %v", p.As, DRconv(a1), DRconv(a2), DRconv(a3), DRconv(a4)) ++ prasm(p) ++ if ops == nil { ++ ops = optab ++ } ++ return &ops[0] ++} ++ ++func cmp(a int, b int) bool { ++ if a == b { ++ return true ++ } ++ switch a { ++ case C_LCON: ++ if b == C_SUCON || b == C_MCON { ++ return true ++ } ++ ++ case C_MCON: ++ if b == C_SUCON { ++ return true ++ } ++ ++ case C_LAUTO: ++ if b == C_SAUTO { ++ return true ++ } ++ ++ case C_LOREG: ++ if b == C_ZOREG || b == C_SOREG { ++ return true ++ } ++ ++ case C_SOREG: ++ if b == C_ZOREG { ++ return true ++ } ++ ++ } ++ ++ return false ++} ++ ++type ocmp []Optab ++ ++func (x ocmp) Len() int { ++ return len(x) ++} ++ ++func (x ocmp) Swap(i, j int) { ++ x[i], x[j] = x[j], x[i] ++} ++ ++func (x ocmp) Less(i, j int) bool { ++ p1 := &x[i] ++ p2 := &x[j] ++ n := int(p1.as) - int(p2.as) ++ if n != 0 { ++ return n < 0 ++ } ++ n = int(p1.a1) - int(p2.a1) ++ if n != 0 { ++ return n < 0 ++ } ++ n = int(p1.a2) - int(p2.a2) ++ if n != 0 { ++ return n < 0 ++ } ++ n = int(p1.a3) - int(p2.a3) ++ if n != 0 { ++ return n < 0 ++ } ++ n = int(p1.a4) - int(p2.a4) ++ if n != 0 { ++ return n < 0 ++ } ++ return false ++} ++ ++func opset(a, b0 obj.As) { ++ oprange[a&obj.AMask] = oprange[b0] ++} ++ ++func buildop(ctxt *obj.Link) { ++ if oprange[AADDL&obj.AMask] != nil { ++ // Already initialized; stop now. ++ // This happens in the cmd/asm tests, ++ // each of which re-initializes the arch. ++ return ++ } ++ ++ var n int ++ ++ for i := 0; i < C_NCLASS; i++ { ++ for n = 0; n < C_NCLASS; n++ { ++ if cmp(n, i) { ++ xcmp[i][n] = true ++ } ++ } ++ } ++ for n = 0; optab[n].as != obj.AXXX; n++ { ++ } ++ sort.Sort(ocmp(optab[:n])) ++ for i := 0; i < n; i++ { ++ r := optab[i].as ++ r0 := r & obj.AMask ++ start := i ++ for optab[i].as == r { ++ i++ ++ } ++ oprange[r0] = optab[start:i] ++ i-- ++ ++ switch r { ++ default: ++ ctxt.Diag("unknown op in build: %v", r) ++ ctxt.DiagFlush() ++ log.Fatalf("bad code") ++ case ASYS_CALL: ++ opset(ASYS_CALL_B, r0) ++ case AEXCB: ++ opset(APRI_LD, r0) ++ opset(APRI_ST, r0) ++ case AADDW: ++ opset(AADDL, r0) ++ opset(ASUBL, r0) ++ opset(ASUBW, r0) ++ opset(AMULW, r0) ++ opset(AMULL, r0) ++ opset(AUMULH, r0) ++ opset(ACMPEQ, r0) ++ opset(ACMPLT, r0) ++ opset(ACMPLE, r0) ++ opset(ACMPULT, r0) ++ opset(ACMPULE, r0) ++ opset(AAND, r0) ++ opset(ABIS, r0) ++ opset(AXOR, r0) ++ opset(AORNOT, r0) ++ opset(ASLL, r0) ++ opset(ASRL, r0) ++ opset(ASRA, r0) ++ opset(ASEXTB, r0) ++ opset(ASEXTH, r0) ++ opset(AS4ADDW, r0) ++ opset(AS4SUBW, r0) ++ opset(AS8ADDW, r0) ++ opset(AS8SUBW, r0) ++ opset(AS4ADDL, r0) ++ opset(AS4SUBL, r0) ++ opset(AS8ADDL, r0) ++ opset(AS8SUBL, r0) ++ opset(ABIC, r0) ++ opset(AEQV, r0) ++ opset(AINSLB, r0) ++ opset(AINSLH, r0) ++ opset(AINSLW, r0) ++ opset(AINSLL, r0) ++ opset(AINSHB, r0) ++ opset(AINSHH, r0) ++ opset(AINSHW, r0) ++ opset(AINSHL, r0) ++ opset(AEXTLB, r0) ++ opset(AEXTLH, r0) ++ opset(AEXTLW, r0) ++ opset(AEXTLL, r0) ++ opset(AEXTHB, r0) ++ opset(AEXTHH, r0) ++ opset(AEXTHW, r0) ++ opset(AEXTHL, r0) ++ opset(AMASKLB, r0) ++ opset(AMASKLH, r0) ++ opset(AMASKLW, r0) ++ opset(AMASKLL, r0) ++ opset(AMASKHB, r0) ++ opset(AMASKHH, r0) ++ opset(AMASKHW, r0) ++ opset(AMASKHL, r0) ++ opset(ACMPGEB, r0) ++ opset(AZAP, r0) ++ opset(AZAPNOT, r0) ++ opset(ASBT, r0) ++ opset(ACBT, r0) ++ opset(ACRC32CL, r0) ++ opset(ACRC32CW, r0) ++ opset(ACRC32CH, r0) ++ opset(ACRC32CB, r0) ++ opset(ACRC32L, r0) ++ opset(ACRC32W, r0) ++ opset(ACRC32H, r0) ++ opset(ACRC32B, r0) ++ case ABR: ++ opset(ABSR, r0) ++ opset(ABEQ, r0) ++ opset(ABGE, r0) ++ opset(ABGT, r0) ++ opset(ABLE, r0) ++ opset(ABLT, r0) ++ opset(ABNE, r0) ++ opset(ABLBC, r0) ++ opset(ABLBS, r0) ++ case AFBGE: ++ opset(AFBGT, r0) ++ opset(AFBEQ, r0) ++ opset(AFBLE, r0) ++ opset(AFBLT, r0) ++ opset(AFBNE, r0) ++ case AMEMB: ++ opset(AIMEMB, r0) ++ case ARD_F: ++ opset(AWR_F, r0) ++ // opset(ARTC, r0) ++ case ALLDW: ++ opset(ALLDL, r0) ++ opset(ALSTW, r0) ++ opset(ALSTL, r0) ++ case AFMAS: ++ opset(AFMAD, r0) ++ opset(AFMSS, r0) ++ opset(AFMSD, r0) ++ opset(AFNMAS, r0) ++ opset(AFNMAD, r0) ++ opset(AFNMSS, r0) ++ opset(AFNMSD, r0) ++ opset(AFSELEQ, r0) ++ opset(AFSELNE, r0) ++ opset(AFSELLT, r0) ++ opset(AFSELLE, r0) ++ opset(AFSELGT, r0) ++ opset(AFSELGE, r0) ++ case ASELEQ: ++ opset(ASELNE, r0) ++ opset(ASELGE, r0) ++ opset(ASELGT, r0) ++ opset(ASELLE, r0) ++ opset(ASELLT, r0) ++ opset(ASELLBC, r0) ++ opset(ASELLBS, r0) ++ case ALDBU: ++ opset(ALDHU, r0) ++ opset(ALDW, r0) ++ opset(ALDL, r0) ++ opset(ALDBUA, r0) ++ opset(ALDHUA, r0) ++ opset(ALDWA, r0) ++ opset(ALDLA, r0) ++ opset(AFLDSA, r0) ++ opset(AFLDDA, r0) ++ case AVLDD: ++ opset(AVLDS, r0) ++ opset(ALDL_U, r0) ++ case ASTB: ++ opset(ASTH, r0) ++ opset(ASTW, r0) ++ opset(ASTL, r0) ++ opset(ASTBA, r0) ++ opset(ASTHA, r0) ++ opset(ASTWA, r0) ++ opset(ASTLA, r0) ++ opset(AFSTSA, r0) ++ opset(AFSTDA, r0) ++ case AVSTD: ++ opset(AVSTS, r0) ++ opset(ASTL_U, r0) ++ case ACTPOP: ++ opset(ACTLZ, r0) ++ opset(ACTTZ, r0) ++ opset(ADIVW, r0) ++ opset(AUDIVW, r0) ++ opset(AREMW, r0) ++ opset(AUREMW, r0) ++ opset(ADIVL, r0) ++ opset(AUDIVL, r0) ++ opset(AREML, r0) ++ opset(AUREML, r0) ++ case AFIMOVS: ++ opset(AFIMOVD, r0) ++ case AIFMOVS: ++ opset(AIFMOVD, r0) ++ case AFADDS: ++ opset(AFADDD, r0) ++ opset(AFSUBS, r0) ++ opset(AFSUBD, r0) ++ opset(AFMULS, r0) ++ opset(AFMULD, r0) ++ opset(AFDIVS, r0) ++ opset(AFDIVD, r0) ++ opset(AFCMPEQ, r0) ++ opset(AFCMPLE, r0) ++ opset(AFCMPLT, r0) ++ opset(AFCMPUN, r0) ++ opset(AFCPYS, r0) ++ opset(AFCPYSE, r0) ++ opset(AFCPYSN, r0) ++ case AFSQRTS: ++ opset(AFSQRTD, r0) ++ opset(AFCVTSD, r0) ++ opset(AFCVTDS, r0) ++ opset(AFCVTDL_G, r0) ++ opset(AFCVTDL_P, r0) ++ opset(AFCVTDL_Z, r0) ++ opset(AFCVTDL_N, r0) ++ opset(AFCVTDL, r0) ++ opset(AFCVTWL, r0) ++ opset(AFCVTLW, r0) ++ opset(AFCVTLS, r0) ++ opset(AFCVTLD, r0) ++ case ARFPCR: ++ opset(AWFPCR, r0) ++ case ASETFPEC0: ++ opset(ASETFPEC1, r0) ++ opset(ASETFPEC2, r0) ++ opset(ASETFPEC3, r0) ++ case AFLDD: ++ opset(AFLDS, r0) ++ case AFSTD: ++ opset(AFSTS, r0) ++ case ALDI: ++ opset(ALDIH, r0) ++ case obj.AJMP: ++ opset(obj.ACALL, r0) ++ case AADDPI: ++ opset(AADDPIS, r0) ++ // SIMD v2 ++ case AVAND: ++ opset(AVOR, r0) ++ opset(AVXOR, r0) ++ opset(AVORNOT, r0) ++ opset(AVBIC, r0) ++ case AVCPYB: ++ opset(AVCPYH, r0) ++ case AVADDW: ++ opset(AVADDL, r0) ++ opset(AVSUBW, r0) ++ opset(AVSUBL, r0) ++ opset(AVCMPUEQB, r0) ++ opset(AVCMPUGTB, r0) ++ opset(AVMAXB, r0) ++ opset(AVMAXH, r0) ++ opset(AVMAXW, r0) ++ opset(AVMAXL, r0) ++ opset(AVUMAXB, r0) ++ opset(AVUMAXH, r0) ++ opset(AVUMAXW, r0) ++ opset(AVUMAXL, r0) ++ opset(AVMINB, r0) ++ opset(AVMINH, r0) ++ opset(AVMINW, r0) ++ opset(AVMINL, r0) ++ opset(AVUMINB, r0) ++ opset(AVUMINH, r0) ++ opset(AVUMINW, r0) ++ opset(AVUMINL, r0) ++ case AVCTPOP: ++ opset(AVCTLZ, r0) ++ case AMOVB: ++ opset(AMOVH, r0) ++ opset(AMOVW, r0) ++ opset(AMOVV, r0) ++ case AMOVBU: ++ opset(AMOVHU, r0) ++ opset(AMOVWU, r0) ++ case ASYMADDR, ++ ALDGP, ++ obj.ANOP, ++ obj.AFUNCDATA, ++ obj.APCDATA, ++ obj.AUNDEF, ++ obj.ARET, ++ ANOOP, ++ AMOVD, ++ AWORD: ++ break ++ } ++ ++ } ++ ++} ++ ++// 操作码 ++func SP(x uint32, y uint32) uint32 { ++ return x<<30 | y<<26 ++} ++ ++// 带功能码的指令 ++func FLD(x uint32) uint32 { ++ return SP(0, 0x1E) | x<<12 ++} ++func FMM(x uint32, y uint32) uint32 { ++ return SP(0, 6) | x<<8 | y<<0 ++} ++ ++func FA(x uint32, y uint32) uint32 { ++ return SP(1, 0) | x<<9 | y<<5 ++} ++ ++func VFA(x uint32, y uint32) uint32 { ++ return SP(1, 0xa) | x<<9 | y<<5 ++} ++ ++func FAF(x uint32, y uint32) uint32 { ++ return SP(1, 8) | x<<9 | y<<5 ++} ++ ++func FAI(x uint32, y uint32) uint32 { ++ return SP(1, 2) | x<<9 | y<<5 ++} ++ ++func FCA(x uint32, y uint32) uint32 { ++ return SP(1, 9) | x<<14 | y<<10 ++} ++ ++func VFCA(x uint32, y uint32) uint32 { ++ return SP(1, 0xb) | x<<14 | y<<10 ++} ++ ++func VLOG(x uint32, y uint32) uint32 { ++ return SP(1, 4) | x<<26 | y<<10 ++} ++ ++// 系统调用指令 ++func OP_SYSCALL(op uint32, fn uint32) uint32 { ++ return op | fn ++} ++ ++// 转移控制指令 ++func OP_CONTROL(op uint32, ra int16, disp int32) uint32 { ++ return op | uint32(ra)<<21 | uint32(disp)&(1<<21-1) ++} ++ ++// 存储器指令 ++func OP_MEMORY(op uint32, ra int16, rb int16, disp int16) uint32 { ++ return op | uint32(ra)<<21 | uint32(rb)<<16 | uint32(uint16(disp)) ++} ++ ++// 杂项指令 ++func OP_MISI_MEMORY(op uint32, ra int16, rb int16) uint32 { ++ return op | uint32(ra)<<21 | uint32(rb)<<16 ++} ++ ++// 带功能域的存储器指令 ++func OP_FUNC_MEMORY(op uint32, ra int16, rb int16, disp int16) uint32 { ++ return op | uint32(ra)<<21 | uint32(rb)<<16 | uint32(uint16(disp)) ++} ++ ++// 简单运算指令寄存器格式 ++func OP_ARITHMETIC(op uint32, ra int16, rb int16, rc int16) uint32 { ++ return op | uint32(ra)<<21 | uint32(rb)<<16 | uint32(rc) ++} ++ ++// 简单运算指令立即数格式 ++func OP_ARITHMETIC_I(op uint32, ra int16, ib int16, rc int16) uint32 { ++ return op | uint32(ra)<<21 | uint32(ib)<<13 | uint32(rc) ++} ++ ++// 简单运算指令立即数格式 ++func OP_ADDPI(op uint32, rc int16, ib int16) uint32 { ++ return op | uint32(ib)<<13 | uint32(rc) ++} ++ ++// 浮点复合运算指令 ++func OP_COMPLEX_ARITHMETIC(op uint32, ra int16, rb int16, rc int16, rd int16) uint32 { ++ return op | uint32(ra)<<21 | uint32(rb)<<16 | uint32(rc)<<5 | uint32(rd) ++} ++ ++func (c *ctxt77) asmout(p *obj.Prog, o *Optab, out []uint32) { ++ o1 := uint32(0) ++ o2 := uint32(0) ++ o3 := uint32(0) ++ o4 := uint32(0) ++ o5 := uint32(0) ++ ++ switch o.type_ { ++ default: ++ c.ctxt.Diag("unknown type %d %v", o.type_) ++ prasm(p) ++ ++ case 0: /* buildNull */ ++ break ++ case 1: /*OPC_SYSCALL*/ ++ o1 = OP_SYSCALL(c.oprrr(p.As), uint32(p.From.Offset)) ++ case 2: /*OPC_MEMORY*/ ++ disp := p.To.Offset ++ ++ if (disp > 0 && disp&0xffff != disp) || ++ (disp < 0 && -disp&0xffff != -disp) { ++ c.ctxt.Diag("Memory instruction with immediate(0x%x) bigger than 0xffff at\n%v\n", disp, p) ++ } ++ ++ o1 = OP_MEMORY(c.oprrr(p.As), getRegister(p.From.Reg), getRegister(p.To.Reg), int16(disp)) ++ case 3: /*OPC_CONTROL*/ ++ if p.To.Type == obj.TYPE_BRANCH { ++ target := p.To.Val.(*obj.Prog) ++ offset := (target.Pc - p.Pc - 4) ++ //offset := (p.To.Target().Pc - p.Pc - 4) ++ o1 = OP_CONTROL(c.oprrr(p.As), getRegister(p.From.Reg), int32(offset)/4) ++ } else { ++ o1 = OP_CONTROL(c.oprrr(p.As), getRegister(p.From.Reg), int32(p.To.Offset)/4) ++ } ++ case 4: /*OPC_MISI_MEMORY*/ ++ o1 = OP_MISI_MEMORY(c.oprrr(p.As), getRegister(p.From.Reg), getRegister(p.To.Reg)) ++ case 5: /*OPC_FUNC_MEMORY*/ ++ disp := p.To.Offset ++ ++ if (disp >= 0x1000) || (disp <= -0x1000) { ++ c.ctxt.Diag("Memory instruction with immediate(0x%x) bigger than 0x1000 at\n%v\n", disp, p) ++ } ++ if (p.As == ALSTW || p.As == ALSTL) && p.Pc&0x7 != 0 { ++ o1 = OP_MEMORY(c.oprrr(ALDIH), REGZERO, REGSP, 0) ++ o2 = OP_FUNC_MEMORY(c.oprrr(p.As), getRegister(p.From.Reg), getRegister(p.To.Reg), int16(disp)) ++ } else { ++ o1 = OP_FUNC_MEMORY(c.oprrr(p.As), getRegister(p.From.Reg), getRegister(p.To.Reg), int16(disp)) ++ } ++ case 6: /*OPC_ARITHMETIC*/ ++ o1 = OP_ARITHMETIC(c.oprrr(p.As), getRegister(p.From.Reg), getReg2(p), getRegister(p.To.Reg)) ++ case 7: /*OPC_ARITHMETIC_I*/ ++ ib := p.RestArgs[0].Offset ++ ++ if ib > 255 { ++ c.ctxt.Diag("Arithmetic instruction with immediate(0x%x) bigger than 0xff at\n%v\n", ib, p) ++ } ++ ++ o1 = OP_ARITHMETIC_I(c.opirr(p.As), getRegister(p.From.Reg), int16(ib), getRegister(p.To.Reg)) ++ case 8: /*OPC_COMPLEX_ARITHMETIC*/ ++ o1 = OP_COMPLEX_ARITHMETIC(c.oprrr(p.As), getRegister(p.From.Reg), getReg2(p), getFrom3Reg(p), getRegister(p.To.Reg)) ++ ++ case 9: /*buildCall,obj.AJMP, obj.ACALL*/ ++ sym := p.To.Sym ++ r := getRegister(p.From.Reg) ++ pv := REG_R27 & int16(31) ++ if buildcfg.GOSW64 == 6 { ++ o1 = OP_ARITHMETIC(c.oprrr(ABIS), 31, 31, 31) // only for alignment ++ o2 = OP_ADDPI(c.oprrr(AADDPI), REG_R26&31, 4) // addpi r, sym ++ o3 = OP_SYSCALL(c.oprrr(ALBR), 0) ++ addrel(c.ctxt, c.cursym, int32(p.Pc+8), p.To.Offset, sym, objabi.R_CALLSW64) ++ } else { ++ o1 = OP_MEMORY(c.oprrr(ALDIH), pv, REGSB&31, 0) // ldih R27, sym(GP) ++ addrel(c.ctxt, c.cursym, int32(p.Pc), p.To.Offset, sym, objabi.R_SW64_GPRELHIGH) ++ o2 = OP_MEMORY(c.oprrr(ALDI), pv, pv, 0) // ldi R27, sym_lo(R27) ++ addrel(c.ctxt, c.cursym, int32(p.Pc+4), p.To.Offset, sym, objabi.R_SW64_GPRELLOW) ++ o3 = OP_MEMORY(c.oprrr(p.As), r, pv, 0) //CALL/JMP R, (R27) ++ addrel(c.ctxt, c.cursym, int32(p.Pc+8), p.To.Offset, sym, objabi.R_SW64_HINT) ++ } ++ case 10: /*buildCall,ABSR, ABR,ABEQ, ABGE, ABGT, ABLE, ABLT,ABNE, ABLBC, ABLBS, AFBEQ, AFBGE, AFBGT, AFBLE, AFBLT, AFBNE*/ ++ sym := p.To.Sym ++ addrel(c.ctxt, c.cursym, int32(p.Pc), p.To.Offset, sym, objabi.R_SW64_BRADDR) ++ ++ if p.To.Type == obj.TYPE_BRANCH { ++ target := p.To.Val.(*obj.Prog) ++ offset := (target.Pc - p.Pc - 4) ++ //offset := (p.To.Target().Pc - p.Pc - 4) ++ o1 = OP_CONTROL(c.oprrr(p.As), getRegister(p.From.Reg), int32(offset)/4) ++ } else { ++ o1 = OP_CONTROL(c.oprrr(p.As), getRegister(p.From.Reg), int32(p.To.Offset)/4) ++ } ++ case 11: /*buildNoop*/ ++ p.As = ALDIH ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = REGZERO ++ p.To.Type = obj.TYPE_REG ++ p.To.Reg = REGSP ++ disp := p.To.Offset ++ ++ if (disp > 0 && disp&0xffff != disp) || ++ (disp < 0 && -disp&0xffff != -disp) { ++ c.ctxt.Diag("Memory instruction with immediate(0x%x) bigger than 0xffff at\n%v\n", disp, p) ++ } ++ ++ o1 = OP_MEMORY(c.oprrr(p.As), getRegister(p.From.Reg), getRegister(p.To.Reg), int16(disp)) ++ case 12: /*buildLoad,ALDL, ALDW, ALDHU, ALDBU, ASYMADDR*/ ++ sym := p.To.Sym ++ r := getRegister(p.From.Reg) ++ as := p.As ++ if as == ASYMADDR { ++ as = ALDI ++ } ++ o1 = OP_MEMORY(c.oprrr(ALDIH), r, REGSB&31, 0) // ldih r, sym(gp) ++ addrel(c.ctxt, c.cursym, int32(p.Pc), p.To.Offset, sym, objabi.R_SW64_GPRELHIGH) ++ o2 = OP_MEMORY(c.oprrr(as), r, r, 0) // ldx r, sym_lo(r) ++ addrel(c.ctxt, c.cursym, int32(p.Pc+4), p.To.Offset, sym, objabi.R_SW64_GPRELLOW) ++ case 13: /*buildStore*/ ++ sym := p.To.Sym ++ ++ if sym == nil { ++ c.ctxt.Diag("buildStore not support %v", p) ++ } ++ ++ // STx Rn, sym(SB) ++ r := getRegister(p.From.Reg) ++ if buildcfg.GOSW64 == 5 { ++ o1 = OP_ADDPI(c.oprrr(AADDPIS), REGTMP&31, 0) // addpis r, sym ++ addrel8(c.ctxt, c.cursym, int32(p.Pc), p.To.Offset, sym, objabi.R_SW64_ADDR) ++ o2 = OP_MEMORY(c.oprrr(p.As), r, REGTMP&31, 0) // STx Rn, sym_lo(TMP) ++ } else { ++ o1 = OP_MEMORY(c.oprrr(ALDIH), REGTMP&31, REGSB&31, 0) // ldih TMP, sym(gp) ++ addrel(c.ctxt, c.cursym, int32(p.Pc), p.To.Offset, sym, objabi.R_SW64_GPRELHIGH) ++ o2 = OP_MEMORY(c.oprrr(p.As), r, REGTMP&31, 0) // STx Rn, sym_lo(TMP) ++ addrel(c.ctxt, c.cursym, int32(p.Pc+4), p.To.Offset, sym, objabi.R_SW64_GPRELLOW) ++ } ++ case 14: ++ //LDI AT, $const ++ ib := p.RestArgs[0].Offset ++ q := c.newprog() ++ q.Pc = p.Pc ++ q.As = ALDI ++ q.From.Type = obj.TYPE_REG ++ q.From.Reg = REGTMP ++ q.To.Type = obj.TYPE_CONST ++ q.To.Offset = ib ++ disp := q.To.Offset ++ ++ if (disp > 0 && disp&0xffff != disp) || ++ (disp < 0 && -disp&0xffff != -disp) { ++ c.ctxt.Diag("Memory instruction with immediate(0x%x) bigger than 0xffff at\n%v\n", disp, q) ++ } ++ ++ o1 = OP_MEMORY(c.oprrr(q.As), getRegister(q.From.Reg), getRegister(q.To.Reg), int16(disp)) ++ // XXX Rn1, AT, Rn2 ++ o2 = OP_ARITHMETIC(c.oprrr(p.As), getRegister(p.From.Reg), REGTMP&31, getRegister(p.To.Reg)) ++ case 15: /*buildLoad,AFLDD, AFLDS*/ ++ sym := p.To.Sym ++ if buildcfg.GOSW64 >= 5 { ++ o1 = OP_ADDPI(c.oprrr(AADDPIS), REGTMP&31, 0) // addpis r, sym ++ addrel8(c.ctxt, c.cursym, int32(p.Pc), p.To.Offset, sym, objabi.R_SW64_ADDR) ++ o2 = OP_MEMORY(c.oprrr(ALDI), REGTMP&31, REGTMP&31, 0) // STx Rn, sym_lo(TMP) ++ } else { ++ o1 = OP_MEMORY(c.oprrr(ALDIH), REGTMP&31, REGSB&31, 0) // LDIH AT, sym(gp) ++ addrel(c.ctxt, c.cursym, int32(p.Pc), p.To.Offset, sym, objabi.R_SW64_GPRELHIGH) ++ o2 = OP_MEMORY(c.oprrr(ALDI), REGTMP&31, REGTMP&31, 0) // LDI AT, sym_lo(AT) ++ addrel(c.ctxt, c.cursym, int32(p.Pc+4), p.To.Offset, sym, objabi.R_SW64_GPRELLOW) ++ } ++ o3 = OP_MEMORY(c.oprrr(p.As), getRegister(p.From.Reg), REGTMP&31, 0) // FLDX, Fn, (AT) ++ case 16: ++ //SYMADDR AT, $int64.ib ++ ib := p.RestArgs[0].Offset ++ q := c.newprog() ++ q.Pc = p.Pc ++ q.As = ASYMADDR ++ q.From.Type = obj.TYPE_REG ++ q.From.Reg = REGTMP ++ q.To.Type = obj.TYPE_MEM ++ q.To.Sym = c.ctxt.Int64Sym(ib) ++ q.To.Name = obj.NAME_EXTERN ++ sym := q.To.Sym ++ r := getRegister(q.From.Reg) ++ as := q.As ++ if as == ASYMADDR { ++ as = ALDI ++ } ++ if buildcfg.GOSW64 == 5 { ++ o1 = OP_ADDPI(c.oprrr(AADDPIS), r, 0) // addpis r, sym ++ addrel8(c.ctxt, c.cursym, int32(p.Pc), p.To.Offset, sym, objabi.R_SW64_ADDR) ++ o2 = OP_MEMORY(c.oprrr(as), r, r, 0) // STx Rn, sym_lo(TMP) ++ } else { ++ o1 = OP_MEMORY(c.oprrr(ALDIH), r, REGSB&31, 0) // ldih r, sym(gp) ++ addrel(c.ctxt, c.cursym, int32(q.Pc), q.To.Offset, sym, objabi.R_SW64_GPRELHIGH) ++ o2 = OP_MEMORY(c.oprrr(as), r, r, 0) // ldx r, sym_lo(r) ++ addrel(c.ctxt, c.cursym, int32(q.Pc+4), q.To.Offset, sym, objabi.R_SW64_GPRELLOW) ++ } ++ // LDL AT, (AT) ++ q2 := c.newprog() ++ q2.As = ALDL ++ q2.Pc = p.Pc + 8 ++ q2.From.Type = obj.TYPE_REG ++ q2.From.Reg = REGTMP ++ q2.To.Type = obj.TYPE_MEM ++ q2.To.Reg = REGTMP ++ disp := q2.To.Offset ++ ++ if (disp > 0 && disp&0xffff != disp) || (disp < 0 && -disp&0xffff != -disp) { ++ c.ctxt.Diag("Memory instruction with immediate(0x%x) bigger than 0xffff at\n%v\n", disp, q2) ++ } ++ ++ o3 = OP_MEMORY(c.oprrr(q2.As), getRegister(q2.From.Reg), getRegister(q2.To.Reg), int16(disp)) ++ // XXX Rn1, AT, Rn2 ++ o4 = OP_ARITHMETIC(c.oprrr(p.As), getRegister(p.From.Reg), REGTMP&31, getRegister(p.To.Reg)) ++ ++ case 17: ++ // LDx/STx Ra, off(Rb) ++ // convert to ---> ++ // ADDL Rb, $off, REGTMP #len 16 ++ // LDx/STx Ra, (REGTMP) #len 4 ++ rb := p.To.Reg ++ off := p.To.Offset ++ ++ // ADDL Rb, $off, REGTMP ++ addl := c.newprog() ++ addl.Pc = p.Pc ++ addl.As = AADDL ++ addl.From = obj.Addr{ ++ Type: obj.TYPE_REG, ++ Reg: rb, ++ } ++ addl.AddRestSource(obj.Addr{ ++ Type: obj.TYPE_CONST, ++ Offset: off, ++ }) ++ addl.To = obj.Addr{ ++ Type: obj.TYPE_REG, ++ Reg: REGTMP, ++ } ++ ++ //SYMADDR AT, $int64.ib ++ ib := addl.RestArgs[0].Offset ++ q := c.newprog() ++ q.Pc = addl.Pc ++ q.As = ASYMADDR ++ q.From.Type = obj.TYPE_REG ++ q.From.Reg = REGTMP ++ q.To.Type = obj.TYPE_MEM ++ q.To.Sym = c.ctxt.Int64Sym(ib) ++ q.To.Name = obj.NAME_EXTERN ++ sym := q.To.Sym ++ r := getRegister(q.From.Reg) ++ as := q.As ++ if as == ASYMADDR { ++ as = ALDI ++ } ++ // if buildcfg.GOSW64 == 4 { ++ // o1 = OP_ADDPI(c.oprrr(AADDPIS), REGTMP&31, 0) // addpis r, sym ++ // addrel8(c.ctxt, c.cursym, int32(p.Pc), p.To.Offset, sym, objabi.R_SW64_ADDR) ++ // o2 = OP_MEMORY(c.oprrr(p.As), r, REGTMP&31, 0) // STx Rn, sym_lo(TMP) ++ // } else { ++ o1 = OP_MEMORY(c.oprrr(ALDIH), r, REGSB&31, 0) // ldih r, sym(gp) ++ addrel(c.ctxt, c.cursym, int32(q.Pc), q.To.Offset, sym, objabi.R_SW64_GPRELHIGH) ++ o2 = OP_MEMORY(c.oprrr(as), r, r, 0) // ldx r, sym_lo(r) ++ addrel(c.ctxt, c.cursym, int32(q.Pc+4), q.To.Offset, sym, objabi.R_SW64_GPRELLOW) ++ // } ++ // LDL AT, (AT) ++ q2 := c.newprog() ++ q2.As = ALDL ++ q2.Pc = addl.Pc + 8 ++ q2.From.Type = obj.TYPE_REG ++ q2.From.Reg = REGTMP ++ q2.To.Type = obj.TYPE_MEM ++ q2.To.Reg = REGTMP ++ disp := q2.To.Offset ++ ++ if (disp > 0 && disp&0xffff != disp) || (disp < 0 && -disp&0xffff != -disp) { ++ c.ctxt.Diag("Memory instruction with immediate(0x%x) bigger than 0xffff at\n%v\n", disp, q2) ++ } ++ ++ o3 = OP_MEMORY(c.oprrr(q2.As), getRegister(q2.From.Reg), getRegister(q2.To.Reg), int16(disp)) ++ // XXX Rn1, AT, Rn2 ++ o4 = OP_ARITHMETIC(c.oprrr(addl.As), getRegister(addl.From.Reg), REGTMP&31, getRegister(addl.To.Reg)) ++ // LDx Ra, (REGTMP) ++ p.To = obj.Addr{ ++ Type: obj.TYPE_MEM, ++ Reg: REGTMP, ++ } ++ ++ //disp := p.To.Offset ++ if (disp > 0 && disp&0xffff != disp) || ++ (disp < 0 && -disp&0xffff != -disp) { ++ c.ctxt.Diag("Memory instruction with immediate(0x%x) bigger than 0xffff at\n%v\n", disp, p) ++ } ++ ++ o5 = OP_MEMORY(c.oprrr(p.As), getRegister(p.From.Reg), getRegister(p.To.Reg), int16(p.To.Offset)) ++ ++ case 18: /* buildTrap */ ++ o1 = 80 ++ case 19: /* buildWORD */ ++ o1 = uint32(p.From.Offset) ++ case 20: /*buildLDGP*/ ++ dummysym := c.cursym ++ ++ gp := getRegister(p.From.Reg) ++ r := getRegister(p.To.Reg) ++ ++ if p.To.Reg == REGZERO { ++ // If the ATEXT+0 isn't the noop, then ++ // runtime.goexit will be invoked at o3 which is ldgp ++ // without setup $at. see the logical in ++ // runtime/proc.go' func newproc1 about ++ // newg.sched.pc = funcPC(goexit) + sys.PCQuantum ++ o1 = OP_MEMORY(c.oprrr(ALDIH), gp, gp, 0) // only for alignment ++ ++ //insert a "BR AT, 0" to find the correct PC value ++ o2 = OP_CONTROL(c.oprrr(ABR), REGTMP, 0) ++ o3 = OP_MEMORY(c.oprrr(ALDIH), gp, REGTMP&31, 0) ++ addrel(c.ctxt, c.cursym, int32(p.Pc+8), 4, dummysym, objabi.R_SW64_GPDISP) ++ o4 = OP_MEMORY(c.oprrr(ALDI), gp, gp, 0) //ldi $gp, m($gp) ++ } else { ++ if p.To.Reg == REG_R27 && p.Pc != 0 { ++ p.To.Offset = p.Pc ++ } ++ o1 = OP_MEMORY(c.oprrr(ALDIH), gp, r, 0) //ldih $gp, n($r) ++ addrel(c.ctxt, c.cursym, int32(p.Pc), 4, dummysym, objabi.R_SW64_GPDISP) ++ o2 = OP_MEMORY(c.oprrr(ALDI), gp, gp, 0) //ldi $gp, m($gp) ++ ++ o3 = OP_MEMORY(c.oprrr(ALDI), gp, gp, int16(p.To.Offset)) ++ o4 = OP_MEMORY(c.oprrr(ALDIH), gp, gp, 0) // only for alignment ++ } ++ case 21: /*buildCallByReg*/ ++ offset := p.To.Offset ++ if (p.As != obj.AJMP && p.As != obj.ACALL) || p.To.Sym != nil || !isint16(offset) { ++ c.ctxt.Diag("buildCallByReg doesn't support %v", p) ++ return ++ } ++ ra := getRegister(p.From.Reg) ++ pv := getRegister(p.To.Reg) ++ o1 = OP_MEMORY(c.oprrr(p.As), ra, pv, int16(offset)) //CALL/JMP RA, (Rn ++ case 22: /*LDx Reg,(TLS_LE)(SB)*/ ++ if p.To.Sym == nil || p.From.Type != obj.TYPE_REG || !isint16(p.To.Offset) { ++ c.ctxt.Diag("%v is not support TLS_LE", p) ++ } ++ ++ offset := int16(p.To.Offset) ++ rn := int16(p.From.Reg & 31) ++ r0 := int16(REG_R0 & 31) ++ sym := p.To.Sym ++ // sys_call 0x9e ++ o1 = OP_SYSCALL(c.oprrr(ASYS_CALL), 0x9e) ++ // LDIH R0, sym(R0) !tprelhi ++ o2 = OP_MEMORY(c.oprrr(ALDIH), r0, r0, 0) ++ addrel(c.ctxt, c.cursym, int32(p.Pc+4), 0, sym, objabi.R_SW64_TPRELHI) ++ // STx/LDx Rn, sym(R0) !tprello ++ o3 = OP_MEMORY(c.oprrr(p.As), rn, r0, offset) ++ addrel(c.ctxt, c.cursym, int32(p.Pc+8), 0, sym, objabi.R_SW64_TPRELLO) ++ ++ case 23: /*LDx Reg,(TLS_IE)(SB)*/ ++ if p.To.Sym == nil || p.From.Type != obj.TYPE_REG || !isint16(p.To.Offset) { ++ c.ctxt.Diag("%v is not support TLS_IE", p) ++ } ++ offset := int16(p.To.Offset) ++ rn := int16(p.From.Reg & 31) ++ r0 := int16(REG_R0 & 31) ++ rtmp := int16(REGTMP & 31) ++ sym := p.To.Sym ++ // sys_call 0x9e ++ o1 = OP_SYSCALL(c.oprrr(ASYS_CALL), 0x9e) ++ ++ //LDL RTMP, offset($sym) !gottprel ++ o2 = OP_MEMORY(c.oprrr(ALDL), rtmp, REGSB&31, offset) ++ addrel(c.ctxt, c.cursym, int32(p.Pc+4), 0, sym, objabi.R_SW64_GOTTPREL) ++ ++ //ADDL R0, RTMP, RTMP ++ o3 = OP_MEMORY(c.oprrr(AADDL), r0, rtmp, rtmp) ++ //STx/LDx Rn, 0(RTMP) ++ o4 = OP_MEMORY(c.oprrr(p.As), rn, rtmp, 0) ++ ++ case 24: /*retjmp*/ ++ sym := p.To.Sym ++ //r := getRegister(p.From.Reg) ++ pv := REG_R27 & int16(31) ++ o1 = OP_MEMORY(c.oprrr(ALDIH), pv, REGSB&31, 0) // ldih R27, sym(GP) ++ addrel(c.ctxt, c.cursym, int32(p.Pc), p.To.Offset, sym, objabi.R_SW64_GPRELHIGH) ++ o2 = OP_MEMORY(c.oprrr(ALDI), pv, pv, 0) // ldi R27, sym_lo(R27) ++ addrel(c.ctxt, c.cursym, int32(p.Pc+4), p.To.Offset, sym, objabi.R_SW64_GPRELLOW) ++ o3 = OP_MEMORY(c.oprrr(obj.AJMP), REGLINK&31, pv, 0) //CALL/JMP R, (R27) ++ addrel(c.ctxt, c.cursym, int32(p.Pc+8), p.To.Offset, sym, objabi.R_SW64_HINT) ++ case 25: /*MOVD sym@GOT */ ++ o1 = OP_MEMORY(c.oprrr(ALDIH), REGTMP, REGSB&31, 0) // ldih r, sym(gp) ++ addrel(c.ctxt, c.cursym, int32(p.Pc), p.From.Offset, p.From.Sym, objabi.R_SW64_LITERAL_GOT) ++ o2 = OP_MEMORY(c.oprrr(ALDL), REGTMP&31, REGTMP&31, 0) // ldx r, sym_lo(r) ++ addrel(c.ctxt, c.cursym, int32(p.Pc+4), p.From.Offset, p.From.Sym, objabi.R_SW64_LITERAL) ++ case 26: /*SYMADDR Rx, sym@GOT */ ++ o1 = OP_MEMORY(c.oprrr(ALDIH), p.From.Reg, REGSB&31, 0) // ldih r, sym(gp) ++ addrel(c.ctxt, c.cursym, int32(p.Pc), p.To.Offset, p.To.Sym, objabi.R_SW64_LITERAL_GOT) ++ o2 = OP_MEMORY(c.oprrr(ALDL), p.From.Reg&31, p.From.Reg&31, 0) // ldx r, sym_lo(r) ++ addrel(c.ctxt, c.cursym, int32(p.Pc+4), p.To.Offset, p.To.Sym, objabi.R_SW64_LITERAL) ++ case 27: /*ADDPI Rx, sym@GOT */ ++ // o1 = OP_MEMORY(c.oprrr(ALDIH), r, REGSB&31, 0) // ldih r, sym(gp) ++ // addrel(c.ctxt, c.cursym, int32(p.Pc), p.To.Offset, 0, objabi.R_SW64_LITERAL_GOT) ++ o1 = OP_ADDPI(c.oprrr(p.As), getRegister(p.To.Reg), 0) ++ //addrel(c.ctxt, c.cursym, int32(p.Pc), p.To.Offset, p.To.Sym, objabi.R_SW64_LITERAL) ++ case 30: /*Vop V1, V2, V3*/ ++ rf := int16(p.From.Reg) ++ rt := int16(p.To.Reg) ++ r := int16(p.Reg) ++ if r == 0 { ++ r = rt ++ } ++ o1 = OP_ARITHMETIC(c.oprrr(p.As), getRegister(rf), getRegister(r), getRegister(rt)) ++ case 31: /* VLOG Vx, Vy, Vz */ ++ rf := int16(p.From.Reg) ++ rt := int16(p.To.Reg) ++ r := int16(p.Reg) ++ if r == 0 { ++ r = rt ++ } ++ o1 = OP_COMPLEX_ARITHMETIC(c.oprrr(p.As), getRegister(rf), getRegister(r), 31, getRegister(rt)) ++ case 32: /* VLDD Vx , disp(Rx) */ ++ disp := p.To.Offset ++ ++ if (disp > 0 && disp&0xffff != disp) || ++ (disp < 0 && -disp&0xffff != -disp) { ++ c.ctxt.Diag("Memory instruction with immediate(0x%x) bigger than 0xffff at\n%v\n", disp, p) ++ } ++ o1 = OP_MEMORY(c.oprrr(p.As), getRegister(p.From.Reg), getRegister(p.To.Reg), int16(disp)) ++ case 33: /* VCPYX Vx , Vy, Vz */ ++ o1 = OP_COMPLEX_ARITHMETIC(c.oprrr(p.As), getRegister(p.From.Reg), 31, 31, getRegister(p.To.Reg)) ++ case 34: /* VCPYX Vx , Vy, Vz */ ++ rf := int16(p.From.Reg) ++ rt := int16(p.To.Reg) ++ if rt == 0 { ++ rt = rf ++ } ++ o1 = OP_ARITHMETIC(c.oprrr(p.As), getRegister(rf), 31, getRegister(rt)) ++ case 35: /* MOVX Rx, Rx*/ ++ as := p.As ++ rt, rf := p.To.Reg, p.From.Reg ++ switch as { ++ case AMOVB: // MOVB -> SEXTB ++ o1 = OP_ARITHMETIC(c.oprrr(ASEXTB), REGZERO, getRegister(rf), getRegister(rt)) ++ ++ case AMOVH: // MOVH -> SEXTH ++ o1 = OP_ARITHMETIC(c.oprrr(ASEXTH), REGZERO, getRegister(rf), getRegister(rt)) ++ ++ case AMOVW: // MOVW x -> ADDWconst x [0] ++ o1 = OP_ARITHMETIC_I(c.opirr(AADDW), getRegister(rf), 0, getRegister(rt)) ++ ++ case AMOVV: // MOVV -> BIS ++ o1 = OP_ARITHMETIC_I(c.opirr(ABIS), getRegister(rf), 0, getRegister(rt)) ++ ++ default: ++ c.ctxt.Diag("bad sign extract %v", as) ++ } ++ case 36: /* MOVUX Rx, Rx*/ ++ as := p.As ++ rt, rf := p.To.Reg, p.From.Reg ++ v := 1 ++ switch as { ++ case AMOVBU: ++ v = 1 ++ case AMOVHU: ++ v = 3 ++ case AMOVWU: ++ v = 15 ++ default: ++ c.ctxt.Diag("bad unsign extract %v", as) ++ } ++ o1 = OP_ARITHMETIC_I(c.opirr(AZAPNOT), getRegister(rf), int16(v), getRegister(rt)) ++ } ++ out[0] = o1 ++ out[1] = o2 ++ out[2] = o3 ++ out[3] = o4 ++ out[4] = o5 ++ return ++} ++ ++func (c *ctxt77) oprrr(a obj.As) uint32 { ++ switch a { ++ case ASYS_CALL_B: ++ return SP(0, 0) | (0 << 25) ++ case ASYS_CALL: ++ return SP(0, 0) | (1 << 25) ++ case obj.AUNDEF: ++ return 0 ++ case AEXCB: ++ return SP(1, 0) ++ case ACALL: ++ return SP(0, 1) ++ case ALBR: ++ return SP(0, 0x1d) ++ case AJMP: ++ return SP(0, 3) ++ case ARET: ++ return SP(0, 2) ++ case ABR: ++ return SP(0, 4) ++ case ABSR: ++ return SP(0, 5) ++ case AMEMB: ++ return FMM(0, 0) ++ case AIMEMB: ++ return FMM(0, 1) ++ case ARTC: ++ return FMM(0, 32) ++ case ARD_F: ++ return FMM(16, 0) ++ case AWR_F: ++ return FMM(16, 32) ++ case ALLDW: ++ return SP(0, 8) | (0 << 12) ++ case ALLDL: ++ return SP(0, 8) | (1 << 12) ++ case ALSTW: ++ return SP(0, 8) | (8 << 12) ++ case ALSTL: ++ return SP(0, 8) | (9 << 12) ++ case AADDW: ++ return FA(0, 0) ++ case ASUBW: ++ return FA(0, 1) ++ case AS4ADDW: ++ return FA(0, 2) ++ case AS4SUBW: ++ return FA(0, 3) ++ case AS8ADDW: ++ return FA(0, 4) ++ case AS8SUBW: ++ return FA(0, 5) ++ case AADDL: ++ return FA(0, 8) ++ case ASUBL: ++ return FA(0, 9) ++ case AS4ADDL: ++ return FA(0, 10) ++ case AS4SUBL: ++ return FA(0, 11) ++ case AS8ADDL: ++ return FA(0, 12) ++ case AS8SUBL: ++ return FA(0, 13) ++ case AMULW: ++ return FA(1, 0) ++ case AMULL: ++ return FA(1, 8) ++ case AUMULH: ++ return FA(1, 9) ++ case ADIVW: ++ return FA(1, 1) ++ case AUDIVW: ++ return FA(1, 2) ++ case AREMW: ++ return FA(1, 3) ++ case AUREMW: ++ return FA(1, 4) ++ case ADIVL: ++ return FA(1, 0xa) ++ case AUDIVL: ++ return FA(1, 0xb) ++ case AREML: ++ return FA(1, 0xc) ++ case AUREML: ++ return FA(1, 0xd) ++ case ASBT: ++ return FA(2, 0xd) ++ case ACBT: ++ return FA(2, 0xe) ++ case ACRC32CL: ++ return FA(2, 7) ++ case ACRC32CW: ++ return FA(2, 6) ++ case ACRC32CH: ++ return FA(2, 5) ++ case ACRC32CB: ++ return FA(2, 4) ++ case ACRC32L: ++ return FA(2, 3) ++ case ACRC32W: ++ return FA(2, 2) ++ case ACRC32H: ++ return FA(2, 1) ++ case ACRC32B: ++ return FA(2, 0) ++ case AADDPI: ++ return FA(1, 0xe) ++ case AADDPIS: ++ return FA(1, 0xf) ++ case ACMPEQ: ++ return FA(2, 8) ++ case ACMPLT: ++ return FA(2, 9) ++ case ACMPLE: ++ return FA(2, 10) ++ case ACMPULT: ++ return FA(2, 11) ++ case ACMPULE: ++ return FA(2, 12) ++ case AAND: ++ return FA(3, 8) ++ case ABIC: ++ return FA(3, 9) ++ case ABIS: ++ return FA(3, 10) ++ case AORNOT: ++ return FA(3, 11) ++ case AXOR: ++ return FA(3, 12) ++ case AEQV: ++ return FA(3, 13) ++ case AINSLB: ++ return FA(4, 0) ++ case AINSLH: ++ return FA(4, 1) ++ case AINSLW: ++ return FA(4, 2) ++ case AINSLL: ++ return FA(4, 3) ++ case AINSHB: ++ return FA(4, 4) ++ case AINSHH: ++ return FA(4, 5) ++ case AINSHW: ++ return FA(4, 6) ++ case AINSHL: ++ return FA(4, 7) ++ case ASLL: ++ return FA(4, 8) ++ case ASRL: ++ return FA(4, 9) ++ case ASRA: ++ return FA(4, 10) ++ case AEXTLB: ++ return FA(5, 0) ++ case AEXTLH: ++ return FA(5, 1) ++ case AEXTLW: ++ return FA(5, 2) ++ case AEXTLL: ++ return FA(5, 3) ++ case AEXTHB: ++ return FA(5, 4) ++ case AEXTHH: ++ return FA(5, 5) ++ case AEXTHW: ++ return FA(5, 6) ++ case AEXTHL: ++ return FA(5, 7) ++ case ACTPOP: ++ return FA(5, 8) ++ case ACTLZ: ++ return FA(5, 9) ++ case ACTTZ: ++ return FA(5, 10) ++ case AMASKLB: ++ return FA(6, 0) ++ case AMASKLH: ++ return FA(6, 1) ++ case AMASKLW: ++ return FA(6, 2) ++ case AMASKLL: ++ return FA(6, 3) ++ case AMASKHB: ++ return FA(6, 4) ++ case AMASKHH: ++ return FA(6, 5) ++ case AMASKHW: ++ return FA(6, 6) ++ case AMASKHL: ++ return FA(6, 7) ++ case AZAP: ++ return FA(6, 8) ++ case AZAPNOT: ++ return FA(6, 9) ++ case ASEXTB: ++ return FA(6, 10) ++ case ASEXTH: ++ return FA(6, 11) ++ case ACMPGEB: ++ return FA(6, 12) ++ case AFIMOVS: ++ return FA(7, 0) ++ case AFIMOVD: ++ return FA(7, 8) ++ case ASELEQ: ++ return SP(1, 1) | (0 << 5) ++ case ASELGE: ++ return SP(1, 1) | (1 << 5) ++ case ASELGT: ++ return SP(1, 1) | (2 << 5) ++ case ASELLE: ++ return SP(1, 1) | (3 << 5) ++ case ASELLT: ++ return SP(1, 1) | (4 << 5) ++ case ASELNE: ++ return SP(1, 1) | (5 << 5) ++ case ASELLBC: ++ return SP(1, 1) | (6 << 5) ++ case ASELLBS: ++ return SP(1, 1) | (7 << 5) ++ case APRI_LD: ++ return SP(2, 5) ++ case ABEQ: ++ return SP(3, 0) ++ case ABNE: ++ return SP(3, 1) ++ case ABLT: ++ return SP(3, 2) ++ case ABLE: ++ return SP(3, 3) ++ case ABGT: ++ return SP(3, 4) ++ case ABGE: ++ return SP(3, 5) ++ case ABLBC: ++ return SP(3, 6) ++ case ABLBS: ++ return SP(3, 7) ++ case AFBEQ: ++ return SP(3, 8) ++ case AFBNE: ++ return SP(3, 9) ++ case AFBLT: ++ return SP(3, 10) ++ case AFBLE: ++ return SP(3, 11) ++ case AFBGT: ++ return SP(3, 12) ++ case AFBGE: ++ return SP(3, 13) ++ case AFADDS: ++ return FAF(0, 0) ++ case AFADDD: ++ return FAF(0, 1) ++ case AFSUBS: ++ return FAF(0, 2) ++ case AFSUBD: ++ return FAF(0, 3) ++ case AFMULS: ++ return FAF(0, 4) ++ case AFMULD: ++ return FAF(0, 5) ++ case AFDIVS: ++ return FAF(0, 6) ++ case AFDIVD: ++ return FAF(0, 7) ++ case AFSQRTS: ++ return FAF(0, 8) ++ case AFSQRTD: ++ return FAF(0, 9) ++ case AFCMPEQ: ++ return FAF(1, 0) ++ case AFCMPLE: ++ return FAF(1, 1) ++ case AFCMPLT: ++ return FAF(1, 2) ++ case AFCMPUN: ++ return FAF(1, 3) ++ case AFCVTSD: ++ return FAF(2, 0) ++ case AFCVTDS: ++ return FAF(2, 1) ++ case AFCVTDL_G: ++ return FAF(2, 2) ++ case AFCVTDL_P: ++ return FAF(2, 3) ++ case AFCVTDL_Z: ++ return FAF(2, 4) ++ case AFCVTDL_N: ++ return FAF(2, 5) ++ case AFCVTDL: ++ return FAF(2, 7) ++ case AFCVTWL: ++ return FAF(2, 8) ++ case AFCVTLW: ++ return FAF(2, 9) ++ case AFCVTLS: ++ return FAF(2, 13) ++ case AFCVTLD: ++ return FAF(2, 15) ++ case AFCPYS: ++ return FAF(3, 0) ++ case AFCPYSE: ++ return FAF(3, 1) ++ case AFCPYSN: ++ return FAF(3, 2) ++ case AIFMOVS: ++ return FAF(4, 0) ++ case AIFMOVD: ++ return FAF(4, 1) ++ case ARFPCR: ++ return FAF(5, 0) ++ case AWFPCR: ++ return FAF(5, 1) ++ case ASETFPEC0: ++ return FAF(5, 4) ++ case ASETFPEC1: ++ return FAF(5, 5) ++ case ASETFPEC2: ++ return FAF(5, 6) ++ case ASETFPEC3: ++ return FAF(5, 7) ++ case AFMAS: ++ return FCA(0, 0) ++ case AFMAD: ++ return FCA(0, 1) ++ case AFMSS: ++ return FCA(0, 2) ++ case AFMSD: ++ return FCA(0, 3) ++ case AFNMAS: ++ return FCA(0, 4) ++ case AFNMAD: ++ return FCA(0, 5) ++ case AFNMSS: ++ return FCA(0, 6) ++ case AFNMSD: ++ return FCA(0, 7) ++ case AFSELEQ: ++ return FCA(1, 0) ++ case AFSELNE: ++ return FCA(1, 1) ++ case AFSELLT: ++ return FCA(1, 2) ++ case AFSELLE: ++ return FCA(1, 3) ++ case AFSELGT: ++ return FCA(1, 4) ++ case AFSELGE: ++ return FCA(1, 5) ++ case ALDBU: ++ return SP(2, 0) ++ case ALDHU: ++ return SP(2, 1) ++ case ALDW: ++ return SP(2, 2) ++ case ALDL: ++ return SP(2, 3) ++ case ALDL_U: ++ return SP(2, 4) ++ case ALDBUA: ++ return FLD(0) ++ case ALDHUA: ++ return FLD(1) ++ case ALDWA: ++ return FLD(2) ++ case ALDLA: ++ return FLD(3) ++ case AFLDSA: ++ return FLD(4) ++ case AFLDDA: ++ return FLD(5) ++ case ASTBA: ++ return FLD(6) ++ case ASTHA: ++ return FLD(7) ++ case ASTWA: ++ return FLD(8) ++ case ASTLA: ++ return FLD(9) ++ case AFSTSA: ++ return FLD(10) ++ case AFSTDA: ++ return FLD(11) ++ case AFLDS: ++ return SP(2, 6) ++ case AFLDD: ++ return SP(2, 7) ++ case ASTB: ++ return SP(2, 8) ++ case ASTH: ++ return SP(2, 9) ++ case ASTW: ++ return SP(2, 10) ++ case ASTL: ++ return SP(2, 11) ++ case ASTL_U: ++ return SP(2, 12) ++ case APRI_ST: ++ return SP(2, 13) ++ case AFSTS: ++ return SP(2, 14) ++ case AFSTD: ++ return SP(2, 15) ++ case ALDI: ++ return SP(3, 14) ++ case ALDIH: ++ return SP(3, 15) ++ // SIMD v2 ++ case AVOR: ++ return VLOG(1, 0x3c) ++ case AVAND: ++ return VLOG(1, 0) ++ case AVXOR: ++ return VLOG(0, 0x1c) ++ case AVORNOT: ++ return VLOG(0, 1) ++ case AVBIC: ++ return VLOG(0, 0x1f) ++ case AVLDS: ++ return SP(0, 0xc) ++ case AVLDD: ++ return SP(0, 0xd) ++ case AVSTS: ++ return SP(0, 0xe) ++ case AVSTD: ++ return SP(0, 0xf) ++ case AVADDW: ++ return VFA(0, 0) ++ case AVADDL: ++ return VFA(0, 0xe) ++ case AVSUBW: ++ return VFA(0, 1) ++ case AVSUBL: ++ return VFA(0, 0xf) ++ case AVCMPUEQB: ++ return VFA(4, 0xb) ++ case AVCMPUGTB: ++ return VFA(4, 0xc) ++ case AVMAXB: ++ return VFA(1, 0xe) ++ case AVMINB: ++ return VFA(1, 0xf) ++ case AVMAXH: ++ return VFA(5, 0x0) ++ case AVMINH: ++ return VFA(5, 0x1) ++ case AVMAXW: ++ return VFA(5, 0x2) ++ case AVMINW: ++ return VFA(5, 0x3) ++ case AVMAXL: ++ return VFA(5, 0x4) ++ case AVMINL: ++ return VFA(5, 0x5) ++ case AVUMAXB: ++ return VFA(5, 0x6) ++ case AVUMINB: ++ return VFA(5, 0x7) ++ case AVUMAXH: ++ return VFA(5, 0x8) ++ case AVUMINH: ++ return VFA(5, 0x9) ++ case AVUMAXW: ++ return VFA(5, 0xa) ++ case AVUMINW: ++ return VFA(5, 0xb) ++ case AVUMAXL: ++ return VFA(5, 0xc) ++ case AVUMINL: ++ return VFA(5, 0xd) ++ case AVCPYB: ++ return VFCA(3, 2) ++ case AVCPYH: ++ return VFCA(3, 2) ++ case AVCTPOP: ++ return VFA(1, 8) ++ case AVCTLZ: ++ return VFA(1, 9) ++ } ++ ++ if a < 0 { ++ c.ctxt.Diag("bad orr opcode -%v", -a) ++ } else { ++ c.ctxt.Diag("bad orr opcode %v", a) ++ } ++ return 0 ++} ++ ++func (c *ctxt77) opirr(a obj.As) uint32 { ++ switch a { ++ case AADDW: ++ return FAI(0, 0) ++ case ASUBW: ++ return FAI(0, 1) ++ case AS4ADDW: ++ return FAI(0, 2) ++ case AS4SUBW: ++ return FAI(0, 3) ++ case AS8ADDW: ++ return FAI(0, 4) ++ case AS8SUBW: ++ return FAI(0, 5) ++ case AADDL: ++ return FAI(0, 8) ++ case ASUBL: ++ return FAI(0, 9) ++ case AS4ADDL: ++ return FAI(0, 10) ++ case AS4SUBL: ++ return FAI(0, 11) ++ case AS8ADDL: ++ return FAI(0, 12) ++ case AS8SUBL: ++ return FAI(0, 13) ++ case AMULW: ++ return FAI(1, 0) ++ case AMULL: ++ return FAI(1, 8) ++ case AUMULH: ++ return FAI(1, 9) ++ case ACMPEQ: ++ return FAI(2, 8) ++ case ACMPLT: ++ return FAI(2, 9) ++ case ACMPLE: ++ return FAI(2, 10) ++ case ACMPULT: ++ return FAI(2, 11) ++ case ACMPULE: ++ return FAI(2, 12) ++ case AAND: ++ return FAI(3, 8) ++ case ABIC: ++ return FAI(3, 9) ++ case ABIS: ++ return FAI(3, 10) ++ case AORNOT: ++ return FAI(3, 11) ++ case AXOR: ++ return FAI(3, 12) ++ case AEQV: ++ return FAI(3, 13) ++ case AINSLB: ++ return FAI(4, 0) ++ case AINSLH: ++ return FAI(4, 1) ++ case AINSLW: ++ return FAI(4, 2) ++ case AINSLL: ++ return FAI(4, 3) ++ case AINSHB: ++ return FAI(4, 4) ++ case AINSHH: ++ return FAI(4, 5) ++ case AINSHW: ++ return FAI(4, 6) ++ case AINSHL: ++ return FAI(4, 7) ++ case ASLL: ++ return FAI(4, 8) ++ case ASRL: ++ return FAI(4, 9) ++ case ASRA: ++ return FAI(4, 10) ++ case AEXTLB: ++ return FAI(5, 0) ++ case AEXTLH: ++ return FAI(5, 1) ++ case AEXTLW: ++ return FAI(5, 2) ++ case AEXTLL: ++ return FAI(5, 3) ++ case AEXTHB: ++ return FAI(5, 4) ++ case AEXTHH: ++ return FAI(5, 5) ++ case AEXTHW: ++ return FAI(5, 6) ++ case AEXTHL: ++ return FAI(5, 7) ++ case AMASKLB: ++ return FAI(6, 0) ++ case AMASKLH: ++ return FAI(6, 1) ++ case AMASKLW: ++ return FAI(6, 2) ++ case AMASKLL: ++ return FAI(6, 3) ++ case AMASKHB: ++ return FAI(6, 4) ++ case AMASKHH: ++ return FAI(6, 5) ++ case AMASKHW: ++ return FAI(6, 6) ++ case AMASKHL: ++ return FAI(6, 7) ++ case AZAP: ++ return FAI(6, 8) ++ case AZAPNOT: ++ return FAI(6, 9) ++ case ASEXTB: ++ return FAI(6, 10) ++ case ASEXTH: ++ return FAI(6, 11) ++ case ACMPGEB: ++ return FAI(6, 12) ++ case ASBT: ++ return FAI(2, 0xd) ++ case ACBT: ++ return FAI(2, 0xe) ++ case ASELEQ: ++ return SP(1, 3) | (0 << 5) ++ case ASELGE: ++ return SP(1, 3) | (1 << 5) ++ case ASELGT: ++ return SP(1, 3) | (2 << 5) ++ case ASELLE: ++ return SP(1, 3) | (3 << 5) ++ case ASELLT: ++ return SP(1, 3) | (4 << 5) ++ case ASELNE: ++ return SP(1, 3) | (5 << 5) ++ case ASELLBC: ++ return SP(1, 3) | (6 << 5) ++ case ASELLBS: ++ return SP(1, 3) | (7 << 5) ++ case AVADDW: ++ return VFA(2, 0) ++ case AVADDL: ++ return VFA(2, 0xe) ++ case AVSUBW: ++ return VFA(2, 1) ++ case AVSUBL: ++ return VFA(2, 0xf) ++ } ++ if a < 0 { ++ c.ctxt.Diag("bad irr opcode -%v", -a) ++ } else { ++ c.ctxt.Diag("bad irr opcode %v", a) ++ } ++ return 0 ++} ++ ++func getRegister(v int16) int16 { ++ if v == 0 { ++ return REGZERO & 31 ++ } ++ return v & 31 ++} ++func getReg2(p *obj.Prog) int16 { ++ reg := p.Reg ++ if reg == 0 && len(p.RestArgs) != 0 { ++ reg = p.RestArgs[0].Reg ++ } ++ return reg & 31 ++} ++ ++func getFrom3Reg(p *obj.Prog) int16 { ++ reg := p.RestArgs[1].Reg ++ if reg == 0 { ++ panic(fmt.Sprintf("illegal From3 reg: %v", reg)) ++ } ++ return reg & 31 ++} ++ ++func addrel(ctxt *obj.Link, cursym *obj.LSym, off int32, add int64, target *obj.LSym, rt objabi.RelocType) { ++ cursym.AddRel(ctxt, obj.Reloc{ ++ Add: add, ++ Siz: 4, ++ Off: off, ++ Sym: target, ++ Type: rt, //SJQ ++ }) ++} ++ ++func addrel8(ctxt *obj.Link, cursym *obj.LSym, off int32, add int64, target *obj.LSym, rt objabi.RelocType) { ++ cursym.AddRel(ctxt, obj.Reloc{ ++ Add: add, ++ Siz: 4, ++ Off: off, ++ Sym: target, ++ Type: rt, //SJQ ++ }) ++} +diff --git a/src/cmd/internal/obj/sw64/list77.go b/src/cmd/internal/obj/sw64/list77.go +new file mode 100644 +index 0000000000..bf9cf36ed3 +--- /dev/null ++++ b/src/cmd/internal/obj/sw64/list77.go +@@ -0,0 +1,89 @@ ++// cmd/9l/list.c from Vita Nuova. ++// ++// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. ++// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) ++// Portions Copyright © 1997-1999 Vita Nuova Limited ++// Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com) ++// Portions Copyright © 2004,2006 Bruce Ellis ++// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) ++// Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others ++// Portions Copyright © 2009 The Go Authors. All rights reserved. ++// ++// Permission is hereby granted, free of charge, to any person obtaining a copy ++// of this software and associated documentation files (the "Software"), to deal ++// in the Software without restriction, including without limitation the rights ++// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++// copies of the Software, and to permit persons to whom the Software is ++// furnished to do so, subject to the following conditions: ++// ++// The above copyright notice and this permission notice shall be included in ++// all copies or substantial portions of the Software. ++// ++// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ++// THE SOFTWARE. ++ ++package sw64 ++ ++import ( ++ "cmd/internal/obj" ++ "fmt" ++) ++ ++func init() { ++ obj.RegisterRegister(obj.RBaseSW64, REG_R0+1024, rconv) ++ // obj.RegisterRegister(obj.RBaseSW64, REG_LAST+1, rconv) ++ obj.RegisterOpcode(obj.ABaseSW64, Anames) ++} ++ ++func rconv(r int) string { ++ if r == 0 { ++ return "NONE" ++ } ++ //if r == REGG { ++ if r == REG_R15 { ++ // Special case. ++ return "g" ++ } ++ //if r == REGSB { ++ if r == REG_R29 { ++ // Special case. ++ return "RSB" ++ } ++ //if r == REGSP { ++ if r == REG_R30 { ++ // Special case. ++ return "SP" ++ } ++ if r == REGCTXT { ++ return "REGCTXT" ++ } ++ if r == REGZERO { ++ return "ZERO" ++ } ++ if IsRReg(r) { ++ return fmt.Sprintf("R%d", r-REG_R0) ++ } ++ if IsFReg(r) { ++ return fmt.Sprintf("F%d", r-REG_F0) ++ } ++ if REG_V0 <= r && r <= REG_V31 { ++ return fmt.Sprintf("V%d", r-REG_V0) ++ } ++ return fmt.Sprintf("badreg(%d)", r) ++ ++} ++ ++func DRconv(a int) string { ++ s := "C_??" ++ if a >= C_NONE && a <= C_NCLASS { ++ s = cnames77[a] ++ } ++ var fp string ++ fp += s ++ return fp ++} +diff --git a/src/cmd/internal/obj/sw64/obj77.go b/src/cmd/internal/obj/sw64/obj77.go +new file mode 100644 +index 0000000000..0a3251bdcf +--- /dev/null ++++ b/src/cmd/internal/obj/sw64/obj77.go +@@ -0,0 +1,1075 @@ ++// 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 sw64 ++ ++import ( ++ "cmd/internal/obj" ++ "cmd/internal/objabi" ++ "cmd/internal/sys" ++ "internal/abi" ++ "log" ++) ++ ++func (c *ctxt77) stacksplit(p *obj.Prog, framesize int32) *obj.Prog { ++ p = insertLDGP(p, c.newprog, REGZERO) ++ ++ if c.ctxt.Flag_maymorestack != "" { ++ p = c.ctxt.StartUnsafePoint(p, c.newprog) ++ // Spill Arguments. This has to happen before we open ++ // any more frame space. ++ p = c.cursym.Func().SpillRegisterArgs(p, c.newprog) ++ ++ frameSize := 2 * c.ctxt.Arch.PtrSize ++ ++ // Save LR and REGCTXT. ++ // STL RA, $-16(SP) ++ p = obj.Appendp(p, c.newprog) ++ p.As = ASTL ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = REGLINK ++ p.To.Type = obj.TYPE_MEM ++ p.To.Offset = int64(-frameSize) ++ p.To.Reg = REGSP ++ ++ // STL REGCTXT, $-8(SP) ++ p = obj.Appendp(p, c.newprog) ++ p.As = ASTL ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = REGCTXT ++ p.To.Type = obj.TYPE_MEM ++ p.To.Offset = int64(-c.ctxt.Arch.PtrSize) ++ p.To.Reg = REGSP ++ ++ // LDI SP, $-16(SP) ++ p = obj.Appendp(p, c.newprog) ++ p.As = ALDI ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = REGSP ++ p.To.Type = obj.TYPE_ADDR ++ p.To.Reg = REGSP ++ p.To.Offset = int64(-frameSize) ++ p.Spadj = int32(frameSize) ++ ++ // CALL maymorestack ++ p = obj.Appendp(p, c.newprog) ++ p.As = obj.ACALL ++ p.From.Type, p.From.Reg = obj.TYPE_REG, REGLINK ++ p.To.Type = obj.TYPE_BRANCH ++ p.To.Name = obj.NAME_EXTERN ++ // See ../x86/obj6.go ++ p.To.Sym = c.ctxt.LookupABI(c.ctxt.Flag_maymorestack, c.cursym.ABI()) ++ ++ // Restore LR and REGCTXT. ++ // LDL RA, $0(SP) ++ p = obj.Appendp(p, c.newprog) ++ p.As = ALDL ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = REGLINK ++ p.To.Type = obj.TYPE_MEM ++ p.To.Reg = REGSP ++ p.To.Offset = 0 ++ ++ // LDL REGCTXT, $8(SP) ++ p = obj.Appendp(p, c.newprog) ++ p.As = ALDL ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = REGCTXT ++ p.To.Type = obj.TYPE_MEM ++ p.To.Reg = REGSP ++ p.To.Offset = int64(c.ctxt.Arch.PtrSize) ++ ++ // LDI SP, $16(SP), ++ p = obj.Appendp(p, c.newprog) ++ p.As = ALDI ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = REGSP ++ p.To.Type = obj.TYPE_ADDR ++ p.To.Reg = REGSP ++ p.To.Offset = int64(frameSize) ++ p.Spadj = int32(-frameSize) ++ ++ // Unspill arguments ++ p = c.cursym.Func().UnspillRegisterArgsSW64(p, c.newprog) ++ p = c.ctxt.EndUnsafePoint(p, c.newprog, -1) ++ } ++ ++ // Jump back to here after morestack returns. ++ p = obj.Appendp(p, c.newprog) ++ begin := p ++ ++ // LDL R1, g_stackguard(g) ++ p.As = ALDL ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = REG_R1 ++ ++ p.To.Type = obj.TYPE_MEM ++ p.To.Reg = REGG ++ p.To.Offset = 2 * int64(c.ctxt.Arch.PtrSize) // G.stackguard0 ++ if c.cursym.CFunc() { ++ p.To.Offset = 3 * int64(c.ctxt.Arch.PtrSize) // G.stackguard1 ++ } ++ ++ // Mark the stack bound check and morestack call async nonpreemptible. ++ // If we get preempted here, when resumed the preemption request is ++ // cleared, but we'll still call morestack, which will double the stack ++ // unnecessarily. See issue #35470. ++ // p = c.ctxt.StartUnsafePoint(p, c.newprog) ++ ++ var to_done, to_more *obj.Prog ++ ++ if framesize <= abi.StackSmall { ++ // if SP > stackguard { goto done } ++ // CMPULE stackguard, SP, R1 ++ // BNE R1 , done ++ p = obj.Appendp(p, c.newprog) ++ ++ p.As = ACMPULE ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = REG_R1 ++ p.AddRestSource(obj.Addr{ ++ Type: obj.TYPE_REG, ++ Reg: REGSP, ++ }) ++ p.To.Type = obj.TYPE_REG ++ p.To.Reg = REG_R1 ++ p = obj.Appendp(p, c.newprog) ++ p.As = ABNE ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = REG_R1 ++ p.To.Type = obj.TYPE_BRANCH ++ to_done = p ++ } else { ++ // large stack: SP-framesize < stackguard-StackSmall ++ offset := int64(framesize) - abi.StackSmall ++ if framesize > abi.StackBig { ++ // Such a large stack we need to protect against underflow. ++ // The runtime guarantees SP > abi.StackBig, but ++ // framesize is large enough that SP-framesize may ++ // underflow, causing a direct comparison with the ++ // stack guard to incorrectly succeed. We explicitly ++ // guard against underflow. ++ // ++ // LDI R2, $(framesize-StackSmall) ++ // CMPULE R2, SP, R0 ++ // BNE R0, label-of-call-to-morestack ++ if offset > 32767 { ++ hi := int16(offset >> 16) ++ lo := int16(offset & 0xffff) ++ if lo < 0 { ++ hi = hi + 1 ++ lo = int16(offset - int64(hi)<<16) ++ } ++ p = obj.Appendp(p, c.newprog) ++ p.As = ALDIH ++ p.To.Type = obj.TYPE_CONST ++ p.To.Offset = int64(hi) ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = REG_R2 ++ p = obj.Appendp(p, c.newprog) ++ p.As = ALDI ++ p.From.Type, p.From.Reg = obj.TYPE_REG, REG_R2 ++ p.To.Type, p.To.Offset, p.To.Reg = obj.TYPE_ADDR, int64(lo), REG_R2 ++ } else { ++ p = obj.Appendp(p, c.newprog) ++ p.As = ALDI ++ p.To.Type = obj.TYPE_CONST ++ p.To.Offset = offset ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = REG_R2 ++ } ++ ++ // CMPULE R2, SP, R0 ++ // BNE R0, label-of-call-to-morestack ++ p = obj.Appendp(p, c.newprog) ++ p.As = ACMPULE ++ p.From.Type, p.From.Reg = obj.TYPE_REG, REGSP ++ p.AddRestSource(obj.Addr{Type: obj.TYPE_REG, Reg: REG_R2}) ++ p.To.Type, p.To.Reg = obj.TYPE_REG, REG_R0 ++ p = obj.Appendp(p, c.newprog) ++ p.As = ABNE ++ p.From.Type, p.From.Reg = obj.TYPE_REG, REG_R0 ++ p.To.Type = obj.TYPE_BRANCH ++ to_more = p ++ } ++ // Check against the stack guard. We've ensured this won't underflow. ++ // LDI R1, $-(framesize-StackSmall) ++ // SUBL R1, SP, R2 ++ // // if R2 > stackguard { goto done } ++ // CMPULE stackguard, R2, R1 ++ // BNE R1, done ++ ++ // LDI R1, $(framesize+(StackGuard-StackSmall)) ++ if offset > 32767 { ++ hi := int16(offset >> 16) ++ lo := int16(offset & 0xffff) ++ if lo < 0 { ++ hi = hi + 1 ++ lo = int16(offset - int64(hi)<<16) ++ } ++ p = obj.Appendp(p, c.newprog) ++ p.As = ALDIH ++ p.To.Type = obj.TYPE_CONST ++ p.To.Offset = int64(hi) ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = REG_R2 ++ p = obj.Appendp(p, c.newprog) ++ p.As = ALDI ++ p.From.Type, p.From.Reg = obj.TYPE_REG, REG_R2 ++ p.To.Type, p.To.Offset, p.To.Reg = obj.TYPE_ADDR, int64(lo), REG_R2 ++ } else { ++ p = obj.Appendp(p, c.newprog) ++ p.As = ALDI ++ p.To.Type = obj.TYPE_CONST ++ p.To.Offset = offset ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = REG_R2 ++ } ++ ++ //SUBL SP, R2, R2 ++ p = obj.Appendp(p, c.newprog) ++ p.As = ASUBL ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = REGSP ++ p.Reg = REG_R2 ++ p.To.Type = obj.TYPE_REG ++ p.To.Reg = REG_R2 ++ ++ // CMPULE stackguard, R2 ,R0 ++ p = obj.Appendp(p, c.newprog) ++ p.As = ACMPULE ++ p.From.Type, p.From.Reg = obj.TYPE_REG, REG_R1 ++ p.AddRestSource(obj.Addr{Type: obj.TYPE_REG, Reg: REG_R2}) ++ p.To.Type, p.To.Reg = obj.TYPE_REG, REG_R0 ++ // q1: BNE R0, done ++ p = obj.Appendp(p, c.newprog) ++ p.As = ABNE ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = REG_R0 ++ p.To.Type = obj.TYPE_BRANCH ++ to_done = p ++ } ++ ++ // q1: BNE R1, done ++ // p = obj.Appendp(p, c.newprog) ++ // q1 := p ++ // ++ // p.As = ABNE ++ // p.From.Type = obj.TYPE_REG ++ // p.From.Reg = REG_R1 ++ // p.To.Type = obj.TYPE_BRANCH ++ ++ // LDI R3, LINK ++ p = obj.Appendp(p, c.newprog) ++ p.As = ALDI ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = REG_R3 ++ p.To.Type = obj.TYPE_REG ++ p.To.Reg = REGLINK ++ if to_more != nil { ++ to_more.To.SetTarget(p) ++ } ++ ++ p = c.ctxt.EmitEntryLiveness(c.cursym, p, c.newprog) ++ //p = c.ctxt.EmitEntryStackMap(c.cursym, p, c.newprog) ++ ++ // Spill the register args that could be clobbered by the ++ // morestack code ++ p = c.cursym.Func().SpillRegisterArgs(p, c.newprog) ++ ++ // JMP runtime.morestack(SB) ++ p = obj.Appendp(p, c.newprog) ++ p.As = AJMP ++ p.From.Type = obj.TYPE_REG ++ //Don't use RA, otherwise the GP value will wrong because when ++ //the morestack return the RA is not the next instruction address. ++ p.From.Reg = REG_R2 ++ p.To.Type = obj.TYPE_BRANCH ++ p.To.Name = obj.NAME_EXTERN ++ ++ if c.cursym.CFunc() { ++ p.To.Sym = c.ctxt.Lookup("runtime.morestackc") ++ } else if !c.cursym.Func().Text.From.Sym.NeedCtxt() { ++ p.To.Sym = c.ctxt.Lookup("runtime.morestack_noctxt") ++ } else { ++ p.To.Sym = c.ctxt.Lookup("runtime.morestack") ++ } ++ // if to_more != nil { ++ // to_more.To.SetTarget(p) ++ // } ++ ++ //zxw new add ++ //p = c.ctxt.EndUnsafePoint(p, c.newprog, -1) ++ ++ p = c.cursym.Func().UnspillRegisterArgsSW64(p, c.newprog) ++ ++ // JMP start ++ p = obj.Appendp(p, c.newprog) ++ p.As = ABR ++ p.From.Type, p.From.Reg = obj.TYPE_REG, REGZERO ++ p.To.Type, p.To.Val = obj.TYPE_BRANCH, begin ++ ++ // placeholder for q1's jump target ++ p = obj.Appendp(p, c.newprog) ++ p.As = obj.ANOP // zero-width place holder ++ to_done.To.SetTarget(p) ++ ++ return p ++} ++ ++func (c *ctxt77) addnop(p *obj.Prog) { ++ q := c.newprog() ++ q.As = ANOOP ++ q.Pos = p.Pos ++ q.Link = p.Link ++ p.Link = q ++} ++ ++func insertLDGP(q *obj.Prog, newprog obj.ProgAlloc, rip int16) *obj.Prog { ++ q = obj.Appendp(q, newprog) ++ q.As = ALDGP ++ q.From = obj.Addr{Type: obj.TYPE_REG, Reg: REG_R29} ++ q.To = obj.Addr{Type: obj.TYPE_REG, Reg: rip} ++ return q ++} ++ ++func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { ++ // 1. handle ARET and ATEXT to setup function prologue and epilogue ++ // 2. adjust Prog.Spadj if the prog change hardward SP ++ ++ if cursym.Func().Text == nil || cursym.Func().Text.Link == nil { ++ return ++ } ++ ++ c := ctxt77{ctxt: ctxt, newprog: newprog, cursym: cursym} ++ p := c.cursym.Func().Text ++ textstksiz := p.To.Offset ++ ++ if textstksiz == -ctxt.Arch.FixedFrameSize { ++ // Historical way to mark NOFRAME. ++ p.From.Sym.Set(obj.AttrNoFrame, true) ++ textstksiz = 0 ++ } ++ if textstksiz < 0 { ++ c.ctxt.Diag("negative frame size %d - did you mean NOFRAME?", textstksiz) ++ } ++ if p.From.Sym.NoFrame() { ++ if textstksiz != 0 { ++ c.ctxt.Diag("NOFRAME functions must have a frame size of 0, not %d", textstksiz) ++ } ++ } ++ ++ c.cursym.Func().Args = p.To.Val.(int32) ++ c.cursym.Func().Locals = int32(textstksiz) ++ ++ if textstksiz < 0 { ++ ctxt.Diag("Use NOFRAME attribute instead of a negative frame size.\n%v\n", p) ++ return ++ } ++ ++ /* ++ * find leaf subroutines ++ * strip NOPs ++ * expand RET ++ */ ++ ++ for p := c.cursym.Func().Text; p != nil; p = p.Link { ++ switch p.As { ++ case obj.ATEXT: ++ p.Mark |= LEAF ++ ++ case obj.ARET: ++ break ++ ++ case ACALL, ++ obj.ADUFFZERO, ++ obj.ADUFFCOPY: ++ c.cursym.Func().Text.Mark &^= LEAF ++ fallthrough ++ ++ case AJMP, ++ ABR, ++ ABSR, ++ ABNE, ++ ABEQ, ++ ABLT, ++ ABLE, ++ ABGT, ++ ABGE, ++ ABLBC, ++ ABLBS, ++ AFBNE, ++ AFBEQ, ++ AFBLT, ++ AFBLE, ++ AFBGT, ++ AFBGE: ++ q1 := p.To.Target() ++ ++ if q1 != nil { ++ for q1.As == obj.ANOP { ++ q1 = q1.Link ++ //p.Pcond = q1 ++ p.To.Val = q1 ++ } ++ } ++ ++ break ++ } ++ ++ } ++ ++ autosize := int32(0) ++ var retjmp *obj.LSym ++ for p := cursym.Func().Text; p != nil; p = p.Link { ++ o := p.As ++ switch o { ++ case obj.ATEXT: ++ autosize = int32(textstksiz) ++ q := p ++ if p.Mark&LEAF != 0 && autosize == 0 { ++ // A leaf function with no locals has no frame. ++ p.From.Sym.Set(obj.AttrNoFrame, true) ++ } ++ ++ if !p.From.Sym.NoFrame() { ++ // If there is a stack frame at all, it includes ++ // space to save the LR. ++ autosize += int32(c.ctxt.Arch.FixedFrameSize) ++ } ++ if cursym.Attribute.NoFrame() { ++ if textstksiz != 0 { ++ ctxt.Diag("NoFrame symbol %v with non zero frame size(%d)", cursym, textstksiz) ++ } ++ autosize = 0 ++ } ++ ++ var manuallr *obj.Prog ++ var manualsp *obj.Prog ++ var preprog *obj.Prog ++ //convert virtual SP to hardware SP ++ //see also: https://bj.git.sndu.cn/xiabin/go-sw64/wikis/stack-frame-layout ++ for p := cursym.Func().Text; p != nil; p = p.Link { ++ switch p.To.Name { ++ case obj.NAME_PARAM: ++ p.To.Type = obj.TYPE_ADDR ++ p.To.Reg = REGSP ++ p.To.Offset += int64(autosize) + c.ctxt.Arch.FixedFrameSize ++ p.To.Sym = nil ++ case obj.NAME_AUTO: ++ p.To.Type = obj.TYPE_ADDR ++ p.To.Reg = REGSP ++ p.To.Offset += int64(autosize) ++ p.To.Sym = nil ++ } ++ if cursym.Attribute.NoFrame() && (manuallr == nil || manualsp == nil) { ++ switch p.As { ++ case ASTL: ++ if manuallr == nil && p.From.Reg == REGLINK && p.To.Reg == REGSP { ++ manuallr = p ++ } else { ++ preprog = p ++ } ++ case ALDI: ++ if manualsp == nil && p.From.Reg == REGSP && p.To.Reg == REGSP { ++ manualsp = p ++ } else { ++ preprog = p ++ } ++ default: ++ preprog = p ++ } ++ } ++ } ++ ++ if autosize == 0 && c.cursym.Func().Text.Mark&LEAF == 0 { ++ if c.cursym.Func().Text.From.Sym.NoSplit() { ++ if ctxt.Debugvlog { ++ ctxt.Logf("save suppressed in: %s\n", c.cursym.Name) ++ } ++ ++ c.cursym.Func().Text.Mark |= LEAF ++ } ++ } ++ ++ //p.To.Offset = int64(autosize) - ctxt.Arch.FixedFrameSize ++ ++ if c.cursym.Func().Text.Mark&LEAF != 0 { ++ c.cursym.Set(obj.AttrLeaf, true) ++ if p.From.Sym.NoFrame() { ++ //break ++ } ++ } ++ ++ if !p.From.Sym.NoSplit() { ++ q = c.stacksplit(q, autosize) // emit split check ++ } ++ if autosize != 0 { ++ q = c.ctxt.StartUnsafePoint(q, c.newprog) ++ ++ // STL RA, $-autosize(SP) ++ q = obj.Appendp(q, newprog) ++ q.As = ASTL ++ q.From.Type = obj.TYPE_REG ++ q.From.Reg = REGLINK ++ q.To.Type = obj.TYPE_MEM ++ q.To.Reg = REGSP ++ q.To.Offset = int64(-autosize) ++ ++ // LDI SP, $-autosize(SP) ++ q = obj.Appendp(q, newprog) ++ q.Spadj = autosize ++ q.As = ALDI ++ q.From.Type = obj.TYPE_REG ++ q.From.Reg = REGSP ++ q.To.Type = obj.TYPE_ADDR ++ q.To.Reg = REGSP ++ q.To.Offset = int64(-autosize) ++ q = c.ctxt.EndUnsafePoint(q, c.newprog, -1) ++ } else if manuallr != nil && manualsp != nil { ++ if preprog.As == obj.AFUNCDATA && manuallr.Link == manualsp { ++ // This is a workaround for preempt_sw64.s ++ preprog.Link = manualsp.Link ++ q = c.ctxt.StartUnsafePoint(q, c.newprog) ++ q.Link = manuallr ++ q = q.Link ++ q.Link = manualsp ++ q = q.Link ++ q.Spadj = int32(-q.To.Offset) ++ q = c.ctxt.EndUnsafePoint(q, c.newprog, -1) ++ } ++ } ++ // snyh_TODO: #131 ++ q = insertLDGP(q, newprog, REGZERO) ++ ++ if c.cursym.Func().Text.From.Sym.Wrapper() { ++ // if(g->panic != nil && g->panic->argp == FP) ++ // g->panic->argp = bottom-of-frame ++ ++ // LDL R1, g_panic(g) ++ q = obj.Appendp(q, newprog) ++ q.As = ALDL ++ q.From = obj.Addr{Type: obj.TYPE_REG, Reg: REG_R1} ++ q.To = obj.Addr{ ++ Type: obj.TYPE_MEM, ++ Reg: REGG, ++ Offset: 4 * int64(c.ctxt.Arch.PtrSize), // G.panic ++ } ++ ++ // BEQ R1, end ++ q = obj.Appendp(q, newprog) ++ q.As = ABEQ ++ q.From.Type = obj.TYPE_REG ++ q.From.Reg = REG_R1 ++ q.To.Type = obj.TYPE_BRANCH ++ p1 := q ++ ++ // LDL R2, panic_argp(R1) ++ q = obj.Appendp(q, newprog) ++ q.As = ALDL ++ q.From = obj.Addr{Type: obj.TYPE_REG, Reg: REG_R2} ++ q.To = obj.Addr{ ++ Type: obj.TYPE_MEM, ++ Reg: REG_R1, ++ Offset: 0, // Panic.argp ++ } ++ ++ // ADDL SP, $autosize+FixedFrameSize, R3 ++ q = obj.Appendp(q, newprog) ++ q.As = AADDL ++ q.From.Type = obj.TYPE_REG ++ q.From.Reg = REGSP ++ q.AddRestSource(obj.Addr{ ++ Type: obj.TYPE_CONST, ++ Offset: int64(autosize) + ctxt.Arch.FixedFrameSize, ++ }) ++ q.To.Type = obj.TYPE_REG ++ q.To.Reg = REG_R3 ++ ++ // CMPEQ R2, R3, R0 ++ q = obj.Appendp(q, newprog) ++ q.As = ACMPEQ ++ q.From.Type = obj.TYPE_REG ++ q.From.Reg = REG_R2 ++ q.AddRestSource(obj.Addr{ ++ Type: obj.TYPE_REG, ++ Reg: REG_R3, ++ }) ++ q.To.Type = obj.TYPE_REG ++ q.To.Reg = REG_R0 ++ // BEQ R0, end ++ q = obj.Appendp(q, newprog) ++ q.As = ABEQ ++ q.From.Type = obj.TYPE_REG ++ q.From.Reg = REG_R0 ++ q.To.Type = obj.TYPE_BRANCH ++ p2 := q ++ ++ // ADD SP, $FIXED_FRAME, R2 ++ q = obj.Appendp(q, newprog) ++ q.As = AADDL ++ q.From.Type = obj.TYPE_REG ++ q.From.Reg = REGSP ++ q.AddRestSource(obj.Addr{ ++ Type: obj.TYPE_CONST, ++ Offset: ctxt.Arch.FixedFrameSize, ++ }) ++ q.To.Type = obj.TYPE_REG ++ q.To.Reg = REG_R2 ++ ++ // STL R2, panic_argp(R1) ++ q = obj.Appendp(q, newprog) ++ q.As = ASTL ++ q.From.Type = obj.TYPE_REG ++ q.From.Reg = REG_R2 ++ q.To.Type = obj.TYPE_MEM ++ q.To.Reg = REG_R1 ++ q.To.Offset = 0 // Panic.argp ++ ++ // end: ++ q = obj.Appendp(q, newprog) ++ q.As = obj.ANOP ++ p1.To.Val = q ++ p2.To.Val = q ++ } ++ p = q ++ ++ case obj.ARET: ++ retjmp = p.To.Sym ++ ++ if cursym.Func().Text.Mark&LEAF != 0 { ++ if autosize == 0 { ++ p.As = AJMP ++ p.From.Reg = REGZERO ++ p.From.Type = obj.TYPE_REG ++ ++ p.To.Name = obj.NAME_NONE ++ p.To.Sym = nil ++ if retjmp != nil { // retjmp ++ p.To.Type = obj.TYPE_BRANCH ++ p.To.Name = obj.NAME_EXTERN ++ p.To.Sym = retjmp ++ } else { ++ p.To.Type = obj.TYPE_MEM ++ p.To.Offset = 0 ++ p.To.Reg = REGLINK ++ } ++ break ++ } ++ } ++ ++ if autosize != 0 && retjmp == nil { ++ tmp := newprog() ++ *tmp = *p ++ ++ // We can't use q = obj.Appendp(q, newprog), ++ // because the RET may be a jump target, and Appendp ++ // will change the pointer value of q ++ // LDL RA, $0(SP) ++ q := p ++ q.As = ALDL ++ q.From.Type = obj.TYPE_REG ++ q.From.Reg = REGLINK ++ q.To.Type = obj.TYPE_MEM ++ q.To.Reg = REGSP ++ ++ //LDI SP, $autosize(SP) ++ q = obj.Appendp(q, newprog) ++ q.As = ALDI ++ q.From.Type = obj.TYPE_REG ++ q.From.Reg = REGSP ++ q.To.Type = obj.TYPE_ADDR ++ q.To.Reg = REGSP ++ q.To.Offset = int64(autosize) ++ q.Spadj = -autosize ++ ++ q = obj.Appendp(q, newprog) ++ *q = *tmp ++ ++ //insert a noop for restore spadj ++ q = obj.Appendp(q, newprog) ++ q.As = obj.ANOP ++ q.Spadj = autosize ++ p = q ++ ++ } ++ if retjmp != nil { ++ if autosize == 0 { ++ tmp := newprog() ++ *tmp = *p ++ ++ // We can't use q = obj.Appendp(q, newprog), ++ // because the RET may be a jump target, and Appendp ++ // will change the pointer value of q ++ // STL RA, $(int64(autosize) - c.ctxt.Arch.FixedFrameSize)(SP) ++ q := p ++ q.As = ASTL ++ q.From.Type = obj.TYPE_REG ++ q.From.Reg = REGLINK ++ q.To = obj.Addr{ ++ Type: obj.TYPE_MEM, ++ Reg: REGSP, ++ Offset: -c.ctxt.Arch.FixedFrameSize, ++ } ++ ++ // LDI SP, $(int64(autosize) - c.ctxt.Arch.FixedFrameSize)(SP) ++ q = obj.Appendp(q, newprog) ++ q.As = ALDI ++ q.Spadj = autosize ++ q.From.Type = obj.TYPE_REG ++ q.From.Reg = REGSP ++ q.To.Type = obj.TYPE_ADDR ++ q.To.Reg = REGSP ++ q.To.Offset = -c.ctxt.Arch.FixedFrameSize ++ ++ q = obj.Appendp(q, newprog) ++ *q = *tmp ++ //insert a noop for restore spadj ++ q = obj.Appendp(q, newprog) ++ q.As = obj.ANOP ++ q.Spadj = autosize ++ p = q ++ } ++ ++ tmp1 := newprog() ++ *tmp1 = *p ++ ++ q1 := p ++ // snyh_TODO: #131 ++ q1 = insertLDGP(q1, newprog, REGZERO) ++ ++ //insert a noop for restore spadj ++ q1 = obj.Appendp(q1, newprog) ++ q1.As = obj.ANOP ++ q1.Spadj = autosize ++ ++ // LDL RA, $0(SP) ++ q1 = obj.Appendp(q1, newprog) ++ q1.As = ALDL ++ q1.From.Type = obj.TYPE_REG ++ q1.From.Reg = REGLINK ++ q1.To.Type = obj.TYPE_MEM ++ q1.To.Reg = REGSP ++ ++ if autosize != 0 { ++ //LDI SP, $autosize(SP) ++ q1 = obj.Appendp(q1, newprog) ++ q1.As = ALDI ++ q1.From.Type = obj.TYPE_REG ++ q1.From.Reg = REGSP ++ q1.To.Type = obj.TYPE_ADDR ++ q1.To.Reg = REGSP ++ q1.To.Offset = int64(autosize) ++ q1.Spadj = -autosize ++ } else { ++ //LDI SP, $8(SP) ++ q1 = obj.Appendp(q1, newprog) ++ q1.As = ALDI ++ q1.From.Type = obj.TYPE_REG ++ q1.From.Reg = REGSP ++ q1.To.Type = obj.TYPE_ADDR ++ q1.To.Reg = REGSP ++ q1.To.Offset = int64(autosize) + c.ctxt.Arch.FixedFrameSize ++ q1.Spadj = -autosize - int32(c.ctxt.Arch.FixedFrameSize) ++ } ++ ++ //RET ZERO,RA ++ q1 = obj.Appendp(q1, newprog) ++ q1.As = ARET ++ q1.From.Type = obj.TYPE_REG ++ q1.From.Reg = REGZERO ++ q1.To.Type = obj.TYPE_MEM ++ q1.To.Reg = REGLINK ++ ++ p = q1 ++ } ++ case obj.AGETCALLERPC: ++ if cursym.Leaf() { ++ q := p ++ /* LDI Rd, LR */ ++ q.As = ALDI ++ q.To.Type = obj.TYPE_REG ++ q.To.Reg = REGLINK ++ p = q ++ } else { ++ q := p ++ /* LDL Rd, (RSP) */ ++ q.As = ALDL ++ q.To.Type = obj.TYPE_MEM ++ q.To.Reg = REGSP ++ p = q ++ } ++ } ++ ++ if p.From.Type == obj.TYPE_REG && p.From.Reg == REGSP && p.Spadj == 0 && (p.As == ASTL || p.As == ALDL) { ++ f := c.cursym.Func() ++ if f.FuncFlag&abi.FuncFlagSPWrite == 0 { ++ c.cursym.Func().FuncFlag |= abi.FuncFlagSPWrite ++ if ctxt.Debugvlog || !ctxt.IsAsm { ++ ctxt.Logf("auto-SPWRITE: %s %v\n", c.cursym.Name, p) ++ if !ctxt.IsAsm { ++ ctxt.Diag("invalid auto-SPWRITE in non-assembly") ++ ctxt.DiagFlush() ++ log.Fatalf("bad SPWRITE") ++ } ++ } ++ } ++ } ++ } ++ ++ for p := cursym.Func().Text; p != nil; p = p.Link { ++ switch p.As { ++ case obj.ACALL, obj.AJMP: ++ p = insertLDGP(p, newprog, REGZERO) ++ } ++ } ++} ++ ++func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) { ++ c := ctxt77{ctxt: ctxt, newprog: newprog} ++ ++ p.From.Class = 0 ++ p.To.Class = 0 ++ switch p.As { ++ case ACALL: ++ if p.From.Type == obj.TYPE_NONE { ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = REGLINK ++ } ++ case AJMP: ++ if p.To.Type == obj.TYPE_BRANCH { ++ p.As = ABR ++ } ++ if p.From.Type == obj.TYPE_NONE { ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = REGZERO ++ } ++ case ARET: ++ if p.To.Type == obj.TYPE_NONE && p.From.Type == obj.TYPE_NONE { ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = REGZERO ++ p.To.Type = obj.TYPE_MEM ++ p.To.Reg = REGLINK ++ } ++ case ABR, ++ ABSR: ++ if p.From.Type == obj.TYPE_NONE { ++ p.From.Type = obj.TYPE_REG ++ p.From.Reg = REGZERO ++ } ++ case ALDF: ++ if p.To.Type == obj.TYPE_FCONST { ++ f32 := float32(p.To.Val.(float64)) ++ p.As = AFLDS ++ p.To.Type = obj.TYPE_MEM ++ p.To.Sym = ctxt.Float32Sym(f32) ++ p.To.Name = obj.NAME_EXTERN ++ p.To.Offset = 0 ++ } ++ case ALDI: ++ if p.To.Type == obj.TYPE_FCONST { ++ f64 := float64(p.To.Val.(float64)) ++ p.As = AFLDD ++ p.To.Type = obj.TYPE_MEM ++ p.To.Sym = ctxt.Float64Sym(f64) ++ p.To.Name = obj.NAME_EXTERN ++ p.To.Offset = 0 ++ } else if p.To.Type == obj.TYPE_CONST && !isint16(p.To.Offset) { ++ p.As = ALDL ++ p.To.Type = obj.TYPE_MEM ++ p.To.Sym = ctxt.Int64Sym(p.To.Offset) ++ p.To.Name = obj.NAME_EXTERN ++ p.To.Offset = 0 ++ } ++ /*case AIFMOVS, ++ AIFMOVD, ++ AFIMOVS, ++ AFIMOVD: ++ p.AddRestSource(obj.Addr{ ++ Type: obj.TYPE_REG, ++ Reg: REGZERO, ++ })*/ ++ case AFCVTSD, ++ AFCVTDS, ++ AFCVTDL, ++ AFCVTLS, ++ AFCVTLD, ++ AFCVTLW, ++ AFCVTWL, ++ AFSQRTS, ++ AFSQRTD, ++ ACTLZ, ++ ACTTZ, ++ ACTPOP, ++ ASEXTB, ++ ASEXTH, ++ AFCVTDL_Z, ++ AFCVTDL_P, ++ AFCVTDL_G, ++ AFCVTDL_N: ++ p.AddRestSource(p.From) ++ p.From.Reg = REGZERO ++ p.From.Type = obj.TYPE_REG ++ } ++ ++ // use in plugin mode or share mode ++ if c.ctxt.Flag_dynlink { ++ c.rewriteToUseGot(p) ++ } ++ c.insertCrossModule(p) ++} ++ ++func (c *ctxt77) insertCrossModule(p *obj.Prog) { ++ if p.As != obj.ACALL || p.To.Sym == nil { ++ return ++ } ++ ++ if p.To.Sym.Name == "runtime.deferreturn" && p.Mark&CHANGED == 0 { ++ p1 := insertLDGP(p, c.newprog, REGZERO) ++ p1.Mark |= NOSCHED ++ p2 := obj.Appendp(p1, c.newprog) ++ p2.As = p.As ++ p2.To = p.To ++ p2.From = p.From ++ p2.Mark |= CHANGED ++ obj.Nopout(p) ++ } ++} ++ ++// Rewrite p, if necessary, to access global data via the global offset table. ++func (c *ctxt77) rewriteToUseGot(p *obj.Prog) { ++ if p.As == obj.ADUFFCOPY || p.As == obj.ADUFFZERO { ++ // ADUFFxxx $offset ++ // becomes ++ // MOVD runtime.duffxxx@GOT, REGTMP ++ // LDI $offset, REGTMP ++ // LDI LR, REGTMP ++ // CALL LR ++ var sym *obj.LSym ++ if p.As == obj.ADUFFZERO { ++ sym = c.ctxt.Lookup("runtime.duffzero") ++ } else { ++ sym = c.ctxt.Lookup("runtime.duffcopy") ++ } ++ offset := p.To.Offset ++ p.As = AMOVD ++ p.From.Type = obj.TYPE_MEM ++ p.From.Name = obj.NAME_GOTREF ++ p.From.Sym = sym ++ p.To.Type = obj.TYPE_REG ++ p.To.Reg = REGTMP ++ p.To.Name = obj.NAME_NONE ++ p.To.Offset = 0 ++ p.To.Sym = nil ++ ++ p1 := obj.Appendp(p, c.newprog) ++ p1.As = ALDI ++ p1.From.Type = obj.TYPE_REG ++ p1.From.Reg = REGTMP ++ p1.AddRestSource(obj.Addr{Type: obj.TYPE_CONST, Offset: offset}) ++ p1.To.Type = obj.TYPE_REG ++ p1.To.Reg = REGTMP ++ ++ p2 := obj.Appendp(p, c.newprog) ++ p2.As = ALDI ++ p2.From.Type = obj.TYPE_REG ++ p2.From.Reg = REG_R27 ++ p2.To.Type = obj.TYPE_REG ++ p2.To.Reg = REGTMP ++ ++ p3 := obj.Appendp(p1, c.newprog) ++ p3.As = obj.ACALL ++ p3.To.Type = obj.TYPE_REG ++ p3.To.Reg = REG_R27 ++ } ++ ++ // We only care about global data: NAME_EXTERN means a global ++ // symbol in the Go sense, and p.Sym.Local is true for a few ++ // internally defined symbols. ++ ++ if p.To.Type == obj.TYPE_ADDR && p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() { ++ // SYMADDR $sym, Rx becomes SYMADDR sym@GOT, Rx ++ // SYMADDR $sym+, Rx becomes SYMADDR sym@GOT, Rx; LDI , Rx ++ if p.As != ASYMADDR { ++ c.ctxt.Diag("do not know how to handle symbol not symaddr in %v with -dynlink", p) ++ } ++ if p.From.Type != obj.TYPE_REG { ++ c.ctxt.Diag("do not know how to handle symbol address insn to non-register in %v with -dynlink", p) ++ } ++ p.To.Type = obj.TYPE_MEM ++ p.To.Name = obj.NAME_GOTREF ++ if p.From.Offset != 0 { ++ q := obj.Appendp(p, c.newprog) ++ q.As = ALDI ++ q.From = p.To ++ p.AddRestSource(obj.Addr{Type: obj.TYPE_CONST, Offset: p.From.Offset}) ++ q.To = p.To ++ } ++ } ++ // if p.GetFrom3() != nil && p.GetFrom3().Name == obj.NAME_EXTERN { ++ // c.ctxt.Diag("don't know how to handle %v with -dynlink", p) ++ // } ++ ++ var source *obj.Addr ++ // LDx Ry, sym becomes LDL REGTMP, sym@GOT; LDx Ry, (REGTMP) ++ // STx Ry, sym becomes LDL REGTMP, sym@GOT; STx Ry, (REGTMP) ++ // An addition may be inserted between the two MOVs if there is an offset. ++ if p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() { ++ if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() { ++ c.ctxt.Diag("cannot handle NAME_EXTERN on both sides in %v with -dynlink", p) ++ } ++ source = &p.From ++ } else if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() { ++ source = &p.To ++ } else { ++ return ++ } ++ // Simple symbol relocation no need places in got table ++ if p.As == obj.ATEXT || p.As == obj.AFUNCDATA || p.As == obj.ACALL || p.As == obj.ARET || p.As == obj.AJMP { ++ return ++ } // so as tls ++ if source.Sym.Type == objabi.STLSBSS { ++ return ++ } ++ if source.Type != obj.TYPE_MEM { ++ c.ctxt.Diag("don't know how to handle %v with -dynlink", p) ++ } ++ p1 := obj.Appendp(p, c.newprog) ++ p2 := obj.Appendp(p1, c.newprog) ++ p1.As = AMOVD ++ p1.From.Type = obj.TYPE_MEM ++ p1.From.Sym = source.Sym ++ p1.From.Name = obj.NAME_GOTREF ++ p1.To.Type = obj.TYPE_REG ++ p1.To.Reg = REGTMP ++ ++ p2.As = p.As ++ p2.From = p.From ++ p2.To = p.To ++ if p.From.Name == obj.NAME_EXTERN { ++ p2.From.Reg = REGTMP ++ p2.From.Name = obj.NAME_NONE ++ p2.From.Sym = nil ++ } else if p.To.Name == obj.NAME_EXTERN { ++ p2.To.Reg = REGTMP ++ p2.To.Name = obj.NAME_NONE ++ p2.To.Sym = nil ++ } else { ++ return ++ } ++ obj.Nopout(p) ++} ++ ++var LinkSW64 = obj.LinkArch{ ++ Arch: sys.ArchSW64, ++ Init: buildop, ++ Preprocess: preprocess, ++ Assemble: span77, ++ Progedit: progedit, ++ DWARFRegisters: SW64DWARFRegisters, ++} ++ ++//单参数指令,且参数为目的数 ==>(Prog.To = a[0]) ++//不在这个列表的则参数为源数 ==>(Prog.From = a[0]) ++var unaryDst = map[obj.As]bool{} +diff --git a/src/cmd/internal/obj/util.go b/src/cmd/internal/obj/util.go +index 26de22122a..b9e8f00fbe 100644 +--- a/src/cmd/internal/obj/util.go ++++ b/src/cmd/internal/obj/util.go +@@ -520,6 +520,7 @@ const ( + RBaseRISCV = 15 * 1024 // range [15k, 16k) + RBaseWasm = 16 * 1024 + RBaseLOONG64 = 19 * 1024 // range [19K, 22k) ++ RBaseSW64 = 28 * 1024 // range [28k, 29k) + ) + + // RegisterRegister binds a pretty-printer (Rconv) for register +diff --git a/src/cmd/internal/objabi/reloctype.go b/src/cmd/internal/objabi/reloctype.go +index 9106b085ea..b66c24be1f 100644 +--- a/src/cmd/internal/objabi/reloctype.go ++++ b/src/cmd/internal/objabi/reloctype.go +@@ -374,6 +374,36 @@ const ( + // symbol's DWARF compile unit. + R_ADDRCUOFF + ++ // A 21 bit branch. ++ // R_SW64_BRADDR replace displacement value, e.g. [20:0] of control format instruction ++ R_SW64_BRADDR ++ R_SW64_GPDISP ++ ++ /* The high 16 bits of the displacement from TP to the target. */ ++ R_SW64_TPRELHI ++ /* The low 16 bits of the displacement from TP to the target. */ ++ R_SW64_TPRELLO ++ ++ /* Creates a 64-bit offset in the got for the displacement from TP to the target. */ ++ R_SW64_GOTTPREL ++ ++ // R_SW64_HINT replace displacement value, e.g. [15:0] of JMP/CALL/RET ++ R_SW64_HINT ++ ++ /* The high 16 bits of the displacement from GP to the target. */ ++ R_SW64_GPRELHIGH ++ /* The low 16 bits of the displacement from GP to the target. */ ++ R_SW64_GPRELLOW ++ ++ /* Load address form GP to the target */ ++ R_SW64_LITERAL_GOT ++ R_SW64_LITERAL ++ ++ /*TODO:*/ ++ R_SW64_ADDR ++ R_SW64_PCREL ++ R_CALLSW64 ++ + // R_WASMIMPORT resolves to the index of the WebAssembly function import. + R_WASMIMPORT + +@@ -410,7 +440,7 @@ const ( + func (r RelocType) IsDirectCall() bool { + switch r { + case R_CALL, R_CALLARM, R_CALLARM64, R_CALLLOONG64, R_CALLMIPS, R_CALLPOWER, +- R_RISCV_CALL, R_RISCV_JAL, R_RISCV_JAL_TRAMP: ++ R_RISCV_CALL, R_RISCV_JAL, R_RISCV_JAL_TRAMP, R_SW64_HINT: + return true + } + return false +diff --git a/src/cmd/internal/objabi/reloctype_string.go b/src/cmd/internal/objabi/reloctype_string.go +index fd0e401db1..c7970e6bbd 100644 +--- a/src/cmd/internal/objabi/reloctype_string.go ++++ b/src/cmd/internal/objabi/reloctype_string.go +@@ -1,4 +1,4 @@ +-// Code generated by "stringer -type=RelocType"; DO NOT EDIT. ++// Code generated by "stringer -type=RelocType ./src/cmd/internal/objabi/reloctype.go"; DO NOT EDIT. + + package objabi + +@@ -99,15 +99,28 @@ func _() { + _ = x[R_ADDRMIPSU-89] + _ = x[R_ADDRMIPSTLS-90] + _ = x[R_ADDRCUOFF-91] +- _ = x[R_WASMIMPORT-92] +- _ = x[R_XCOFFREF-93] +- _ = x[R_PEIMAGEOFF-94] +- _ = x[R_INITORDER-95] ++ _ = x[R_SW64_BRADDR-92] ++ _ = x[R_SW64_GPDISP-93] ++ _ = x[R_SW64_TPRELHI-94] ++ _ = x[R_SW64_TPRELLO-95] ++ _ = x[R_SW64_GOTTPREL-96] ++ _ = x[R_SW64_HINT-97] ++ _ = x[R_SW64_GPRELHIGH-98] ++ _ = x[R_SW64_GPRELLOW-99] ++ _ = x[R_SW64_LITERAL_GOT-100] ++ _ = x[R_SW64_LITERAL-101] ++ _ = x[R_SW64_ADDR-102] ++ _ = x[R_SW64_PCREL-103] ++ _ = x[R_CALLSW64-104] ++ _ = x[R_WASMIMPORT-105] ++ _ = x[R_XCOFFREF-106] ++ _ = x[R_PEIMAGEOFF-107] ++ _ = x[R_INITORDER-108] + } + +-const _RelocType_name = "R_ADDRR_ADDRPOWERR_ADDRARM64R_ADDRMIPSR_ADDROFFR_SIZER_CALLR_CALLARMR_CALLARM64R_CALLINDR_CALLPOWERR_CALLMIPSR_CONSTR_PCRELR_TLS_LER_TLS_IER_GOTOFFR_PLT0R_PLT1R_PLT2R_USEFIELDR_USETYPER_USEIFACER_USEIFACEMETHODR_USENAMEDMETHODR_METHODOFFR_KEEPR_POWER_TOCR_GOTPCRELR_JMPMIPSR_DWARFSECREFR_DWARFFILEREFR_ARM64_TLS_LER_ARM64_TLS_IER_ARM64_GOTPCRELR_ARM64_GOTR_ARM64_PCRELR_ARM64_PCREL_LDST8R_ARM64_PCREL_LDST16R_ARM64_PCREL_LDST32R_ARM64_PCREL_LDST64R_ARM64_LDST8R_ARM64_LDST16R_ARM64_LDST32R_ARM64_LDST64R_ARM64_LDST128R_POWER_TLS_LER_POWER_TLS_IER_POWER_TLSR_POWER_TLS_IE_PCREL34R_POWER_TLS_LE_TPREL34R_ADDRPOWER_DSR_ADDRPOWER_GOTR_ADDRPOWER_GOT_PCREL34R_ADDRPOWER_PCRELR_ADDRPOWER_TOCRELR_ADDRPOWER_TOCREL_DSR_ADDRPOWER_D34R_ADDRPOWER_PCREL34R_RISCV_JALR_RISCV_JAL_TRAMPR_RISCV_CALLR_RISCV_PCREL_ITYPER_RISCV_PCREL_STYPER_RISCV_TLS_IER_RISCV_TLS_LER_RISCV_GOT_HI20R_RISCV_PCREL_HI20R_RISCV_PCREL_LO12_IR_RISCV_PCREL_LO12_SR_RISCV_BRANCHR_RISCV_RVC_BRANCHR_RISCV_RVC_JUMPR_PCRELDBLR_LOONG64_ADDR_HIR_LOONG64_ADDR_LOR_LOONG64_TLS_LE_HIR_LOONG64_TLS_LE_LOR_CALLLOONG64R_LOONG64_TLS_IE_HIR_LOONG64_TLS_IE_LOR_LOONG64_GOT_HIR_LOONG64_GOT_LOR_LOONG64_ADD64R_LOONG64_SUB64R_JMP16LOONG64R_JMP21LOONG64R_JMPLOONG64R_ADDRMIPSUR_ADDRMIPSTLSR_ADDRCUOFFR_WASMIMPORTR_XCOFFREFR_PEIMAGEOFFR_INITORDER" ++const _RelocType_name = "R_ADDRR_ADDRPOWERR_ADDRARM64R_ADDRMIPSR_ADDROFFR_SIZER_CALLR_CALLARMR_CALLARM64R_CALLINDR_CALLPOWERR_CALLMIPSR_CONSTR_PCRELR_TLS_LER_TLS_IER_GOTOFFR_PLT0R_PLT1R_PLT2R_USEFIELDR_USETYPER_USEIFACER_USEIFACEMETHODR_USENAMEDMETHODR_METHODOFFR_KEEPR_POWER_TOCR_GOTPCRELR_JMPMIPSR_DWARFSECREFR_DWARFFILEREFR_ARM64_TLS_LER_ARM64_TLS_IER_ARM64_GOTPCRELR_ARM64_GOTR_ARM64_PCRELR_ARM64_PCREL_LDST8R_ARM64_PCREL_LDST16R_ARM64_PCREL_LDST32R_ARM64_PCREL_LDST64R_ARM64_LDST8R_ARM64_LDST16R_ARM64_LDST32R_ARM64_LDST64R_ARM64_LDST128R_POWER_TLS_LER_POWER_TLS_IER_POWER_TLSR_POWER_TLS_IE_PCREL34R_POWER_TLS_LE_TPREL34R_ADDRPOWER_DSR_ADDRPOWER_GOTR_ADDRPOWER_GOT_PCREL34R_ADDRPOWER_PCRELR_ADDRPOWER_TOCRELR_ADDRPOWER_TOCREL_DSR_ADDRPOWER_D34R_ADDRPOWER_PCREL34R_RISCV_JALR_RISCV_JAL_TRAMPR_RISCV_CALLR_RISCV_PCREL_ITYPER_RISCV_PCREL_STYPER_RISCV_TLS_IER_RISCV_TLS_LER_RISCV_GOT_HI20R_RISCV_PCREL_HI20R_RISCV_PCREL_LO12_IR_RISCV_PCREL_LO12_SR_RISCV_BRANCHR_RISCV_RVC_BRANCHR_RISCV_RVC_JUMPR_PCRELDBLR_LOONG64_ADDR_HIR_LOONG64_ADDR_LOR_LOONG64_TLS_LE_HIR_LOONG64_TLS_LE_LOR_CALLLOONG64R_LOONG64_TLS_IE_HIR_LOONG64_TLS_IE_LOR_LOONG64_GOT_HIR_LOONG64_GOT_LOR_LOONG64_ADD64R_LOONG64_SUB64R_JMP16LOONG64R_JMP21LOONG64R_JMPLOONG64R_ADDRMIPSUR_ADDRMIPSTLSR_ADDRCUOFFR_SW64_BRADDRR_SW64_GPDISPR_SW64_TPRELHIR_SW64_TPRELLOR_SW64_GOTTPRELR_SW64_HINTR_SW64_GPRELHIGHR_SW64_GPRELLOWR_SW64_LITERAL_GOTR_SW64_LITERALR_SW64_ADDRR_SW64_PCRELR_CALLSW64R_WASMIMPORTR_XCOFFREFR_PEIMAGEOFFR_INITORDER" + +-var _RelocType_index = [...]uint16{0, 6, 17, 28, 38, 47, 53, 59, 68, 79, 88, 99, 109, 116, 123, 131, 139, 147, 153, 159, 165, 175, 184, 194, 210, 226, 237, 243, 254, 264, 273, 286, 300, 314, 328, 344, 355, 368, 387, 407, 427, 447, 460, 474, 488, 502, 517, 531, 545, 556, 578, 600, 614, 629, 652, 669, 687, 708, 723, 742, 753, 770, 782, 801, 820, 834, 848, 864, 882, 902, 922, 936, 954, 970, 980, 997, 1014, 1033, 1052, 1065, 1084, 1103, 1119, 1135, 1150, 1165, 1179, 1193, 1205, 1216, 1229, 1240, 1252, 1262, 1274, 1285} ++var _RelocType_index = [...]uint16{0, 6, 17, 28, 38, 47, 53, 59, 68, 79, 88, 99, 109, 116, 123, 131, 139, 147, 153, 159, 165, 175, 184, 194, 210, 226, 237, 243, 254, 264, 273, 286, 300, 314, 328, 344, 355, 368, 387, 407, 427, 447, 460, 474, 488, 502, 517, 531, 545, 556, 578, 600, 614, 629, 652, 669, 687, 708, 723, 742, 753, 770, 782, 801, 820, 834, 848, 864, 882, 902, 922, 936, 954, 970, 980, 997, 1014, 1033, 1052, 1065, 1084, 1103, 1119, 1135, 1150, 1165, 1179, 1193, 1205, 1216, 1229, 1240, 1253, 1266, 1280, 1294, 1309, 1320, 1336, 1351, 1369, 1383, 1394, 1406, 1416, 1428, 1438, 1450, 1461} + + func (i RelocType) String() string { + i -= 1 +diff --git a/src/cmd/internal/objfile/elf.go b/src/cmd/internal/objfile/elf.go +index 8923290cff..27eed3f1c4 100644 +--- a/src/cmd/internal/objfile/elf.go ++++ b/src/cmd/internal/objfile/elf.go +@@ -133,7 +133,9 @@ func (f *elfFile) goarch() string { + } + case elf.EM_S390: + return "s390x" +- } ++ case elf.EM_SW64: ++ return "sw64" ++ } + return "" + } + diff --git a/0003-cmd-link-Add-sw64-port.patch b/0003-cmd-link-Add-sw64-port.patch new file mode 100644 index 0000000000000000000000000000000000000000..8d5560da2349520dfa9a4902a299a2360b5e5986 --- /dev/null +++ b/0003-cmd-link-Add-sw64-port.patch @@ -0,0 +1,1101 @@ +diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go +index a6b94a829f..df1c04a50e 100644 +--- a/src/cmd/link/internal/ld/data.go ++++ b/src/cmd/link/internal/ld/data.go +@@ -328,7 +328,7 @@ func (st *relocSymState) relocsym(s loader.Sym, P []byte) { + if target.IsExternal() && target.IsElf() { + nExtReloc++ + o = 0 +- if !target.IsAMD64() { ++ if !target.IsAMD64() && !target.IsSW64() { + o = r.Add() + } + break +@@ -354,7 +354,7 @@ func (st *relocSymState) relocsym(s loader.Sym, P []byte) { + if target.IsExternal() && target.IsElf() { + nExtReloc++ + o = 0 +- if !target.IsAMD64() { ++ if !target.IsAMD64() && !target.IsSW64() { + o = r.Add() + } + if target.Is386() { +@@ -392,7 +392,7 @@ func (st *relocSymState) relocsym(s loader.Sym, P []byte) { + + o = xadd + if target.IsElf() { +- if target.IsAMD64() { ++ if target.IsAMD64() || target.IsSW64() { + o = 0 + } + } else if target.IsDarwin() { +@@ -466,7 +466,7 @@ func (st *relocSymState) relocsym(s loader.Sym, P []byte) { + xadd := r.Add() + ldr.SymValue(rs) - int64(ldr.SymSect(rs).Vaddr) + + o = xadd +- if target.IsElf() && target.IsAMD64() { ++ if target.IsElf() && (target.IsAMD64() || target.IsSW64()) { + o = 0 + } + break +@@ -541,7 +541,7 @@ func (st *relocSymState) relocsym(s loader.Sym, P []byte) { + + o = xadd + if target.IsElf() { +- if target.IsAMD64() { ++ if target.IsAMD64() || target.IsSW64() { + o = 0 + } + } else if target.IsDarwin() { +@@ -625,7 +625,15 @@ func (st *relocSymState) relocsym(s loader.Sym, P []byte) { + } else if o != int64(int32(o)) && o != int64(uint32(o)) { + st.err.Errorf(s, "non-pc-relative relocation address for %s is too big: %#x", ldr.SymName(rs), uint64(o)) + } +- target.Arch.ByteOrder.PutUint32(P[off:], uint32(o)) ++ if target.IsSW64() && rt == objabi.R_SW64_GPDISP && !target.IsExternal() { ++ Hi := uint16(o >> 16) ++ Lo := uint16(o) ++ target.Arch.ByteOrder.PutUint16(P[off:], Hi) ++ target.Arch.ByteOrder.PutUint16(P[off+4:], Lo) ++ ++ } else { ++ target.Arch.ByteOrder.PutUint32(P[off:], uint32(o)) ++ } + case 8: + target.Arch.ByteOrder.PutUint64(P[off:], uint64(o)) + } +diff --git a/src/cmd/link/internal/ld/deadcode.go b/src/cmd/link/internal/ld/deadcode.go +index cdf7deb31b..5608097283 100644 +--- a/src/cmd/link/internal/ld/deadcode.go ++++ b/src/cmd/link/internal/ld/deadcode.go +@@ -324,6 +324,20 @@ func (d *deadcodePass) flood() { + } + } + } ++// TODO: temporary solution, preferably add new relocation type ++func isSW64DirectCall(index int, relocs loader.Relocs) bool { ++ var reloc_types [3]objabi.RelocType; ++ for i := 0; i < 3; i++ { ++ reloc_types[i] = relocs.At(index + i).Type() ++ } ++ if reloc_types[0] == objabi.R_SW64_GPRELHIGH && reloc_types[2] == objabi.R_SW64_HINT { ++ return true; ++ } else if reloc_types[0] == objabi.R_SW64_GPRELLOW && reloc_types[1] == objabi.R_SW64_HINT { ++ return true; ++ } else { ++ return false; ++ } ++} + + // mapinitcleanup walks all pkg init functions and looks for weak relocations + // to mapinit symbols that are no longer reachable. It rewrites +@@ -335,7 +349,7 @@ func (d *deadcodePass) mapinitcleanup() { + for i := 0; i < relocs.Count(); i++ { + r := relocs.At(i) + rs := r.Sym() +- if r.Weak() && r.Type().IsDirectCall() && !d.ldr.AttrReachable(rs) { ++ if r.Weak() && (r.Type().IsDirectCall() || isSW64DirectCall(i, relocs)) && !d.ldr.AttrReachable(rs) { + // double check to make sure target is indeed map.init + rsn := d.ldr.SymName(rs) + if !strings.Contains(rsn, "map.init") { +diff --git a/src/cmd/link/internal/ld/elf.go b/src/cmd/link/internal/ld/elf.go +index e6a525198f..73c2a4dbdb 100644 +--- a/src/cmd/link/internal/ld/elf.go ++++ b/src/cmd/link/internal/ld/elf.go +@@ -234,7 +234,7 @@ we write section and prog headers. + func Elfinit(ctxt *Link) { + ctxt.IsELF = true + +- if ctxt.Arch.InFamily(sys.AMD64, sys.ARM64, sys.Loong64, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X) { ++ if ctxt.Arch.InFamily(sys.AMD64, sys.ARM64, sys.Loong64, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X, sys.SW64) { + elfRelType = ".rela" + } else { + elfRelType = ".rel" +@@ -249,7 +249,7 @@ func Elfinit(ctxt *Link) { + ehdr.Flags = 2 /* Version 2 ABI */ + } + fallthrough +- case sys.AMD64, sys.ARM64, sys.Loong64, sys.MIPS64, sys.RISCV64: ++ case sys.AMD64, sys.ARM64, sys.Loong64, sys.MIPS64, sys.RISCV64, sys.SW64: + if ctxt.Arch.Family == sys.MIPS64 { + ehdr.Flags = 0x20000004 /* MIPS 3 CPIC */ + } +@@ -990,7 +990,8 @@ func elfdynhash(ctxt *Link) { + } + + // s390x (ELF64) hash table entries are 8 bytes +- if ctxt.Arch.Family == sys.S390X { ++ // so as sw64 (ELF64) ++ if ctxt.Arch.Family == sys.S390X || ctxt.Arch.Family == sys.SW64 { + s.AddUint64(ctxt.Arch, uint64(nbucket)) + s.AddUint64(ctxt.Arch, uint64(nsym)) + for i := 0; i < nbucket; i++ { +@@ -1628,7 +1629,7 @@ func (ctxt *Link) doelf() { + dynamic.SetType(sym.SELFSECT) + } + +- if ctxt.IsS390X() { ++ if ctxt.IsS390X() || ctxt.IsSW64() { + // S390X uses .got instead of .got.plt + gotplt = got + } +@@ -1673,6 +1674,11 @@ func (ctxt *Link) doelf() { + Elfwritedynent(ctxt.Arch, dynamic, elf.DT_PPC64_OPT, 0) + } + ++ if ctxt.IsSW64() { ++ // sw64 use DT_LOPROC to mark plt is read only ++ elfWriteDynEntSym(ctxt, dynamic, elf.DT_LOPROC, plt.Sym()) ++ } ++ + // Solaris dynamic linker can't handle an empty .rela.plt if + // DT_JMPREL is emitted so we have to defer generation of elf.DT_PLTREL, + // DT_PLTRELSZ, and elf.DT_JMPREL dynamic entries until after we know the +@@ -1833,6 +1839,8 @@ func asmbElf(ctxt *Link) { + eh.Machine = uint16(elf.EM_RISCV) + case sys.S390X: + eh.Machine = uint16(elf.EM_S390) ++ case sys.SW64: ++ eh.Machine = uint16(elf.EM_SW64) + } + + elfreserve := int64(ELFRESERVE) +@@ -2119,7 +2127,7 @@ func asmbElf(ctxt *Link) { + sh = elfshname(".plt") + sh.Type = uint32(elf.SHT_PROGBITS) + sh.Flags = uint64(elf.SHF_ALLOC + elf.SHF_EXECINSTR) +- if elf.Machine(eh.Machine) == elf.EM_X86_64 { ++ if elf.Machine(eh.Machine) == elf.EM_X86_64 || elf.Machine(eh.Machine) == elf.EM_SW64 { + sh.Entsize = 16 + } else if elf.Machine(eh.Machine) == elf.EM_S390 { + sh.Entsize = 32 +diff --git a/src/cmd/link/internal/ld/pcln.go b/src/cmd/link/internal/ld/pcln.go +index ea08fd3d31..c67c8bd343 100644 +--- a/src/cmd/link/internal/ld/pcln.go ++++ b/src/cmd/link/internal/ld/pcln.go +@@ -149,6 +149,8 @@ func computeDeferReturn(ctxt *Link, deferReturnSym, s loader.Sym) uint32 { + // no change + case sys.S390X: + deferreturn -= 2 ++ case sys.SW64: ++ deferreturn -= 8 + default: + panic(fmt.Sprint("Unhandled architecture:", target.Arch.Family)) + } +diff --git a/src/cmd/link/internal/ld/target.go b/src/cmd/link/internal/ld/target.go +index d0ce99f3e9..ae0c985146 100644 +--- a/src/cmd/link/internal/ld/target.go ++++ b/src/cmd/link/internal/ld/target.go +@@ -132,6 +132,10 @@ func (t *Target) IsWasm() bool { + return t.Arch.Family == sys.Wasm + } + ++func (t *Target) IsSW64() bool { ++ return t.Arch.Family == sys.SW64 ++} ++ + // + // OS Functions + // +diff --git a/src/cmd/link/internal/loadelf/ldelf.go b/src/cmd/link/internal/loadelf/ldelf.go +index e0363b5535..0af6ed3092 100644 +--- a/src/cmd/link/internal/loadelf/ldelf.go ++++ b/src/cmd/link/internal/loadelf/ldelf.go +@@ -381,6 +381,11 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, f *bio.Reader, + if mach != elf.EM_S390 || class != elf.ELFCLASS64 { + return errorf("elf object but not s390x") + } ++ ++ case sys.SW64: ++ if mach != elf.EM_SW64 || class != elf.ELFCLASS64 { ++ return errorf("elf object but not sw64") ++ } + } + + // load section list into memory. +@@ -987,6 +992,7 @@ func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, uint8, error) { + PPC64 = uint32(sys.PPC64) + RISCV64 = uint32(sys.RISCV64) + S390X = uint32(sys.S390X) ++ SW64 = uint32(sys.SW64) + ) + + switch uint32(arch.Family) | elftype<<16 { +@@ -1046,6 +1052,12 @@ func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, uint8, error) { + return 1, 1, nil + + case PPC64 | uint32(elf.R_PPC64_TOC16)<<16, ++ SW64 | uint32(elf.R_SW64_SREL16)<<16, ++ SW64 | uint32(39)<<16, ++ SW64 | uint32(40)<<16, ++ SW64 | uint32(elf.R_SW64_LITUSE)<<16, ++ SW64 | uint32(elf.R_SW64_HINT)<<16, ++ SW64 | uint32(elf.R_SW64_LITERAL_GOT)<<16, + S390X | uint32(elf.R_390_16)<<16, + S390X | uint32(elf.R_390_GOT16)<<16, + S390X | uint32(elf.R_390_PC16)<<16, +@@ -1089,6 +1101,13 @@ func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, uint8, error) { + I386 | uint32(elf.R_386_GOTOFF)<<16, + I386 | uint32(elf.R_386_GOTPC)<<16, + I386 | uint32(elf.R_386_GOT32X)<<16, ++ SW64 | uint32(elf.R_SW64_LITERAL)<<16, ++ SW64 | uint32(elf.R_SW64_GPRELHIGH)<<16, ++ SW64 | uint32(elf.R_SW64_GPRELLOW)<<16, ++ SW64 | uint32(elf.R_SW64_SREL32)<<16, ++ SW64 | uint32(elf.R_SW64_REFLONG)<<16, ++ SW64 | uint32(elf.R_SW64_BRADDR)<<16, ++ SW64 | uint32(elf.R_SW64_GPDISP)<<16, + PPC64 | uint32(elf.R_PPC64_REL24)<<16, + PPC64 | uint32(elf.R_PPC64_REL24_NOTOC)<<16, + PPC64 | uint32(elf.R_PPC64_REL24_P9NOTOC)<<16, +@@ -1111,6 +1130,7 @@ func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, uint8, error) { + PPC64 | uint32(elf.R_PPC64_PCREL34)<<16, + PPC64 | uint32(elf.R_PPC64_GOT_PCREL34)<<16, + PPC64 | uint32(elf.R_PPC64_PLT_PCREL34_NOTOC)<<16, ++ SW64 | uint32(elf.R_SW64_REFQUAD)<<16, + S390X | uint32(elf.R_390_GLOB_DAT)<<16, + S390X | uint32(elf.R_390_RELATIVE)<<16, + S390X | uint32(elf.R_390_GOTOFF)<<16, +diff --git a/src/cmd/link/internal/sw64/asm.go b/src/cmd/link/internal/sw64/asm.go +new file mode 100644 +index 0000000000..93feccc520 +--- /dev/null ++++ b/src/cmd/link/internal/sw64/asm.go +@@ -0,0 +1,712 @@ ++// 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 sw64 ++ ++import ( ++ "cmd/internal/objabi" ++ "cmd/link/internal/ld" ++ "cmd/link/internal/loader" ++ "cmd/link/internal/sym" ++ "debug/elf" ++ "log" ++) ++ ++var pltHeaderSize int64 ++var internalLinkingCgo bool = false ++ ++func gentext(ctxt *ld.Link, ldr *loader.Loader) { ++ initfunc, addmoduledata := ld.PrepareAddmoduledata(ctxt) ++ if initfunc == nil { ++ return ++ } ++ ++ o := func(op uint32) { ++ initfunc.AddUint32(ctxt.Arch, op) ++ } ++ ++ // 0000000000000000 : ++ // 0: 00 00 bb ff ldih ldih$r29,0($r27) ++ // 0: R_SW_64_GPDISP .text+0x4 ++ // 4: 00 00 bd fb ldi $r29,0($r29) ++ o(0xffbb0000) ++ rel0, _ := initfunc.AddRel(objabi.R_SW64_GPDISP) ++ rel0.SetOff(0) ++ rel0.SetSiz(4) ++ rel0.SetAdd(4) ++ //TODO: how to find a new way to find pc symbol? ++ rel0.SetSym(ldr.LookupOrCreateSym("go:link.addmoduledata", 0)) ++ o(0xfbbd0000) ++ ++ // 8: 00 00 1d fc ldih r0, 0(r29) ++ // 0: R_SW_64_GPRELHI local.moduledata ++ // c: 00 00 00 f8 ldi r0, 0(r0) ++ // 4: R_SW_64_GPRELLO local.moduledata ++ o(0xfc1d0000) ++ rel, _ := initfunc.AddRel(objabi.R_SW64_GPRELHIGH) ++ rel.SetOff(8) ++ rel.SetSiz(4) ++ rel.SetSym(ctxt.Moduledata) ++ ++ o(0xf8000000) ++ rel1, _ := initfunc.AddRel(objabi.R_SW64_GPRELLOW) ++ rel1.SetOff(12) ++ rel1.SetSiz(4) ++ rel1.SetSym(ctxt.Moduledata) ++ ++ // 10: 00 00 7d ff ldih r27, 0(r29) ++ // 8: R_SW_64_GPRELHI runtime.addmoduledata ++ // 14: 00 00 7b fb ldi r27, 0(r27) ++ // 12: R_SW_64_GPRELLO runtime.addmoduledata ++ // 18: 00 00 fb 0f jmp (r31),(r27),1 ++ o(0xff7d0000) ++ rel2, _ := initfunc.AddRel(objabi.R_SW64_GPRELHIGH) ++ rel2.SetOff(16) ++ rel2.SetSiz(4) ++ rel2.SetSym(addmoduledata) ++ o(0xfb7b0000) ++ rel3, _ := initfunc.AddRel(objabi.R_SW64_GPRELLOW) ++ rel3.SetOff(20) ++ rel3.SetSiz(4) ++ rel3.SetSym(addmoduledata) ++ o(0x0ffb0000) ++ ++ // filled nop ++ o(0x43ff075f) ++ o(0x43ff075f) ++ o(0x1bff0080) //unreachable ++} ++ ++func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym, r loader.Reloc, rIdx int) bool { ++ //TODO ++ targ := r.Sym() ++ var targType sym.SymKind ++ if targ != 0 { ++ targType = ldr.SymType(targ) ++ } ++ ++ const pcrel = 1 ++ switch r.Type() { ++ default: ++ if r.Type() >= objabi.ElfRelocOffset { ++ ldr.Errorf(s, "unexpected relocation type %d (%s)", r.Type(), sym.RelocName(target.Arch, r.Type())) ++ return false ++ } ++ ++ case objabi.ElfRelocOffset + objabi.RelocType(elf.R_SW64_GPDISP): ++ if targType == sym.SDYNIMPORT { ++ ldr.Errorf(s, "unexpected relocation for dynamic symbol %s", ldr.SymName(targ)) ++ } ++ su := ldr.MakeSymbolUpdater(s) ++ su.SetRelocType(rIdx, objabi.R_SW64_GPDISP) ++ su.SetRelocAdd(rIdx, r.Add()+4) ++ return true ++ ++ // Handle relocations found in ELF object files. ++ case objabi.ElfRelocOffset + objabi.RelocType(elf.R_SW64_SREL16): ++ if targType == sym.SDYNIMPORT { ++ ldr.Errorf(s, "unexpected R_SW64_SREL16 relocation for dynamic symbol %s", ldr.SymName(targ)) ++ } ++ su := ldr.MakeSymbolUpdater(s) ++ su.SetRelocType(rIdx, objabi.R_PCREL) ++ su.SetRelocAdd(rIdx, r.Add()+2) ++ return true ++ ++ case objabi.ElfRelocOffset + objabi.RelocType(elf.R_SW64_SREL32): ++ if targType == sym.SDYNIMPORT { ++ ldr.Errorf(s, "unexpected R_SW64_SREL16 relocation for dynamic symbol %s", ldr.SymName(targ)) ++ } ++ su := ldr.MakeSymbolUpdater(s) ++ su.SetRelocType(rIdx, objabi.R_PCREL) ++ su.SetRelocAdd(rIdx, r.Add()+4) ++ return true ++ ++ case objabi.ElfRelocOffset + objabi.RelocType(elf.R_SW64_SREL64): ++ if targType == sym.SDYNIMPORT { ++ ldr.Errorf(s, "unexpected R_SW64_SREL64 relocation for dynamic symbol %s", ldr.SymName(targ)) ++ } ++ su := ldr.MakeSymbolUpdater(s) ++ su.SetRelocType(rIdx, objabi.R_PCREL) ++ su.SetRelocAdd(rIdx, r.Add()+8) ++ return true ++ ++ case objabi.ElfRelocOffset + objabi.RelocType(elf.R_SW64_BRADDR): ++ // TODO: do we need do something about it? ++ su := ldr.MakeSymbolUpdater(s) ++ su.SetRelocType(rIdx, objabi.R_SW64_BRADDR) ++ return true ++ ++ case objabi.ElfRelocOffset + objabi.RelocType(elf.R_SW64_LITERAL_GOT): ++ // TODO:as literal_got doesn't achieve completily we just ignore it ++ return true ++ ++ case objabi.ElfRelocOffset + objabi.RelocType(elf.R_SW64_LITUSE), ++ objabi.ElfRelocOffset + objabi.RelocType(elf.R_SW64_HINT): ++ // TODO:this is not necessary for reloc ignore it ++ return true ++ ++ case objabi.ElfRelocOffset + objabi.RelocType(elf.R_SW64_LITERAL): ++ if targType == sym.SDYNIMPORT { ++ // have symbol ++ // literal need a plt slot in dynmic link ++ addpltsym(target, ldr, syms, targ) ++ } ++ su := ldr.MakeSymbolUpdater(s) ++ su.SetRelocType(rIdx, objabi.R_SW64_LITERAL) ++ // if LITERAL contant a reg call, ++ // it is already created a plt entry in .got, ++ // so we change target to it. ++ sv := ldr.SymGot(targ) ++ splt := ldr.SymPlt(targ) ++ if sv != -1 && splt != -1 { ++ su.SetRelocSym(rIdx, syms.GOT) ++ su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymGot(targ))) ++ return true ++ } ++ // fall back to using GOT ++ ld.AddGotSym(target, ldr, syms, targ, uint32(elf.R_SW64_GLOB_DAT)) ++ su.SetRelocSym(rIdx, syms.GOT) ++ su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymGot(targ))+8) ++ return true ++ ++ case objabi.ElfRelocOffset + objabi.RelocType(elf.R_SW64_GPRELHIGH), ++ objabi.ElfRelocOffset + objabi.RelocType(elf.R_SW64_GPRELLOW): ++ if targType == sym.SDYNIMPORT { ++ ldr.Errorf(s, "unexpected relocation for dynamic symbol %s", ldr.SymName(targ)) ++ } ++ if targType == 0 || targType == sym.SXREF { ++ ldr.Errorf(s, "unknown symbol %s", ldr.SymName(targ)) ++ } ++ var rel objabi.RelocType ++ if r.Type() == objabi.ElfRelocOffset+objabi.RelocType(elf.R_SW64_GPRELHIGH) { ++ rel = objabi.R_SW64_GPRELHIGH ++ } else { ++ rel = objabi.R_SW64_GPRELLOW ++ } ++ su := ldr.MakeSymbolUpdater(s) ++ su.SetRelocType(rIdx, rel) ++ return true ++ ++ case objabi.ElfRelocOffset + objabi.RelocType(elf.R_SW64_REFLONG), ++ objabi.ElfRelocOffset + objabi.RelocType(elf.R_SW64_REFQUAD): ++ if targType == sym.SDYNIMPORT { ++ ldr.Errorf(s, "unexpected R_SW64_*ABS* relocation for dynamic symbol %s", ldr.SymName(targ)) ++ } ++ su := ldr.MakeSymbolUpdater(s) ++ su.SetRelocType(rIdx, objabi.R_ADDR) ++ if target.IsPIE() && target.IsInternal() { ++ // For internal linking PIE, this R_ADDR relocation cannot ++ // be resolved statically. We need to generate a dynamic ++ // relocation. Let the code below handle it. ++ break ++ } ++ return true ++ } ++ ++ // Reread the reloc to incorporate any changes in type above. ++ relocs := ldr.Relocs(s) ++ r = relocs.At(rIdx) ++ ++ switch r.Type() { ++ case objabi.R_CALL, ++ objabi.R_PCREL: ++ if targType != sym.SDYNIMPORT { ++ // nothing to do, the relocation will be laid out in reloc ++ return true ++ } ++ if target.IsExternal() { ++ // External linker will do this relocation. ++ return true ++ } ++ // Internal linking. ++ if r.Add() != 0 { ++ ldr.Errorf(s, "PLT call with non-zero addend (%v)", r.Add()) ++ } ++ // Build a PLT entry and change the relocation target to that entry. ++ addpltsym(target, ldr, syms, targ) ++ su := ldr.MakeSymbolUpdater(s) ++ su.SetRelocSym(rIdx, syms.PLT) ++ su.SetRelocAdd(rIdx, int64(ldr.SymPlt(targ))) ++ return true ++ ++ case objabi.R_ADDR: ++ if ldr.SymType(s) == sym.STEXT { ++ // The code is asking for the address of an external ++ // function. We provide it with the address of the ++ // correspondent GOT symbol. ++ ld.AddGotSym(target, ldr, syms, targ, uint32(elf.R_SW64_GLOB_DAT)) ++ su := ldr.MakeSymbolUpdater(s) ++ su.SetRelocSym(rIdx, syms.GOT) ++ su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymGot(targ))) ++ return true ++ } ++ ++ // Process dynamic relocations for the data sections. ++ if target.IsPIE() && target.IsInternal() { ++ // When internally linking, generate dynamic relocations ++ // for all typical R_ADDR relocations. The exception ++ // are those R_ADDR that are created as part of generating ++ // the dynamic relocations and must be resolved statically. ++ // ++ // There are three phases relevant to understanding this: ++ // ++ // dodata() // we are here ++ // address() // symbol address assignment ++ // reloc() // resolution of static R_ADDR relocs ++ // ++ // At this point symbol addresses have not been ++ // assigned yet (as the final size of the .rela section ++ // will affect the addresses), and so we cannot write ++ // the Elf64_Rela.r_offset now. Instead we delay it ++ // until after the 'address' phase of the linker is ++ // complete. We do this via Addaddrplus, which creates ++ // a new R_ADDR relocation which will be resolved in ++ // the 'reloc' phase. ++ // ++ // These synthetic static R_ADDR relocs must be skipped ++ // now, or else we will be caught in an infinite loop ++ // of generating synthetic relocs for our synthetic ++ // relocs. ++ // ++ // Furthermore, the rela sections contain dynamic ++ // relocations with R_ADDR relocations on ++ // Elf64_Rela.r_offset. This field should contain the ++ // symbol offset as determined by reloc(), not the ++ // final dynamically linked address as a dynamic ++ // relocation would provide. ++ switch ldr.SymName(s) { ++ case ".dynsym", ".rela", ".rela.plt", ".got.plt", ".dynamic": ++ return false ++ } ++ } else { ++ // Either internally linking a static executable, ++ // in which case we can resolve these relocations ++ // statically in the 'reloc' phase, or externally ++ // linking, in which case the relocation will be ++ // prepared in the 'reloc' phase and passed to the ++ // external linker in the 'asmb' phase. ++ if ldr.SymType(s) != sym.SDATA && ldr.SymType(s) != sym.SRODATA { ++ break ++ } ++ } ++ ++ // Generate R_SW64_RELATIVE relocations for best ++ // efficiency in the dynamic linker. ++ // ++ // As noted above, symbol addresses have not been ++ // assigned yet, so we can't generate the final reloc ++ // entry yet. We ultimately want: ++ // ++ // r_offset = s + r.Off ++ // r_info = R_SW64_RELATIVE ++ // r_addend = targ + r.Add ++ // ++ // The dynamic linker will set *offset = base address + ++ // addend. ++ // ++ // AddAddrPlus is used for r_offset and r_addend to ++ // generate new R_ADDR relocations that will update ++ // these fields in the 'reloc' phase. ++ rela := ldr.MakeSymbolUpdater(syms.Rela) ++ rela.AddAddrPlus(target.Arch, s, int64(r.Off())) ++ if r.Siz() == 8 { ++ rela.AddUint64(target.Arch, elf.R_INFO(0, uint32(elf.R_SW64_RELATIVE))) ++ } else { ++ ldr.Errorf(s, "unexpected relocation for dynamic symbol %s", ldr.SymName(targ)) ++ } ++ rela.AddAddrPlus(target.Arch, targ, int64(r.Add())) ++ // Not mark r done here. So we still apply it statically, ++ // so in the file content we'll also have the right offset ++ // to the relocation target. So it can be examined statically ++ // (e.g. go version). ++ return true ++ } ++ ++ return false ++} ++ ++func elfsetupplt(ctxt *ld.Link, ldr *loader.Loader, plt, gotplt *loader.SymbolBuilder, dynamic loader.Sym) { ++ internalLinkingCgo = true ++ if plt.Size() == 0 { ++ // TODO: this is a little different with gnu pltHeader ++ ++ // rel offset ++ // subl r27,r28,r25 ++ plt.AddUint32(ctxt.Arch, 0x437c0139) ++ ++ // set .got to r28 ++ // ldi r28, 17(r28) ++ plt.AddUint32(ctxt.Arch, 0xfb9d8001) ++ ++ // s4subl r25,r25,r25 ++ plt.AddUint32(ctxt.Arch, 0x43390179) ++ ++ // ldi r28, 32767(r28) ++ plt.AddUint32(ctxt.Arch, 0xfb9cffef) ++ ++ // load resolver to jump target ++ // ldl r27,0(r28) ++ plt.AddUint32(ctxt.Arch, 0x8f7c0000) ++ ++ // addl r25,r25,r25 ++ plt.AddUint32(ctxt.Arch, 0x43390119) ++ ++ // load map info to reg r28 ++ // ldl r28,8(r28) ++ plt.AddUint32(ctxt.Arch, 0x8f9c0008) ++ // jmp $r31,($r27),1f27a0 ++ plt.AddUint32(ctxt.Arch, 0x0ffb0000) ++ ++ // br r28, .plt ++ plt.AddUint32(ctxt.Arch, 0x139ffff7) ++ ++ // check gotplt.size == 0 ++ if gotplt.Size() != 0 { ++ ctxt.Errorf(gotplt.Sym(), "got.plt is not empty at the very beginning") ++ } ++ pltHeaderSize = plt.Size() ++ ++ // will be fill in ld.so ++ gotplt.AddUint64(ctxt.Arch, 0) ++ gotplt.AddUint64(ctxt.Arch, 0) ++ } ++ return ++} ++ ++func elfreloc1(ctxt *ld.Link, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym, r loader.ExtReloc, ri int, sectoff int64) bool { ++ out.Write64(uint64(sectoff)) ++ ++ elfsym := ld.ElfSymForReloc(ctxt, r.Xsym) ++ switch r.Type { ++ case objabi.R_SW64_HINT: ++ out.Write64(uint64(elf.R_SW64_HINT) | uint64(elfsym)<<32) ++ case objabi.R_SW64_GPDISP: ++ out.Write64(uint64(elf.R_SW64_GPDISP) | uint64(elfsym)<<32) ++ case objabi.R_SW64_BRADDR: ++ out.Write64(uint64(elf.R_SW64_BRADDR) | uint64(elfsym)<<32) ++ case objabi.R_SW64_GPRELHIGH: ++ out.Write64(uint64(elf.R_SW64_GPRELHIGH) | uint64(elfsym)<<32) ++ case objabi.R_SW64_GPRELLOW: ++ out.Write64(uint64(elf.R_SW64_GPRELLOW) | uint64(elfsym)<<32) ++ case objabi.R_SW64_LITERAL_GOT: ++ out.Write64(uint64(elf.R_SW64_LITERAL_GOT) | uint64(elfsym)<<32) ++ case objabi.R_SW64_ADDR: ++ out.Write64(uint64(elf.R_SW64_ADD_PCREL_HI_13) | uint64(elfsym)<<32) ++ out.Write64(uint64(r.Xadd)) ++ out.Write64(uint64(sectoff + 4)) ++ out.Write64(uint64(elf.R_SW64_ADD_ABS_LO_16) | uint64(elfsym)<<32) ++ case objabi.R_SW64_LITERAL: ++ out.Write64(uint64(elf.R_SW64_LITERAL) | uint64(elfsym)<<32) ++ case objabi.R_SW64_TPRELHI: ++ out.Write64(uint64(39) | uint64(elfsym)<<32) ++ case objabi.R_SW64_TPRELLO: ++ out.Write64(uint64(40) | uint64(elfsym)<<32) ++ case objabi.R_SW64_GOTTPREL: ++ out.Write64(uint64(37) | uint64(elfsym)<<32) ++ case objabi.R_ADDR, objabi.R_DWARFSECREF: ++ switch r.Size { ++ case 4: ++ out.Write64(uint64(elf.R_SW64_REFLONG) | uint64(elfsym)<<32) ++ case 8: ++ out.Write64(uint64(elf.R_SW64_REFQUAD) | uint64(elfsym)<<32) ++ default: ++ return false ++ } ++ case objabi.R_CALL, objabi.R_CALLIND: ++ return true ++ default: ++ return false ++ } ++ out.Write64(uint64(r.Xadd)) ++ return true ++} ++ ++func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loader.Reloc, s loader.Sym, val int64) (o int64, nExtReloc int, ok bool) { ++ if target.IsExternal() { ++ switch r.Type() { ++ case ++ objabi.R_CALL, objabi.R_CALLIND, ++ objabi.R_SW64_GPDISP, ++ objabi.R_SW64_BRADDR, ++ objabi.R_SW64_HINT, ++ objabi.R_SW64_GOTTPREL, ++ objabi.R_SW64_GPRELHIGH, objabi.R_SW64_GPRELLOW, ++ objabi.R_SW64_LITERAL_GOT, objabi.R_SW64_LITERAL, ++ objabi.R_SW64_TPRELHI, objabi.R_SW64_TPRELLO: ++ return val, 1, true ++ default: ++ return val, 0, false ++ } ++ } ++ ++ const isOk = true ++ const noExtReloc = 0 ++ rs := r.Sym() ++ switch r.Type() { ++ case objabi.R_CALL, objabi.R_CALLIND: ++ return val, noExtReloc, isOk ++ case objabi.R_SW64_GPDISP: ++ pc := ldr.SymValue(rs) + int64(r.Off()) ++ base := uint32(val) & 0xffff0000 ++ var hi, lo int16 ++ if internalLinkingCgo { ++ hi, lo = gpdispAddrDyn(pc, ldr, syms) ++ } else { ++ hi, lo = gpdispAddr(pc) ++ } ++ ++ if base != uint32(val) { ++ log.Fatalf("The R_SW64_GPDISP %v has been broken in %v.", r, s) ++ } ++ val = int64((uint32(hi) << 16) + uint32(uint16(lo))) ++ return val, noExtReloc, isOk ++ case objabi.R_SW64_ADDR: ++ // pc := ldr.SymValue(s) + int64(r.Off()) ++ // off := ldr.SymValue(rs) + r.Add() - pc ++ t := ldr.SymAddr(rs) + r.Add() - ((ldr.SymValue(s) + int64(r.Off())) &^ 0xffff) ++ // println("symbol addr is", ldr.SymAddr(rs), r.Add()) ++ // println("symbol value is", ldr.SymValue(rs), r.Off()) ++ // println("pc is", pc) ++ // println("off is", off) ++ // println(" t is", t) ++ if t >= 1<<29 || t < -1<<29 { ++ ldr.Errorf(s, "program too large, address relocation distance = %d", t) ++ } ++ ++ hi, lo := splitAddr(t) ++ var o0, o1 uint32 ++ ++ o0 = uint32(val) ++ o1 = uint32(val >> 32) ++ ++ o0 |= uint32((uint32(hi) & 0xffff) << 13) ++ o1 |= uint32(uint32(lo) & 0xffff) ++ ++ // when laid out, the instruction order must always be o1, o2. ++ return int64(o1)<<32 | int64(o0), noExtReloc, true ++ ++ case objabi.R_SW64_TPRELHI, objabi.R_SW64_TPRELLO: ++ hi, lo := splitSymAddr(ldr, r, 16) ++ base := uint32(val) & 0xffff0000 ++ if base != uint32(val) { ++ log.Fatalf("The R_SW64_TPRELLO/HI %v has been broken in %v.", r, s) ++ } ++ if r.Type() == objabi.R_SW64_TPRELHI { ++ val = int64(base + uint32(uint16(hi))) ++ } else { ++ val = int64(base + uint32(uint16(lo))) ++ } ++ return val, noExtReloc, isOk ++ ++ case objabi.R_SW64_GOTTPREL: ++ base := uint32(val) & 0xffff0000 ++ v := ldr.SymAddr(rs) + int64(2*target.Arch.PtrSize) + r.Add() ++ if base != uint32(val) { ++ log.Fatalf("The R_SW64_GOTTPREL %v has been broken in %v.", r, s) ++ } ++ val := int64(base + uint32(uint16(v))) ++ return val, noExtReloc, isOk ++ ++ case objabi.R_SW64_GPRELLOW, objabi.R_SW64_GPRELHIGH: ++ var hi, lo int16 ++ if internalLinkingCgo { ++ hi, lo = splitGPRelAddrDyn(ldr, r, syms) ++ } else { ++ hi, lo = splitGPRelAddr(ldr, r) ++ } ++ base := uint32(val) & 0xffff0000 ++ if base != uint32(val) { ++ log.Fatalf("The R_SW64_GPRELxx %v has been broken in %v.", ldr.SymName(s), r) ++ } ++ if r.Type() == objabi.R_SW64_GPRELHIGH { ++ val = int64(base + uint32(uint16(hi))) ++ } else { ++ val = int64(base + uint32(uint16(lo))) ++ } ++ return val, noExtReloc, isOk ++ ++ case objabi.R_SW64_BRADDR: ++ off := (ldr.SymValue(rs)+r.Add()-(ldr.SymValue(s)+int64(r.Off())))/4 - 1 ++ mask := (int64(1) << 21) - 1 ++ disp := (int64(1) << 20) - 1 ++ if off > disp || off < -disp { ++ log.Fatalf("BRADDR from %v to %v is too long %v\n", ++ s, r.Sym(), off) ++ } ++ off &= mask ++ val = off + val ++ return val, noExtReloc, isOk ++ ++ case objabi.R_CALLSW64: ++ off := ldr.SymValue(rs) + r.Add() - (ldr.SymValue(s) + int64(r.Off())) ++ if off > (1<<27) || off < -(1<<27) { ++ log.Fatalf("CALLSW64 from %v to %v is too long %v\n", ++ s, r.Sym(), off) ++ } ++ val |= ((off >> 2) & 0x3FFFFFF) ++ return val, noExtReloc, isOk ++ ++ case objabi.R_SW64_HINT: ++ off := (ldr.SymValue(rs)+r.Add()-(ldr.SymValue(s)+int64(r.Off())))/4 - 1 ++ mask := (int64(1) << 16) - 1 ++ if int64(int16(off)) != off { ++ return val, noExtReloc, isOk ++ } ++ off &= mask ++ val = off + val ++ return val, noExtReloc, isOk ++ case objabi.R_SW64_LITERAL_GOT, objabi.R_SW64_LITERAL: ++ base := uint32(val) & 0xffff0000 ++ //TODO: As we process off set in adddynrel, we try doing this ++ off := int64(r.Add()) - 8 - 32784 ++ if off > 32768 { ++ log.Fatalf("off is too big, we can't handle it") ++ } ++ hi, lo := splitAddr(off) ++ if r.Type() == objabi.R_SW64_LITERAL_GOT { ++ val = int64(base + uint32(uint16(hi))) ++ } else { ++ val = int64(base + uint32(uint16(lo))) ++ } ++ return val, noExtReloc, isOk ++ } ++ return val, 0, false ++} ++ ++func splitAddr(addr int64) (hi int16, lo int16) { ++ hi = int16(addr >> 16) ++ lo = int16(addr & 0xffff) ++ if lo < 0 { ++ hi = hi + 1 ++ lo = int16(addr - int64(hi)<<16) ++ } ++ return ++} ++ ++func gpAddr() int64 { ++ return 0x7fffffff ++} ++ ++func gpDynmic(ldr *loader.Loader, syms *ld.ArchSyms) int64 { ++ return ldr.SymValue(syms.GOT) + 32784 ++} ++ ++func gpdispAddrDyn(pc int64, ldr *loader.Loader, syms *ld.ArchSyms) (hi int16, lo int16) { ++ addr := gpDynmic(ldr, syms) - pc ++ hi, lo = splitAddr(addr) ++ if int64(hi)<<16+int64(lo) != addr { ++ log.Fatalf("PC 0x%x is out of range when build GP displacement\n", pc) ++ } ++ return ++} ++ ++func gpdispAddr(pc int64) (hi int16, lo int16) { ++ addr := gpAddr() - pc ++ hi, lo = splitAddr(addr) ++ if int64(hi)<<16+int64(lo) != addr { ++ log.Fatalf("PC 0x%x is out of range when build GP displacement\n", pc) ++ } ++ return ++} ++ ++func splitGPRelAddr(ldr *loader.Loader, r loader.Reloc) (hi int16, lo int16) { ++ rs := r.Sym() ++ addr := ldr.SymValue(rs) + r.Add() - gpAddr() ++ hi, lo = splitAddr(addr) ++ if int64(hi)<<16+int64(lo) != addr { ++ log.Fatalf("Symbol %q is out of range when split GP relative address\n", r.Sym()) ++ } ++ return ++} ++ ++func splitGPRelAddrDyn(ldr *loader.Loader, r loader.Reloc, syms *ld.ArchSyms) (hi int16, lo int16) { ++ rs := r.Sym() ++ addr := ldr.SymValue(rs) + r.Add() - gpDynmic(ldr, syms) ++ hi, lo = splitAddr(addr) ++ if int64(hi)<<16+int64(lo) != addr { ++ log.Fatalf("Symbol %q is out of range when split GP relative address\n", r.Sym()) ++ } ++ return ++} ++ ++// splitSymaddr split address of s to two 16 signed bit ++func splitSymAddr(ldr *loader.Loader, r loader.Reloc, off int64) (hi int16, lo int16) { ++ rs := r.Sym() ++ addr := ldr.SymValue(rs) + r.Add() + off ++ hi, lo = splitAddr(addr) ++ if int64(hi)<<16+int64(lo) != addr { ++ log.Fatalf("Symbol %q is out of range when split symbol address\n", ++ r.Sym()) ++ } ++ return ++} ++ ++func archrelocvariant(*ld.Target, *loader.Loader, loader.Reloc, sym.RelocVariant, loader.Sym, int64, []byte) int64 { ++ log.Fatalf("unexpected relocation variant") ++ return -1 ++} ++ ++func extreloc(target *ld.Target, ldr *loader.Loader, r loader.Reloc, s loader.Sym) (loader.ExtReloc, bool) { ++ switch r.Type() { ++ case objabi.R_CALL, objabi.R_CALLIND, ++ objabi.R_SW64_GPDISP, ++ objabi.R_SW64_BRADDR, ++ objabi.R_SW64_HINT, ++ objabi.R_SW64_GOTTPREL, ++ objabi.R_SW64_LITERAL_GOT, objabi.R_SW64_LITERAL, ++ objabi.R_SW64_TPRELHI, objabi.R_SW64_TPRELLO: ++ return ld.ExtrelocViaOuterSym(ldr, r, s), true ++ case objabi.R_SW64_GPRELHIGH, objabi.R_SW64_GPRELLOW: ++ return ld.ExtrelocViaOuterSym(ldr, r, s), true ++ } ++ return loader.ExtReloc{}, false ++} ++ ++func splitPCRelAddr(ldr *loader.Loader, r loader.Reloc) (hi int16, lo int16) { ++ rs := r.Sym() ++ addr := ldr.SymValue(rs) + r.Add() - gpAddr() ++ hi, lo = splitAddr(addr) ++ if int64(hi)<<16+int64(lo) != addr { ++ log.Fatalf("Symbol %q is out of range when split GP relative address\n", r.Sym()) ++ } ++ return ++} ++ ++func addpltsym(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym) { ++ if ldr.SymPlt(s) >= 0 { ++ return ++ } ++ ++ ld.Adddynsym(ldr, target, syms, s) ++ ++ if target.IsElf() { ++ plt := ldr.MakeSymbolUpdater(syms.PLT) ++ got := ldr.MakeSymbolUpdater(syms.GOT) ++ rela := ldr.MakeSymbolUpdater(syms.RelaPLT) ++ if plt.Size() == 0 { ++ panic("plt is not set up") ++ } ++ ++ // br $R28, pltHeaderEnd ++ disp := plt.Size() - pltHeaderSize + 8 ++ br := 0x13e00000 | (-int32(disp/4) & 0x1fffff) ++ plt.AddUint32(target.Arch, uint32(br)) ++ ++ // got ++ // create got entry for extern jump ++ got.AddAddrPlus(target.Arch, plt.Sym(), plt.Size()-4) ++ ldr.SetGot(s, int32(got.Size())) ++ ++ // rela ++ rela.AddAddrPlus(target.Arch, got.Sym(), got.Size()-8) ++ sDynid := ldr.SymDynid(s) ++ ++ rela.AddUint64(target.Arch, elf.R_INFO(uint32(sDynid), uint32(elf.R_SW64_JMP_SLOT))) ++ rela.AddUint64(target.Arch, 0) ++ ++ ldr.SetPlt(s, int32(plt.Size())-16) ++ } else { ++ ldr.Errorf(s, "addpltsym: unsupported binary format") ++ } ++} +diff --git a/src/cmd/link/internal/sw64/l.go b/src/cmd/link/internal/sw64/l.go +new file mode 100644 +index 0000000000..e43fbe5e37 +--- /dev/null ++++ b/src/cmd/link/internal/sw64/l.go +@@ -0,0 +1,17 @@ ++// 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 sw64 ++ ++const ( ++ maxAlign = 32 // max data alignment ++ minAlign = 1 // min data alignment ++ funcAlign = 16 ++) ++ ++/* Used by ../internal/ld/dwarf.go */ ++const ( ++ dwarfRegSP = 30 ++ dwarfRegLR = 26 ++) +diff --git a/src/cmd/link/internal/sw64/obj.go b/src/cmd/link/internal/sw64/obj.go +new file mode 100644 +index 0000000000..dea8bcb4d9 +--- /dev/null ++++ b/src/cmd/link/internal/sw64/obj.go +@@ -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. ++ ++package sw64 ++ ++import ( ++ "cmd/internal/objabi" ++ "cmd/internal/sys" ++ "cmd/link/internal/ld" ++) ++ ++func Init() (*sys.Arch, ld.Arch) { ++ arch := sys.ArchSW64 ++ ++ theArch := ld.Arch{ ++ Funcalign: funcAlign, ++ Maxalign: maxAlign, ++ Minalign: minAlign, ++ Dwarfregsp: dwarfRegSP, ++ Dwarfreglr: dwarfRegLR, ++ ++ Archinit: archinit, ++ Adddynrel: adddynrel, ++ Archreloc: archreloc, ++ Archrelocvariant: archrelocvariant, ++ Extreloc: extreloc, ++ Gentext: gentext, ++ ++ ELF: ld.ELFArch{ ++ Linuxdynld: "/lib/ld-linux.so.2", ++ LinuxdynldMusl: "/lib/ld-musl-sw_64.so.1", ++ Freebsddynld: "XXX", ++ Openbsddynld: "XXX", ++ Netbsddynld: "XXX", ++ Solarisdynld: "XXX", ++ ++ Reloc1: elfreloc1, ++ RelocSize: 24, ++ SetupPLT: elfsetupplt, ++ }, ++ } ++ ++ return arch, theArch ++} ++ ++func archinit(ctxt *ld.Link) { ++ switch ctxt.HeadType { ++ default: ++ ld.Exitf("unknown -H option: %v", ctxt.HeadType) ++ ++ case objabi.Hlinux: /* sw64 elf */ ++ ld.Elfinit(ctxt) ++ ld.HEADR = ld.ELFRESERVE ++ if *ld.FlagRound == -1 { ++ *ld.FlagRound = 0x10000 ++ } ++ if *ld.FlagTextAddr == -1 { ++ *ld.FlagTextAddr = ld.Rnd(0x10000, *ld.FlagRound) + int64(ld.HEADR) ++ } ++ } ++} +diff --git a/src/cmd/link/internal/sym/reloc.go b/src/cmd/link/internal/sym/reloc.go +index e614caa5d8..08d7903f0f 100644 +--- a/src/cmd/link/internal/sym/reloc.go ++++ b/src/cmd/link/internal/sym/reloc.go +@@ -63,6 +63,8 @@ func RelocName(arch *sys.Arch, r objabi.RelocType) string { + return elf.R_390(nr).String() + case sys.RISCV64: + return elf.R_RISCV(nr).String() ++ case sys.SW64: ++ return elf.R_SW64(nr).String() + default: + panic("unreachable") + } +diff --git a/src/cmd/link/main.go b/src/cmd/link/main.go +index 16e5a01151..ea4259c474 100644 +--- a/src/cmd/link/main.go ++++ b/src/cmd/link/main.go +@@ -16,6 +16,7 @@ import ( + "cmd/link/internal/ppc64" + "cmd/link/internal/riscv64" + "cmd/link/internal/s390x" ++ "cmd/link/internal/sw64" + "cmd/link/internal/wasm" + "cmd/link/internal/x86" + "fmt" +@@ -68,6 +69,8 @@ func main() { + arch, theArch = s390x.Init() + case "wasm": + arch, theArch = wasm.Init() ++ case "sw64": ++ arch, theArch = sw64.Init() + } + ld.Main(arch, theArch) + } diff --git a/0003-cmd-runtime-enable-race-detector-on-loong64.patch b/0003-cmd-runtime-enable-race-detector-on-loong64.patch new file mode 100644 index 0000000000000000000000000000000000000000..0d61dcc5fcb6091e4e881d6ebe0a579b2ba30792 --- /dev/null +++ b/0003-cmd-runtime-enable-race-detector-on-loong64.patch @@ -0,0 +1,626 @@ +From f84142ce620b086cc90f728861a76e5066c22ed9 Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Sat, 19 Aug 2023 09:22:34 +0800 +Subject: [PATCH 03/44] cmd,runtime: enable race detector on loong64 + +The race feature depends on llvm. And support for building the tsan library on +linux/loong64 has been added in this patch [1], which has been merged into the +branch main and will be supported in the upcoming llvm18. + +[1]: https://github.com/llvm/llvm-project/pull/72819 + +Co-authored-by: Xiaolin Zhao +Change-Id: If389318215476890295ed771297c6c088cfc84b3 +--- + src/cmd/dist/test.go | 2 +- + src/internal/platform/supported.go | 2 +- + src/race.bash | 3 +- + src/runtime/asm_loong64.s | 1 + + src/runtime/race/README | 3 +- + src/runtime/race/race.go | 2 +- + src/runtime/race_loong64.s | 509 +++++++++++++++++++++++ + 8 files changed, 517 insertions(+), 5 deletions(-) + create mode 100644 src/runtime/race_loong64.s + +diff --git a/src/cmd/dist/test.go b/src/cmd/dist/test.go +index 9728ef29cb..044268ada0 100644 +--- a/src/cmd/dist/test.go ++++ b/src/cmd/dist/test.go +@@ -1674,7 +1674,7 @@ func (t *tester) makeGOROOTUnwritable() (undo func()) { + func raceDetectorSupported(goos, goarch string) bool { + switch goos { + case "linux": +- return goarch == "amd64" || goarch == "ppc64le" || goarch == "arm64" || goarch == "s390x" ++ return goarch == "amd64" || goarch == "ppc64le" || goarch == "arm64" || goarch == "s390x" || goarch == "loong64" + case "darwin": + return goarch == "amd64" || goarch == "arm64" + case "freebsd", "netbsd", "windows": +diff --git a/src/internal/platform/supported.go b/src/internal/platform/supported.go +index 79ed6d4b1c..52cad096cb 100644 +--- a/src/internal/platform/supported.go ++++ b/src/internal/platform/supported.go +@@ -23,7 +23,7 @@ func (p OSArch) String() string { + func RaceDetectorSupported(goos, goarch string) bool { + switch goos { + case "linux": +- return goarch == "amd64" || goarch == "ppc64le" || goarch == "arm64" || goarch == "s390x" ++ return goarch == "amd64" || goarch == "ppc64le" || goarch == "arm64" || goarch == "s390x" || goarch == "loong64" + case "darwin": + return goarch == "amd64" || goarch == "arm64" + case "freebsd", "netbsd", "windows": +diff --git a/src/race.bash b/src/race.bash +index f1a168bfbb..ae9f57ffd7 100755 +--- a/src/race.bash ++++ b/src/race.bash +@@ -9,7 +9,7 @@ + set -e + + function usage { +- echo 'race detector is only supported on linux/amd64, linux/ppc64le, linux/arm64, linux/s390x, freebsd/amd64, netbsd/amd64, openbsd/amd64, darwin/amd64, and darwin/arm64' 1>&2 ++ echo 'race detector is only supported on linux/amd64, linux/ppc64le, linux/arm64, linux/loong64, linux/s390x, freebsd/amd64, netbsd/amd64, openbsd/amd64, darwin/amd64, and darwin/arm64' 1>&2 + exit 1 + } + +@@ -19,6 +19,7 @@ case $(uname -s -m) in + "Linux x86_64") ;; + "Linux ppc64le") ;; + "Linux aarch64") ;; ++ "Linux loongarch64") ;; + "Linux s390x") ;; + "FreeBSD amd64") ;; + "NetBSD amd64") ;; +diff --git a/src/runtime/asm_loong64.s b/src/runtime/asm_loong64.s +index 1c5ced4512..1bd8276835 100644 +--- a/src/runtime/asm_loong64.s ++++ b/src/runtime/asm_loong64.s +@@ -37,6 +37,7 @@ TEXT runtime·rt0_go(SB),NOSPLIT|TOPFRAME,$0 + JAL (R25) + + nocgo: ++ JAL runtime·save_g(SB) + // update stackguard after _cgo_init + MOVV (g_stack+stack_lo)(g), R19 + ADDV $const_stackGuard, R19 +diff --git a/src/runtime/race/README b/src/runtime/race/README +index 47c51ca9c1..06865d2b34 100644 +--- a/src/runtime/race/README ++++ b/src/runtime/race/README +@@ -13,5 +13,6 @@ internal/amd64v1/race_windows.syso built with LLVM 51bfeff0e4b0757ff773da6882f4d + internal/amd64v3/race_linux.syso built with LLVM 51bfeff0e4b0757ff773da6882f4d538996c9b04 and Go e7d582b55dda36e76ce4d0ce770139ca0915b7c5. + race_darwin_arm64.syso built with LLVM 51bfeff0e4b0757ff773da6882f4d538996c9b04 and Go e7d582b55dda36e76ce4d0ce770139ca0915b7c5. + race_linux_arm64.syso built with LLVM 51bfeff0e4b0757ff773da6882f4d538996c9b04 and Go e7d582b55dda36e76ce4d0ce770139ca0915b7c5. +-race_linux_ppc64le.syso built with LLVM 51bfeff0e4b0757ff773da6882f4d538996c9b04 and Go e7d582b55dda36e76ce4d0ce770139ca0915b7c5. ++race_linux_loong64.syso built with LLVM 9d3fbf97bef3f19da4e0a047f017b8142f59b3fd and Go 988b718f4130ab5b3ce5a5774e1a58e83c92a163. ++race_linux_ppc64le.syso built with LLVM 41cb504b7c4b18ac15830107431a0c1eec73a6b2 and Go 851ecea4cc99ab276109493477b2c7e30c253ea8. + race_linux_s390x.syso built with LLVM 51bfeff0e4b0757ff773da6882f4d538996c9b04 and Go e7d582b55dda36e76ce4d0ce770139ca0915b7c5. +diff --git a/src/runtime/race/race.go b/src/runtime/race/race.go +index 9c508ebc2b..9fd75424ca 100644 +--- a/src/runtime/race/race.go ++++ b/src/runtime/race/race.go +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build race && ((linux && (amd64 || arm64 || ppc64le || s390x)) || ((freebsd || netbsd || openbsd || windows) && amd64)) ++//go:build race && ((linux && (amd64 || arm64 || loong64 || ppc64le || s390x)) || ((freebsd || netbsd || openbsd || windows) && amd64)) + + package race + +diff --git a/src/runtime/race_loong64.s b/src/runtime/race_loong64.s +new file mode 100644 +index 0000000000..0512efc045 +--- /dev/null ++++ b/src/runtime/race_loong64.s +@@ -0,0 +1,509 @@ ++// 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 race ++ ++#include "go_asm.h" ++#include "funcdata.h" ++#include "textflag.h" ++#include "cgo/abi_loong64.h" ++ ++// The following thunks allow calling the gcc-compiled race runtime directly ++// from Go code without going all the way through cgo. ++// First, it's much faster (up to 50% speedup for real Go programs). ++// Second, it eliminates race-related special cases from cgocall and scheduler. ++// Third, in long-term it will allow to remove cyclic runtime/race dependency on cmd/go. ++ ++// A brief recap of the loong64 calling convention. ++// Arguments are passed in R4...R11, the rest is on stack. ++// Callee-saved registers are: R23...R30. ++// Temporary registers are: R12...R20 ++// SP must be 16-byte aligned. ++ ++// When calling racecalladdr, R20 is the call target address. ++ ++// The race ctx, ThreadState *thr below, is passed in R4 and loaded in racecalladdr. ++ ++// Load g from TLS. (See tls_loong64.s) ++#define load_g \ ++ MOVV runtime·tls_g(SB), g ++ ++#define RARG0 R4 ++#define RARG1 R5 ++#define RARG2 R6 ++#define RARG3 R7 ++#define RCALL R20 ++ ++// func runtime·raceread(addr uintptr) ++// Called from instrumented code. ++// Defined as ABIInternal so as to avoid introducing a wrapper, ++// which would make caller's PC ineffective. ++TEXT runtime·raceread(SB), NOSPLIT, $0-8 ++#ifdef GOEXPERIMENT_regabiargs ++ MOVV R4, RARG1 ++#else ++ MOVV addr+0(FP), RARG1 ++#endif ++ MOVV R1, RARG2 ++ // void __tsan_read(ThreadState *thr, void *addr, void *pc); ++ MOVV $__tsan_read(SB), RCALL ++ JMP racecalladdr<>(SB) ++ ++// func runtime·RaceRead(addr uintptr) ++TEXT runtime·RaceRead(SB), NOSPLIT, $0-8 ++ // This needs to be a tail call, because raceread reads caller pc. ++ JMP runtime·raceread(SB) ++ ++// func runtime·racereadpc(void *addr, void *callpc, void *pc) ++TEXT runtime·racereadpc(SB), NOSPLIT, $0-24 ++ MOVV addr+0(FP), RARG1 ++ MOVV callpc+8(FP), RARG2 ++ MOVV pc+16(FP), RARG3 ++ // void __tsan_read_pc(ThreadState *thr, void *addr, void *callpc, void *pc); ++ MOVV $__tsan_read_pc(SB), RCALL ++ JMP racecalladdr<>(SB) ++ ++// func runtime·racewrite(addr uintptr) ++// Called from instrumented code. ++// Defined as ABIInternal so as to avoid introducing a wrapper, ++// which would make caller's PC ineffective. ++TEXT runtime·racewrite(SB), NOSPLIT, $0-8 ++#ifdef GOEXPERIMENT_regabiargs ++ MOVV R4, RARG1 ++#else ++ MOVV addr+0(FP), RARG1 ++#endif ++ MOVV R1, RARG2 ++ // void __tsan_write(ThreadState *thr, void *addr, void *pc); ++ MOVV $__tsan_write(SB), RCALL ++ JMP racecalladdr<>(SB) ++ ++// func runtime·RaceWrite(addr uintptr) ++TEXT runtime·RaceWrite(SB), NOSPLIT, $0-8 ++ // This needs to be a tail call, because racewrite reads caller pc. ++ JMP runtime·racewrite(SB) ++ ++// func runtime·racewritepc(void *addr, void *callpc, void *pc) ++TEXT runtime·racewritepc(SB), NOSPLIT, $0-24 ++ MOVV addr+0(FP), RARG1 ++ MOVV callpc+8(FP), RARG2 ++ MOVV pc+16(FP), RARG3 ++ // void __tsan_write_pc(ThreadState *thr, void *addr, void *callpc, void *pc); ++ MOVV $__tsan_write_pc(SB), RCALL ++ JMP racecalladdr<>(SB) ++ ++// func runtime·racereadrange(addr, size uintptr) ++// Called from instrumented code. ++// Defined as ABIInternal so as to avoid introducing a wrapper, ++// which would make caller's PC ineffective. ++TEXT runtime·racereadrange(SB), NOSPLIT, $0-16 ++#ifdef GOEXPERIMENT_regabiargs ++ MOVV R5, RARG2 ++ MOVV R4, RARG1 ++#else ++ MOVV addr+0(FP), RARG1 ++ MOVV size+8(FP), RARG2 ++#endif ++ MOVV R1, RARG3 ++ // void __tsan_read_range(ThreadState *thr, void *addr, uintptr size, void *pc); ++ MOVV $__tsan_read_range(SB), RCALL ++ JMP racecalladdr<>(SB) ++ ++// func runtime·RaceReadRange(addr, size uintptr) ++TEXT runtime·RaceReadRange(SB), NOSPLIT, $0-16 ++ // This needs to be a tail call, because racereadrange reads caller pc. ++ JMP runtime·racereadrange(SB) ++ ++// func runtime·racereadrangepc1(void *addr, uintptr sz, void *pc) ++TEXT runtime·racereadrangepc1(SB), NOSPLIT, $0-24 ++ MOVV addr+0(FP), RARG1 ++ MOVV size+8(FP), RARG2 ++ MOVV pc+16(FP), RARG3 ++ ADDV $4, RARG3 // pc is function start, tsan wants return address. ++ // void __tsan_read_range(ThreadState *thr, void *addr, uintptr size, void *pc); ++ MOVV $__tsan_read_range(SB), RCALL ++ JMP racecalladdr<>(SB) ++ ++// func runtime·racewriterange(addr, size uintptr) ++// Called from instrumented code. ++// Defined as ABIInternal so as to avoid introducing a wrapper, ++// which would make caller's PC ineffective. ++TEXT runtime·racewriterange(SB), NOSPLIT, $0-16 ++#ifdef GOEXPERIMENT_regabiargs ++ MOVV R5, RARG2 ++ MOVV R4, RARG1 ++#else ++ MOVV addr+0(FP), RARG1 ++ MOVV size+8(FP), RARG2 ++#endif ++ MOVV R1, RARG3 ++ // void __tsan_write_range(ThreadState *thr, void *addr, uintptr size, void *pc); ++ MOVV $__tsan_write_range(SB), RCALL ++ JMP racecalladdr<>(SB) ++ ++// func runtime·RaceWriteRange(addr, size uintptr) ++TEXT runtime·RaceWriteRange(SB), NOSPLIT, $0-16 ++ // This needs to be a tail call, because racewriterange reads caller pc. ++ JMP runtime·racewriterange(SB) ++ ++// func runtime·racewriterangepc1(void *addr, uintptr sz, void *pc) ++TEXT runtime·racewriterangepc1(SB), NOSPLIT, $0-24 ++ MOVV addr+0(FP), RARG1 ++ MOVV size+8(FP), RARG2 ++ MOVV pc+16(FP), RARG3 ++ ADDV $4, RARG3 // pc is function start, tsan wants return address. ++ // void __tsan_write_range(ThreadState *thr, void *addr, uintptr size, void *pc); ++ MOVV $__tsan_write_range(SB), RCALL ++ JMP racecalladdr<>(SB) ++ ++// Call a __tsan function from Go code. ++// ++// RCALL = tsan function address ++// RARG0 = *ThreadState a.k.a. g_racectx from g ++// RARG1 = addr passed to __tsan function ++// ++// If addr (RARG1) is out of range, do nothing. Otherwise, setup goroutine ++// context and invoke racecall. Other arguments already set. ++TEXT racecalladdr<>(SB), NOSPLIT, $0-0 ++ // Check that addr is within [arenastart, arenaend) or within [racedatastart, racedataend). ++ MOVV runtime·racearenastart(SB), R12 ++ BLT RARG1, R12, data ++ MOVV runtime·racearenaend(SB), R12 ++ BLT RARG1, R12, call ++data: ++ MOVV runtime·racedatastart(SB), R12 ++ BLT RARG1, R12, ret ++ MOVV runtime·racedataend(SB), R12 ++ BGE RARG1, R12, ret ++call: ++ load_g ++ MOVV g_racectx(g), RARG0 ++ JMP racecall<>(SB) ++ret: ++ RET ++ ++// func runtime·racefuncenter(pc uintptr) ++// Called from instrumented code. ++TEXT runtime·racefuncenter(SB), NOSPLIT, $0-8 ++#ifdef GOEXPERIMENT_regabiargs ++ MOVV R4, RCALL ++#else ++ MOVV callpc+0(FP), RCALL ++#endif ++ JMP racefuncenter<>(SB) ++ ++// Common code for racefuncenter ++// RCALL = caller's return address ++TEXT racefuncenter<>(SB), NOSPLIT, $0-0 ++ load_g ++ MOVV g_racectx(g), RARG0 // goroutine racectx ++ MOVV RCALL, RARG1 ++ // void __tsan_func_enter(ThreadState *thr, void *pc); ++ MOVV $__tsan_func_enter(SB), RCALL ++ JAL racecall<>(SB) ++ RET ++ ++// func runtime·racefuncexit() ++// Called from instrumented code. ++TEXT runtime·racefuncexit(SB), NOSPLIT, $0-0 ++ load_g ++ MOVV g_racectx(g), RARG0 // race context ++ // void __tsan_func_exit(ThreadState *thr); ++ MOVV $__tsan_func_exit(SB), RCALL ++ JMP racecall<>(SB) ++ ++// Atomic operations for sync/atomic package. ++// R7 = addr of arguments passed to this function, it can ++// be fetched at 24(R3) in racecallatomic after two times JAL ++// RARG0, RARG1, RARG2 set in racecallatomic ++ ++// Load ++TEXT sync∕atomic·LoadInt32(SB), NOSPLIT, $0-12 ++ GO_ARGS ++ MOVV $__tsan_go_atomic32_load(SB), RCALL ++ JAL racecallatomic<>(SB) ++ RET ++ ++TEXT sync∕atomic·LoadInt64(SB), NOSPLIT, $0-16 ++ GO_ARGS ++ MOVV $__tsan_go_atomic64_load(SB), RCALL ++ JAL racecallatomic<>(SB) ++ RET ++ ++TEXT sync∕atomic·LoadUint32(SB), NOSPLIT, $0-12 ++ GO_ARGS ++ JMP sync∕atomic·LoadInt32(SB) ++ ++TEXT sync∕atomic·LoadUint64(SB), NOSPLIT, $0-16 ++ GO_ARGS ++ JMP sync∕atomic·LoadInt64(SB) ++ ++TEXT sync∕atomic·LoadUintptr(SB), NOSPLIT, $0-16 ++ GO_ARGS ++ JMP sync∕atomic·LoadInt64(SB) ++ ++TEXT sync∕atomic·LoadPointer(SB), NOSPLIT, $0-16 ++ GO_ARGS ++ JMP sync∕atomic·LoadInt64(SB) ++ ++// Store ++TEXT sync∕atomic·StoreInt32(SB), NOSPLIT, $0-12 ++ GO_ARGS ++ MOVV $__tsan_go_atomic32_store(SB), RCALL ++ JAL racecallatomic<>(SB) ++ RET ++ ++TEXT sync∕atomic·StoreInt64(SB), NOSPLIT, $0-16 ++ GO_ARGS ++ MOVV $__tsan_go_atomic64_store(SB), RCALL ++ JAL racecallatomic<>(SB) ++ RET ++ ++TEXT sync∕atomic·StoreUint32(SB), NOSPLIT, $0-12 ++ GO_ARGS ++ JMP sync∕atomic·StoreInt32(SB) ++ ++TEXT sync∕atomic·StoreUint64(SB), NOSPLIT, $0-16 ++ GO_ARGS ++ JMP sync∕atomic·StoreInt64(SB) ++ ++TEXT sync∕atomic·StoreUintptr(SB), NOSPLIT, $0-16 ++ GO_ARGS ++ JMP sync∕atomic·StoreInt64(SB) ++ ++// Swap ++TEXT sync∕atomic·SwapInt32(SB), NOSPLIT, $0-20 ++ GO_ARGS ++ MOVV $__tsan_go_atomic32_exchange(SB), RCALL ++ JAL racecallatomic<>(SB) ++ RET ++ ++TEXT sync∕atomic·SwapInt64(SB), NOSPLIT, $0-24 ++ GO_ARGS ++ MOVV $__tsan_go_atomic64_exchange(SB), RCALL ++ JAL racecallatomic<>(SB) ++ RET ++ ++TEXT sync∕atomic·SwapUint32(SB), NOSPLIT, $0-20 ++ GO_ARGS ++ JMP sync∕atomic·SwapInt32(SB) ++ ++TEXT sync∕atomic·SwapUint64(SB), NOSPLIT, $0-24 ++ GO_ARGS ++ JMP sync∕atomic·SwapInt64(SB) ++ ++TEXT sync∕atomic·SwapUintptr(SB), NOSPLIT, $0-24 ++ GO_ARGS ++ JMP sync∕atomic·SwapInt64(SB) ++ ++// Add ++TEXT sync∕atomic·AddInt32(SB), NOSPLIT, $0-20 ++ GO_ARGS ++ MOVV $__tsan_go_atomic32_fetch_add(SB), RCALL ++ JAL racecallatomic<>(SB) ++ MOVW add+8(FP), RARG0 // convert fetch_add to add_fetch ++ MOVW ret+16(FP), RARG1 ++ ADD RARG0, RARG1, RARG0 ++ MOVW RARG0, ret+16(FP) ++ RET ++ ++TEXT sync∕atomic·AddInt64(SB), NOSPLIT, $0-24 ++ GO_ARGS ++ MOVV $__tsan_go_atomic64_fetch_add(SB), RCALL ++ JAL racecallatomic<>(SB) ++ MOVV add+8(FP), RARG0 // convert fetch_add to add_fetch ++ MOVV ret+16(FP), RARG1 ++ ADDV RARG0, RARG1, RARG0 ++ MOVV RARG0, ret+16(FP) ++ RET ++ ++TEXT sync∕atomic·AddUint32(SB), NOSPLIT, $0-20 ++ GO_ARGS ++ JMP sync∕atomic·AddInt32(SB) ++ ++TEXT sync∕atomic·AddUint64(SB), NOSPLIT, $0-24 ++ GO_ARGS ++ JMP sync∕atomic·AddInt64(SB) ++ ++TEXT sync∕atomic·AddUintptr(SB), NOSPLIT, $0-24 ++ GO_ARGS ++ JMP sync∕atomic·AddInt64(SB) ++ ++// CompareAndSwap ++TEXT sync∕atomic·CompareAndSwapInt32(SB), NOSPLIT, $0-17 ++ GO_ARGS ++ MOVV $__tsan_go_atomic32_compare_exchange(SB), RCALL ++ JAL racecallatomic<>(SB) ++ RET ++ ++TEXT sync∕atomic·CompareAndSwapInt64(SB), NOSPLIT, $0-25 ++ GO_ARGS ++ MOVV $__tsan_go_atomic64_compare_exchange(SB), RCALL ++ JAL racecallatomic<>(SB) ++ RET ++ ++TEXT sync∕atomic·CompareAndSwapUint32(SB), NOSPLIT, $0-17 ++ GO_ARGS ++ JMP sync∕atomic·CompareAndSwapInt32(SB) ++ ++TEXT sync∕atomic·CompareAndSwapUint64(SB), NOSPLIT, $0-25 ++ GO_ARGS ++ JMP sync∕atomic·CompareAndSwapInt64(SB) ++ ++TEXT sync∕atomic·CompareAndSwapUintptr(SB), NOSPLIT, $0-25 ++ GO_ARGS ++ JMP sync∕atomic·CompareAndSwapInt64(SB) ++ ++// Generic atomic operation implementation. ++// RCALL = addr of target function ++TEXT racecallatomic<>(SB), NOSPLIT, $0 ++ // Set up these registers ++ // RARG0 = *ThreadState ++ // RARG1 = caller pc ++ // RARG2 = pc ++ // RARG3 = addr of incoming arg list ++ ++ // Trigger SIGSEGV early. ++ MOVV 24(R3), RARG3 // 1st arg is addr. after two times JAL, get it at 24(R3) ++ MOVB (RARG3), R12 // segv here if addr is bad ++ ++ // Check that addr is within [arenastart, arenaend) or within [racedatastart, racedataend). ++ MOVV runtime·racearenastart(SB), R12 ++ BLT RARG3, R12, racecallatomic_data ++ MOVV runtime·racearenaend(SB), R12 ++ BLT RARG3, R12, racecallatomic_ok ++ ++racecallatomic_data: ++ MOVV runtime·racedatastart(SB), R12 ++ BLT RARG3, R12, racecallatomic_ignore ++ MOVV runtime·racedataend(SB), R12 ++ BGE RARG3, R12, racecallatomic_ignore ++ ++racecallatomic_ok: ++ // Addr is within the good range, call the atomic function. ++ load_g ++ MOVV g_racectx(g), RARG0 // goroutine context ++ MOVV 8(R3), RARG1 // caller pc ++ MOVV RCALL, RARG2 // pc ++ ADDV $24, R3, RARG3 ++ JAL racecall<>(SB) // does not return ++ RET ++ ++racecallatomic_ignore: ++ // Addr is outside the good range. ++ // Call __tsan_go_ignore_sync_begin to ignore synchronization during the atomic op. ++ // An attempt to synchronize on the address would cause crash. ++ MOVV RCALL, R25 // remember the original function ++ MOVV $__tsan_go_ignore_sync_begin(SB), RCALL ++ load_g ++ MOVV g_racectx(g), RARG0 // goroutine context ++ JAL racecall<>(SB) ++ MOVV R25, RCALL // restore the original function ++ ++ // Call the atomic function. ++ // racecall will call LLVM race code which might clobber R22 (g) ++ load_g ++ MOVV g_racectx(g), RARG0 // goroutine context ++ MOVV 8(R3), RARG1 // caller pc ++ MOVV RCALL, RARG2 // pc ++ ADDV $24, R3, RARG3 // arguments ++ JAL racecall<>(SB) ++ ++ // Call __tsan_go_ignore_sync_end. ++ MOVV $__tsan_go_ignore_sync_end(SB), RCALL ++ MOVV g_racectx(g), RARG0 // goroutine context ++ JAL racecall<>(SB) ++ RET ++ ++// func runtime·racecall(void(*f)(...), ...) ++// Calls C function f from race runtime and passes up to 4 arguments to it. ++// The arguments are never heap-object-preserving pointers, so we pretend there are no arguments. ++TEXT runtime·racecall(SB), NOSPLIT, $0-0 ++ MOVV fn+0(FP), RCALL ++ MOVV arg0+8(FP), RARG0 ++ MOVV arg1+16(FP), RARG1 ++ MOVV arg2+24(FP), RARG2 ++ MOVV arg3+32(FP), RARG3 ++ JMP racecall<>(SB) ++ ++// Switches SP to g0 stack and calls (RCALL). Arguments already set. ++TEXT racecall<>(SB), NOSPLIT|NOFRAME, $0-0 ++ MOVV g_m(g), R12 ++ // Switch to g0 stack. ++ MOVV R3, R23 // callee-saved, preserved across the CALL ++ MOVV R1, R24 // callee-saved, preserved across the CALL ++ MOVV m_g0(R12), R13 ++ BEQ R13, g, call // already on g0 ++ MOVV (g_sched+gobuf_sp)(R13), R3 ++call: ++ JAL (RCALL) ++ MOVV R23, R3 ++ JAL (R24) ++ RET ++ ++// C->Go callback thunk that allows to call runtime·racesymbolize from C code. ++// Direct Go->C race call has only switched SP, finish g->g0 switch by setting correct g. ++// The overall effect of Go->C->Go call chain is similar to that of mcall. ++// RARG0 contains command code. RARG1 contains command-specific context. ++// See racecallback for command codes. ++TEXT runtime·racecallbackthunk(SB), NOSPLIT|NOFRAME, $0 ++ // Handle command raceGetProcCmd (0) here. ++ // First, code below assumes that we are on curg, while raceGetProcCmd ++ // can be executed on g0. Second, it is called frequently, so will ++ // benefit from this fast path. ++ BNE RARG0, R0, rest ++ MOVV g, R15 ++ load_g ++ MOVV g_m(g), RARG0 ++ MOVV m_p(RARG0), RARG0 ++ MOVV p_raceprocctx(RARG0), RARG0 ++ MOVV RARG0, (RARG1) ++ MOVV R15, g ++ JMP (R1) ++rest: ++ // Save callee-saved registers (Go code won't respect that). ++ // 8(R3) and 16(R3) are for args passed through racecallback ++ ADDV $-176, R3 ++ MOVV R1, 0(R3) ++ ++ SAVE_R22_TO_R31(8*3) ++ SAVE_F24_TO_F31(8*13) ++ // Set g = g0. ++ load_g ++ MOVV g_m(g), R15 ++ MOVV m_g0(R15), R14 ++ BEQ R14, g, noswitch // branch if already on g0 ++ MOVV R14, g ++ ++#ifdef GOEXPERIMENT_regabiargs ++ JAL runtime·racecallback(SB) ++#else ++ MOVV RARG0, 8(R3) // func arg ++ MOVV RARG1, 16(R3) // func arg ++ JAL runtime·racecallback(SB) ++#endif ++ // All registers are smashed after Go code, reload. ++ MOVV g_m(g), R15 ++ MOVV m_curg(R15), g // g = m->curg ++ret: ++ // Restore callee-saved registers. ++ MOVV 0(R3), R1 ++ RESTORE_F24_TO_F31(8*13) ++ RESTORE_R22_TO_R31(8*3) ++ ADDV $176, R3 ++ JMP (R1) ++ ++noswitch: ++ // already on g0 ++#ifdef GOEXPERIMENT_regabiargs ++ JAL runtime·racecallback(SB) ++#else ++ MOVV RARG0, 8(R3) // func arg ++ MOVV RARG1, 16(R3) // func arg ++ JAL runtime·racecallback(SB) ++#endif ++ JMP ret ++ ++// tls_g, g value for each thread in TLS ++GLOBL runtime·tls_g+0(SB), TLSBSS+DUPOK, $8 +-- +2.38.1 + diff --git a/0004-cmd-asm-Add-sw64-port.patch b/0004-cmd-asm-Add-sw64-port.patch new file mode 100644 index 0000000000000000000000000000000000000000..3af15d2dd8ab1cdede40bfe0bce1fdd961c21ced --- /dev/null +++ b/0004-cmd-asm-Add-sw64-port.patch @@ -0,0 +1,186 @@ +diff --git a/src/cmd/asm/internal/arch/arch.go b/src/cmd/asm/internal/arch/arch.go +index 8481a8f378..122d30bfa4 100644 +--- a/src/cmd/asm/internal/arch/arch.go ++++ b/src/cmd/asm/internal/arch/arch.go +@@ -81,6 +81,8 @@ func Set(GOARCH string, shared bool) *Arch { + return archS390x() + case "wasm": + return archWasm() ++ case "sw64": ++ return archSW64() + } + return nil + } +diff --git a/src/cmd/asm/internal/arch/sw64.go b/src/cmd/asm/internal/arch/sw64.go +new file mode 100644 +index 0000000000..3857b4e051 +--- /dev/null ++++ b/src/cmd/asm/internal/arch/sw64.go +@@ -0,0 +1,95 @@ ++// 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. ++ ++// This file encapsulates some of the odd characteristics of the ++// sw64 instruction set, to minimize its interaction ++// with the core of the assembler. ++ ++package arch ++ ++import ( ++ "cmd/internal/obj" ++ "cmd/internal/obj/sw64" ++ "fmt" ++) ++ ++func jumpSW64(word string) bool { ++ switch word { ++ case "CALL", "JMP", ++ "BR", "BSR", ++ "BEQ", "BNE", "BLT", "BLE", "BGT", "BGE", ++ "BLBC", "BLBS", "FBEQ", "FBNE", "FBLT", ++ "FBGT", "FBGE": ++ return true ++ } ++ return false ++} ++ ++func sw64RegisterNumber(name string, n int16) (int16, bool) { ++ //snyh_TODO: update by cmd/internal/obj/sw64/a.out.go ++ switch name { ++ case "R": ++ if 0 <= n && n <= 32 { ++ return sw64.REG_R0 + n, true ++ } ++ case "F": ++ if 0 <= n && n <= 32 { ++ return sw64.REG_F0 + n, true ++ } ++ case "V": ++ if 0 <= n && n <= 32 { ++ return sw64.REG_V0 + n, true ++ } ++ } ++ return 0, false ++} ++ ++func archSW64() *Arch { ++ register := make(map[string]int16) ++ for i := sw64.REG_R0; i <= sw64.REG_R31; i++ { ++ register[obj.Rconv(i)] = int16(i) ++ } ++ for i := sw64.REG_R0; i <= sw64.REG_R31; i++ { ++ register[fmt.Sprintf("R%d", i-sw64.REG_R0)] = int16(i) ++ } ++ for i := sw64.REG_F0; i <= sw64.REG_F31; i++ { ++ register[obj.Rconv(i)] = int16(i) ++ } ++ for i := sw64.REG_V0; i <= sw64.REG_V31; i++ { ++ register[obj.Rconv(i)] = int16(i) ++ } ++ ++ // Pseudo-registers. ++ register["SB"] = RSB ++ register["FP"] = RFP ++ register["PC"] = RPC ++ ++ registerPrefix := map[string]bool{ ++ "T": true, ++ "S": true, ++ "A": true, ++ "F": true, ++ "R": true, ++ "V": true, ++ } ++ ++ instructions := make(map[string]obj.As) ++ for i, s := range obj.Anames { ++ instructions[s] = obj.As(i) ++ } ++ for i, s := range sw64.Anames { ++ if obj.As(i) >= obj.A_ARCHSPECIFIC { ++ instructions[s] = obj.As(i) + obj.ABaseSW64 ++ } ++ } ++ ++ return &Arch{ ++ LinkArch: &sw64.LinkSW64, ++ Instructions: instructions, ++ Register: register, ++ RegisterPrefix: registerPrefix, ++ RegisterNumber: sw64RegisterNumber, ++ IsJump: jumpSW64, ++ } ++} +diff --git a/src/cmd/asm/internal/asm/asm.go b/src/cmd/asm/internal/asm/asm.go +index 9fc7fa5598..4a01b8ffc9 100644 +--- a/src/cmd/asm/internal/asm/asm.go ++++ b/src/cmd/asm/internal/asm/asm.go +@@ -563,6 +563,9 @@ func (p *Parser) asmJump(op obj.As, cond string, a []obj.Addr) { + case target.Type == obj.TYPE_CONST: + // JMP $4 + *targetAddr = a[0] ++ if p.arch.Family == sys.SW64 { ++ *targetAddr = a[1] ++ } + case target.Type == obj.TYPE_NONE: + // JMP + default: +@@ -782,6 +785,17 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) { + prog.AddRestSource(a[1]) + } + prog.To = a[2] ++ case sys.SW64: ++ prog.From = a[0] ++ ++ if a[1].Type == obj.TYPE_REG { ++ prog.Reg = p.getRegister(prog, op, &a[1]) ++ } else { ++ prog.AddRestSourceArgs([]obj.Addr{a[1]}) ++ } ++ ++ prog.To = a[2] ++ + default: + p.errorf("TODO: implement three-operand instructions for this architecture") + return +@@ -816,6 +830,12 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) { + prog.To = a[3] + break + } ++ if p.arch.Family == sys.SW64 { ++ prog.From = a[0] ++ prog.AddRestSourceArgs([]obj.Addr{a[1], a[2]}) ++ prog.To = a[3] ++ break ++ } + if p.arch.Family == sys.ARM64 { + prog.From = a[0] + prog.Reg = p.getRegister(prog, op, &a[1]) +diff --git a/src/cmd/asm/internal/asm/testdata/sw64.s b/src/cmd/asm/internal/asm/testdata/sw64.s +new file mode 100644 +index 0000000000..0ce54734f7 +--- /dev/null ++++ b/src/cmd/asm/internal/asm/testdata/sw64.s +@@ -0,0 +1,21 @@ ++#include "../../../../../runtime/textflag.h" ++TEXT foo(SB), NOSPLIT, $0 ++ ADDW R17, $0x4d, R0 //00 a0 29 4a ++ S4ADDW R17, R3, R1 // 41 00 23 42 ++ S4SUBL R3, R9, R11 // 6b 01 69 40 ++ S8SUBL R3, $0, R11 // 6b 01 60 48 ++ STB R3, 4(R0) // 04 00 60 a0 ++ SYS_CALL $1 // 01 00 00 02 ++ BSR R2, $52 // 0d 00 40 14 ++ DIVW R1, R2, R3 ++ UDIVW R1, R2, R3 ++ REMW R1, R2, R3 ++ UREMW R1, R2, R3 ++ DIVL R1, R2, R3 ++ UDIVL R1, R2, R3 ++ REML R1, R2, R3 ++ UREML R1, R2, R3 ++ ADDPI $_rt0_sw64_lib_go(SB), R1 ++ ADDPIS $_rt0_sw64_lib_go(SB), R1 ++ SBT R1, R2, R3 ++ CBT R1, R2, R3 diff --git a/0004-runtime-delete-on-register-ABI-fallback-path-for-rac.patch b/0004-runtime-delete-on-register-ABI-fallback-path-for-rac.patch new file mode 100644 index 0000000000000000000000000000000000000000..54922d9071f7d3b9635639e6d87b4e67ab1d5546 --- /dev/null +++ b/0004-runtime-delete-on-register-ABI-fallback-path-for-rac.patch @@ -0,0 +1,111 @@ +From 5623cd585fd5891d1f6d6d93256e4252b95b9dae Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Mon, 6 Nov 2023 17:13:43 +0800 +Subject: [PATCH 04/44] runtime: delete on-register ABI fallback path for race + of loong64 + +Co-authored-by: Xiaolin Zhao +Change-Id: Ie8c4a137205e29dd7dc63825f502b1f6b2f1c205 +--- + src/runtime/race_loong64.s | 34 ---------------------------------- + 1 file changed, 34 deletions(-) + +diff --git a/src/runtime/race_loong64.s b/src/runtime/race_loong64.s +index 0512efc045..04f264b21b 100644 +--- a/src/runtime/race_loong64.s ++++ b/src/runtime/race_loong64.s +@@ -40,11 +40,7 @@ + // Defined as ABIInternal so as to avoid introducing a wrapper, + // which would make caller's PC ineffective. + TEXT runtime·raceread(SB), NOSPLIT, $0-8 +-#ifdef GOEXPERIMENT_regabiargs + MOVV R4, RARG1 +-#else +- MOVV addr+0(FP), RARG1 +-#endif + MOVV R1, RARG2 + // void __tsan_read(ThreadState *thr, void *addr, void *pc); + MOVV $__tsan_read(SB), RCALL +@@ -69,11 +65,7 @@ TEXT runtime·racereadpc(SB), NOSPLIT, $0-24 + // Defined as ABIInternal so as to avoid introducing a wrapper, + // which would make caller's PC ineffective. + TEXT runtime·racewrite(SB), NOSPLIT, $0-8 +-#ifdef GOEXPERIMENT_regabiargs + MOVV R4, RARG1 +-#else +- MOVV addr+0(FP), RARG1 +-#endif + MOVV R1, RARG2 + // void __tsan_write(ThreadState *thr, void *addr, void *pc); + MOVV $__tsan_write(SB), RCALL +@@ -98,13 +90,8 @@ TEXT runtime·racewritepc(SB), NOSPLIT, $0-24 + // Defined as ABIInternal so as to avoid introducing a wrapper, + // which would make caller's PC ineffective. + TEXT runtime·racereadrange(SB), NOSPLIT, $0-16 +-#ifdef GOEXPERIMENT_regabiargs + MOVV R5, RARG2 + MOVV R4, RARG1 +-#else +- MOVV addr+0(FP), RARG1 +- MOVV size+8(FP), RARG2 +-#endif + MOVV R1, RARG3 + // void __tsan_read_range(ThreadState *thr, void *addr, uintptr size, void *pc); + MOVV $__tsan_read_range(SB), RCALL +@@ -130,13 +117,8 @@ TEXT runtime·racereadrangepc1(SB), NOSPLIT, $0-24 + // Defined as ABIInternal so as to avoid introducing a wrapper, + // which would make caller's PC ineffective. + TEXT runtime·racewriterange(SB), NOSPLIT, $0-16 +-#ifdef GOEXPERIMENT_regabiargs + MOVV R5, RARG2 + MOVV R4, RARG1 +-#else +- MOVV addr+0(FP), RARG1 +- MOVV size+8(FP), RARG2 +-#endif + MOVV R1, RARG3 + // void __tsan_write_range(ThreadState *thr, void *addr, uintptr size, void *pc); + MOVV $__tsan_write_range(SB), RCALL +@@ -186,11 +168,7 @@ ret: + // func runtime·racefuncenter(pc uintptr) + // Called from instrumented code. + TEXT runtime·racefuncenter(SB), NOSPLIT, $0-8 +-#ifdef GOEXPERIMENT_regabiargs + MOVV R4, RCALL +-#else +- MOVV callpc+0(FP), RCALL +-#endif + JMP racefuncenter<>(SB) + + // Common code for racefuncenter +@@ -476,13 +454,7 @@ rest: + BEQ R14, g, noswitch // branch if already on g0 + MOVV R14, g + +-#ifdef GOEXPERIMENT_regabiargs + JAL runtime·racecallback(SB) +-#else +- MOVV RARG0, 8(R3) // func arg +- MOVV RARG1, 16(R3) // func arg +- JAL runtime·racecallback(SB) +-#endif + // All registers are smashed after Go code, reload. + MOVV g_m(g), R15 + MOVV m_curg(R15), g // g = m->curg +@@ -496,13 +468,7 @@ ret: + + noswitch: + // already on g0 +-#ifdef GOEXPERIMENT_regabiargs + JAL runtime·racecallback(SB) +-#else +- MOVV RARG0, 8(R3) // func arg +- MOVV RARG1, 16(R3) // func arg +- JAL runtime·racecallback(SB) +-#endif + JMP ret + + // tls_g, g value for each thread in TLS +-- +2.38.1 + diff --git a/0005-cmd-internal-obj-loong64-remove-unused-register-alia.patch b/0005-cmd-internal-obj-loong64-remove-unused-register-alia.patch new file mode 100644 index 0000000000000000000000000000000000000000..34a43a06ff29f3746fc70132c426bacdfed426e9 --- /dev/null +++ b/0005-cmd-internal-obj-loong64-remove-unused-register-alia.patch @@ -0,0 +1,27 @@ +From 2ecb3ca09093ce12b2e47d97cbff223a950de0bb Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Thu, 16 Nov 2023 17:28:46 +0800 +Subject: [PATCH 05/44] cmd/internal/obj/loong64: remove unused register alias + definitions + +Change-Id: Ie788747372cd47cb3780e75b35750bb08bd166fc +--- + src/cmd/internal/obj/loong64/a.out.go | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/src/cmd/internal/obj/loong64/a.out.go b/src/cmd/internal/obj/loong64/a.out.go +index e6984dcba7..53b005af4d 100644 +--- a/src/cmd/internal/obj/loong64/a.out.go ++++ b/src/cmd/internal/obj/loong64/a.out.go +@@ -225,8 +225,6 @@ const ( + REGZERO = REG_R0 // set to zero + REGLINK = REG_R1 + REGSP = REG_R3 +- REGRET = REG_R20 // not use +- REGARG = -1 // -1 disables passing the first argument in register + REGRT1 = REG_R20 // reserved for runtime, duffzero and duffcopy + REGRT2 = REG_R21 // reserved for runtime, duffcopy + REGCTXT = REG_R29 // context for closures +-- +2.38.1 + diff --git a/0005-runtime-Add-sw64-port.patch b/0005-runtime-Add-sw64-port.patch new file mode 100644 index 0000000000000000000000000000000000000000..c113c4d1399715ee290632f5c737781de6f49600 --- /dev/null +++ b/0005-runtime-Add-sw64-port.patch @@ -0,0 +1,4478 @@ +diff --git a/src/runtime/asm_sw64.s b/src/runtime/asm_sw64.s +new file mode 100644 +index 0000000000..8e8add0e8f +--- /dev/null ++++ b/src/runtime/asm_sw64.s +@@ -0,0 +1,1162 @@ ++// 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. ++ ++#include "go_asm.h" ++#include "go_tls.h" ++#include "funcdata.h" ++#include "textflag.h" ++ ++// _rt0_sw64_lib is common startup code for most sw64 systems when ++// using -buildmode=c-archive or -buildmode=c-shared. The linker will ++// arrange to invoke this function as a global constructor (for ++// c-archive) or when the shared library is loaded (for c-shared). ++// We expect argc and argv to be passed in the usual C ABI registers ++// a0 and a1. ++TEXT _rt0_sw64_lib(SB), NOSPLIT, $0x50 ++ // 1. SAVE R16, R17 ++ STL R16, _rt0_sw64_lib_argc<>(SB) ++ STL R17, _rt0_sw64_lib_argv<>(SB) ++ ++ // 2. save C ABI registers ++ LDI SP, $-64(SP) ++ STL R9, 0*8(SP) ++ STL R10, 1*8(SP) ++ STL R11, 2*8(SP) ++ STL R12, 3*8(SP) ++ STL R13, 4*8(SP) ++ STL R14, 5*8(SP) ++ STL R15, 6*8(SP) ++ ++ CALL runtime·libpreinit(SB) ++ // 3. Create a new thread to finish Go runtime initialization. ++ LDL R27, _cgo_sys_thread_create(SB) ++ BEQ R27, nocgo ++ ++ SYMADDR R16, $_rt0_sw64_lib_go(SB) ++ LDI R17, $0 ++ CALL R26, (R27) ++ JMP restore ++nocgo: ++ LDI R16, $0x800000 ++ STL R16, 0(SP) ++ SYMADDR R17, $_rt0_sw64_lib_go(SB) ++ STL R17, 8(SP) ++ CALL runtime·newosproc0(SB) ++restore: ++ LDL R9, 0*8(SP) ++ LDL R10, 1*8(SP) ++ LDL R11, 2*8(SP) ++ LDL R12, 3*8(SP) ++ LDL R13, 4*8(SP) ++ LDL R14, 5*8(SP) ++ LDL R15, 6*8(SP) ++ LDI SP, $64(SP) ++ RET ++ ++// _rt0_sw64_lib_go initializes the Go runtime. ++// This is started in a separate thread by _rt0_sw64_lib. ++TEXT _rt0_sw64_lib_go(SB),NOSPLIT,$0 ++ LDL R16, _rt0_sw64_lib_argc<>(SB) ++ LDL R17, _rt0_sw64_lib_argv<>(SB) ++ CALL runtime·rt0_go(SB) ++ RET ++ ++DATA _rt0_sw64_lib_argc<>(SB)/8, $0 ++GLOBL _rt0_sw64_lib_argc<>(SB),NOPTR, $8 ++DATA _rt0_sw64_lib_argv<>(SB)/8, $0 ++GLOBL _rt0_sw64_lib_argv<>(SB),NOPTR, $8 ++ ++ ++// _rt0_sw64 is common startup code for most sw64 systems when using ++// internal linking. This is the entry point for the program from the ++// kernel for an ordinary -buildmode=exe program. The stack holds the ++// number of arguments and the C-style argv. ++TEXT _rt0_sw64(SB), NOFRAME|NOSPLIT, $0 ++ LDL R16, 0(SP) // argc ++ LDI R17, 8(SP) // argv ++ JMP runtime·rt0_go(SB) ++ ++TEXT main(SB), NOFRAME|NOSPLIT, $0 ++ SETFPEC1 ++ JMP runtime·rt0_go(SB) ++ ++TEXT runtime·rt0_go(SB), NOSPLIT|TOPFRAME, $16 ++ // copy args ++ STL R16, $argc-16(SP) ++ STL R17, $argv-8(SP) ++ ++ SYMADDR g, $runtime·g0(SB) ++ LDI R1, $-64*1024(SP) ++ STL R1, g_stackguard0(g) ++ STL R1, g_stackguard1(g) ++ STL R1, (g_stack+stack_lo)(g) ++ STL SP, (g_stack+stack_hi)(g) ++ ++ // if there is a _cgo_init, call it using the gcc ABI. ++ LDL R27, _cgo_init(SB) ++ BEQ R27, nocgo ++ ++ LDI R16, g ++ SYMADDR R17, $setg_gcc<>(SB) ++ LDI R18, ZERO ++ LDI R19, ZERO ++ CALL R26, (R27) ++ SETFPEC1 ++nocgo: ++ SYMADDR g, $runtime·g0(SB) ++ SYMADDR R0, $runtime·m0(SB) ++ STL g, m_g0(R0) ++ STL R0, g_m(g) ++ ++ CALL runtime·check(SB) ++ ++ // args are already prepared ++ CALL runtime·args(SB) ++ CALL runtime·osinit(SB) ++ CALL runtime·schedinit(SB) ++ // create a new goroutine to start program ++ SYMADDR R1, $runtime·mainPC(SB) ++ SUBL SP, $16, SP ++ STL R1, 8(SP) ++ STL ZERO, 0(SP) ++ CALL runtime·newproc(SB) ++ ADDL SP, $16, SP ++ CALL runtime·mstart(SB) ++ RET ++ ++DATA runtime·mainPC+0(SB)/8,$runtime·main(SB) ++GLOBL runtime·mainPC(SB),RODATA,$8 ++ ++// This is not obey by Go ABI, see SW64Ops.go ++// R1 R0 R0 R1 ++// func udiv(n, d uint64) (q, r uint64) { ++TEXT runtime·udiv(SB), NOSPLIT, $0 ++ SUBL SP, $80, SP ++ ++ LDI R5, ZERO ++ STL R1, $capn+16(SP) ++ ++ LDI R3, R1 ++ LDI R2, $0x8000000000000000 ++ CMPULE R2, R3, R3 ++ BEQ R3, l80 ++ STL R2, $capn+16(SP) ++l80: ++ LDI R3, ZERO ++ STL ZERO, $i+8(SP) ++l96: ++ LDL R4, $capn+16(SP) ++ ++ CMPULT R0, R4, R2 ++ BEQ R2, l184 ++ LDI R2, R0 ++ ++ SLL R2, $1, R2 ++ LDI R0, R2 ++ LDI R2, $i+8(SP) ++ LDL R2, (R2) ++ ++ ADDL R2, $1, R2 ++ ++ STL R2, $i+8(SP) ++ ++ BR ZERO, l96 ++l184: ++ LDL R2, $i+8(SP) ++ CMPLE R3, R2, R2 ++ BEQ R2, l384 ++l208: ++ SLL R5, $1, R5 ++ CMPULE R0, R1, R2 ++ BEQ R2, l316 ++ SUBL R1, R0, R1 ++ BIS R5, $1, R5 ++l316: ++ LDI R2, R0 ++ SRL R2, $1, R2 ++ LDI R0, R2 ++ BR ZERO, l340 ++l340: ++ LDL R2, $i+8(SP) ++ SUBL R2, $1, R2 ++ STL R2, $i+8(SP) ++ BR ZERO, l184 ++l384: ++ LDI R0, R5 ++ ADDL SP, $80, SP ++ RET ++ ++TEXT runtime·breakpoint(SB), NOFRAME|NOSPLIT, $0 ++ SYS_CALL_B $0x80 ++ RET ++ ++// Switch to m->g0's stack, call fn(g). ++// Fn must never return. It should gogo(&g->sched) ++// to keep running g. ++ ++// func mcall(fn func(*g)) ++TEXT runtime·mcall(SB), NOFRAME|NOSPLIT, $0-8 ++#ifdef GOEXPERIMENT_regabiargs ++ LDI REGCTXT, R16 ++#else ++ LDL REGCTXT, fn+0(FP) ++#endif ++ // Save caller state in g->sched ++ STL SP, (g_sched+gobuf_sp)(g) ++ STL R26, (g_sched+gobuf_pc)(g) ++ STL ZERO, (g_sched+gobuf_lr)(g) ++ ++ // Switch to m->g0 & its stack, call fn. ++ LDI R1, g ++ LDL R3, g_m(g) ++ LDL g, m_g0(R3) ++ CALL runtime·save_g(SB) ++ CMPEQ g, R1, R7 ++ BEQ R7, ok ++ CALL runtime·badmcall(SB) ++ok: ++ LDL SP, (g_sched+gobuf_sp)(g) ++ SUBL SP, $16, SP ++ STL ZERO, 0(SP) // dummy LR ++#ifdef GOEXPERIMENT_regabiargs ++ LDI R16, R1 // arg = g ++#else ++ STL R1, 8(SP) // arg = g ++#endif ++ LDL R27, 0(REGCTXT) // code pointer ++ JMP (R27) ++ //ADDL SP, $16, SP ++ CALL runtime·badmcall2(SB) ++ ++// func systemstack(fn func()) ++TEXT runtime·systemstack(SB), NOSPLIT, $0-8 ++ LDL R1, fn+0(FP) ++ LDI REGCTXT, R1 ++ ++ LDL R2, g_m(g) ++ ++ LDL R3, m_gsignal(R2) ++ CMPEQ g, R3, R3 ++ BNE R3, noswitch ++ ++ LDL R3, m_g0(R2) // save g0 in R3 ++ CMPEQ g, R3, R4 ++ BNE R4, noswitch ++ ++ LDL R4, m_curg(R2) ++ CMPEQ g, R4, R4 ++ BNE R4, switch ++ ++ CALL runtime·badsystemstack(SB) ++ CALL runtime·abort(SB) ++ RET ++switch: ++ // save our state in g->sched. Pretend to ++ // be systemstack_switch if the G stack is scanned. ++ CALL gosave_systemstack_switch<>(SB) ++ ++ // switch to g0 ++ LDI g, R3 ++ CALL runtime·save_g(SB) ++ LDL R1, (g_sched+gobuf_sp)(g) ++ LDI SP, R1 ++ ++ LDL R27, 0(REGCTXT) ++ CALL (R27) ++ ++ // switch back to g ++ LDL R1, g_m(g) ++ LDL g, m_curg(R1) ++ CALL runtime·save_g(SB) ++ LDL SP, (g_sched+gobuf_sp)(g) ++ STL ZERO, (g_sched+gobuf_sp)(g) ++ RET ++noswitch: ++ // already on m stack, just call directly ++ // Using a tail call here cleans up tracebacks since we won't stop ++ // at an intermediate systemstack. ++ LDL R27, 0(REGCTXT) ++ LDL R26, 0(SP) ++ ADDL SP, $8, SP ++ JMP (R27) ++ ++// systemstack_switch is a dummy routine that systemstack leaves at the bottom ++// of the G stack. We need to distinguish the routine that ++// lives at the bottom of the G stack from the one that lives ++// at the top of the system stack because the one at the top of ++// the system stack terminates the stack walk (see topofstack()). ++TEXT runtime·systemstack_switch(SB), NOSPLIT, $0-0 ++ UNDEF ++ CALL (R27) // make sure this function is not leaf ++ RET ++ ++TEXT runtime·asminit(SB), NOFRAME|NOSPLIT, $0-0 ++ RET ++ ++// func switchToCrashStack0(fn func()) ++TEXT runtime·switchToCrashStack0(SB), NOSPLIT, $0-8 ++ LDI REGCTXT, R16 // context register ++ LDL R17, g_m(g) // curm ++ ++ // set g to gcrash ++ SYMADDR g, $runtime·gcrash(SB) // g = &gcrash ++ CALL runtime·save_g(SB) ++ STL R17, g_m(g) // g.m = curm ++ STL g, m_g0(R17) // curm.g0 = g ++ ++ // switch to crashstack ++ LDL R17, (g_stack+stack_hi)(g) ++ SUBL R17, $(4*8), R17 ++ ++ // call target function ++ LDL R27, 0(REGCTXT) ++ CALL (R27) ++ ++ // should never return ++ CALL runtime·abort(SB) ++ UNDEF ++ ++/* ++ * support for morestack ++ */ ++ ++// Called during function prolog when more stack is needed. ++// ++// The traceback routines see morestack on a g0 as being ++// the top of a stack (for example, morestack calling newstack ++// calling the scheduler calling newm calling gc), so we must ++// record an argument size. For that purpose, it has no arguments. ++// ++// R2 is return address; R3 is PC ++TEXT runtime·morestack(SB), NOFRAME|NOSPLIT, $0-0 ++ // Called from f. ++ // Set g->sched to context in f. ++ STL SP, (g_sched+gobuf_sp)(g) ++ STL R2, (g_sched+gobuf_pc)(g) ++ STL R3, (g_sched+gobuf_lr)(g) ++ STL REGCTXT, (g_sched+gobuf_ctxt)(g) ++ ++ // Cannot grow scheduler stack (m->g0). ++ LDL R7, g_m(g) ++ LDL R8, m_g0(R7) ++ CMPEQ g, R8, R1 ++ BEQ R1, 3(PC) // if g != g.m.g0 ++ CALL runtime·badmorestackg0(SB) ++ CALL runtime·abort(SB) ++ ++ // Cannot grow signal stack (m->gsignal). ++ LDL R8, m_gsignal(R7) ++ CMPEQ g, R8, R1 ++ BEQ R1, 3(PC) // if g != g.m.gsignal ++ CALL runtime·badmorestackgsignal(SB) ++ CALL runtime·abort(SB) ++ ++ // Called from f. ++ // Set m->morebuf to f's caller. ++ STL R3, (m_morebuf+gobuf_pc)(R7) // f's caller's PC ++ STL SP, (m_morebuf+gobuf_sp)(R7) // f's caller's SP ++ STL g, (m_morebuf+gobuf_g)(R7) ++ ++ // Call newstack on m->g0's stack. ++ LDL g, m_g0(R7) ++ CALL runtime·save_g(SB) ++ LDL SP, (g_sched+gobuf_sp)(g) ++ // Create a stack frame on g0 to call newstack. ++ STL ZERO, -8(SP) ++ SUBL SP, $8, SP ++ CALL runtime·newstack(SB) ++ ++ // Not reached, but make sure the return PC from the call to newstack ++ // is still in this function, and not the beginning of the next. ++ UNDEF ++ ++ ++TEXT runtime·morestack_noctxt(SB), NOFRAME|NOSPLIT, $0-0 ++ LDI REGCTXT, ZERO ++ JMP runtime·morestack(SB) ++ ++#ifdef GOEXPERIMENT_regabiargs ++// spillArgs stores return values from registers to a *internal/abi.RegArgs in R9. ++TEXT ·spillArgs(SB),NOSPLIT,$0-0 ++ STL R16, (0*8)(R9) ++ STL R17, (1*8)(R9) ++ STL R18, (2*8)(R9) ++ STL R19, (3*8)(R9) ++ STL R20, (4*8)(R9) ++ STL R21, (5*8)(R9) ++ STL R22, (6*8)(R9) ++ STL R23, (7*8)(R9) ++ STL R24, (8*8)(R9) ++ FSTD F16, (9*8)(R9) ++ FSTD F17, (10*8)(R9) ++ FSTD F18, (11*8)(R9) ++ FSTD F19, (12*8)(R9) ++ FSTD F20, (13*8)(R9) ++ FSTD F21, (14*8)(R9) ++ FSTD F22, (15*8)(R9) ++ FSTD F23, (16*8)(R9) ++ FSTD F24, (17*8)(R9) ++ RET ++ ++// unspillArgs loads args into registers from a *internal/abi.RegArgs in R9. ++TEXT ·unspillArgs(SB),NOSPLIT,$0-0 ++ LDL R16, (0*8)(R9) ++ LDL R17, (1*8)(R9) ++ LDL R18, (2*8)(R9) ++ LDL R19, (3*8)(R9) ++ LDL R20, (4*8)(R9) ++ LDL R21, (5*8)(R9) ++ LDL R22, (6*8)(R9) ++ LDL R23, (7*8)(R9) ++ LDL R24, (8*8)(R9) ++ FLDD F16, (9*8)(R9) ++ FLDD F17, (10*8)(R9) ++ FLDD F18, (11*8)(R9) ++ FLDD F19, (12*8)(R9) ++ FLDD F20, (13*8)(R9) ++ FLDD F21, (14*8)(R9) ++ FLDD F22, (15*8)(R9) ++ FLDD F23, (16*8)(R9) ++ FLDD F24, (17*8)(R9) ++ RET ++#else ++TEXT ·spillArgs(SB),NOSPLIT,$0-0 ++ RET ++ ++TEXT ·unspillArgs(SB),NOSPLIT,$0-0 ++ RET ++#endif ++ ++// void setg(G*); set g. for use by needm. ++TEXT runtime·setg(SB), NOSPLIT, $0-8 ++ LDL g, gg+0(FP) ++ // This only happens if iscgo, so jump straight to save_g ++ CALL runtime·save_g(SB) ++ RET ++ ++ ++TEXT runtime·return0(SB), NOSPLIT, $0 ++ LDI R0, $0 ++ RET ++ ++ ++// The top-most function running on a goroutine ++TEXT runtime·goexit(SB), NOFRAME|NOSPLIT|TOPFRAME, $0-0 ++ LDI ZERO, $0 ++ JMP runtime·goexit1(SB) ++ LDI ZERO, $0 ++ ++// This is called from .init_array and follows the platform, not Go, ABI ++TEXT runtime·addmoduledata(SB),NOSPLIT,$0-0 ++ LDL R1, runtime·lastmoduledatap(SB) ++ STL R0, moduledata_next(R1) // local.moduledata passed to R0 ++ STL R0, runtime·lastmoduledatap(SB) ++ RET ++ ++// void gogo(Gobuf*) ++// restore state from Gobuf; longjmp ++TEXT runtime·gogo(SB), NOSPLIT|NOFRAME, $0-8 ++ LDL R3, buf+0(FP) ++ LDL R4, gobuf_g(R3) ++ LDL ZERO, 0(R4) // make sure g != nil ++ JMP gogo<>(SB) ++ ++TEXT gogo<>(SB), NOSPLIT|NOFRAME, $0 ++ LDI g, R4 ++ CALL runtime·save_g(SB) ++ ++ LDL SP, gobuf_sp(R3) ++ LDL R26, gobuf_lr(R3) ++ LDL R0, gobuf_ret(R3) ++ LDL REGCTXT, gobuf_ctxt(R3) ++ ++ STL ZERO, gobuf_sp(R3) ++ STL ZERO, gobuf_ret(R3) ++ STL ZERO, gobuf_lr(R3) ++ STL ZERO, gobuf_ctxt(R3) ++ ++ LDL R27, gobuf_pc(R3) ++ JMP (R27) ++ RET ++ ++TEXT runtime·procyield(SB), NOFRAME|NOSPLIT, $0-0 ++ RET ++ ++// changed R19 to R1 ++#define DISPATCH(NAME, MAXSIZE) \ ++ LDI R0, $MAXSIZE \ ++ CMPULT R0, R1, R0 \ ++ BNE R0, 4(PC) \ ++ SYMADDR R27, $NAME(SB) \ ++ JMP (R27) \ ++ RET ++ ++TEXT reflect·call(SB), NOFRAME|NOSPLIT, $0-0 ++ JMP ·reflectcall(SB) ++ ++// func call(stackArgsType *_type, f *FuncVal, stackArgs *byte, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs) ++TEXT ·reflectcall(SB), NOFRAME|NOSPLIT, $0-48 ++ LDW R1, frameSize+32(FP) // R1 used in DISPACH macro ++// LDW R19, frameSize+32(FP) // R19 used in DISPACH macro ++ DISPATCH(runtime·call32, 32) ++ DISPATCH(runtime·call64, 64) ++ DISPATCH(runtime·call128, 128) ++ DISPATCH(runtime·call256, 256) ++ DISPATCH(runtime·call512, 512) ++ DISPATCH(runtime·call1024, 1024) ++ DISPATCH(runtime·call2048, 2048) ++ DISPATCH(runtime·call4096, 4096) ++ DISPATCH(runtime·call8192, 8192) ++ DISPATCH(runtime·call16384, 16384) ++ DISPATCH(runtime·call32768, 32768) ++ DISPATCH(runtime·call65536, 65536) ++ DISPATCH(runtime·call131072, 131072) ++ DISPATCH(runtime·call262144, 262144) ++ DISPATCH(runtime·call524288, 524288) ++ DISPATCH(runtime·call1048576, 1048576) ++ DISPATCH(runtime·call2097152, 2097152) ++ DISPATCH(runtime·call4194304, 4194304) ++ DISPATCH(runtime·call8388608, 8388608) ++ DISPATCH(runtime·call16777216, 16777216) ++ DISPATCH(runtime·call33554432, 33554432) ++ DISPATCH(runtime·call67108864, 67108864) ++ DISPATCH(runtime·call134217728, 134217728) ++ DISPATCH(runtime·call268435456, 268435456) ++ DISPATCH(runtime·call536870912, 536870912) ++ DISPATCH(runtime·call1073741824, 1073741824) ++ ++ CALL runtime·badreflectcall(SB) ++ RET ++ ++#define CALLFN(NAME,MAXSIZE) \ ++TEXT NAME(SB), WRAPPER, $MAXSIZE-48 \ ++ NO_LOCAL_POINTERS; \ ++ /* copy arguments to stack */ \ ++ LDL R1, stackArgs+16(FP) \ ++ LDW R2, stackArgsSize+24(FP) \ ++ LDI R3, SP \ ++ ADDL R3, $8, R3 \ ++ ADDL R3, R2, R2 \ ++loop: \ ++ CMPEQ R3, R2, R0 \ ++ BNE R0, ok \ ++ LDBU R4, (R1) \ ++ STB R4, (R3) \ ++ ADDL R1, $1, R1 \ ++ ADDL R3, $1, R3 \ ++ JMP loop \ ++ok: \ ++ /* set up argument registers */ \ ++ LDL R9, regArgs+40(FP) \ ++ CALL ·unspillArgs(SB) \ ++ /* call function */ \ ++ LDL REGCTXT, fn+8(FP) \ ++ LDL R27, (REGCTXT) \ ++ PCDATA $PCDATA_StackMapIndex, $0; \ ++ CALL (R27) \ ++ /* copy return values back */ \ ++ LDL R9, regArgs+40(FP) \ ++ CALL ·spillArgs(SB) \ ++ LDL R5, stackArgsType+0(FP) \ ++ LDL R1, stackArgs+16(FP) \ ++ LDW R2, stackArgsSize+24(FP) \ ++ LDW R4, stackRetOffset+28(FP) \ ++ ADDL SP, $8, R3 \ ++ ADDL R4, R3, R3 \ ++ ADDL R4, R1, R1 \ ++ SUBL R2, R4, R2 \ ++ CALL callRet<>(SB) \ ++ RET ++ ++// callRet copies return values back at the end of call*. This is a ++// separate function so it can allocate stack space for the arguments ++// to reflectcallmove. It does not follow the Go ABI; it expects its ++// arguments in registers. ++TEXT callRet<>(SB), NOSPLIT, $40-0 ++ NO_LOCAL_POINTERS ++ STL R5, 8(SP) // argtype ++ STL R1, 16(SP) // dst ++ STL R3, 24(SP) // src ++ STL R2, 32(SP) // size ++ STL R9, 40(SP) // regs ++ // reflectcallmove(typ *_type, dst, src unsafe.Pointer, size uintptr) ++ CALL runtime·reflectcallmove(SB) ++ RET ++ ++CALLFN(·call16, 16) ++CALLFN(·call32, 32) ++CALLFN(·call64, 64) ++CALLFN(·call128, 128) ++CALLFN(·call256, 256) ++CALLFN(·call512, 512) ++CALLFN(·call1024, 1024) ++CALLFN(·call2048, 2048) ++CALLFN(·call4096, 4096) ++CALLFN(·call8192, 8192) ++CALLFN(·call16384, 16384) ++CALLFN(·call32768, 32768) ++CALLFN(·call65536, 65536) ++CALLFN(·call131072, 131072) ++CALLFN(·call262144, 262144) ++CALLFN(·call524288, 524288) ++CALLFN(·call1048576, 1048576) ++CALLFN(·call2097152, 2097152) ++CALLFN(·call4194304, 4194304) ++CALLFN(·call8388608, 8388608) ++CALLFN(·call16777216, 16777216) ++CALLFN(·call33554432, 33554432) ++CALLFN(·call67108864, 67108864) ++CALLFN(·call134217728, 134217728) ++CALLFN(·call268435456, 268435456) ++CALLFN(·call536870912, 536870912) ++CALLFN(·call1073741824, 1073741824) ++ ++ ++TEXT ·checkASM(SB),NOSPLIT,$0-1 ++ LDI R1, $1 ++ STB R1, ret+0(FP) ++ RET ++ ++ ++TEXT runtime·abort(SB), NOFRAME|NOSPLIT, $0-0 ++ LDW ZERO,(ZERO) ++ UNDEF ++ ++TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME,$0 ++ CALL runtime·mstart0(SB) ++ RET // not reached ++ ++// Save state of caller into g->sched, ++// but using fake PC from systemstack_switch. ++// Must only be called from functions with no locals ($0) ++// or else unwinding from systemstack_switch is incorrect. ++// Smashes R1. ++TEXT gosave_systemstack_switch<>(SB), NOFRAME|NOSPLIT,$0 ++ SYMADDR R1, $runtime·systemstack_switch(SB) ++ ADDL R1, $8, R1 ++ STL R1, (g_sched+gobuf_pc)(g) ++ STL SP, (g_sched+gobuf_sp)(g) ++ STL ZERO, (g_sched+gobuf_lr)(g) ++ STL ZERO, (g_sched+gobuf_ret)(g) ++ // Assert ctxt is zero. See func save. ++ LDL R1, (g_sched+gobuf_ctxt)(g) ++ BEQ R1, 2(PC) ++ CALL runtime·abort(SB) ++ RET ++ ++TEXT ·asmcgocall_no_g(SB),NOSPLIT,$0-16 ++ LDL R27, fn+0(FP) ++ LDL R16, arg+8(FP) ++ CALL (R27) ++ RET ++ ++// func asmcgocall(fn, arg unsafe.Pointer) int32 ++// Call fn(arg) on the scheduler stack, ++// aligned appropriately for the gcc ABI. ++// See cgocall.go for more details. ++TEXT ·asmcgocall(SB), NOSPLIT, $0-20 ++ LDL R27, fn+0(FP) ++ LDL R16, arg+8(FP) ++ ++ LDI R8, R27 ++ LDI R3, SP ++ LDI R2, g ++ ++ // Figure out if we need to switch to m->g0 stack. ++ // We get called to create new OS threads too, and those ++ // come in on the m->g0 stack already. Or we might already ++ // be on the m->gsignal stack. ++ LDL R5, g_m(g) ++ LDL R6, m_gsignal(R5) ++ CMPEQ R6, g, R0 ++ BNE R0, g0 ++ ++ LDL R6, m_g0(R5) ++ CMPEQ R6, g, R0 ++ BNE R0, g0 ++ ++ CALL gosave_systemstack_switch<>(SB) ++ LDI g, R6 ++ CALL runtime·save_g(SB) ++ ++ // restore fn value from old SP ++ LDI R27, R8 ++ LDL SP, (g_sched+gobuf_sp)(g) ++ // Now on a scheduling stack (a pthread-created stack). ++g0: ++ // Save room for two of our pointers. ++ LDI SP, $-16(SP) ++ STL R2, 0(SP) ++ LDL R2, (g_stack+stack_hi)(R2) ++ SUBL R2, R3, R2 ++ STL R2, 8(SP) ++ CALL R26, (R27) ++ // Restore g, stack pointer. R2 is return value. ++ LDL g, 0(SP) ++ CALL runtime·save_g(SB) ++ LDL R5, (g_stack+stack_hi)(g) ++ LDL R6, 8(SP) ++ SUBL R5, R6, R5 ++ LDI SP, R5 ++ ++ STW R0, ret+16(FP) ++ RET ++ ++// void setg_gcc(G*); set g in C TLS. ++// Must obey the gcc calling convention. ++TEXT setg_gcc<>(SB), NOSPLIT, $0 ++ LDI g, R16 ++ CALL runtime·save_g(SB) ++ RET ++ ++// Called from cgo wrappers, this function returns g->m->curg.stack.hi. ++// Must obey the gcc calling convention. ++TEXT _cgo_topofstack(SB), NOSPLIT, $16 ++ // g (R15) might be clobbered by load_g. They ++ // are callee-save in the gcc calling convention, so save them. ++ STL R28, savedR28-16(SP) ++ STL g, savedG-8(SP) ++ ++ CALL runtime·load_g(SB) ++ ++ LDL R1, g_m(g) ++ LDL R1, m_curg(R1) ++ LDL R0, (g_stack+stack_hi)(R1) // return value in R0 ++ ++ LDL g, savedG-8(SP) ++ LDL R28, savedR28-16(SP) ++ RET ++ ++ ++// cgocallback_gofunc(FuncVal*, void *frame, uintptr framesize, uintptr ctxt) ++// See cgocall.go for more details. ++TEXT ·cgocallback(SB), NOSPLIT, $24-24 ++ NO_LOCAL_POINTERS ++ ++ // Skip cgocallbackg, just dropm when fn is nil, and frame is the saved g. ++ // It is used to dropm while thread is exiting. ++ LDL R16, fn+0(FP) ++ BNE R16, loadg ++ // Restore the g from frame. ++ LDL g, frame+8(FP) ++ JMP dropm ++ ++loadg: ++ // Load m and g from thread-local storage. ++ LDBU R1, runtime·iscgo(SB) ++ BEQ R1, nocgo ++ CALL runtime·load_g(SB) ++nocgo: ++ ++ // If g is nil, Go did not create the current thread, ++ // or if this thread never called into Go on pthread platforms. ++ // Call needm to obtain one for temporary use. ++ // In this case, we're running on the thread stack, so there's ++ // lots of space, but the linker doesn't know. Hide the call from ++ // the linker analysis by using an indirect call. ++ BEQ g, needm ++ LDL R3, g_m(g) ++ STL R3, savedm-8(SP) ++ JMP havem ++ ++needm: ++ STL g, savedm-8(SP) // g is zero, so is m. ++ SYMADDR R27, $runtime·needAndBindM(SB) ++ CALL R26, (R27) ++ ++ // Set m->sched.sp = SP, so that if a panic happens ++ // during the function we are about to execute, it will ++ // have a valid SP to run on the g0 stack. ++ // The next few lines (after the havem label) ++ // will save this SP onto the stack and then write ++ // the same SP back to m->sched.sp. That seems redundant, ++ // but if an unrecovered panic happens, unwindm will ++ // restore the g->sched.sp from the stack location ++ // and then systemstack will try to use it. If we don't set it here, ++ // that restored SP will be uninitialized (typically 0) and ++ // will not be usable. ++ LDL R3, g_m(g) ++ LDL R1, m_g0(R3) ++ STL SP, (g_sched+gobuf_sp)(R1) ++ ++havem: ++ // Now there's a valid m, and we're running on its m->g0. ++ // Save current m->g0->sched.sp on stack and then set it to SP. ++ // Save current sp in m->g0->sched.sp in preparation for ++ // switch back to m->curg stack. ++ // NOTE: unwindm knows that the saved g->sched.sp is at 8(R29) aka savedsp-16(SP). ++ ++ LDL R1, m_g0(R3) ++ LDL R2, (g_sched+gobuf_sp)(R1) ++ STL R2, savedsp-24(SP) ++ STL SP, (g_sched+gobuf_sp)(R1) ++ ++ // Switch to m->curg stack and call runtime.cgocallbackg. ++ // Because we are taking over the execution of m->curg ++ // but *not* resuming what had been running, we need to ++ // save that information (m->curg->sched) so we can restore it. ++ // We can restore m->curg->sched.sp easily, because calling ++ // runtime.cgocallbackg leaves SP unchanged upon return. ++ // To save m->curg->sched.pc, we push it onto the stack. ++ // This has the added benefit that it looks to the traceback ++ // routine like cgocallbackg is going to return to that ++ // PC (because the frame we allocate below has the same ++ // size as cgocallback_gofunc's frame declared above) ++ // so that the traceback will seamlessly trace back into ++ // the earlier calls. ++ // ++ // In the new goroutine, -8(SP) is unused (where SP refers to ++ // m->curg's SP while we're setting it up, before we've adjusted it). ++ LDL g, m_curg(R3) ++ CALL runtime·save_g(SB) ++ LDL R2, (g_sched+gobuf_sp)(g) ++ LDL R27, (g_sched+gobuf_pc)(g) ++ STL R27, -32(R2) // save LR ++ // Gather our arguments into registers. ++ LDL R16, fn+0(FP) ++ LDL R17, frame+8(FP) ++ LDL R18, ctxt+16(FP) ++ LDI SP, $-32(R2) //switch stack ++ STL R16, 8(SP) ++ STL R17, 16(SP) ++ STL R18, 24(SP) ++ CALL runtime·cgocallbackg(SB) ++ ++ // Restore g->sched (== m->curg->sched) from saved values. ++ LDL R27, 0(SP) ++ STL R27, (g_sched+gobuf_pc)(g) ++ LDI R2, $32(SP) ++ STL R2, (g_sched+gobuf_sp)(g) ++ ++ // Switch back to m->g0's stack and restore m->g0->sched.sp. ++ // (Unlike m->curg, the g0 goroutine never uses sched.pc, ++ // so we do not have to restore it.) ++ LDL R3, g_m(g) ++ LDL g, m_g0(R3) ++ CALL runtime·save_g(SB) ++ LDL SP, (g_sched+gobuf_sp)(g) ++ LDL R2, savedsp-24(SP) ++ STL R2, (g_sched+gobuf_sp)(g) ++ ++ // If the m on entry was nil, we called needm above to borrow an m, ++ // 1. for the duration of the call on non-pthread platforms, ++ // 2. or the duration of the C thread alive on pthread platforms. ++ // If the m on entry wasn't nil, ++ // 1. the thread might be a Go thread, ++ // 2. or it's wasn't the first call from a C thread on pthread platforms, ++ // since the we skip dropm to resue the m in the first call. ++ LDL R3, savedm-8(SP) ++ BNE R3, droppedm ++ ++ // Skip dropm to reuse it in the next call, when a pthread key has been created. ++ LDL R3, _cgo_pthread_key_created(SB) ++ // It means cgo is disabled when _cgo_pthread_key_created is a nil pointer, need dropm. ++ BEQ R3, dropm ++ LDL R3, (R3) ++ BNE R3, droppedm ++dropm: ++ SYMADDR R27, $runtime·dropm(SB) ++ CALL R26, (R27) ++droppedm: ++ // Done! ++ RET ++ ++ ++// gcWriteBarrier informs the GC about heap pointer writes. ++// ++// gcWriteBarrier does NOT follow the Go ABI. It accepts the ++// number of bytes of buffer needed in R14, and returns a pointer ++// to the buffer space in R14. ++// It clobbers R28 (the linker temp register). ++// The act of CALLing gcWriteBarrier will clobber R26 (LR). ++// It does not clobber any other general-purpose registers, ++// but may clobber others (e.g., floating point registers). ++TEXT gcWriteBarrier<>(SB),NOSPLIT,$208 ++ // Save the registers clobbered by the fast path. ++ STL R1, 200(SP) ++ STL R2, 208(SP) ++retry: ++ LDL R1, g_m(g) ++ LDL R1, m_p(R1) ++ LDL R2, (p_wbBuf+wbBuf_next)(R1) ++ LDL R28, (p_wbBuf+wbBuf_end)(R1)// R28 is linker temp register ++ // Increment wbBuf.next position. ++ ADDL R2, R14, R2 ++ // Is the buffer full? ++ CMPULT R28, R2, R28 ++ BNE R28, flush ++ // Commit to the larger buffer. ++ STL R2, (p_wbBuf+wbBuf_next)(R1) ++ // Make return value (the original next position) ++ SUBL R2, R14, R14 ++ LDL R1, 200(SP) ++ LDL R2, 208(SP) ++ RET ++ ++flush: ++ // Save all general purpose registers since these could be ++ // clobbered by wbBufFlush and were not saved by the caller. ++ STL R13, 8(SP) ++ STL R14, 16(SP) ++ STL R0, 24(SP) ++ // R1 already saved ++ // R2 already saved ++ STL R3, 32(SP) ++ STL R4, 40(SP) ++ STL R5, 48(SP) ++ STL R6, 56(SP) ++ STL R7, 64(SP) ++ STL R8, 72(SP) ++ STL R9, 80(SP) ++ STL R10, 88(SP) ++ STL R11, 96(SP) ++ STL R12, 104(SP) ++ // R13 already saved ++ // R14 already saved. ++ // R15 is g. ++ STL R16, 112(SP) ++ STL R17, 120(SP) ++ STL R18, 128(SP) ++ STL R19, 136(SP) ++ STL R20, 144(SP) ++ STL R21, 152(SP) ++ STL R22, 160(SP) ++ STL R23, 168(SP) ++ STL R24, 176(SP) ++ STL R25, 184(SP) ++ // R26 is link register. ++ STL R27, 192(SP) ++ // R28 is tmp register. ++ // R29 is SB. ++ // R30 is SP. ++ // R31 is ZERO. ++ ++ CALL runtime·wbBufFlush(SB) ++ ++ LDL R13, 8(SP) ++ LDL R14, 16(SP) ++ LDL R0, 24(SP) ++ LDL R3, 32(SP) ++ LDL R4, 40(SP) ++ LDL R5, 48(SP) ++ LDL R6, 56(SP) ++ LDL R7, 64(SP) ++ LDL R8, 72(SP) ++ LDL R9, 80(SP) ++ LDL R10, 88(SP) ++ LDL R11, 96(SP) ++ LDL R12, 104(SP) ++ LDL R16, 112(SP) ++ LDL R17, 120(SP) ++ LDL R18, 128(SP) ++ LDL R19, 136(SP) ++ LDL R20, 144(SP) ++ LDL R21, 152(SP) ++ LDL R22, 160(SP) ++ LDL R23, 168(SP) ++ LDL R24, 176(SP) ++ LDL R25, 184(SP) ++ LDL R27, 192(SP) ++ JMP retry ++ ++TEXT runtime·gcWriteBarrier1(SB),NOSPLIT,$0 ++ LDI R14, $8 ++ JMP gcWriteBarrier<>(SB) ++TEXT runtime·gcWriteBarrier2(SB),NOSPLIT,$0 ++ LDI R14, $16 ++ JMP gcWriteBarrier<>(SB) ++TEXT runtime·gcWriteBarrier3(SB),NOSPLIT,$0 ++ LDI R14, $24 ++ JMP gcWriteBarrier<>(SB) ++TEXT runtime·gcWriteBarrier4(SB),NOSPLIT,$0 ++ LDI R14, $32 ++ JMP gcWriteBarrier<>(SB) ++TEXT runtime·gcWriteBarrier5(SB),NOSPLIT,$0 ++ LDI R14, $40 ++ JMP gcWriteBarrier<>(SB) ++TEXT runtime·gcWriteBarrier6(SB),NOSPLIT,$0 ++ LDI R14, $48 ++ JMP gcWriteBarrier<>(SB) ++TEXT runtime·gcWriteBarrier7(SB),NOSPLIT,$0 ++ LDI R14, $56 ++ JMP gcWriteBarrier<>(SB) ++TEXT runtime·gcWriteBarrier8(SB),NOSPLIT,$0 ++ LDI R14, $64 ++ JMP gcWriteBarrier<>(SB) ++ ++// func cputicks() int64 ++//TEXT runtime·cputicks(SB),NOSPLIT,$0-8 ++// RTC R0 ++// STL R0, ret+0(FP) ++// RET ++ ++//zxw new add ++// Note: these functions use a special calling convention to save generated code space. ++// Arguments are passed in registers, but the space for those arguments are allocated ++// in the caller's stack frame. These stubs write the args into that stack space and ++// then tail call to the corresponding runtime handler. ++// The tail call makes these stubs disappear in backtraces. ++TEXT runtime·panicIndex(SB),NOSPLIT,$0-16 ++#ifdef GOEXPERIMENT_regabiargs ++ LDI R16, R1 ++ LDI R17, R2 ++#else ++ STL R1, x+0(FP) ++ STL R2, y+8(FP) ++#endif ++ JMP runtime·goPanicIndex(SB) ++TEXT runtime·panicIndexU(SB),NOSPLIT,$0-16 ++#ifdef GOEXPERIMENT_regabiargs ++ LDI R16, R1 ++ LDI R17, R2 ++#else ++ STL R1, x+0(FP) ++ STL R2, y+8(FP) ++#endif ++ JMP runtime·goPanicIndexU(SB) ++TEXT runtime·panicSliceAlen(SB),NOSPLIT,$0-16 ++#ifdef GOEXPERIMENT_regabiargs ++ LDI R16, R2 ++ LDI R17, R3 ++#else ++ STL R2, x+0(FP) ++ STL R3, y+8(FP) ++#endif ++ JMP runtime·goPanicSliceAlen(SB) ++TEXT runtime·panicSliceAlenU(SB),NOSPLIT,$0-16 ++#ifdef GOEXPERIMENT_regabiargs ++ LDI R16, R2 ++ LDI R17, R3 ++#else ++ STL R2, x+0(FP) ++ STL R3, y+8(FP) ++#endif ++ JMP runtime·goPanicSliceAlenU(SB) ++TEXT runtime·panicSliceAcap(SB),NOSPLIT,$0-16 ++#ifdef GOEXPERIMENT_regabiargs ++ LDI R16, R2 ++ LDI R17, R3 ++#else ++ STL R2, x+0(FP) ++ STL R3, y+8(FP) ++#endif ++ JMP runtime·goPanicSliceAcap(SB) ++TEXT runtime·panicSliceAcapU(SB),NOSPLIT,$0-16 ++#ifdef GOEXPERIMENT_regabiargs ++ LDI R16, R2 ++ LDI R17, R3 ++#else ++ STL R2, x+0(FP) ++ STL R3, y+8(FP) ++#endif ++ JMP runtime·goPanicSliceAcapU(SB) ++TEXT runtime·panicSliceB(SB),NOSPLIT,$0-16 ++#ifdef GOEXPERIMENT_regabiargs ++ LDI R16, R1 ++ LDI R17, R2 ++#else ++ STL R1, x+0(FP) ++ STL R2, y+8(FP) ++#endif ++ JMP runtime·goPanicSliceB(SB) ++TEXT runtime·panicSliceBU(SB),NOSPLIT,$0-16 ++#ifdef GOEXPERIMENT_regabiargs ++ LDI R16, R1 ++ LDI R17, R2 ++#else ++ STL R1, x+0(FP) ++ STL R2, y+8(FP) ++#endif ++ JMP runtime·goPanicSliceBU(SB) ++TEXT runtime·panicSlice3Alen(SB),NOSPLIT,$0-16 ++#ifdef GOEXPERIMENT_regabiargs ++ LDI R16, R3 ++ LDI R17, R4 ++#else ++ STL R3, x+0(FP) ++ STL R4, y+8(FP) ++#endif ++ JMP runtime·goPanicSlice3Alen(SB) ++TEXT runtime·panicSlice3AlenU(SB),NOSPLIT,$0-16 ++#ifdef GOEXPERIMENT_regabiargs ++ LDI R16, R3 ++ LDI R17, R4 ++#else ++ STL R3, x+0(FP) ++ STL R4, y+8(FP) ++#endif ++ JMP runtime·goPanicSlice3AlenU(SB) ++TEXT runtime·panicSlice3Acap(SB),NOSPLIT,$0-16 ++#ifdef GOEXPERIMENT_regabiargs ++ LDI R16, R3 ++ LDI R17, R4 ++#else ++ STL R3, x+0(FP) ++ STL R4, y+8(FP) ++#endif ++ JMP runtime·goPanicSlice3Acap(SB) ++TEXT runtime·panicSlice3AcapU(SB),NOSPLIT,$0-16 ++#ifdef GOEXPERIMENT_regabiargs ++ LDI R16, R3 ++ LDI R17, R4 ++#else ++ STL R3, x+0(FP) ++ STL R4, y+8(FP) ++#endif ++ JMP runtime·goPanicSlice3AcapU(SB) ++TEXT runtime·panicSlice3B(SB),NOSPLIT,$0-16 ++#ifdef GOEXPERIMENT_regabiargs ++ LDI R16, R2 ++ LDI R17, R3 ++#else ++ STL R2, x+0(FP) ++ STL R3, y+8(FP) ++#endif ++ JMP runtime·goPanicSlice3B(SB) ++TEXT runtime·panicSlice3BU(SB),NOSPLIT,$0-16 ++#ifdef GOEXPERIMENT_regabiargs ++ LDI R16, R2 ++ LDI R17, R3 ++#else ++ STL R2, x+0(FP) ++ STL R3, y+8(FP) ++#endif ++ JMP runtime·goPanicSlice3BU(SB) ++TEXT runtime·panicSlice3C(SB),NOSPLIT,$0-16 ++#ifdef GOEXPERIMENT_regabiargs ++ LDI R16, R1 ++ LDI R17, R2 ++#else ++ STL R1, x+0(FP) ++ STL R2, y+8(FP) ++#endif ++ JMP runtime·goPanicSlice3C(SB) ++TEXT runtime·panicSlice3CU(SB),NOSPLIT,$0-16 ++#ifdef GOEXPERIMENT_regabiargs ++ LDI R16, R1 ++ LDI R17, R2 ++#else ++ STL R1, x+0(FP) ++ STL R2, y+8(FP) ++#endif ++ JMP runtime·goPanicSlice3CU(SB) ++TEXT runtime·panicSliceConvert(SB),NOSPLIT,$0-16 ++#ifdef GOEXPERIMENT_regabiargs ++ LDI R16, R3 ++ LDI R17, R4 ++#else ++ STL R3, x+0(FP) ++ STL R4, y+8(FP) ++#endif ++ JMP runtime·goPanicSliceConvert(SB) ++ ++ ++TEXT runtime·memhash(SB),NOSPLIT|NOFRAME,$0-32 ++ JMP runtime·memhashFallback(SB) ++TEXT runtime·strhash(SB),NOSPLIT|NOFRAME,$0-24 ++ JMP runtime·strhashFallback(SB) ++TEXT runtime·memhash32(SB),NOSPLIT|NOFRAME,$0-24 ++ JMP runtime·memhash32Fallback(SB) ++TEXT runtime·memhash64(SB),NOSPLIT|NOFRAME,$0-24 ++ JMP runtime·memhash64Fallback(SB) +diff --git a/src/runtime/atomic_sw64.s b/src/runtime/atomic_sw64.s +new file mode 100644 +index 0000000000..02698b990e +--- /dev/null ++++ b/src/runtime/atomic_sw64.s +@@ -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 sw64 ++// +build sw64 ++ ++#include "textflag.h" ++ ++// func publicationBarrier() ++TEXT ·publicationBarrier(SB),NOSPLIT|NOFRAME,$0-0 ++ MEMB ++ RET +diff --git a/src/runtime/cgo/asm_sw64.s b/src/runtime/cgo/asm_sw64.s +new file mode 100644 +index 0000000000..ef0c6b9fa3 +--- /dev/null ++++ b/src/runtime/cgo/asm_sw64.s +@@ -0,0 +1,80 @@ ++// 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 sw64 ++// +build sw64 ++ ++#include "textflag.h" ++ ++// Set the x_crosscall2_ptr C function pointer variable point to crosscall2. ++// It's such a pointer chain: _crosscall2_ptr -> x_crosscall2_ptr -> crosscall2 ++TEXT ·set_crosscall2(SB),NOSPLIT,$0-0 ++ LDL R16, _crosscall2_ptr(SB) ++ SYMADDR R17, $crosscall2(SB) ++ STL R17, (R16) ++ RET ++// Called by C code generated by cmd/cgo. ++// func crosscall2(fn, a unsafe.Pointer, n int32, ctxt uintptr) ++// Saves C callee-saved registers and calls cgocallback with three arguments. ++// fn is the PC of a func(a unsafe.Pointer) function. ++TEXT crosscall2(SB), NOFRAME|NOSPLIT, $0 ++ /* ++ * We still need to save all callee save register as before, and then ++ * push 3 args for fn (R16, R17, R19), skipping R18. ++ * Also note that at procedure entry in gc world, 8(SP) will be the ++ * first arg. ++ */ ++ LDI SP, $-8*23(SP) ++ ++ STL R16, (8*1)(SP) // void* ++ STL R17, (8*2)(SP) // int32 ++ STL R19, (8*3)(SP) // uintptr ++ ++ STL R9, (8*4)(SP) ++ STL R10, (8*5)(SP) ++ STL R11, (8*6)(SP) ++ STL R12, (8*7)(SP) ++ STL R13, (8*8)(SP) ++ STL R14, (8*9)(SP) ++ ++ STL RSB, (8*12)(SP) ++ STL g, (8*13)(SP) ++ STL R26, (8*14)(SP) ++ ++ FSTD F2, (8*15)(SP) ++ FSTD F3, (8*16)(SP) ++ FSTD F4, (8*17)(SP) ++ FSTD F5, (8*18)(SP) ++ FSTD F6, (8*19)(SP) ++ FSTD F7, (8*20)(SP) ++ FSTD F8, (8*21)(SP) ++ FSTD F9, (8*22)(SP) ++ ++ CALL runtime·load_g(SB) ++ ++ CALL runtime·cgocallback(SB) ++ ++ LDL R9, (8*4)(SP) ++ LDL R10, (8*5)(SP) ++ LDL R11, (8*6)(SP) ++ LDL R12, (8*7)(SP) ++ LDL R13, (8*8)(SP) ++ LDL R14, (8*9)(SP) ++ ++ LDL RSB, (8*12)(SP) ++ LDL g, (8*13)(SP) ++ LDL R26, (8*14)(SP) ++ ++ FLDD F2, (8*15)(SP) ++ FLDD F3, (8*16)(SP) ++ FLDD F4, (8*17)(SP) ++ FLDD F5, (8*18)(SP) ++ FLDD F6, (8*19)(SP) ++ FLDD F7, (8*20)(SP) ++ FLDD F8, (8*21)(SP) ++ FLDD F9, (8*22)(SP) ++ ++ ++ LDI SP, $8*23(SP) ++ RET +diff --git a/src/runtime/cgo/gcc_linux_sw64.c b/src/runtime/cgo/gcc_linux_sw64.c +new file mode 100644 +index 0000000000..b0d1c97026 +--- /dev/null ++++ b/src/runtime/cgo/gcc_linux_sw64.c +@@ -0,0 +1,82 @@ ++// 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. ++ ++// +build cgo ++// +build linux ++// +build sw64 ++ ++#include ++#include ++#include ++#include ++#include ++#include "libcgo.h" ++#include "libcgo_unix.h" ++ ++static void *threadentry(void*); ++ ++void (*x_cgo_inittls)(void **tlsg, void **tlsbase); ++//void (*setg_gcc)(void*); ++static void (*setg_gcc)(void*); ++ ++void ++_cgo_sys_thread_start(ThreadStart *ts) ++{ ++ pthread_attr_t attr; ++ sigset_t ign, oset; ++ pthread_t p; ++ size_t size; ++ int err; ++ ++ sigfillset(&ign); ++ pthread_sigmask(SIG_SETMASK, &ign, &oset); ++ ++ // Not sure why the memset is necessary here, ++ // but without it, we get a bogus stack size ++ // out of pthread_attr_getstacksize. C'est la Linux. ++ memset(&attr, 0, sizeof attr); ++ pthread_attr_init(&attr); ++ size = 0; ++ pthread_attr_getstacksize(&attr, &size); ++ // Leave stacklo=0 and set stackhi=size; mstart will do the rest. ++ ts->g->stackhi = size; ++ err = _cgo_try_pthread_create(&p, &attr, threadentry, ts); ++ ++ pthread_sigmask(SIG_SETMASK, &oset, nil); ++ ++ if (err != 0) { ++ fatalf("pthread_create failed: %s", strerror(err)); ++ } ++} ++ ++extern void crosscall1(void (*fn)(void), void (*setg_gcc)(void*), void *g); ++static void* ++threadentry(void *v) ++{ ++ ThreadStart ts; ++ ++ ts = *(ThreadStart*)v; ++ free(v); ++ ++ assert(setg_gcc != 0); ++ crosscall1(ts.fn, setg_gcc, (void*)ts.g); ++ return nil; ++} ++ ++void ++x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase) ++{ ++ pthread_attr_t attr; ++ size_t size; ++ ++ setg_gcc = setg; ++ pthread_attr_init(&attr); ++ pthread_attr_getstacksize(&attr, &size); ++ g->stacklo = (uintptr)&attr - size + 4096; ++ pthread_attr_destroy(&attr); ++ ++ if (x_cgo_inittls) { ++ x_cgo_inittls(tlsg, tlsbase); ++ } ++} +diff --git a/src/runtime/cgo/gcc_sw64.S b/src/runtime/cgo/gcc_sw64.S +new file mode 100644 +index 0000000000..3fcff96072 +--- /dev/null ++++ b/src/runtime/cgo/gcc_sw64.S +@@ -0,0 +1,106 @@ ++// 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. ++ ++// +build sw64 ++ ++#include ++/* ++ * void crosscall1(void (*fn)(void), void (*setg_gcc)(void *g), void *g) ++ * ++ * Calling into the gc tool chain, where all registers are caller save. ++ * Called from standard SW_64 ABI, where $9-$14, are callee-save, ++ * so they must be saved explicitly, along with $26 (RA). ++ */ ++ ++#if defined(__sw_64_sw6__) ++ #define LDD ldt ++ #define STD stt ++ #define CALL jsr ++#else ++ #define LDD fldd ++ #define STD fstd ++ #define CALL call ++#endif ++ ++ .set noat ++ .align 2 ++ .globl crosscall1 ++ .ent crosscall1 ++crosscall1: ++ ++ .frame fp, 16, ra, 0 ++ .cfi_startproc ++ ldi sp, -160(sp) ++ .cfi_def_cfa_offset 160 ++ ++ stl $26, 0(sp) ++ stl $15, 56(sp) ++ stl $29, 64(sp) ++ .cfi_offset 26, -16 ++ .cfi_offset 15, -56 ++ bis $31,$30,$15 ++ .cfi_def_cfa_register 15 ++ ++ stl $9, 8(sp) ++ stl $10, 16(sp) ++ stl $11, 24(sp) ++ stl $12, 32(sp) ++ stl $13, 40(sp) ++ stl $14, 48(sp) ++ ++ STD $f2, 88 (sp) ++ STD $f3, 96 (sp) ++ STD $f4, 104(sp) ++ STD $f5, 112(sp) ++ STD $f6, 120(sp) ++ STD $f7, 128(sp) ++ STD $f8, 136(sp) ++ STD $f9, 144(sp) ++ ++ #a0=fn, a1=setg_gcc, a2=g ++ stl a0, 72(sp) ++ ++ ldi $27, 0(a1) ++ ldi a0, 0(a2) ++ ldi a1, 0(zero) ++ ldi a2, 0(zero) ++ CALL $26, ($27), 0 #call setg_gcc (clobbers A0 ?) ++ ++ ldl $27, 72(sp) ++ ldi a0, 0(zero) ++ ldi a1, 0(zero) ++ ldi a2, 0(zero) ++ CALL $26, ($27), 0 #call fn ++ ++ ldl $9, 8(sp) ++ ldl $10, 16(sp) ++ ldl $11, 24(sp) ++ ldl $12, 32(sp) ++ ldl $13, 40(sp) ++ ldl $14, 48(sp) ++ ++ ldl $15, 56(sp) ++ .cfi_restore 15 ++ ++ LDD $f2, 88 (sp) ++ LDD $f3, 96 (sp) ++ LDD $f4, 104(sp) ++ LDD $f5, 112(sp) ++ LDD $f6, 120(sp) ++ LDD $f7, 128(sp) ++ LDD $f8, 136(sp) ++ LDD $f9, 144(sp) ++ ++ ldl $29, 64(sp) ++ ++ ldl $26, 0(sp) ++ .cfi_restore 26 ++ ++ ldi sp, 160(sp) ++ .cfi_def_cfa 30, 0 ++ ++ ret $31,($26),1 ++ .cfi_endproc ++ ++ .end crosscall1 +diff --git a/src/runtime/cpuflags_sw64.go b/src/runtime/cpuflags_sw64.go +new file mode 100644 +index 0000000000..cd73712628 +--- /dev/null ++++ b/src/runtime/cpuflags_sw64.go +@@ -0,0 +1,17 @@ ++// 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 runtime ++ ++import ( ++ "internal/cpu" ++) ++ ++var sw64UseSIMDLoads bool ++ ++func init() { ++ if cpu.SW64.IsCore4 { ++ sw64UseSIMDLoads = true ++ } ++} +diff --git a/src/runtime/cputicks.go b/src/runtime/cputicks.go +index 2cf3240333..9ffed61b4e 100644 +--- a/src/runtime/cputicks.go ++++ b/src/runtime/cputicks.go +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build !arm && !arm64 && !mips64 && !mips64le && !mips && !mipsle && !wasm ++//go:build !arm && !arm64 && !mips64 && !mips64le && !mips && !mipsle && !wasm && !sw64 + + package runtime + +diff --git a/src/runtime/defs_linux_amd64.h b/src/runtime/defs_linux_amd64.h +new file mode 100644 +index 0000000000..e69de29bb2 +diff --git a/src/runtime/defs_linux_sw64.go b/src/runtime/defs_linux_sw64.go +new file mode 100644 +index 0000000000..b2d10bf198 +--- /dev/null ++++ b/src/runtime/defs_linux_sw64.go +@@ -0,0 +1,227 @@ ++// Generated using cgo, then manually converted into appropriate naming and code ++// for the Go runtime. ++// go tool cgo -godefs defs_linux.go defs1_linux.go defs2_linux.go ++ ++package runtime ++ ++import "unsafe" ++ ++const ( ++ _EINTR = 0x4 ++ _EAGAIN = 0x23 ++ _ENOMEM = 0xc ++ _ENOSYS = 0x59 ++ ++ _PROT_NONE = 0x0 ++ _PROT_READ = 0x1 ++ _PROT_WRITE = 0x2 ++ _PROT_EXEC = 0x4 ++ ++ _MAP_ANON = 0x10 ++ _MAP_PRIVATE = 0x2 ++ _MAP_FIXED = 0x100 ++ ++ _MADV_DONTNEED = 0x6 ++ _MADV_FREE = 0x8 ++ _MADV_HUGEPAGE = 0xe ++ _MADV_NOHUGEPAGE = 0xf ++ //TODO: support since linux 6.1 ++ _MADV_COLLAPSE = 0x19 ++ ++ _SA_ONSTACK = 0x1 ++ _SA_RESTART = 0x2 ++ _SA_SIGINFO = 0x40 ++ ++ _SI_KERNEL = 0x80 ++ _SI_TIMER = -0x2 ++ ++ _SIGHUP = 0x1 ++ _SIGINT = 0x2 ++ _SIGQUIT = 0x3 ++ _SIGILL = 0x4 ++ _SIGTRAP = 0x5 ++ _SIGABRT = 0x6 ++ _SIGEMT = 0x7 ++ _SIGFPE = 0x8 ++ _SIGKILL = 0x9 ++ _SIGBUS = 0xa ++ _SIGSEGV = 0xb ++ _SIGSYS = 0xc ++ _SIGPIPE = 0xd ++ _SIGALRM = 0xe ++ _SIGTERM = 0xf ++ _SIGURG = 0x10 ++ _SIGSTOP = 0x11 ++ _SIGTSTP = 0x12 ++ _SIGCONT = 0x13 ++ _SIGCHLD = 0x14 ++ _SIGTTIN = 0x15 ++ _SIGTTOU = 0x16 ++ _SIGIO = 0x17 ++ _SIGXCPU = 0x18 ++ _SIGXFSZ = 0x19 ++ _SIGVTALRM = 0x1a ++ _SIGPROF = 0x1b ++ _SIGWINCH = 0x1c ++ _SIGINFO = 0x1d ++ _SIGUSR1 = 0x1e ++ _SIGUSR2 = 0x1f ++ ++ _SIGRTMIN = 0x20 ++ ++ _FPE_INTDIV = 0x1 ++ _FPE_INTOVF = 0x2 ++ _FPE_FLTDIV = 0x3 ++ _FPE_FLTOVF = 0x4 ++ _FPE_FLTUND = 0x5 ++ _FPE_FLTRES = 0x6 ++ _FPE_FLTINV = 0x7 ++ _FPE_FLTSUB = 0x8 ++ ++ _BUS_ADRALN = 0x1 ++ _BUS_ADRERR = 0x2 ++ _BUS_OBJERR = 0x3 ++ ++ _SEGV_MAPERR = 0x1 ++ _SEGV_ACCERR = 0x2 ++ ++ _ITIMER_REAL = 0x0 ++ _ITIMER_VIRTUAL = 0x1 ++ _ITIMER_PROF = 0x2 ++ ++ _CLOCK_THREAD_CPUTIME_ID = 0x3 ++ ++ _SIGEV_THREAD_ID = 0x4 ++) ++ ++type usigset struct { ++ __val [16]uint64 ++} ++ ++type timespec struct { ++ tv_sec int64 ++ tv_nsec int64 ++} ++ ++//go:nosplit ++func (ts *timespec) setNsec(ns int64) { ++ ts.tv_sec = ns / 1e9 ++ ts.tv_nsec = ns % 1e9 ++} ++ ++/* ++func (ts *timespec) set_sec(x int64) { ++ ts.tv_sec = x ++} ++ ++func (ts *timespec) set_nsec(x int32) { ++ ts.tv_nsec = int64(x) ++} ++*/ ++type timeval struct { ++ tv_sec int64 ++ tv_usec int64 ++} ++ ++func (tv *timeval) set_usec(x int32) { ++ tv.tv_usec = int64(x) ++} ++ ++type sigactiont struct { ++ sa_handler uintptr ++ sa_flags int32 ++ sa_mask [1]uint64 ++ ++ sa_restorer uintptr //noused ++} ++ ++type siginfoFields struct { ++ si_signo int32 ++ si_errno int32 ++ si_code int32 ++ _pad_cgo_0 [4]byte ++ ++ si_addr uint64 ++// _X_sifields [128 - 8*3]byte ++} ++ ++type siginfo struct { ++ siginfoFields ++ ++ // Pad struct to the max size in the kernel. ++ _ [_si_max_size - unsafe.Sizeof(siginfoFields{})]byte ++} ++ ++type itimerspec struct { ++ it_interval timespec ++ it_value timespec ++} ++ ++type itimerval struct { ++ it_interval timeval ++ it_value timeval ++} ++ ++type sigeventFields struct { ++ value uintptr ++ signo int32 ++ notify int32 ++ // below here is a union; sigev_notify_thread_id is the only field we use ++ sigev_notify_thread_id int32 ++} ++ ++type sigevent struct { ++ sigeventFields ++ ++ // Pad struct to the max size in the kernel. ++ _ [_sigev_max_size - unsafe.Sizeof(sigeventFields{})]byte ++} ++ ++const ( ++ _O_RDONLY = 0x0 ++ _O_WRONLY = 0x1 ++ _O_CREAT = 0x200 ++ _O_TRUNC = 0x400 ++ _O_NONBLOCK = 0x4 ++ _O_CLOEXEC = 0x200000 ++ _SA_RESTORER = 0 //don't set this ++) ++ ++type stackt struct { ++ ss_sp *byte ++ ss_flags int32 ++ _pad_cgo_0 [4]byte ++ ss_size uintptr ++} ++ ++type sigcontext struct { ++ sc_onstack uint64 ++ sc_mask uint64 ++ sc_pc uint64 ++ sc_ps uint64 ++ sc_regs [32]uint64 ++ sc_ownedfp int64 ++ sc_fpregs [128]int64 // if not defined CONFIG_SW_SMID ++ ++ sc_fpcr uint64 ++ sc_fp_control uint64 ++ sc_reserved1 uint64 ++ sc_reserved2 uint64 ++ sc_ssize uint64 ++ sc_sbase *int8 ++ sc_traparg_a0 uint64 ++ sc_traparg_a1 uint64 ++ sc_traparg_a2 uint64 ++ sc_fp_trap_pc uint64 ++ sc_fp_trigger_sum uint64 ++ sc_fp_trigger_inst uint64 ++} ++ ++type ucontext struct { ++ uc_flags uint64 ++ uc_link *ucontext ++ __uc_osf_sigmask uint64 ++ uc_stack stackt ++ uc_mcontext sigcontext ++ uc_sigmask usigset ++} +diff --git a/src/runtime/duff_sw64.s b/src/runtime/duff_sw64.s +new file mode 100644 +index 0000000000..16a4fbf7d5 +--- /dev/null ++++ b/src/runtime/duff_sw64.s +@@ -0,0 +1,909 @@ ++// Code generated by mkduff.go; DO NOT EDIT. ++// Run go generate from src/runtime to update. ++// See mkduff.go for comments. ++ ++//go:build sw64 ++ ++#include "textflag.h" ++ ++TEXT runtime·duffzero(SB), NOSPLIT|NOFRAME, $0-0 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ STL R31, 8(R1) ++ ADDL R1, $8, R1 ++ RET ++ ++TEXT runtime·duffcopy(SB), NOSPLIT|NOFRAME, $0-0 ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ LDL R28, (R1) ++ ADDL R1, $8, R1 ++ STL R28, (R2) ++ ADDL R2, $8, R2 ++ ++ RET +diff --git a/src/runtime/gcinfo_test.go b/src/runtime/gcinfo_test.go +index 02457f682e..8caccc7bb6 100644 +--- a/src/runtime/gcinfo_test.go ++++ b/src/runtime/gcinfo_test.go +@@ -164,7 +164,7 @@ func infoBigStruct() []byte { + typeScalar, typeScalar, typeScalar, typeScalar, // t int; y uint16; u uint64 + typePointer, typeScalar, // i string + } +- case "arm64", "amd64", "loong64", "mips64", "mips64le", "ppc64", "ppc64le", "riscv64", "s390x", "wasm": ++ case "arm64", "amd64", "loong64", "mips64", "mips64le", "ppc64", "ppc64le", "riscv64", "s390x", "wasm", "sw64": + return []byte{ + typePointer, // q *int + typeScalar, typeScalar, typeScalar, // w byte; e [17]byte +diff --git a/src/runtime/hash64.go b/src/runtime/hash64.go +index 124bb7d77a..c481ec7580 100644 +--- a/src/runtime/hash64.go ++++ b/src/runtime/hash64.go +@@ -5,7 +5,7 @@ + // Hashing algorithm inspired by + // wyhash: https://github.com/wangyi-fudan/wyhash + +-//go:build amd64 || arm64 || loong64 || mips64 || mips64le || ppc64 || ppc64le || riscv64 || s390x || wasm ++//go:build amd64 || arm64 || loong64 || mips64 || mips64le || ppc64 || ppc64le || riscv64 || s390x || wasm || sw64 + + package runtime + +diff --git a/src/runtime/malloc.go b/src/runtime/malloc.go +index 73d663f7f5..e15d862bc3 100644 +--- a/src/runtime/malloc.go ++++ b/src/runtime/malloc.go +@@ -530,6 +530,8 @@ func mallocinit() { + p = uintptr(i)<<40 | uintptrMask&(0x0013<<28) + case GOARCH == "arm64": + p = uintptr(i)<<40 | uintptrMask&(0x0040<<32) ++ case GOARCH == "sw64": ++ p = uintptr(i)<<34 | uintptrMask&(0xc0<<28) + case GOOS == "aix": + if i == 0 { + // We don't use addresses directly after 0x0A00000000000000 +diff --git a/src/runtime/memclr_sw64.s b/src/runtime/memclr_sw64.s +new file mode 100644 +index 0000000000..91b8878d38 +--- /dev/null ++++ b/src/runtime/memclr_sw64.s +@@ -0,0 +1,49 @@ ++// 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 sw64 ++// +build sw64 ++ ++#include "textflag.h" ++ ++// func memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr) ++TEXT runtime·memclrNoHeapPointers(SB),NOSPLIT,$0-16 ++#ifndef GOEXPERIMENT_regabiargs ++ LDL R16, ptr+0(FP) ++ LDL R17, n+8(FP) ++#endif ++ ADDL R16, R17, R4 ++ ++ // if less than 8 bytes, do one byte at a time ++ CMPULT R17, $8, R3 ++ BNE R3, out ++ ++ // do one byte at a time until 8-aligned ++ AND R16, $7, R3 ++ BEQ R3, words ++ ++ STB R31, (R16) ++ ADDL R16, $1, R16 ++ JMP -4(PC) ++ ++words: ++ // do 8 bytes at a time if there is room ++ ADDL R4, $-7, R17 ++ ++ CMPULE R17, R16, R3 ++ BNE R3, out ++ ++ STL R31, (R16) ++ ADDL R16, $8, R16 ++ JMP -4(PC) ++ ++out: ++ CMPEQ R16, R4, R3 ++ BNE R3, done ++ ++ STB R31, (R16) ++ ADDL R16, $1, R16 ++ JMP -4(PC) ++done: ++ RET +diff --git a/src/runtime/memmove_sw64.s b/src/runtime/memmove_sw64.s +new file mode 100644 +index 0000000000..3ed30490e6 +--- /dev/null ++++ b/src/runtime/memmove_sw64.s +@@ -0,0 +1,114 @@ ++// 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 sw64 ++// +build sw64 ++ ++#include "textflag.h" ++ ++// func memmove(to, from unsafe.Pointer, n uintptr) ++TEXT runtime·memmove(SB), NOFRAME|NOSPLIT, $0-24 ++#ifndef GOEXPERIMENT_regabiargs ++ LDL R16, to+0(FP) ++ LDL R17, from+8(FP) ++ LDL R18, n+16(FP) ++#endif ++ BNE R18, check ++ RET ++ ++check: ++ CMPULE R16,R17,R4 ++ BEQ R4,backward ++ ++ ADDL R16,R18,R6 // end pointer ++ ++ // if the two pointers are not of same alignments, do byte copying ++ SUBL R16,R17,R4 ++ AND R4,$7,R4 ++ BNE R4, out ++ ++ // if less than 8 bytes, do byte copying ++ CMPULT R18,$8,R4 ++ BNE R4,out ++ // do one byte at a time until 8-aligned ++ AND R16,$7,R5 ++ BEQ R5,words ++ LDBU R3, (R17) ++ ADDL R17, $1, R17 ++ ++ STB R3, (R16) ++ ADDL R16,$1,R16 ++ JMP -6(PC) ++ ++words: ++ // do 8 bytes at a time if there is room ++ SUBL R6,$7,R7 ++ CMPULE R7,R16,R8 ++ BNE R8,out ++ LDL R3,(R17) ++ ADDL R17,$8,R17 ++ ++ STL R3,(R16) ++ ADDL R16,$8,R16 ++ JMP -6(PC) ++ ++out: ++ CMPEQ R16,R6,R8 ++ BNE R8,done ++ LDBU R3, (R17) ++ ADDL R17, $1, R17 ++ ++ STB R3, (R16) ++ ADDL R16,$1,R16 ++ JMP -6(PC) ++ ++done: ++ RET ++ ++backward: ++ ADDL R17,R18,R4 // from-end pointer ++ ADDL R16,R18,R5 // to-end pointer ++ ++ // if the two pointers are not of same alignments, do byte copying ++ SUBL R4,R5,R7 ++ AND R7,$7,R7 ++ BNE R7,out1 ++ ++ // if less than 8 bytes, do byte copying ++ CMPULT R18,$8,R7 ++ BNE R7,out1 ++ ++ // do one byte at a time until 8-aligned ++ AND R5,$7,R6 ++ BEQ R6,words1 ++ SUBL R4,$1,R4 ++ LDBU R3, (R4) ++ SUBL R5,$1,R5 ++ STB R3,(R5) ++ JMP -6(PC) ++ ++words1: ++ // do 8 bytes at a time if there is room ++ ADDL R16,$7,R3 ++ ++ CMPULE R5,R3,R7 ++ BNE R7,out1 ++ SUBL R4,$8,R4 ++ LDL R7,(R4) ++ SUBL R5,$8,R5 ++ STL R7,(R5) ++ JMP -6(PC) ++ ++ ++out1: ++ CMPEQ R16,R5,R7 ++ BNE R7,done1 ++ SUBL R4,$1,R4 ++ LDBU R3, (R4) ++ SUBL R5,$1,R5 ++ STB R3,(R5) ++ JMP -6(PC) ++ ++done1: ++ RET +diff --git a/src/runtime/mkduff.go b/src/runtime/mkduff.go +index b7f07b5087..bda6bfd187 100644 +--- a/src/runtime/mkduff.go ++++ b/src/runtime/mkduff.go +@@ -3,6 +3,7 @@ + // license that can be found in the LICENSE file. + + //go:build ignore ++// +build ignore + + // runtime·duffzero is a Duff's device for zeroing memory. + // The compiler jumps to computed addresses within +@@ -40,6 +41,7 @@ func main() { + gen("ppc64x", tagsPPC64x, zeroPPC64x, copyPPC64x) + gen("mips64x", tagsMIPS64x, zeroMIPS64x, copyMIPS64x) + gen("riscv64", notags, zeroRISCV64, copyRISCV64) ++ gen("sw64", tagsSW64, zeroSW64, copySW64) + } + + func gen(arch string, tags, zero, copy func(io.Writer)) { +@@ -284,3 +286,33 @@ func copyRISCV64(w io.Writer) { + } + fmt.Fprintln(w, "\tRET") + } ++ ++func tagsSW64(w io.Writer) { ++ fmt.Fprintln(w) ++ fmt.Fprintln(w, "//go:build sw64") ++ fmt.Fprintln(w) ++} ++ ++func zeroSW64(w io.Writer) { ++ // R31: always zero ++ // R28 (REGTMP): ptr to memory to be zeroed - 8 ++ // On return, R1 points to the last zeroed dword. ++ fmt.Fprintln(w, "TEXT runtime·duffzero(SB), NOSPLIT|NOFRAME, $0-0") ++ for i := 0; i < 128; i++ { ++ fmt.Fprintln(w, "\tSTL\tR31, 8(R1)") ++ fmt.Fprintln(w, "\tADDL\tR1, $8, R1") ++ } ++ fmt.Fprintln(w, "\tRET") ++} ++ ++func copySW64(w io.Writer) { ++ fmt.Fprintln(w, "TEXT runtime·duffcopy(SB), NOSPLIT|NOFRAME, $0-0") ++ for i := 0; i < 128; i++ { ++ fmt.Fprintln(w, "\tLDL\tR28, (R1)") ++ fmt.Fprintln(w, "\tADDL\tR1, $8, R1") ++ fmt.Fprintln(w, "\tSTL\tR28, (R2)") ++ fmt.Fprintln(w, "\tADDL\tR2, $8, R2") ++ fmt.Fprintln(w) ++ } ++ fmt.Fprintln(w, "\tRET") ++} +diff --git a/src/runtime/mkpreempt.go b/src/runtime/mkpreempt.go +index 08500a90d5..49a72bc1ac 100644 +--- a/src/runtime/mkpreempt.go ++++ b/src/runtime/mkpreempt.go +@@ -86,6 +86,7 @@ var arches = map[string]func(){ + "ppc64x": genPPC64, + "riscv64": genRISCV64, + "s390x": genS390X, ++ "sw64": genSW64, + "wasm": genWasm, + } + var beLe = map[string]bool{"mips64x": true, "mipsx": true, "ppc64x": true} +@@ -606,6 +607,53 @@ func genS390X() { + p("JMP (R10)") + } + ++func genSW64() { ++ regsize := 8 ++ r29 := "RSB" ++ // Add integer registers R0-R14, R16-R25, R27, R29(RSB) ++ // R31 (zero), R28 (REGTMP), R30 (SP), R15 (g), R26 (LR) are special, ++ // and not saved here. ++ var l = layout{sp: "SP", stack: regsize} // add slot to save PC of interrupted instruction (in LR) ++ for i := 0; i <= 27; i++ { ++ if i == 15 || i == 26 { ++ continue // R15 is g, R26 is LR, R28 is REGTMP ++ } ++ reg := fmt.Sprintf("R%d", i) ++ l.addSpecial( ++ "STL " + reg + ", %d(SP)", ++ "LDL " + reg + ", %d(SP)", ++ regsize) ++ } ++ l.addSpecial( ++ "STL " + r29 + ", %d(SP)", ++ "LDL " + r29 + ", %d(SP)", ++ regsize) ++ ++ // Add floating point registers F0-F31. ++ var lfp = layout{sp: "SP", stack: l.stack} ++ for i := 0; i <= 31; i++ { ++ reg := fmt.Sprintf("F%d", i) ++ lfp.addSpecial( ++ "FSTD " + reg + ", %d(SP)", ++ "FLDD " + reg + ", %d(SP)", ++ regsize) ++ } ++ // allocate frame, save PC of interrupted instruction (in LR) ++ p("STL R26,-%d(SP)", lfp.stack) ++ p("LDI SP, -%d(SP)", lfp.stack) ++ ++ l.save() ++ lfp.save() ++ p("CALL ·asyncPreempt2(SB)") ++ lfp.restore() ++ l.restore() ++ ++ p("LDL R26, %d(SP)", lfp.stack) // sigctxt.pushCall has pushed LR (at interrupt) on stack, restore it ++ p("LDL R28, 0(SP)") // load PC to REGTMP ++ p("LDI SP, %d(SP)", lfp.stack+regsize) // pop frame (including the space pushed by sigctxt.pushCall) ++ p("JMP (R28)") ++} ++ + func genWasm() { + p("// No async preemption on wasm") + p("UNDEF") +diff --git a/src/runtime/mpagealloc_64bit.go b/src/runtime/mpagealloc_64bit.go +index 36cd222360..504d4eaf9e 100644 +--- a/src/runtime/mpagealloc_64bit.go ++++ b/src/runtime/mpagealloc_64bit.go +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build amd64 || arm64 || loong64 || mips64 || mips64le || ppc64 || ppc64le || riscv64 || s390x ++//go:build amd64 || arm64 || loong64 || mips64 || mips64le || ppc64 || ppc64le || riscv64 || s390x || sw64 + + package runtime + +diff --git a/src/runtime/os_linux_generic.go b/src/runtime/os_linux_generic.go +index 15fafc14ea..35d44f0897 100644 +--- a/src/runtime/os_linux_generic.go ++++ b/src/runtime/os_linux_generic.go +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build !mips && !mipsle && !mips64 && !mips64le && !s390x && !ppc64 && linux ++//go:build !mips && !mipsle && !mips64 && !mips64le && !s390x && !ppc64 && !sw64 && linux + + package runtime + +diff --git a/src/runtime/os_linux_noauxv.go b/src/runtime/os_linux_noauxv.go +index ff377277aa..8594e25512 100644 +--- a/src/runtime/os_linux_noauxv.go ++++ b/src/runtime/os_linux_noauxv.go +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build linux && !arm && !arm64 && !loong64 && !mips && !mipsle && !mips64 && !mips64le && !s390x && !ppc64 && !ppc64le ++//go:build linux && !arm && !arm64 && !loong64 && !mips && !mipsle && !mips64 && !mips64le && !s390x && !ppc64 && !ppc64le && !sw64 + + package runtime + +diff --git a/src/runtime/os_linux_novdso.go b/src/runtime/os_linux_novdso.go +index d7e1ea0692..9c65ef8c62 100644 +--- a/src/runtime/os_linux_novdso.go ++++ b/src/runtime/os_linux_novdso.go +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build linux && !386 && !amd64 && !arm && !arm64 && !loong64 && !mips64 && !mips64le && !ppc64 && !ppc64le && !riscv64 && !s390x ++//go:build linux && !386 && !amd64 && !arm && !arm64 && !loong64 && !mips64 && !mips64le && !ppc64 && !ppc64le && !riscv64 && !s390x && !sw64 + + package runtime + +diff --git a/src/runtime/os_linux_sw64.go b/src/runtime/os_linux_sw64.go +new file mode 100644 +index 0000000000..866dc9e2f6 +--- /dev/null ++++ b/src/runtime/os_linux_sw64.go +@@ -0,0 +1,56 @@ ++// 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 linux && sw64 ++ ++package runtime ++ ++//var randomNumber uint32 ++ ++func archauxv(tag, val uintptr) { ++ /* switch tag { ++ case _AT_RANDOM: ++ // sysargs filled in startupRandomData, but that ++ // pointer may not be word aligned, so we must treat ++ // it as a byte array. ++ randomNumber = uint32(startupRandomData[4]) | uint32(startupRandomData[5])<<8 | ++ uint32(startupRandomData[6])<<16 | uint32(startupRandomData[7])<<24 ++ }*/ ++} ++func osArchInit() {} ++ ++func cputicks() int64 { ++ // Currently cputicks() is used in blocking profiler and to seed fastrand(). ++ // nanotime() is a poor approximation of CPU ticks that is enough for the profiler. ++ // randomNumber provides better seeding of fastrand. ++ //return nanotime() + int64(randomNumber) ++ return nanotime() ++} ++ ++const ( ++ _NSIG = 64 ++ _SIG_BLOCK = 1 ++ _SIG_UNBLOCK = 2 ++ _SIG_SETMASK = 3 ++ ++ _SS_DISABLE = 2 ++) ++ ++type sigset [1]uint64 ++ ++var sigset_all = sigset{^uint64(0)} ++ ++//go:nosplit ++//go:nowritebarrierrec ++func sigaddset(mask *sigset, i int) { ++ (*mask)[(i-1)/64] |= 1 << ((uint32(i) - 1) & 63) ++} ++ ++func sigdelset(mask *sigset, i int) { ++ (*mask)[(i-1)/64] &^= 1 << ((uint32(i) - 1) & 63) ++} ++ ++func sigfillset(mask *[1]uint64) { ++ (*mask)[0] = ^uint64(0) ++} +diff --git a/src/runtime/preempt_mips64x.s b/src/runtime/preempt_mips64x.s +index 996b592ae0..99e680c39e 100644 +--- a/src/runtime/preempt_mips64x.s ++++ b/src/runtime/preempt_mips64x.s +@@ -1,7 +1,6 @@ + // Code generated by mkpreempt.go; DO NOT EDIT. + + //go:build mips64 || mips64le +- + #include "go_asm.h" + #include "textflag.h" + +diff --git a/src/runtime/preempt_mipsx.s b/src/runtime/preempt_mipsx.s +index 7b169acd99..6d808813d1 100644 +--- a/src/runtime/preempt_mipsx.s ++++ b/src/runtime/preempt_mipsx.s +@@ -1,7 +1,6 @@ + // Code generated by mkpreempt.go; DO NOT EDIT. + + //go:build mips || mipsle +- + #include "go_asm.h" + #include "textflag.h" + +diff --git a/src/runtime/preempt_ppc64x.s b/src/runtime/preempt_ppc64x.s +index 2c4d02edfe..66c33276ec 100644 +--- a/src/runtime/preempt_ppc64x.s ++++ b/src/runtime/preempt_ppc64x.s +@@ -1,7 +1,6 @@ + // Code generated by mkpreempt.go; DO NOT EDIT. + + //go:build ppc64 || ppc64le +- + #include "go_asm.h" + #include "textflag.h" + +diff --git a/src/runtime/preempt_sw64.s b/src/runtime/preempt_sw64.s +new file mode 100644 +index 0000000000..a493676ca5 +--- /dev/null ++++ b/src/runtime/preempt_sw64.s +@@ -0,0 +1,131 @@ ++// Code generated by mkpreempt.go; DO NOT EDIT. ++ ++#include "go_asm.h" ++#include "textflag.h" ++ ++TEXT ·asyncPreempt(SB),NOSPLIT|NOFRAME,$0-0 ++ STL R26,-480(SP) ++ LDI SP, -480(SP) ++ STL R0, 8(SP) ++ STL R1, 16(SP) ++ STL R2, 24(SP) ++ STL R3, 32(SP) ++ STL R4, 40(SP) ++ STL R5, 48(SP) ++ STL R6, 56(SP) ++ STL R7, 64(SP) ++ STL R8, 72(SP) ++ STL R9, 80(SP) ++ STL R10, 88(SP) ++ STL R11, 96(SP) ++ STL R12, 104(SP) ++ STL R13, 112(SP) ++ STL R14, 120(SP) ++ STL R16, 128(SP) ++ STL R17, 136(SP) ++ STL R18, 144(SP) ++ STL R19, 152(SP) ++ STL R20, 160(SP) ++ STL R21, 168(SP) ++ STL R22, 176(SP) ++ STL R23, 184(SP) ++ STL R24, 192(SP) ++ STL R25, 200(SP) ++ STL R27, 208(SP) ++ STL RSB, 216(SP) ++ FSTD F0, 224(SP) ++ FSTD F1, 232(SP) ++ FSTD F2, 240(SP) ++ FSTD F3, 248(SP) ++ FSTD F4, 256(SP) ++ FSTD F5, 264(SP) ++ FSTD F6, 272(SP) ++ FSTD F7, 280(SP) ++ FSTD F8, 288(SP) ++ FSTD F9, 296(SP) ++ FSTD F10, 304(SP) ++ FSTD F11, 312(SP) ++ FSTD F12, 320(SP) ++ FSTD F13, 328(SP) ++ FSTD F14, 336(SP) ++ FSTD F15, 344(SP) ++ FSTD F16, 352(SP) ++ FSTD F17, 360(SP) ++ FSTD F18, 368(SP) ++ FSTD F19, 376(SP) ++ FSTD F20, 384(SP) ++ FSTD F21, 392(SP) ++ FSTD F22, 400(SP) ++ FSTD F23, 408(SP) ++ FSTD F24, 416(SP) ++ FSTD F25, 424(SP) ++ FSTD F26, 432(SP) ++ FSTD F27, 440(SP) ++ FSTD F28, 448(SP) ++ FSTD F29, 456(SP) ++ FSTD F30, 464(SP) ++ FSTD F31, 472(SP) ++ CALL ·asyncPreempt2(SB) ++ FLDD F31, 472(SP) ++ FLDD F30, 464(SP) ++ FLDD F29, 456(SP) ++ FLDD F28, 448(SP) ++ FLDD F27, 440(SP) ++ FLDD F26, 432(SP) ++ FLDD F25, 424(SP) ++ FLDD F24, 416(SP) ++ FLDD F23, 408(SP) ++ FLDD F22, 400(SP) ++ FLDD F21, 392(SP) ++ FLDD F20, 384(SP) ++ FLDD F19, 376(SP) ++ FLDD F18, 368(SP) ++ FLDD F17, 360(SP) ++ FLDD F16, 352(SP) ++ FLDD F15, 344(SP) ++ FLDD F14, 336(SP) ++ FLDD F13, 328(SP) ++ FLDD F12, 320(SP) ++ FLDD F11, 312(SP) ++ FLDD F10, 304(SP) ++ FLDD F9, 296(SP) ++ FLDD F8, 288(SP) ++ FLDD F7, 280(SP) ++ FLDD F6, 272(SP) ++ FLDD F5, 264(SP) ++ FLDD F4, 256(SP) ++ FLDD F3, 248(SP) ++ FLDD F2, 240(SP) ++ FLDD F1, 232(SP) ++ FLDD F0, 224(SP) ++ LDL RSB, 216(SP) ++ LDL R27, 208(SP) ++ LDL R25, 200(SP) ++ LDL R24, 192(SP) ++ LDL R23, 184(SP) ++ LDL R22, 176(SP) ++ LDL R21, 168(SP) ++ LDL R20, 160(SP) ++ LDL R19, 152(SP) ++ LDL R18, 144(SP) ++ LDL R17, 136(SP) ++ LDL R16, 128(SP) ++ LDL R14, 120(SP) ++ LDL R13, 112(SP) ++ LDL R12, 104(SP) ++ LDL R11, 96(SP) ++ LDL R10, 88(SP) ++ LDL R9, 80(SP) ++ LDL R8, 72(SP) ++ LDL R7, 64(SP) ++ LDL R6, 56(SP) ++ LDL R5, 48(SP) ++ LDL R4, 40(SP) ++ LDL R3, 32(SP) ++ LDL R2, 24(SP) ++ LDL R1, 16(SP) ++ LDL R0, 8(SP) ++ LDL R26, 480(SP) ++ LDL R28, 0(SP) ++ LDI SP, 488(SP) ++ JMP (R28) +diff --git a/src/runtime/rand.go b/src/runtime/rand.go +index 1739e9f8f5..ba42a844be 100644 +--- a/src/runtime/rand.go ++++ b/src/runtime/rand.go +@@ -231,7 +231,7 @@ func cheaprand() uint32 { + // by the compiler should be in this list. + if goarch.IsAmd64|goarch.IsArm64|goarch.IsPpc64| + goarch.IsPpc64le|goarch.IsMips64|goarch.IsMips64le| +- goarch.IsS390x|goarch.IsRiscv64|goarch.IsLoong64 == 1 { ++ goarch.IsS390x|goarch.IsRiscv64|goarch.IsLoong64|goarch.IsSw64 == 1 { + mp.cheaprand += 0xa0761d6478bd642f + hi, lo := math.Mul64(mp.cheaprand, mp.cheaprand^0xe7037ed1a0b428db) + return uint32(hi ^ lo) +diff --git a/src/runtime/rt0_linux_sw64.s b/src/runtime/rt0_linux_sw64.s +new file mode 100644 +index 0000000000..f44ae9b0cf +--- /dev/null ++++ b/src/runtime/rt0_linux_sw64.s +@@ -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. ++ ++//go:build linux && sw64 ++// +build linux ++// +build sw64 ++ ++#include "textflag.h" ++ ++TEXT _rt0_sw64_linux(SB), NOFRAME|NOSPLIT, $0 ++ JMP _rt0_sw64(SB) ++ ++TEXT _rt0_sw64_linux_lib(SB), NOSPLIT, $0 ++ CALL _rt0_sw64_lib(SB) ++ RET +diff --git a/src/runtime/runtime_test.go b/src/runtime/runtime_test.go +index f23581acbe..8ff99bee0d 100644 +--- a/src/runtime/runtime_test.go ++++ b/src/runtime/runtime_test.go +@@ -192,6 +192,9 @@ var faultAddrs = []uint64{ + } + + func TestSetPanicOnFault(t *testing.T) { ++ if GOARCH == "sw64" { ++ t.Skip("Some machine need upgrade hmcode to 2018-9+") ++ } + old := debug.SetPanicOnFault(true) + defer debug.SetPanicOnFault(old) + +diff --git a/src/runtime/signal_linux_sw64.go b/src/runtime/signal_linux_sw64.go +new file mode 100644 +index 0000000000..74cf98eb11 +--- /dev/null ++++ b/src/runtime/signal_linux_sw64.go +@@ -0,0 +1,67 @@ ++// 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 linux && sw64 ++// +build linux,sw64 ++ ++package runtime ++ ++import ( ++ "unsafe" ++) ++ ++type sigctxt struct { ++ info *siginfo ++ ctxt unsafe.Pointer ++} ++ ++//go:nosplit ++//go:nowritebarrierrec ++func (c *sigctxt) regs() *sigcontext { return &(*ucontext)(c.ctxt).uc_mcontext } ++ ++func (c *sigctxt) r0() uint64 { return c.regs().sc_regs[0] } ++func (c *sigctxt) r1() uint64 { return c.regs().sc_regs[1] } ++func (c *sigctxt) r2() uint64 { return c.regs().sc_regs[2] } ++func (c *sigctxt) r3() uint64 { return c.regs().sc_regs[3] } ++func (c *sigctxt) r4() uint64 { return c.regs().sc_regs[4] } ++func (c *sigctxt) r5() uint64 { return c.regs().sc_regs[5] } ++func (c *sigctxt) r6() uint64 { return c.regs().sc_regs[6] } ++func (c *sigctxt) r7() uint64 { return c.regs().sc_regs[7] } ++func (c *sigctxt) r8() uint64 { return c.regs().sc_regs[8] } ++func (c *sigctxt) r9() uint64 { return c.regs().sc_regs[9] } ++func (c *sigctxt) r10() uint64 { return c.regs().sc_regs[10] } ++func (c *sigctxt) r11() uint64 { return c.regs().sc_regs[11] } ++func (c *sigctxt) r12() uint64 { return c.regs().sc_regs[12] } ++func (c *sigctxt) r13() uint64 { return c.regs().sc_regs[13] } ++func (c *sigctxt) r14() uint64 { return c.regs().sc_regs[14] } ++func (c *sigctxt) g() uint64 { return c.regs().sc_regs[15] } ++func (c *sigctxt) r16() uint64 { return c.regs().sc_regs[16] } ++func (c *sigctxt) r17() uint64 { return c.regs().sc_regs[17] } ++func (c *sigctxt) r18() uint64 { return c.regs().sc_regs[18] } ++func (c *sigctxt) r19() uint64 { return c.regs().sc_regs[19] } ++func (c *sigctxt) r20() uint64 { return c.regs().sc_regs[20] } ++func (c *sigctxt) r21() uint64 { return c.regs().sc_regs[21] } ++func (c *sigctxt) r22() uint64 { return c.regs().sc_regs[22] } ++func (c *sigctxt) r23() uint64 { return c.regs().sc_regs[23] } ++func (c *sigctxt) r24() uint64 { return c.regs().sc_regs[24] } ++func (c *sigctxt) r25() uint64 { return c.regs().sc_regs[25] } ++func (c *sigctxt) link() uint64 { return c.regs().sc_regs[26] } ++func (c *sigctxt) regctxt() uint64 { return c.regs().sc_regs[27] } ++func (c *sigctxt) rtmp() uint64 { return c.regs().sc_regs[28] } ++func (c *sigctxt) r29() uint64 { return c.regs().sc_regs[29] } ++func (c *sigctxt) sp() uint64 { return c.regs().sc_regs[30] } ++ ++func (c *sigctxt) set_sp(x uint64) { c.regs().sc_regs[30] = x } ++ ++func (c *sigctxt) sigcode() uint32 { return uint32(c.info.si_code) } ++func (c *sigctxt) sigaddr() uint64 { return c.info.si_addr } ++ ++//go:nosplit ++//go:nowritebarrierrec ++func (c *sigctxt) pc() uint64 { return c.regs().sc_pc } ++func (c *sigctxt) set_pc(x uint64) { c.regs().sc_pc = x } ++ ++func (c *sigctxt) set_link(x uint64) { c.regs().sc_regs[26] = x } ++ ++func (c *sigctxt) set_g(x uint64) { c.regs().sc_regs[15] = x } +diff --git a/src/runtime/signal_sw64.go b/src/runtime/signal_sw64.go +new file mode 100644 +index 0000000000..d2356fd57c +--- /dev/null ++++ b/src/runtime/signal_sw64.go +@@ -0,0 +1,97 @@ ++// 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 linux && sw64 ++// +build linux ++// +build sw64 ++ ++package runtime ++ ++import ( ++ "internal/abi" ++ "internal/goarch" ++ "unsafe" ++) ++ ++// snyh_TODO: FIX ALL OF THIS ++ ++func dumpregs(c *sigctxt) { ++ println("r0\t", hex(c.r0())) ++ println("r1\t", hex(c.r1())) ++ println("r2\t", hex(c.r2())) ++ println("r3\t", hex(c.r3())) ++ println("r4\t", hex(c.r4())) ++ println("r5\t", hex(c.r5())) ++ println("r6\t", hex(c.r6())) ++ println("r7\t", hex(c.r7())) ++ println("r8\t", hex(c.r8())) ++ println("r9\t", hex(c.r9())) ++ println("r10\t", hex(c.r10())) ++ println("r11\t", hex(c.r11())) ++ println("r12\t", hex(c.r12())) ++ println("r13\t", hex(c.r13())) ++ println("r14\t", hex(c.r14())) ++ println("g\t", hex(c.g())) ++ println("r16\t", hex(c.r16())) ++ println("r17\t", hex(c.r17())) ++ println("r18\t", hex(c.r18())) ++ println("r19\t", hex(c.r19())) ++ println("r20\t", hex(c.r20())) ++ println("r21\t", hex(c.r21())) ++ println("r22\t", hex(c.r22())) ++ println("r23\t", hex(c.r23())) ++ println("r24\t", hex(c.r24())) ++ println("r25\t", hex(c.r25())) ++ println("ra\t", hex(c.link())) ++ println("ctxt\t", hex(c.regctxt())) ++ println("rtmp\t", hex(c.rtmp())) ++ println("r29\t", hex(c.r29())) ++ println("sp\t", hex(c.sp())) ++} ++ ++//go:nosplit ++//go:nowritebarrierrec ++func (c *sigctxt) sigpc() uintptr { return uintptr(c.pc()) } ++ ++func (c *sigctxt) sigsp() uintptr { return uintptr(c.sp()) } ++func (c *sigctxt) siglr() uintptr { return uintptr(c.link()) } ++func (c *sigctxt) fault() uintptr { return uintptr(c.sigaddr()) } ++ ++// preparePanic sets up the stack to look like a call to sigpanic. ++func (c *sigctxt) preparePanic(sig uint32, gp *g) { ++ // We arrange link, and pc to pretend the panicking ++ // function calls sigpanic directly. ++ // Always save LINK to stack so that panics in leaf ++ // functions are correctly handled. This smashes ++ // the stack frame but we're not going back there ++ // anyway. ++ sp := c.sp() - goarch.PtrSize ++ c.set_sp(sp) ++ *(*uint64)(unsafe.Pointer(uintptr(sp))) = c.link() ++ ++ pc := gp.sigpc ++ ++ if shouldPushSigpanic(gp, pc, uintptr(c.link())) { ++ // Make it look the like faulting PC called sigpanic. ++ c.set_link(uint64(pc)) ++ } ++ // In case we are panicking from external C code ++ sigpanicPC := uint64(abi.FuncPCABIInternal(sigpanic)) ++ c.set_g(uint64(uintptr(unsafe.Pointer(gp)))) ++ c.set_pc(sigpanicPC) ++} ++ ++func (c *sigctxt) pushCall(targetPC, resumePC uintptr) { ++ // Push the LR to stack, as we'll clobber it in order to ++ // push the call. The function being pushed is responsible ++ // for restoring the LR and setting the SP back. ++ // This extra slot is known to gentraceback. ++ sp := c.sp() - 8 ++ c.set_sp(sp) ++ *(*uint64)(unsafe.Pointer(uintptr(sp))) = c.link() ++ // Set up PC and LR to pretend the function being signaled ++ // calls targetPC at the faulting PC. ++ c.set_link(uint64(resumePC)) ++ c.set_pc(uint64(targetPC)) ++} +diff --git a/src/runtime/signal_unix.go b/src/runtime/signal_unix.go +index 96628d6baa..46d53399b8 100644 +--- a/src/runtime/signal_unix.go ++++ b/src/runtime/signal_unix.go +@@ -397,7 +397,7 @@ func preemptM(mp *m) { + //go:nosplit + func sigFetchG(c *sigctxt) *g { + switch GOARCH { +- case "arm", "arm64", "loong64", "ppc64", "ppc64le", "riscv64", "s390x": ++ case "arm", "arm64", "loong64", "ppc64", "ppc64le", "riscv64", "s390x", "sw64": + if !iscgo && inVDSOPage(c.sigpc()) { + // When using cgo, we save the g on TLS and load it from there + // in sigtramp. Just use that. +diff --git a/src/runtime/sigtab_linux_generic.go b/src/runtime/sigtab_linux_generic.go +index fe93bbafb5..671d128d75 100644 +--- a/src/runtime/sigtab_linux_generic.go ++++ b/src/runtime/sigtab_linux_generic.go +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build !mips && !mipsle && !mips64 && !mips64le && linux ++//go:build !mips && !mipsle && !mips64 && !mips64le && !sw64 && linux + + package runtime + +diff --git a/src/runtime/sigtab_linux_sw64.go b/src/runtime/sigtab_linux_sw64.go +new file mode 100644 +index 0000000000..70ccfcc564 +--- /dev/null ++++ b/src/runtime/sigtab_linux_sw64.go +@@ -0,0 +1,75 @@ ++// 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. ++ ++// +build sw64 ++// +build linux ++ ++package runtime ++ ++var sigtable = [...]sigTabT{ ++ /* 0 */ {0, "SIGNONE: no trap"}, ++ /* 1 */ {_SigNotify + _SigKill, "SIGHUP: terminal line hangup"}, ++ /* 2 */ {_SigNotify + _SigKill, "SIGINT: interrupt"}, ++ /* 3 */ {_SigNotify + _SigThrow, "SIGQUIT: quit"}, ++ /* 4 */ {_SigThrow + _SigUnblock, "SIGILL: illegal instruction"}, ++ /* 5 */ {_SigThrow + _SigUnblock, "SIGTRAP: trace trap"}, ++ /* 6 */ {_SigNotify + _SigThrow, "SIGABRT: abort"}, ++ /* 7 */ {_SigThrow, "SIGEMT"}, ++ /* 8 */ {_SigPanic + _SigUnblock, "SIGFPE: floating-point exception"}, ++ /* 9 */ {0, "SIGKILL: kill"}, ++ /* 10 */ {_SigPanic + _SigUnblock, "SIGBUS: bus error"}, ++ /* 11 */ {_SigPanic + _SigUnblock, "SIGSEGV: segmentation violation"}, ++ /* 12 */ {_SigThrow, "SIGSYS: bad system call"}, ++ /* 13 */ {_SigNotify, "SIGPIPE: write to broken pipe"}, ++ /* 14 */ {_SigNotify, "SIGALRM: alarm clock"}, ++ /* 15 */ {_SigNotify + _SigKill, "SIGTERM: termination"}, ++ /* 16 */ {_SigNotify + _SigIgn, "SIGURG: urgent condition on socket"}, ++ /* 17 */ {0, "SIGSTOP: stop, unblockable"}, ++ /* 18 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTSTP: keyboard stop"}, ++ /* 19 */ {_SigNotify + _SigDefault + _SigIgn, "SIGCONT: continue"}, ++ /* 20 */ {_SigNotify + _SigUnblock + _SigIgn, "SIGCHLD: child status has changed"}, ++ /* 21 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTIN: background read from tty"}, ++ /* 22 */ {_SigNotify + _SigDefault + _SigIgn, "SIGTTOU: background write to tty"}, ++ /* 23 */ {_SigNotify, "SIGIO: i/o now possible"}, ++ /* 24 */ {_SigNotify, "SIGXCPU: cpu limit exceeded"}, ++ /* 25 */ {_SigNotify, "SIGXFSZ: file size limit exceeded"}, ++ /* 26 */ {_SigNotify, "SIGVTALRM: virtual alarm clock"}, ++ /* 27 */ {_SigNotify + _SigUnblock, "SIGPROF: profiling alarm clock"}, ++ /* 28 */ {_SigNotify + _SigIgn, "SIGWINCH: window size change"}, ++ /* 29 */ {_SigNotify, "SIGINFO: power failure restart"}, ++ /* 30 */ {_SigNotify, "SIGUSR1: user-defined signal 1"}, ++ /* 31 */ {_SigNotify, "SIGUSR2: user-defined signal 2"}, ++ /* 32 */ {_SigSetStack + _SigUnblock, "signal 32"}, /* SIGCANCEL; see issue 6997 */ ++ /* 33 */ {_SigSetStack + _SigUnblock, "signal 33"}, /* SIGSETXID; see issues 3871, 9400, 12498 */ ++ /* 34 */ {_SigNotify, "signal 34"}, ++ /* 35 */ {_SigNotify, "signal 35"}, ++ /* 36 */ {_SigNotify, "signal 36"}, ++ /* 37 */ {_SigNotify, "signal 37"}, ++ /* 38 */ {_SigNotify, "signal 38"}, ++ /* 39 */ {_SigNotify, "signal 39"}, ++ /* 40 */ {_SigNotify, "signal 40"}, ++ /* 41 */ {_SigNotify, "signal 41"}, ++ /* 42 */ {_SigNotify, "signal 42"}, ++ /* 43 */ {_SigNotify, "signal 43"}, ++ /* 44 */ {_SigNotify, "signal 44"}, ++ /* 45 */ {_SigNotify, "signal 45"}, ++ /* 46 */ {_SigNotify, "signal 46"}, ++ /* 47 */ {_SigNotify, "signal 47"}, ++ /* 48 */ {_SigNotify, "signal 48"}, ++ /* 49 */ {_SigNotify, "signal 49"}, ++ /* 50 */ {_SigNotify, "signal 50"}, ++ /* 51 */ {_SigNotify, "signal 51"}, ++ /* 52 */ {_SigNotify, "signal 52"}, ++ /* 53 */ {_SigNotify, "signal 53"}, ++ /* 54 */ {_SigNotify, "signal 54"}, ++ /* 55 */ {_SigNotify, "signal 55"}, ++ /* 56 */ {_SigNotify, "signal 56"}, ++ /* 57 */ {_SigNotify, "signal 57"}, ++ /* 58 */ {_SigNotify, "signal 58"}, ++ /* 59 */ {_SigNotify, "signal 59"}, ++ /* 60 */ {_SigNotify, "signal 60"}, ++ /* 61 */ {_SigNotify, "signal 61"}, ++ /* 62 */ {_SigNotify, "signal 62"}, ++ /* 63 */ {_SigNotify, "signal 63"}, ++} +diff --git a/src/runtime/stkframe.go b/src/runtime/stkframe.go +index 819b7f6c7d..0913666a9d 100644 +--- a/src/runtime/stkframe.go ++++ b/src/runtime/stkframe.go +@@ -234,7 +234,7 @@ func (frame *stkframe) getStackMap(debug bool) (locals, args bitvector, objs []s + } + + // stack objects. +- if (GOARCH == "amd64" || GOARCH == "arm64" || GOARCH == "loong64" || GOARCH == "ppc64" || GOARCH == "ppc64le" || GOARCH == "riscv64") && ++ if (GOARCH == "amd64" || GOARCH == "arm64" || GOARCH == "loong64" || GOARCH == "ppc64" || GOARCH == "ppc64le" || GOARCH == "riscv64" || GOARCH == "sw64") && + unsafe.Sizeof(abi.RegArgs{}) > 0 && isReflect { + // For reflect.makeFuncStub and reflect.methodValueCall, + // we need to fake the stack object record. +diff --git a/src/runtime/stubs_sw64.go b/src/runtime/stubs_sw64.go +new file mode 100644 +index 0000000000..acd58fcffd +--- /dev/null ++++ b/src/runtime/stubs_sw64.go +@@ -0,0 +1,30 @@ ++// 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 sw64 ++ ++package runtime ++ ++import "unsafe" ++ ++// Called from assembly only; declared for go vet. ++func load_g() ++func save_g() ++ ++func udiv() ++func sw_sigreturn() ++ ++//go:noescape ++func asmcgocall_no_g(fn, arg unsafe.Pointer) ++ ++// Used by reflectcall and the reflect package. ++// ++// Spills/loads arguments in registers to/from an internal/abi.RegArgs ++// respectively. Does not follow the Go ABI. ++func spillArgs() ++func unspillArgs() ++ ++// getfp returns the frame pointer register of its caller or 0 if not implemented. ++// TODO: Make this a compiler intrinsic ++func getfp() uintptr { return 0 } +diff --git a/src/runtime/sys_linux_sw64.s b/src/runtime/sys_linux_sw64.s +new file mode 100644 +index 0000000000..56293d5bbc +--- /dev/null ++++ b/src/runtime/sys_linux_sw64.s +@@ -0,0 +1,619 @@ ++// 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 "go_tls.h" ++#include "funcdata.h" ++#include "textflag.h" ++ ++#define SYS_exit 1 ++#define SYS_read 3 ++#define SYS_write 4 ++#define SYS_close 6 ++#define SYS_brk 17 ++#define SYS_getxpid 20 ++#define SYS_kill 37 ++#define SYS_pipe 42 ++#define SYS_open 45 ++#define SYS_mmap 71 ++#define SYS_munmap 73 ++#define SYS_madvise 75 ++#define SYS_sigaltstack 235 ++#define SYS_clone 312 ++#define SYS_sched_yield 334 ++#define SYS_rt_sigreturn 351 ++#define SYS_rt_sigaction 352 ++#define SYS_rt_sigprocmask 353 ++#define SYS_select 358 ++#define SYS_setitimer 362 ++#define SYS_mincore 375 ++#define SYS_gettid 378 ++#define SYS_tkill 381 ++#define SYS_futex 394 ++#define SYS_sched_getaffinity 396 ++#define SYS_exit_group 405 ++#define SYS_epoll_wait 409 ++#define SYS_clock_gettime 420 ++#define SYS_tgkill 424 ++#define SYS_pipe2 488 ++#define SYS_timer_create 414 ++#define SYS_timer_settime 415 ++#define SYS_timer_delete 418 ++ ++#define SYSCALL(n) \ ++ LDI R0, $n \ ++ SYS_CALL_B $131 ++ ++// func exit(code int32) ++TEXT runtime·exit(SB), NOFRAME|NOSPLIT, $0-4 ++ LDW R16, code+0(FP) ++ SYSCALL(SYS_exit_group) ++ RET ++ ++// func exitThread(wait *atomic.Uint32) ++TEXT runtime·exitThread(SB), NOFRAME|NOSPLIT, $0-8 ++ LDL R1, wait+0(FP) ++ MEMB ++ STW ZERO, (R1) ++ MEMB ++ ++ LDI R16, $0 ++ SYSCALL(SYS_exit) ++ JMP 0(PC) ++ ++// func write(fd uintptr, p unsafe.Pointer, n int32) int32 ++TEXT runtime·write1(SB), NOSPLIT, $0-28 ++ LDL R16, fd+0(FP) ++ LDL R17, p+8(FP) ++ LDW R18, n+16(FP) ++ SYSCALL(SYS_write) ++ BEQ R19, ok ++ SUBL ZERO, R0, R0 ++ok: ++ STW R0, ret+24(FP) ++ RET ++ ++// func read(fd int32, p unsafe.Pointer, n int32) int32 ++TEXT runtime·read(SB),NOSPLIT,$0-28 ++ LDW R16, fd+0(FP) ++ LDL R17, p+8(FP) ++ LDW R18, n+16(FP) ++ SYSCALL(SYS_read) ++ ++ BEQ R19, ok ++ SUBL ZERO, R0, R0 ++ok: ++ STW R0, ret+24(FP) ++ RET ++ ++// func open(name *byte, mode, perm int32) int32 ++TEXT runtime·open(SB), NOSPLIT, $0-20 ++ LDL R16, name+0(FP) ++ LDW R17, mode+8(FP) ++ LDW R18, perm+12(FP) ++ SYSCALL(SYS_open) ++ ++ BEQ R19, ok ++ LDI R0, -1 ++ok: ++ STW R0, ret+16(FP) ++ RET ++ ++// func closefd(fd int32) int32 ++TEXT runtime·closefd(SB), NOSPLIT, $0-12 ++ LDW R16, fd+0(FP) ++ SYSCALL(SYS_close) ++ ++ BEQ R19, ok ++ LDI R0, $-1 ++ok: ++ STW R0, ret+8(FP) ++ RET ++ ++// func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) (p unsafe.Pointer, err int) ++TEXT runtime·mmap(SB),NOSPLIT,$0-48 ++ LDL R16, addr+0(FP) ++ LDL R17, n+8(FP) ++ LDW R18, prot+16(FP) ++ LDW R19, flags+20(FP) ++ LDW R20, fd+24(FP) ++ LDW R21, off+28(FP) ++ ++ SYSCALL(SYS_mmap) ++ ++ BEQ R19, ok ++ STL ZERO, p+32(FP) ++ STL R0, err+40(FP) ++ RET ++ok: ++ STL R0, p+32(FP) ++ STL ZERO, err+40(FP) ++ RET ++ ++// func munmap(addr unsafe.Pointer, n uintptr) ++TEXT runtime·munmap(SB), NOSPLIT, $0-16 ++ LDL R16, addr+0(FP) ++ LDL R17, n+8(FP) ++ SYSCALL(SYS_munmap) ++ RET ++ ++// func mincore(addr unsafe.Pointer, n uintptr, dst *byte) int32 ++TEXT runtime·mincore(SB),NOSPLIT,$0-28 ++ LDL R16, addr+0(FP) ++ LDL R17, n+8(FP) ++ LDL R18, dst+16(FP) ++ SYSCALL(SYS_mincore) ++ SUBL ZERO, R0, R0 ++ STW R0, ret+24(FP) ++ RET ++ ++// func sched_getaffinity(pid, len uintptr, buf *byte) int32 ++TEXT runtime·sched_getaffinity(SB),NOSPLIT,$0-28 ++ LDL R16, pid+0(FP) ++ LDL R17, len+8(FP) ++ LDL R18, buf+16(FP) ++ SYSCALL(SYS_sched_getaffinity) ++ BEQ R19, ok ++ LDI R0, -1 ++ok: ++ STW R0, ret+24(FP) ++ RET ++ ++// func sbrk0() uintptr ++TEXT runtime·sbrk0(SB), NOSPLIT, $0-8 ++ // Implemented as brk(NULL). ++ LDI R16, $0 ++ SYSCALL(SYS_brk) ++ BEQ R19, ok ++ SUBL ZERO, R0, R0 ++ok: ++ STL R0, ret+0(FP) ++ RET ++ ++TEXT runtime·osyield(SB), NOFRAME|NOSPLIT, $0 ++ SYSCALL(SYS_sched_yield) ++ RET ++ ++TEXT runtime·nanotime1(SB), NOSPLIT, $16-8 ++ LDI R9, R30 // R9 is unchanged by C code ++ LDI R1, R30 ++ ++ LDL R10, g_m(g) // R10 = m ++ ++ // Save the old values on stack and restore them on exit. ++ // so this function is reentrant. ++ LDL R16, m_vdsoPC(R10) ++ LDL R17, m_vdsoSP(R10) ++ STL R16, 8(R30) ++ STL R17, 16(R30) ++ ++ LDL R16, $ret-8(FP) ++ // Set vdsoPC and vdsoSP for SIGPROF traceback. ++ STL R26, m_vdsoPC(R10) ++ STL R16, m_vdsoSP(R10) ++ ++ LDL R16, m_curg(R10) ++ LDI R17, g ++ CMPEQ R16, R17, R7 ++ BEQ R7, noswitch ++ ++ LDL R16, m_g0(R10) ++ LDL R1, (g_sched+gobuf_sp)(R16) // Set SP to g0 stack ++ ++noswitch: ++ SUBL R1, $16, R1 ++ AND R1, $~15, R1 // Align for C code ++ LDI R30, R1 ++ ++ LDI R16, $1 // CLOCK_MONOTONIC ++ LDI R17, $0(R30) ++ ++ LDL R27, runtime·vdsoClockgettimeSym(SB) ++ BEQ R27, fallback ++ ++ // Store g on gsignal's stack, so if we receive a signal ++ // during VDSO code we can find the g. ++ // If we don't have a signal stack, we won't receive signal, ++ // so don't bother saving g. ++ // When using cgo, we already saved g on TLS, also don't save ++ // g here. ++ // Also don't save g if we are already on the signal stack. ++ // We won't get a nested signal. ++ LDBU R11, runtime·iscgo(SB) //R11 doesn't change by C code ++ BNE R11, nosaveg ++ LDL R11, m_gsignal(R10) ++ BEQ R11, nosaveg ++ ++ CMPEQ g, R11, R28 ++ BNE R28, nosaveg ++ LDL R11, (g_stack+stack_lo)(R11) ++ STL g, (R11) ++ ++ CALL R26, (R27) ++ STL R31, 0(R11) // clear g slot ++ ++finish: ++ LDL R0, 0(R30) // sec ++ LDL R17, 8(R30) // nsec ++ ++ LDI R30, R9 // restore SP ++ // Restore vdsoPC, vdsoSP ++ // We don't worry about being signaled between the two stores. ++ // If we are not in a signal handler, we'll restore vdsoSP to 0, ++ // and no one will care about vdsoPC. If we are in a signal handler, ++ // we cannot receive another signal. ++ LDL R1, 16(R30) ++ STL R1, m_vdsoSP(R10) ++ LDL R1, 8(R30) ++ STL R1, m_vdsoPC(R10) ++ ++ // sec is in R3, nsec in R5 ++ // return nsec in R3 ++ LDI R16, $1000000000 ++ MULL R0, R16, R0 ++ ADDL R0, R17, R0 ++ STL R0, ret+0(FP) ++ RET ++ ++nosaveg: ++ CALL R26, (R27) ++ JMP finish ++ ++fallback: ++ SYSCALL(SYS_clock_gettime) ++ JMP finish ++ ++TEXT runtime·usleep(SB),NOSPLIT,$16-4 ++ LDW R1, usec+0(FP) ++ LDI R0, $1000000 ++ CALL runtime·udiv(SB) ++ STL R0, 8(SP) ++ STL R1, 16(SP) ++ ++ // select(0, 0, 0, 0, &tv) ++ LDI R16, $0 ++ LDI R17, $0 ++ LDI R18, $0 ++ LDI R19, $0 ++ LDI R20, $8(SP) ++ SYSCALL(SYS_select) ++ RET ++ ++TEXT runtime·walltime(SB), NOSPLIT, $16-12 ++ LDI R9, R30 // R9 is unchanged by C code ++ LDI R1, R30 ++ ++ LDL R10, g_m(g) // R10 = m ++ ++ // Save the old values on stack and restore them on exit. ++ // so this function is reentrant. ++ LDL R16, m_vdsoPC(R10) ++ LDL R17, m_vdsoSP(R10) ++ STL R16, 8(R30) ++ STL R17, 16(R30) ++ ++ LDL R16, $ret-8(FP) ++ // Set vdsoPC and vdsoSP for SIGPROF traceback. ++ STL R26, m_vdsoPC(R10) ++ STL R16, m_vdsoSP(R10) ++ ++ LDL R16, m_curg(R10) ++ LDI R17, g ++ CMPEQ R16, R17, R7 ++ BEQ R7, noswitch ++ ++ LDL R16, m_g0(R10) ++ LDL R1, (g_sched+gobuf_sp)(R16) // Set SP to g0 stack ++ ++noswitch: ++ SUBL R1, $16, R1 ++ AND R1, $~15, R1 // Align for C code ++ LDI R30, R1 ++ ++ LDI R16, $0 // CLOCK_MONOTONIC ++ LDI R17, $0(R30) ++ ++ LDL R27, runtime·vdsoClockgettimeSym(SB) ++ BEQ R27, fallback ++ ++ // Store g on gsignal's stack, so if we receive a signal ++ // during VDSO code we can find the g. ++ // If we don't have a signal stack, we won't receive signal, ++ // so don't bother saving g. ++ // When using cgo, we already saved g on TLS, also don't save ++ // g here. ++ // Also don't save g if we are already on the signal stack. ++ // We won't get a nested signal. ++ LDBU R11, runtime·iscgo(SB) //R11 doesn't change by C code ++ BNE R11, nosaveg ++ LDL R11, m_gsignal(R10) ++ BEQ R11, nosaveg ++ ++ CMPEQ g, R11, R28 ++ BNE R28, nosaveg ++ LDL R11, (g_stack+stack_lo)(R11) ++ STL g, (R11) ++ ++ CALL R26, (R27) ++ STL R31, 0(R11) // clear g slot ++ ++finish: ++ LDL R0, 0(R30) // sec ++ LDL R17, 8(R30) // nsec ++ ++ LDI R30, R9 // restore SP ++ // Restore vdsoPC, vdsoSP ++ // We don't worry about being signaled between the two stores. ++ // If we are not in a signal handler, we'll restore vdsoSP to 0, ++ // and no one will care about vdsoPC. If we are in a signal handler, ++ // we cannot receive another signal. ++ LDL R1, 16(R30) ++ STL R1, m_vdsoSP(R10) ++ LDL R1, 8(R30) ++ STL R1, m_vdsoPC(R10) ++ ++ STL R0, sec+0(FP) ++ STW R17, nsec+8(FP) ++ RET ++ ++nosaveg: ++ CALL R26, (R27) ++ JMP finish ++ ++fallback: ++ SYSCALL(SYS_clock_gettime) ++ JMP finish ++ ++// func madvise(addr unsafe.Pointer, n uintptr, flags int32) ++TEXT runtime·madvise(SB),NOSPLIT,$0-28 ++ LDL R16, addr+0(FP) ++ LDL R17, n+8(FP) ++ LDW R18, flags+16(FP) ++ SYSCALL(SYS_madvise) ++ STW R0,ret+24(FP) ++ // ignore failure - maybe pages are locked ++ RET ++ ++// func rtsigprocmask(how int32, new, old *sigset, size int32) ++TEXT runtime·rtsigprocmask(SB), NOFRAME|NOSPLIT,$0-28 ++ LDW R16, how+0(FP) //there has 4byte pad space ++ LDL R17, new+8(FP) ++ LDL R18, old+16(FP) ++ LDW R19, size+24(FP) ++ SYSCALL(SYS_rt_sigprocmask) ++ BEQ R19, ok ++ LDL ZERO, 0xf1(ZERO) //crash ++ LDI R0, -1 ++ok: ++ RET ++ ++TEXT glibc_sigreturn<>(SB), NOFRAME|NOSPLIT, $0 ++ LDI R16, SP ++ SYSCALL(SYS_rt_sigreturn) ++ ++// func rt_sigaction(sig uintptr, new, old *sigactiont, size uintptr) int32 ++TEXT runtime·rt_sigaction(SB), NOFRAME|NOSPLIT, $0-36 ++ LDL R16, sig+0(FP) ++ LDL R17, new+8(FP) ++ LDL R18, old+16(FP) ++ LDL R19, size+24(FP) ++ SYMADDR R20, glibc_sigreturn<>(SB) ++ ++ SYSCALL(SYS_rt_sigaction) ++ ++ BEQ R19, ok ++ STW R19, ret+32(FP) ++ RET ++ok: ++ STW ZERO, ret+32(FP) ++ RET ++ ++TEXT runtime·cgoSigtramp(SB), NOFRAME|NOSPLIT, $0 ++ JMP runtime·sigtramp(SB) ++ ++// void (*sa_sigaction)(int, siginfo_t *, void *); ++TEXT runtime·sigtramp(SB), NOSPLIT|TOPFRAME, $64 ++ // initialize REGSB = PC&0xffffffff00000000 ++ // BGEZAL R0, 1(PC) ++ // SRLV $32, R31, RSB ++ // SLLV $32, RSB ++ ++ // this might be called in external code context, ++ // where g is not set. ++ LDBU R1, runtime·iscgo(SB) ++ BEQ R1, ok ++ CALL runtime·load_g(SB) ++ok: ++ STW R16, 8(SP) // sig ++ STL R17, 16(SP) // info ++ STL R18, 24(SP) // ctx ++ // func sigtrampgo(sig uint32, info *siginfo, ctx unsafe.Pointer) ++ CALL runtime·sigtrampgo(SB) ++ LDL R17, 16(SP) ++ STL R17, 8(SP) ++ CALL sw_sigreturn(SB) ++ RET ++ ++// func sw_sigreturn(rt_sigframe) ++TEXT sw_sigreturn(SB), NOSPLIT, $0-0 ++ LDL R16, $frame+0(FP) ++ SYSCALL(SYS_rt_sigreturn) ++ RET ++ ++// func sigfwd(fn uintptr, sig uint32, info *siginfo, ctx unsafe.Pointer) ++TEXT runtime·sigfwd(SB), NOSPLIT, $0-32 ++ LDW R16, sig+8(FP) ++ LDL R17, info+16(FP) ++ LDL R18, ctx+24(FP) ++ LDL R27, fn+0(FP) ++ CALL (R27) ++ RET ++ ++// func futex(addr unsafe.Pointer, op int32, val uint32, ts, addr2 unsafe.Pointer, val3 uint32) int32 ++TEXT runtime·futex(SB), NOFRAME|NOSPLIT, $0-44 ++ LDL R16, addr+0(FP) ++ LDW R17, op+8(FP) ++ LDW R18, val+12(FP) ++ LDL R19, ts+16(FP) ++ LDL R20, addr2+24(FP) ++ LDW R21, val3+32(FP) ++ SYSCALL(SYS_futex) ++ BEQ R19, ok ++ SUBL ZERO, R0, R0 ++ok: ++ STW R0, ret+40(FP) ++ RET ++ ++// func sigaltstack(new, old *stackt) ++TEXT runtime·sigaltstack(SB), NOFRAME|NOSPLIT, $0-16 ++ LDL R16, new+0(FP) ++ LDL R17, old+8(FP) ++ SYSCALL(SYS_sigaltstack) ++ BEQ R19, ok ++ LDL R19, (ZERO) // crash ++ok: ++ RET ++ ++// func gettid() uint32 ++TEXT runtime·gettid(SB), NOFRAME|NOSPLIT, $0-4 ++ SYSCALL(SYS_gettid) ++ STW R0, ret+0(FP) ++ RET ++ ++// func clone(flags int32, stk, mp, gp, fn unsafe.Pointer) int32 ++TEXT runtime·clone(SB), NOSPLIT, $0-44 ++ LDW R16, flags+0(FP) ++ LDL R17, stk+8(FP) ++ ++ // Copy mp, gp, fn off parent stack for use by child. ++ // Careful: Linux system call clobbers ???. ++ LDL R1, mp+16(FP) ++ LDL R2, gp+24(FP) ++ LDL R3, fn+32(FP) ++ ++ STL R1, -8(R17) // mp ++ STL R2, -16(R17) // gp ++ STL R3, -24(R17) // fn ++ ++ LDI R1, $77 ++ STL R1, -32(R17) // guard ++ SYSCALL(SYS_clone) ++ BEQ R0, child ++ STW R0, ret+40(FP) // on parent ++ RET ++child: ++ LDL R4, -32(SP) // on child ++ LDI R5, $77 ++ CMPEQ R4, R5, R5 ++ BNE R5, guard_ok ++ LDL R5, 0(ZERO) ++guard_ok: ++ // set up new stack ++ LDL R27, -24(SP) // fn ++ LDL R2, -16(SP) // g ++ LDL R1, -8(SP) // m ++ BEQ R2, nog ++ BEQ R1, nog ++ ++ SYSCALL(SYS_gettid) ++ STL R0, m_procid(R1) ++ ++ STL R1, g_m(R2) ++ LDI g, R2 ++ //CALL runtime·stackcheck(SB) ++nog: ++ // Call fn ++ CALL (R27) ++ ++ // It shouldn't return. If it does, exit that thread. ++ LDI R16, $111 ++ SYSCALL(SYS_exit) ++ RET ++ ++// func raise(sig uint32) ++TEXT runtime·raise(SB), NOFRAME|NOSPLIT, $0 ++ SYSCALL(SYS_getxpid) ++ LDI R9, R0 ++ SYSCALL(SYS_gettid) ++ LDI R17, R0 // arg 2 tid ++ LDI R16, R9 // arg 1 pid ++ LDW R18, sig+0(FP) // arg 3 ++ SYSCALL(SYS_tgkill) ++ RET ++ ++// func raiseproc(sig uint32) ++TEXT runtime·raiseproc(SB), NOFRAME|NOSPLIT, $0 ++ SYSCALL(SYS_getxpid) ++ LDI R16, R0 ++ LDW R17, sig+0(FP) ++ SYSCALL(SYS_kill) ++ RET ++ ++// func setitimer(mode int32, new, old *itimerval) ++TEXT runtime·setitimer(SB), NOFRAME|NOSPLIT, $0-24 ++ LDW R16, mode+0(FP) ++ LDL R17, new+8(FP) ++ LDL R18, old+16(FP) ++ SYSCALL(SYS_setitimer) ++ RET ++ ++// func timer_create(clockid int32, sevp *sigevent, timerid *int32) int32 ++TEXT runtime·timer_create(SB),NOSPLIT,$0-28 ++ LDW R16, clockid+0(FP) ++ LDL R17, sevp+8(FP) ++ LDL R18, timerid+16(FP) ++ SYSCALL(SYS_timer_create) ++ STW R0, ret+24(FP) ++ RET ++ ++// func timer_settime(timerid int32, flags int32, new, old *itimerspec) int32 ++TEXT runtime·timer_settime(SB),NOSPLIT,$0-28 ++ LDW R16, timerid+0(FP) ++ LDW R17, flags+4(FP) ++ LDL R18, new+8(FP) ++ LDL R19, old+16(FP) ++ SYSCALL(SYS_timer_settime) ++ STW R0, ret+24(FP) ++ RET ++ ++// func timer_delete(timerid int32 ++TEXT runtime·timer_delete(SB),NOSPLIT,$0-12 ++ LDW R16, timerid+0(FP) ++ SYSCALL(SYS_timer_delete) ++ STW R0, ret+8(FP) ++ RET ++ ++// func pipe() (r, w int32, errno int32) ++TEXT runtime·pipe(SB),NOSPLIT|NOFRAME,$0-12 ++ LDI R16, $r+0(FP) ++ LDI R17, ZERO ++ SYSCALL(SYS_pipe2) ++ BEQ R19, ok ++ SUBL ZERO, R0, R0 ++ok: ++ STW R0, errno+8(FP) ++ RET ++ ++// func pipe2(flags int32) (r, w int32, errno int32) ++TEXT runtime·pipe2(SB),NOSPLIT|NOFRAME,$0-20 ++ LDI R16, $r+8(FP) ++ LDW R17, flags+0(FP) ++ SYSCALL(SYS_pipe2) ++ BEQ R19, ok ++ SUBL ZERO, R0, R0 ++ok: ++ STW R0, errno+16(FP) ++ RET ++ ++TEXT ·getpid(SB),NOSPLIT|NOFRAME,$0-8 ++ SYSCALL(SYS_getxpid) ++ STL R0, ret+0(FP) ++ RET ++ ++TEXT ·tgkill(SB),NOSPLIT|NOFRAME,$0-24 ++ LDL R16, tgid+0(FP) ++ LDL R17, tid+8(FP) ++ LDL R18, sig+16(FP) ++ SYSCALL(SYS_tgkill) ++ RET +diff --git a/src/runtime/sys_sw64.go b/src/runtime/sys_sw64.go +new file mode 100644 +index 0000000000..0f6a41ffcd +--- /dev/null ++++ b/src/runtime/sys_sw64.go +@@ -0,0 +1,23 @@ ++// 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 sw64 ++// +build sw64 ++ ++package runtime ++ ++// snyh_TODO: FIX ALL OF THIS ++ ++import "unsafe" ++ ++// adjust Gobuf as if it executed a call to fn with context ctxt ++// and then did an immediate Gosave. ++func gostartcall(buf *gobuf, fn, ctxt unsafe.Pointer) { ++ if buf.lr != 0 { ++ throw("invalid use of gostartcall") ++ } ++ buf.lr = buf.pc ++ buf.pc = uintptr(fn) ++ buf.ctxt = ctxt ++} +diff --git a/src/runtime/tagptr_64bit.go b/src/runtime/tagptr_64bit.go +index 9ff11ccd16..5aefc73789 100644 +--- a/src/runtime/tagptr_64bit.go ++++ b/src/runtime/tagptr_64bit.go +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build amd64 || arm64 || loong64 || mips64 || mips64le || ppc64 || ppc64le || riscv64 || s390x || wasm ++//go:build amd64 || arm64 || loong64 || mips64 || mips64le || ppc64 || ppc64le || riscv64 || s390x || wasm || sw64 + + package runtime + +diff --git a/src/runtime/tls_sw64.s b/src/runtime/tls_sw64.s +new file mode 100644 +index 0000000000..ba675d28ae +--- /dev/null ++++ b/src/runtime/tls_sw64.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. ++ ++//go:build sw64 ++// +build sw64 ++ ++#include "go_asm.h" ++#include "go_tls.h" ++#include "funcdata.h" ++#include "textflag.h" ++ ++// If !iscgo, this is a no-op. ++// ++// NOTE: mcall() assumes this clobbers only R28 and R0 ++TEXT runtime·save_g(SB), NOFRAME|NOSPLIT, $0-0 ++ LDBU R28, runtime·iscgo(SB) ++ BEQ R28, nocgo ++ ++ LDI R28, R0 ++ STL g, runtime·tls_g(SB) // TLS relocation clobbers R0 ++ LDI R0, R28 ++ SETFPEC1 ++nocgo: ++ RET ++ ++TEXT runtime·load_g(SB), NOFRAME|NOSPLIT, $0-0 ++ LDI R28, R0 ++ LDL g, runtime·tls_g(SB) // TLS relocation clobbers R0 ++ LDI R0, R28 ++ SETFPEC1 ++ RET ++ ++GLOBL runtime·tls_g(SB), TLSBSS, $8 +diff --git a/src/runtime/vdso_elf64.go b/src/runtime/vdso_elf64.go +index d41d25e770..3cc7b2c525 100644 +--- a/src/runtime/vdso_elf64.go ++++ b/src/runtime/vdso_elf64.go +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build linux && (amd64 || arm64 || loong64 || mips64 || mips64le || ppc64 || ppc64le || riscv64 || s390x) ++//go:build linux && (amd64 || arm64 || loong64 || mips64 || mips64le || ppc64 || ppc64le || riscv64 || s390x || sw64) + + package runtime + +diff --git a/src/runtime/vdso_in_none.go b/src/runtime/vdso_in_none.go +index 3a6ee6f049..6a47908a50 100644 +--- a/src/runtime/vdso_in_none.go ++++ b/src/runtime/vdso_in_none.go +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build (linux && !386 && !amd64 && !arm && !arm64 && !loong64 && !mips64 && !mips64le && !ppc64 && !ppc64le && !riscv64 && !s390x) || !linux ++//go:build (linux && !386 && !amd64 && !arm && !arm64 && !loong64 && !mips64 && !mips64le && !ppc64 && !ppc64le && !riscv64 && !s390x && !sw64) || !linux + + package runtime + +diff --git a/src/runtime/vdso_linux.go b/src/runtime/vdso_linux.go +index 72b17ce4ac..ee634d684a 100644 +--- a/src/runtime/vdso_linux.go ++++ b/src/runtime/vdso_linux.go +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build linux && (386 || amd64 || arm || arm64 || loong64 || mips64 || mips64le || ppc64 || ppc64le || riscv64 || s390x) ++//go:build linux && (386 || amd64 || arm || arm64 || loong64 || mips64 || mips64le || ppc64 || ppc64le || riscv64 || s390x || sw64) + + package runtime + +diff --git a/src/runtime/vdso_linux_sw64.go b/src/runtime/vdso_linux_sw64.go +new file mode 100644 +index 0000000000..8c7d2cceaf +--- /dev/null ++++ b/src/runtime/vdso_linux_sw64.go +@@ -0,0 +1,28 @@ ++// 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 linux && sw64 ++// +build linux ++// +build sw64 ++ ++package runtime ++ ++const ( ++ // vdsoArrayMax is the byte-size of a maximally sized array on this architecture. ++ // See cmd/compile/internal/sw64/galign.go arch.MAXWIDTH initialization. ++ vdsoArrayMax = 1<<50 - 1 ++) ++ ++var vdsoLinuxVersion = vdsoVersionKey{"LINUX_2.6.39", 0x75fcb89} ++ ++// The symbol name is not __kernel_clock_gettime as suggested by the manpage; ++// according to Linux source code it should be __vdso_clock_gettime instead. ++var vdsoSymbolKeys = []vdsoSymbolKey{ ++ {"__vdso_clock_gettime", 0xd35ec75, 0x6e43a318, &vdsoClockgettimeSym}, ++} ++ ++// initialize to fall back to syscall ++var ( ++ vdsoClockgettimeSym uintptr = 0 ++) +diff --git a/src/runtime/vlrt.go b/src/runtime/vlrt.go +index 4b12f593c8..94edd77d09 100644 +--- a/src/runtime/vlrt.go ++++ b/src/runtime/vlrt.go +@@ -23,7 +23,7 @@ + // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + // THE SOFTWARE. + +-//go:build arm || 386 || mips || mipsle ++//go:build arm || 386 || mips || mipsle || sw64 + + package runtime + +diff --git a/test/nosplit.go b/test/nosplit.go +index 4b4c93b1d0..9fc71086f9 100644 +--- a/test/nosplit.go ++++ b/test/nosplit.go +@@ -165,7 +165,7 @@ start 108 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le + start 112 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le amd64 arm64 + start 116 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le amd64 + start 120 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le amd64 arm64 +-start 124 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le amd64 386 ++start 124 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le amd64 386 sw64 + start 128 nosplit call f; f 0 nosplit; REJECT + start 132 nosplit call f; f 0 nosplit; REJECT + start 136 nosplit call f; f 0 nosplit; REJECT +@@ -305,6 +305,9 @@ TestCases: + case "s390x": + ptrSize = 8 + fmt.Fprintf(&buf, "#define REGISTER R10\n") ++ case "sw64": ++ ptrSize = 8 ++ fmt.Fprintf(&buf, "#define REGISTER (R27)\n") + default: + fmt.Fprintf(&buf, "#define REGISTER AX\n") + } diff --git a/0006-internal-bytealg-optimize-IndexByte-and-IndexByteStr.patch b/0006-internal-bytealg-optimize-IndexByte-and-IndexByteStr.patch new file mode 100644 index 0000000000000000000000000000000000000000..b295cb6d9be8b060f1b9ce2adf084cc77b189724 --- /dev/null +++ b/0006-internal-bytealg-optimize-IndexByte-and-IndexByteStr.patch @@ -0,0 +1,160 @@ +From 0b580e45412ffc11f3a1c7ed7165f7a81e51adec Mon Sep 17 00:00:00 2001 +From: Huang Qiqi +Date: Fri, 17 May 2024 17:10:59 +0800 +Subject: [PATCH 06/44] internal/bytealg: optimize IndexByte and + IndexByteString function for loong64 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Benchmark results on Loongson 3C5000 (which is an LA464 implementation): + +goos: linux +goarch: loong64 +pkg: bytes +cpu: Loongson-3C5000 @ 2200.00MHz + │ test/old_3c5000_indexbyte.log │ test/new_3c5000_indexbyte.log │ + │ sec/op │ sec/op vs base │ +IndexByte/10 19.72n ± 0% 13.72n ± 0% -30.44% (p=0.000 n=20) +IndexByte/32 58.27n ± 0% 21.54n ± 0% -63.04% (p=0.000 n=20) +IndexByte/4K 5.609µ ± 0% 2.349µ ± 0% -58.13% (p=0.000 n=20) +IndexByte/4M 3.844m ± 2% 2.408m ± 1% -37.36% (p=0.000 n=20) +IndexByte/64M 62.38m ± 0% 41.83m ± 2% -32.94% (p=0.000 n=20) +geomean 17.29µ 9.309µ -46.17% + +Change-Id: I9d60af0196a0078e829669ccd88f93b5f7a5db0a +--- + src/internal/bytealg/indexbyte_loong64.s | 105 ++++++++++++++++++----- + 1 file changed, 82 insertions(+), 23 deletions(-) + +diff --git a/src/internal/bytealg/indexbyte_loong64.s b/src/internal/bytealg/indexbyte_loong64.s +index c9591b3cda..7811741423 100644 +--- a/src/internal/bytealg/indexbyte_loong64.s ++++ b/src/internal/bytealg/indexbyte_loong64.s +@@ -10,41 +10,100 @@ TEXT ·IndexByte(SB),NOSPLIT,$0-40 + // R5 = b_len + // R6 = b_cap (unused) + // R7 = byte to find +- AND $0xff, R7 ++ ADDV R4, R5 // end + MOVV R4, R6 // store base for later ++ AND $0xff, R7 ++ JMP indexbytebody<>(SB) ++ ++TEXT ·IndexByteString(SB),NOSPLIT,$0-32 ++ // R4 = s_base ++ // R5 = s_len ++ // R6 = byte to find ++ AND $0xff, R6, R7 + ADDV R4, R5 // end +- ADDV $-1, R4 ++ MOVV R4, R6 // store base for later ++ JMP indexbytebody<>(SB) + +- PCALIGN $16 ++// input: ++// R4: b_base ++// R5: end ++// R6: store base for later ++// R7: byte to find ++TEXT indexbytebody<>(SB),NOSPLIT,$0 + loop: ++ ADDV $8, R4, R10 ++ BLT R5, R10, tail ++ MOVV (R4), R8 ++ ++ AND $0xff, R8, R9 ++ BEQ R7, R9, found ++ ++ WORD $0xcf2109 // bstrpick.w r9, r8, 15, 8 ++ BEQ R7, R9, byte_1th ++ ++ WORD $0xd74109 // bstrpick.w r9, r8, 23, 16 ++ BEQ R7, R9, byte_2th ++ ++ WORD $0xdf6109 // bstrpick.w r9, r8, 31, 24 ++ BEQ R7, R9, byte_3th ++ ++ WORD $0xe78109 // bstrpick.w r9, r8, 39, 32 ++ BEQ R7, R9, byte_4th ++ ++ WORD $0xefa109 // bstrpick.w r9, r8, 47, 40 ++ BEQ R7, R9, byte_5th ++ ++ WORD $0xf7c109 // bstrpick.w r9, r8, 55, 48 ++ BEQ R7, R9, byte_6th ++ ++ WORD $0xffe109 // bstrpick.w r9, r8, 63, 56 ++ BEQ R7, R9, byte_7th ++ ++ MOVV R10, R4 ++ JMP loop ++ ++tail: ++ BEQ R4, R5, notfound ++ MOVBU (R4), R8 ++ BEQ R7, R8, found + ADDV $1, R4 +- BEQ R4, R5, notfound +- MOVBU (R4), R8 +- BNE R7, R8, loop ++ JMP tail + +- SUBV R6, R4 // remove base ++byte_1th: ++ ADDV $1, R4 ++ SUBV R6, R4 + RET + +-notfound: +- MOVV $-1, R4 ++byte_2th: ++ ADDV $2, R4 ++ SUBV R6, R4 + RET + +-TEXT ·IndexByteString(SB),NOSPLIT,$0-32 +- // R4 = s_base +- // R5 = s_len +- // R6 = byte to find +- MOVV R4, R7 // store base for later +- ADDV R4, R5 // end +- ADDV $-1, R4 ++byte_3th: ++ ADDV $3, R4 ++ SUBV R6, R4 ++ RET + +- PCALIGN $16 +-loop: +- ADDV $1, R4 +- BEQ R4, R5, notfound +- MOVBU (R4), R8 +- BNE R6, R8, loop ++byte_4th: ++ ADDV $4, R4 ++ SUBV R6, R4 ++ RET ++ ++byte_5th: ++ ADDV $5, R4 ++ SUBV R6, R4 ++ RET + +- SUBV R7, R4 // remove base ++byte_6th: ++ ADDV $6, R4 ++ SUBV R6, R4 ++ RET ++ ++byte_7th: ++ ADDV $7, R4 ++ ++found: ++ SUBV R6, R4 // remove base + RET + + notfound: +-- +2.38.1 + diff --git a/0006-syscall-Add-sw64-port.patch b/0006-syscall-Add-sw64-port.patch new file mode 100644 index 0000000000000000000000000000000000000000..8d52d9e8b716258326c85ee51fa2753cd2aa2c94 --- /dev/null +++ b/0006-syscall-Add-sw64-port.patch @@ -0,0 +1,5585 @@ +diff --git a/src/syscall/asm_linux_sw64.s b/src/syscall/asm_linux_sw64.s +new file mode 100644 +index 0000000000..f30885e839 +--- /dev/null ++++ b/src/syscall/asm_linux_sw64.s +@@ -0,0 +1,49 @@ ++// 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 linux && sw64 ++ ++#include "textflag.h" ++ ++// ++// System calls for sw64, Linux ++// ++ ++#define SYSCALL SYS_CALL_B $131 ++ ++TEXT ·rawSyscallNoError(SB),NOSPLIT,$0-48 ++ LDL R16, a1+8(FP) ++ LDL R17, a2+16(FP) ++ LDL R18, a3+24(FP) ++ LDI R19, ZERO ++ LDI R20, ZERO ++ LDI R21, ZERO ++ LDL R0, trap+0(FP) // syscall entry ++ SYSCALL ++ STL R0, r1+32(FP) ++ STL R20, r2+40(FP) ++ RET ++ ++// func rawVforkSyscall(trap, a1, a2, a3 uintptr) (r1, err uintptr) ++TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-48 ++ LDL R16, a1+8(FP) ++ LDL R17, a2+16(FP) ++ LDL R18, a3+24(FP) ++ LDI R19, ZERO ++ LDI R20, ZERO ++ LDI R21, ZERO ++ LDL R0, trap+0(FP) // syscall entry ++ SYSCALL ++ BEQ R19, ok ++ LDI R1, $-1 ++ STL R1, r1+32(FP) // r1 ++ STL R0, err+40(FP) // errno ++ RET ++ok: ++ STL R0, r1+32(FP) // r1 ++ STL ZERO, err+40(FP) // errno ++ RET ++ ++ ++ +diff --git a/src/syscall/export_linux_sw64_test.go b/src/syscall/export_linux_sw64_test.go +new file mode 100644 +index 0000000000..a8c32adebe +--- /dev/null ++++ b/src/syscall/export_linux_sw64_test.go +@@ -0,0 +1,35 @@ ++// 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 sw64 ++ ++package syscall ++ ++import ( ++ "unsafe" ++) ++ ++var ( ++ RawSyscallNoError = rawSyscallNoError ++ ForceClone3 = &forceClone3 ++ Prlimit = prlimit ++) ++ ++const Sys_GETEUID = sys_GETXUID ++ ++func Tcgetpgrp(fd int) (pgid int32, err error) { ++ _, _, errno := Syscall6(SYS_IOCTL, uintptr(fd), uintptr(TIOCGPGRP), uintptr(unsafe.Pointer(&pgid)), 0, 0, 0) ++ if errno != 0 { ++ return -1, errno ++ } ++ return pgid, nil ++} ++ ++func Tcsetpgrp(fd int, pgid int32) (err error) { ++ _, _, errno := Syscall6(SYS_IOCTL, uintptr(fd), uintptr(TIOCSPGRP), uintptr(unsafe.Pointer(&pgid)), 0, 0, 0) ++ if errno != 0 { ++ return errno ++ } ++ return nil ++} +diff --git a/src/syscall/export_linux_test.go b/src/syscall/export_linux_test.go +index d9309bf234..ab486b4563 100644 +--- a/src/syscall/export_linux_test.go ++++ b/src/syscall/export_linux_test.go +@@ -2,6 +2,8 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + ++//go:build !sw64 ++ + package syscall + + import ( +diff --git a/src/syscall/mkall.sh b/src/syscall/mkall.sh +index b9a0ed3d4f..873c252188 100755 +--- a/src/syscall/mkall.sh ++++ b/src/syscall/mkall.sh +@@ -247,6 +247,13 @@ linux_mips64le) + mksysnum="./mksysnum_linux.pl $unistd_h" + mktypes="GOARCH=$GOARCH go tool cgo -godefs" + ;; ++linux_sw64) ++ GOOSARCH_in=syscall_linux_sw64.go ++ unistd_h=/usr/include/asm/unistd.h ++ mkerrors="./mkerrors_sw64.sh" ++ mksysnum="./mksysnum_linux.pl $unistd_h" ++ mktypes="GOARCH=$GOARCH go tool cgo -godefs" ++ ;; + linux_ppc64) + GOOSARCH_in=syscall_linux_ppc64x.go + unistd_h=/usr/include/asm/unistd.h +diff --git a/src/syscall/mkerrors_sw64.sh b/src/syscall/mkerrors_sw64.sh +new file mode 100755 +index 0000000000..83137902ed +--- /dev/null ++++ b/src/syscall/mkerrors_sw64.sh +@@ -0,0 +1,462 @@ ++#!/usr/bin/env bash ++# 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. ++ ++# Generate Go code listing errors and other #defined constant ++# values (ENAMETOOLONG etc.), by asking the preprocessor ++# about the definitions. ++ ++unset LANG ++export LC_ALL=C ++export LC_CTYPE=C ++ ++CC=${CC:-gcc} ++ ++if [[ "$GOOS" -eq "solaris" ]]; then ++ # Assumes GNU versions of utilities in PATH. ++ export PATH=/usr/gnu/bin:$PATH ++fi ++ ++uname=$(uname) ++ ++includes_AIX=' ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++' ++ ++includes_Darwin=' ++#define _DARWIN_C_SOURCE ++#define KERNEL ++#define _DARWIN_USE_64_BIT_INODE ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++' ++ ++includes_DragonFly=' ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++' ++ ++includes_FreeBSD=' ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#if __FreeBSD__ >= 10 ++#define IFT_CARP 0xf8 // IFT_CARP is deprecated in FreeBSD 10 ++#undef SIOCAIFADDR ++#define SIOCAIFADDR _IOW(105, 26, struct oifaliasreq) // ifaliasreq contains if_data ++#undef SIOCSIFPHYADDR ++#define SIOCSIFPHYADDR _IOW(105, 70, struct oifaliasreq) // ifaliasreq contains if_data ++#endif ++' ++ ++includes_Linux=' ++#define _LARGEFILE_SOURCE ++#define _LARGEFILE64_SOURCE ++#ifndef __LP64__ ++#define _FILE_OFFSET_BITS 64 ++#endif ++#define _GNU_SOURCE ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifndef MSG_FASTOPEN ++#define MSG_FASTOPEN 0x20000000 ++#endif ++ ++#ifndef PTRACE_GETREGS ++#define PTRACE_GETREGS 0xc ++#endif ++ ++#ifndef PTRACE_SETREGS ++#define PTRACE_SETREGS 0xd ++#endif ++' ++ ++includes_NetBSD=' ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++// Needed since refers to it... ++#define schedppq 1 ++' ++ ++includes_OpenBSD=' ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++// We keep some constants not supported in OpenBSD 5.5 and beyond for ++// the promise of compatibility. ++#define EMUL_ENABLED 0x1 ++#define EMUL_NATIVE 0x2 ++#define IPV6_FAITH 0x1d ++#define IPV6_OPTIONS 0x1 ++#define IPV6_RTHDR_STRICT 0x1 ++#define IPV6_SOCKOPT_RESERVED1 0x3 ++#define SIOCGIFGENERIC 0xc020693a ++#define SIOCSIFGENERIC 0x80206939 ++#define WALTSIG 0x4 ++' ++ ++includes_SunOS=' ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++' ++ ++includes=' ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++' ++ ++ccflags="$@" ++ ++# Write go tool cgo -godefs input. ++( ++ echo package syscall ++ echo ++ echo '/*' ++ indirect="includes_$(uname)" ++ echo "${!indirect} $includes" ++ echo '*/' ++ echo 'import "C"' ++ echo ++ echo 'const (' ++ ++ # The gcc command line prints all the #defines ++ # it encounters while processing the input ++ echo "${!indirect} $includes" | $CC -x c - -E -dM $ccflags | ++ awk ' ++ $1 != "#define" || $2 ~ /\(/ || $3 == "" {next} ++ ++ $2 ~ /^E([ABCD]X|[BIS]P|[SD]I|S|FL)$/ {next} # 386 registers ++ $2 ~ /^(SIGEV_|SIGSTKSZ|SIGRT(MIN|MAX))/ {next} ++ $2 ~ /^(SCM_SRCRT)$/ {next} ++ $2 ~ /^(MAP_FAILED)$/ {next} ++ $2 ~ /^CLONE_[A-Z_]+/ {next} # These are defined in exec_linux.go. ++ $2 ~ /^ELF_.*$/ {next} # contains ELF_ARCH, etc. ++ ++ $2 !~ /^ETH_/ && ++ $2 !~ /^EPROC_/ && ++ $2 !~ /^EQUIV_/ && ++ $2 !~ /^EXPR_/ && ++ $2 ~ /^E[A-Z0-9_]+$/ || ++ $2 ~ /^B[0-9_]+$/ || ++ $2 ~ /^V[A-Z0-9]+$/ || ++ $2 ~ /^CS[A-Z0-9]/ || ++ $2 ~ /^I(SIG|CANON|CRNL|EXTEN|MAXBEL|STRIP|UTF8)$/ || ++ $2 ~ /^IGN/ || ++ $2 ~ /^IX(ON|ANY|OFF)$/ || ++ $2 ~ /^IN(LCR|PCK)$/ || ++ $2 ~ /(^FLU?SH)|(FLU?SH$)/ || ++ $2 ~ /^C(LOCAL|READ)$/ || ++ $2 == "BRKINT" || ++ $2 == "HUPCL" || ++ $2 == "PENDIN" || ++ $2 == "TOSTOP" || ++ $2 ~ /^PAR/ || ++ $2 ~ /^SIG[^_]/ || ++ $2 ~ /^O[CNPFP][A-Z]+[^_][A-Z]+$/ || ++ $2 ~ /^IN_/ || ++ $2 ~ /^LOCK_(SH|EX|NB|UN)$/ || ++ $2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|ICMP6|TCP|EVFILT|NOTE|EV|SHUT|PROT|MAP|PACKET|MSG|SCM|MCL|DT|MADV|PR)_/ || ++ $2 == "ICMPV6_FILTER" || ++ $2 == "SOMAXCONN" || ++ $2 == "NAME_MAX" || ++ $2 == "IFNAMSIZ" || ++ $2 ~ /^CTL_(MAXNAME|NET|QUERY)$/ || ++ $2 ~ /^SYSCTL_VERS/ || ++ $2 ~ /^(MS|MNT)_/ || ++ $2 ~ /^TUN(SET|GET|ATTACH|DETACH)/ || ++ $2 ~ /^(O|F|FD|NAME|S|PTRACE|PT)_/ || ++ $2 ~ /^LINUX_REBOOT_CMD_/ || ++ $2 ~ /^LINUX_REBOOT_MAGIC[12]$/ || ++ $2 !~ "NLA_TYPE_MASK" && ++ $2 ~ /^(NETLINK|NLM|NLMSG|NLA|IFA|IFAN|RT|RTCF|RTN|RTPROT|RTNH|ARPHRD|ETH_P)_/ || ++ $2 ~ /^SIOC/ || ++ ($2 ~ /^TIOC/ && $0 !~ /struct/ && $3 !~ "FIONREAD") || ++ $2 !~ "RTF_BITS" && ++ $2 ~ /^(IFF|IFT|NET_RT|RTM|RTF|RTV|RTA|RTAX)_/ || ++ $2 ~ /^BIOC/ || ++ $2 ~ /^RUSAGE_(SELF|CHILDREN|THREAD)/ || ++ $2 ~ /^RLIMIT_(AS|CORE|CPU|DATA|FSIZE|NOFILE|STACK)|RLIM_INFINITY/ || ++ $2 ~ /^PRIO_(PROCESS|PGRP|USER)/ || ++ $2 !~ /^(BPF_TIMEVAL)$/ && ++ $2 ~ /^(BPF|DLT)_/ || ++ $2 !~ "WMESGLEN" && ++ $2 ~ /^W[A-Z0-9]+$/ {printf("\t%s = C.%s\n", $2, $2)} ++ $2 ~ /^__WCOREFLAG$/ {next} ++ $2 ~ /^__W[A-Z0-9]+$/ {printf("\t%s = C.%s\n", substr($2,3), $2)} ++ ++ {next} ++ ' | sort ++ ++ echo ')' ++) >_const.go ++ ++# Pull out the error names for later. ++errors=$( ++ echo '#include ' | $CC -x c - -E -dM $ccflags | ++ awk '$1=="#define" && $2 ~ /^E[A-Z0-9_]+$/ { print $2 }' | ++ sort ++) ++ ++# Pull out the signal names for later. ++signals=$( ++ echo '#include ' | $CC -x c - -E -dM $ccflags | ++ awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print $2 }' | ++ grep -v 'SIGSTKSIZE\|SIGSTKSZ\|SIGRT' | ++ sort ++) ++ ++# Again, writing regexps to a file. ++echo '#include ' | $CC -x c - -E -dM $ccflags | ++ awk '$1=="#define" && $2 ~ /^E[A-Z0-9_]+$/ { print "^\t" $2 "[ \t]*=" }' | ++ sort >_error.grep ++echo '#include ' | $CC -x c - -E -dM $ccflags | ++ awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print "^\t" $2 "[ \t]*=" }' | ++ grep -v 'SIGSTKSIZE\|SIGSTKSZ\|SIGRT' | ++ sort >_signal.grep ++ ++echo '// mkerrors.sh' "$@" ++echo '// Code generated by the command above; DO NOT EDIT.' ++echo ++go tool cgo -godefs -- "$@" _const.go >_error.out ++cat _error.out | grep -vf _error.grep | grep -vf _signal.grep ++echo ++echo '// Errors' ++echo 'const (' ++cat _error.out | grep -f _error.grep | sed 's/=\(.*\)/= Errno(\1)/' ++echo ')' ++ ++echo ++echo '// Signals' ++echo 'const (' ++cat _error.out | grep -f _signal.grep | sed 's/=\(.*\)/= Signal(\1)/' ++echo ')' ++ ++# Run C program to print error and syscall strings. ++( ++ echo -E " ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define nelem(x) (sizeof(x)/sizeof((x)[0])) ++ ++enum { A = 'A', Z = 'Z', a = 'a', z = 'z' }; // avoid need for single quotes below ++ ++int errors[] = { ++" ++ for i in $errors ++ do ++ echo -E ' '$i, ++ done ++ ++ echo -E " ++}; ++ ++int signals[] = { ++" ++ for i in $signals ++ do ++ echo -E ' '$i, ++ done ++ ++ # Use -E because on some systems bash builtin interprets \n itself. ++ echo -E ' ++}; ++ ++static int ++intcmp(const void *a, const void *b) ++{ ++ return *(int*)a - *(int*)b; ++} ++ ++int ++main(void) ++{ ++ int i, j, e; ++ char buf[1024], *p; ++ ++ printf("\n\n// Error table\n"); ++ printf("var errors = [...]string {\n"); ++ qsort(errors, nelem(errors), sizeof errors[0], intcmp); ++ for(i=0; i 0 && errors[i-1] == e) ++ continue; ++ strcpy(buf, strerror(e)); ++ // lowercase first letter: Bad -> bad, but STREAM -> STREAM. ++ if(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z) ++ buf[0] += a - A; ++ printf("\t%d: \"%s\",\n", e, buf); ++ } ++ printf("}\n\n"); ++ ++ printf("\n\n// Signal table\n"); ++ printf("var signals = [...]string {\n"); ++ qsort(signals, nelem(signals), sizeof signals[0], intcmp); ++ for(i=0; i 0 && signals[i-1] == e) ++ continue; ++ strcpy(buf, strsignal(e)); ++ // lowercase first letter: Bad -> bad, but STREAM -> STREAM. ++ if(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z) ++ buf[0] += a - A; ++ // cut trailing : number. ++ p = strrchr(buf, ":"[0]); ++ if(p) ++ *p = '\0'; ++ printf("\t%d: \"%s\",\n", e, buf); ++ } ++ printf("}\n\n"); ++ ++ return 0; ++} ++ ++' ++) >_errors.c ++ ++$CC $ccflags -o _errors _errors.c && $GORUN ./_errors && rm -f _errors.c _errors _const.go _error.grep _signal.grep _error.out +diff --git a/src/syscall/setuidgid_linux.go b/src/syscall/setuidgid_linux.go +index c995d258eb..eaae3deba8 100644 +--- a/src/syscall/setuidgid_linux.go ++++ b/src/syscall/setuidgid_linux.go +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build linux && !386 && !arm ++//go:build linux && !386 && !arm && !sw64 + + package syscall + +diff --git a/src/syscall/setuidgid_linux_sw64.go b/src/syscall/setuidgid_linux_sw64.go +new file mode 100644 +index 0000000000..2424af31a5 +--- /dev/null ++++ b/src/syscall/setuidgid_linux_sw64.go +@@ -0,0 +1,22 @@ ++// 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. ++ ++// +build linux ++// +build sw64 ++ ++package syscall ++ ++const ( ++ sys_GETEUID = SYS_GETXUID ++ sys_GETXUID = SYS_GETXUID ++ ++ sys_SETGID = SYS_SETGID ++ sys_SETUID = SYS_SETUID ++ ++ sys_SETREGID = SYS_SETREGID ++ sys_SETREUID = SYS_SETREUID ++ ++ sys_SETRESGID = SYS_SETRESGID ++ sys_SETRESUID = SYS_SETRESUID ++) +diff --git a/src/syscall/syscall_linux_sw64.go b/src/syscall/syscall_linux_sw64.go +new file mode 100644 +index 0000000000..fdb732e34e +--- /dev/null ++++ b/src/syscall/syscall_linux_sw64.go +@@ -0,0 +1,174 @@ ++// 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 linux && sw64 ++ ++package syscall ++ ++const ( ++ //generate by handle ++ //_snyh_TODO: this should be generate by improving build script ++ FIOCLEX = 0x20006601 ++ FIONCLEX = 0x20006602 ++ FIOASYNC = 0xffffffff8004667d ++ FIONBIO = 0xffffffff8004667e ++ FIONREAD = 0x4004667f ++ TIOCINQ = 0x4004667f ++ FIOQSIZE = 0x40086680 ++ TIOCGETP = 0x40067408 ++ TIOCSETP = 0xffffffff80067409 ++ TIOCSETN = 0xffffffff8006740a ++ TIOCSETC = 0xffffffff80067411 ++ TIOCGETC = 0x40067412 ++ TCSETSW = 0xffffffff802c7415 ++ TCSETSF = 0xffffffff802c7416 ++ TCGETA = 0x40127417 ++ TCSETA = 0xffffffff80127418 ++ TCSETAW = 0xffffffff80127419 ++ TCSETAF = 0xffffffff8012741c ++ TIOCSWINSZ = 0xffffffff80087467 ++ TIOCGWINSZ = 0x40087468 ++ TIOCGLTC = 0x40067474 ++ TIOCSLTC = 0xffffffff80067475 ++) ++ ++const ( ++ //ALL OF THIS constants are WORKAROUND, and should be removing ++ _SYS_dup = SYS_DUP2 ++ _SYS_setgroups = SYS_SETGROUPS ++ ++ _SYS_clone3 = 282 ++ _SYS_faccessat2 = 286 ++ //TODO: support since linux 6.1 ++ _SYS_fchmodat2 = 191 ++) ++ ++//sysnb getxpid() (pid int, ppid int) ++// TODO(snyh): correct handle Getppid and Getpid ++// currently manually remove the implements of Getpid and Getppid ++// in zsyscall_linux_sw64.go ++ ++// TODO(snyh): correct handle Utime ++func Utime(path string, buf *Utimbuf) error { ++ tv := [2]Timeval{ ++ {Sec: buf.Actime}, ++ {Sec: buf.Modtime}, ++ } ++ return utimes(path, &tv) ++} ++ ++//sys Fstat64(fd int, st *Stat_t) (err error) ++//sys Lstat64(path string, st *Stat_t) (err error) ++//sys Stat64(path string, st *Stat_t) (err error) ++func Fstat(fd int, st *Stat_t) (err error) { return Fstat64(fd, st) } ++func Lstat(path string, st *Stat_t) (err error) { return Lstat64(path, st) } ++func Stat(path string, st *Stat_t) (err error) { return Stat64(path, st) } ++ ++//sys getxuid() (uid int, euid int) ++func Getuid() (uid int) { uid, _ = getxuid(); return } ++func Geteuid() (euid int) { _, euid = getxuid(); return } ++ ++//sys getxgid() (gid int, egid int) ++func Getgid() (gid int) { gid, _ = getxgid(); return } ++func Getegid() (egid int) { _, egid = getxgid(); return } ++ ++//sys Statfs(path string, buf *Statfs_t) (err error) ++//sys Fstatfs(fd int, buf *Statfs_t) (err error) ++//sys Dup2(oldfd int, newfd int) (err error) ++//sys Fchown(fd int, uid int, gid int) (err error) ++//sys Ftruncate(fd int, length int64) (err error) ++//sysnb InotifyInit() (fd int, err error) ++//sys Lchown(path string, uid int, gid int) (err error) ++//sys Listen(s int, n int) (err error) ++//sys pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64 ++//sys pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64 ++//sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK ++//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) ++//sys Setfsgid(gid int) (err error) ++//sys Setfsuid(uid int) (err error) ++//sys Shutdown(fd int, how int) (err error) ++//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) ++ ++//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error) ++//sys Truncate(path string, length int64) (err error) ++//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) ++//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) ++//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) ++//sysnb getgroups(n int, list *_Gid_t) (nn int, err error) ++//sys getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) ++//sys setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) ++//sysnb socket(domain int, typ int, proto int) (fd int, err error) ++//sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) ++//sysnb getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) ++//sysnb getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) ++//sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) ++//sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) ++//sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error) ++//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) ++//sys mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) ++ ++type sigset_t struct { ++ X__val [16]uint64 ++} ++ ++//sys pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *sigset_t) (n int, err error) = SYS_PSELECT6 ++ ++func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) { ++ ts := Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000} ++ return pselect(nfd, r, w, e, &ts, nil) ++} ++ ++//sysnb Gettimeofday(tv *Timeval) (err error) ++ ++func Time(t *Time_t) (tt Time_t, err error) { ++ var tv Timeval ++ err = Gettimeofday(&tv) ++ if err != nil { ++ return 0, err ++ } ++ if t != nil { ++ *t = Time_t(tv.Sec) ++ } ++ return Time_t(tv.Sec), nil ++} ++ ++func setTimespec(sec, nsec int64) Timespec { ++ return Timespec{Sec: sec, Nsec: nsec} ++} ++ ++func setTimeval(sec, usec int64) Timeval { ++ return Timeval{Sec: sec, Usec: usec} ++} ++ ++func Ioperm(from int, num int, on int) (err error) { ++ return ENOSYS ++} ++ ++func Iopl(level int) (err error) { ++ return ENOSYS ++} ++ ++// func (r *PtraceRegs) PC() uint64 { return r.Regs[64] } ++ ++// func (r *PtraceRegs) SetPC(pc uint64) { r.Regs[64] = pc } ++ ++func (iov *Iovec) SetLen(length int) { ++ iov.Len = uint64(length) ++} ++ ++func (msghdr *Msghdr) SetControllen(length int) { ++ msghdr.Controllen = uint64(length) ++} ++ ++func (cmsg *Cmsghdr) SetLen(length int) { ++ cmsg.Len = uint64(length) ++} ++ ++//zxw new add ++//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) ++//sys Ustat(dev int, ubuf *Ustat_t) (err error) ++//sys futimesat(dirfd int, path string, times *[2]Timeval) (err error) ++//sys utimes(path string, times *[2]Timeval) (err error) ++//sys fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64 ++//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) +diff --git a/src/syscall/zerrors_linux_sw64.go b/src/syscall/zerrors_linux_sw64.go +new file mode 100644 +index 0000000000..1a20e3aeb3 +--- /dev/null ++++ b/src/syscall/zerrors_linux_sw64.go +@@ -0,0 +1,2100 @@ ++// mkerrors.sh ++// Code generated by the command above; DO NOT EDIT. ++ ++// Code generated by cmd/cgo -godefs; DO NOT EDIT. ++// cgo -godefs -- /home/zhangjh/golang/src/syscall/_const.go ++ ++package syscall ++ ++const ( ++ AF_ALG = 0x26 ++ AF_APPLETALK = 0x5 ++ AF_ASH = 0x12 ++ AF_ATMPVC = 0x8 ++ AF_ATMSVC = 0x14 ++ AF_AX25 = 0x3 ++ AF_BLUETOOTH = 0x1f ++ AF_BRIDGE = 0x7 ++ AF_CAIF = 0x25 ++ AF_CAN = 0x1d ++ AF_DECnet = 0xc ++ AF_ECONET = 0x13 ++ AF_FILE = 0x1 ++ AF_IB = 0x1b ++ AF_IEEE802154 = 0x24 ++ AF_INET = 0x2 ++ AF_INET6 = 0xa ++ AF_IPX = 0x4 ++ AF_IRDA = 0x17 ++ AF_ISDN = 0x22 ++ AF_IUCV = 0x20 ++ AF_KCM = 0x29 ++ AF_KEY = 0xf ++ AF_LLC = 0x1a ++ AF_LOCAL = 0x1 ++ AF_MAX = 0x2d ++ AF_MPLS = 0x1c ++ AF_NETBEUI = 0xd ++ AF_NETLINK = 0x10 ++ AF_NETROM = 0x6 ++ AF_NFC = 0x27 ++ AF_PACKET = 0x11 ++ AF_PHONET = 0x23 ++ AF_PPPOX = 0x18 ++ AF_QIPCRTR = 0x2a ++ AF_RDS = 0x15 ++ AF_ROSE = 0xb ++ AF_ROUTE = 0x10 ++ AF_RXRPC = 0x21 ++ AF_SECURITY = 0xe ++ AF_SMC = 0x2b ++ AF_SNA = 0x16 ++ AF_TIPC = 0x1e ++ AF_UNIX = 0x1 ++ AF_UNSPEC = 0x0 ++ AF_VSOCK = 0x28 ++ AF_WANPIPE = 0x19 ++ AF_X25 = 0x9 ++ AF_XDP = 0x2c ++ ARPHRD_6LOWPAN = 0x339 ++ ARPHRD_ADAPT = 0x108 ++ ARPHRD_APPLETLK = 0x8 ++ ARPHRD_ARCNET = 0x7 ++ ARPHRD_ASH = 0x30d ++ ARPHRD_ATM = 0x13 ++ ARPHRD_AX25 = 0x3 ++ ARPHRD_BIF = 0x307 ++ ARPHRD_CAIF = 0x336 ++ ARPHRD_CAN = 0x118 ++ ARPHRD_CHAOS = 0x5 ++ ARPHRD_CISCO = 0x201 ++ ARPHRD_CSLIP = 0x101 ++ ARPHRD_CSLIP6 = 0x103 ++ ARPHRD_DDCMP = 0x205 ++ ARPHRD_DLCI = 0xf ++ ARPHRD_ECONET = 0x30e ++ ARPHRD_EETHER = 0x2 ++ ARPHRD_ETHER = 0x1 ++ ARPHRD_EUI64 = 0x1b ++ ARPHRD_FCAL = 0x311 ++ ARPHRD_FCFABRIC = 0x313 ++ ARPHRD_FCPL = 0x312 ++ ARPHRD_FCPP = 0x310 ++ ARPHRD_FDDI = 0x306 ++ ARPHRD_FRAD = 0x302 ++ ARPHRD_HDLC = 0x201 ++ ARPHRD_HIPPI = 0x30c ++ ARPHRD_HWX25 = 0x110 ++ ARPHRD_IEEE1394 = 0x18 ++ ARPHRD_IEEE802 = 0x6 ++ ARPHRD_IEEE80211 = 0x321 ++ ARPHRD_IEEE80211_PRISM = 0x322 ++ ARPHRD_IEEE80211_RADIOTAP = 0x323 ++ ARPHRD_IEEE802154 = 0x324 ++ ARPHRD_IEEE802154_MONITOR = 0x325 ++ ARPHRD_IEEE802_TR = 0x320 ++ ARPHRD_INFINIBAND = 0x20 ++ ARPHRD_IP6GRE = 0x337 ++ ARPHRD_IPDDP = 0x309 ++ ARPHRD_IPGRE = 0x30a ++ ARPHRD_IRDA = 0x30f ++ ARPHRD_LAPB = 0x204 ++ ARPHRD_LOCALTLK = 0x305 ++ ARPHRD_LOOPBACK = 0x304 ++ ARPHRD_METRICOM = 0x17 ++ ARPHRD_NETLINK = 0x338 ++ ARPHRD_NETROM = 0x0 ++ ARPHRD_NONE = 0xfffe ++ ARPHRD_PHONET = 0x334 ++ ARPHRD_PHONET_PIPE = 0x335 ++ ARPHRD_PIMREG = 0x30b ++ ARPHRD_PPP = 0x200 ++ ARPHRD_PRONET = 0x4 ++ ARPHRD_RAWHDLC = 0x206 ++ ARPHRD_RAWIP = 0x207 ++ ARPHRD_ROSE = 0x10e ++ ARPHRD_RSRVD = 0x104 ++ ARPHRD_SIT = 0x308 ++ ARPHRD_SKIP = 0x303 ++ ARPHRD_SLIP = 0x100 ++ ARPHRD_SLIP6 = 0x102 ++ ARPHRD_TUNNEL = 0x300 ++ ARPHRD_TUNNEL6 = 0x301 ++ ARPHRD_VOID = 0xffff ++ ARPHRD_VSOCKMON = 0x33a ++ ARPHRD_X25 = 0x10f ++ B0 = 0x0 ++ B1000000 = 0x17 ++ B110 = 0x3 ++ B115200 = 0x11 ++ B1152000 = 0x18 ++ B1200 = 0x9 ++ B134 = 0x4 ++ B150 = 0x5 ++ B1500000 = 0x19 ++ B1800 = 0xa ++ B19200 = 0xe ++ B200 = 0x6 ++ B2000000 = 0x1a ++ B230400 = 0x12 ++ B2400 = 0xb ++ B2500000 = 0x1b ++ B300 = 0x7 ++ B3000000 = 0x1c ++ B3500000 = 0x1d ++ B38400 = 0xf ++ B4000000 = 0x1e ++ B460800 = 0x13 ++ B4800 = 0xc ++ B50 = 0x1 ++ B500000 = 0x14 ++ B57600 = 0x10 ++ B576000 = 0x15 ++ B600 = 0x8 ++ B75 = 0x2 ++ B921600 = 0x16 ++ B9600 = 0xd ++ BPF_A = 0x10 ++ BPF_ABS = 0x20 ++ BPF_ADD = 0x0 ++ BPF_ALU = 0x4 ++ BPF_AND = 0x50 ++ BPF_B = 0x10 ++ BPF_DIV = 0x30 ++ BPF_H = 0x8 ++ BPF_IMM = 0x0 ++ BPF_IND = 0x40 ++ BPF_JA = 0x0 ++ BPF_JEQ = 0x10 ++ BPF_JGE = 0x30 ++ BPF_JGT = 0x20 ++ BPF_JMP = 0x5 ++ BPF_JSET = 0x40 ++ BPF_K = 0x0 ++ BPF_LD = 0x0 ++ BPF_LDX = 0x1 ++ BPF_LEN = 0x80 ++ BPF_LL_OFF = -0x200000 ++ BPF_LSH = 0x60 ++ BPF_MAJOR_VERSION = 0x1 ++ BPF_MAXINSNS = 0x1000 ++ BPF_MEM = 0x60 ++ BPF_MEMWORDS = 0x10 ++ BPF_MINOR_VERSION = 0x1 ++ BPF_MISC = 0x7 ++ BPF_MOD = 0x90 ++ BPF_MSH = 0xa0 ++ BPF_MUL = 0x20 ++ BPF_NEG = 0x80 ++ BPF_NET_OFF = -0x100000 ++ BPF_OR = 0x40 ++ BPF_RET = 0x6 ++ BPF_RSH = 0x70 ++ BPF_ST = 0x2 ++ BPF_STX = 0x3 ++ BPF_SUB = 0x10 ++ BPF_TAX = 0x0 ++ BPF_TXA = 0x80 ++ BPF_W = 0x0 ++ BPF_X = 0x8 ++ BPF_XOR = 0xa0 ++ BRKINT = 0x2 ++ CFLUSH = 0xf ++ CLOCAL = 0x8000 ++ CREAD = 0x800 ++ CS5 = 0x0 ++ CS6 = 0x100 ++ CS7 = 0x200 ++ CS8 = 0x300 ++ CSIGNAL = 0xff ++ CSIZE = 0x300 ++ CSTART = 0x11 ++ CSTATUS = 0x0 ++ CSTOP = 0x13 ++ CSTOPB = 0x400 ++ CSUSP = 0x1a ++ DT_BLK = 0x6 ++ DT_CHR = 0x2 ++ DT_DIR = 0x4 ++ DT_FIFO = 0x1 ++ DT_LNK = 0xa ++ DT_REG = 0x8 ++ DT_SOCK = 0xc ++ DT_UNKNOWN = 0x0 ++ DT_WHT = 0xe ++ ECHO = 0x8 ++ ECHOCTL = 0x40 ++ ECHOE = 0x2 ++ ECHOK = 0x4 ++ ECHOKE = 0x1 ++ ECHONL = 0x10 ++ ECHOPRT = 0x20 ++ ENCODING_DEFAULT = 0x0 ++ ENCODING_FM_MARK = 0x3 ++ ENCODING_FM_SPACE = 0x4 ++ ENCODING_MANCHESTER = 0x5 ++ ENCODING_NRZ = 0x1 ++ ENCODING_NRZI = 0x2 ++ EPOLLERR = 0x8 ++ EPOLLET = 0x80000000 ++ EPOLLEXCLUSIVE = 0x10000000 ++ EPOLLHUP = 0x10 ++ EPOLLIN = 0x1 ++ EPOLLMSG = 0x400 ++ EPOLLONESHOT = 0x40000000 ++ EPOLLOUT = 0x4 ++ EPOLLPRI = 0x2 ++ EPOLLRDBAND = 0x80 ++ EPOLLRDHUP = 0x2000 ++ EPOLLRDNORM = 0x40 ++ EPOLLWAKEUP = 0x20000000 ++ EPOLLWRBAND = 0x200 ++ EPOLLWRNORM = 0x100 ++ EPOLL_CLOEXEC = 0x200000 ++ EPOLL_CTL_ADD = 0x1 ++ EPOLL_CTL_DEL = 0x2 ++ EPOLL_CTL_MOD = 0x3 ++ ETH_P_1588 = 0x88f7 ++ ETH_P_8021AD = 0x88a8 ++ ETH_P_8021AH = 0x88e7 ++ ETH_P_8021Q = 0x8100 ++ ETH_P_80221 = 0x8917 ++ ETH_P_802_2 = 0x4 ++ ETH_P_802_3 = 0x1 ++ ETH_P_802_3_MIN = 0x600 ++ ETH_P_802_EX1 = 0x88b5 ++ ETH_P_AARP = 0x80f3 ++ ETH_P_AF_IUCV = 0xfbfb ++ ETH_P_ALL = 0x3 ++ ETH_P_AOE = 0x88a2 ++ ETH_P_ARCNET = 0x1a ++ ETH_P_ARP = 0x806 ++ ETH_P_ATALK = 0x809b ++ ETH_P_ATMFATE = 0x8884 ++ ETH_P_ATMMPOA = 0x884c ++ ETH_P_AX25 = 0x2 ++ ETH_P_BATMAN = 0x4305 ++ ETH_P_BPQ = 0x8ff ++ ETH_P_CAIF = 0xf7 ++ ETH_P_CAN = 0xc ++ ETH_P_CANFD = 0xd ++ ETH_P_CONTROL = 0x16 ++ ETH_P_CUST = 0x6006 ++ ETH_P_DDCMP = 0x6 ++ ETH_P_DEC = 0x6000 ++ ETH_P_DIAG = 0x6005 ++ ETH_P_DNA_DL = 0x6001 ++ ETH_P_DNA_RC = 0x6002 ++ ETH_P_DNA_RT = 0x6003 ++ ETH_P_DSA = 0x1b ++ ETH_P_DSA_8021Q = 0xdadb ++ ETH_P_ECONET = 0x18 ++ ETH_P_EDSA = 0xdada ++ ETH_P_ERSPAN = 0x88be ++ ETH_P_ERSPAN2 = 0x22eb ++ ETH_P_FCOE = 0x8906 ++ ETH_P_FIP = 0x8914 ++ ETH_P_HDLC = 0x19 ++ ETH_P_HSR = 0x892f ++ ETH_P_IBOE = 0x8915 ++ ETH_P_IEEE802154 = 0xf6 ++ ETH_P_IEEEPUP = 0xa00 ++ ETH_P_IEEEPUPAT = 0xa01 ++ ETH_P_IFE = 0xed3e ++ ETH_P_IP = 0x800 ++ ETH_P_IPV6 = 0x86dd ++ ETH_P_IPX = 0x8137 ++ ETH_P_IRDA = 0x17 ++ ETH_P_LAT = 0x6004 ++ ETH_P_LINK_CTL = 0x886c ++ ETH_P_LLDP = 0x88cc ++ ETH_P_LOCALTALK = 0x9 ++ ETH_P_LOOP = 0x60 ++ ETH_P_LOOPBACK = 0x9000 ++ ETH_P_MACSEC = 0x88e5 ++ ETH_P_MAP = 0xf9 ++ ETH_P_MOBITEX = 0x15 ++ ETH_P_MPLS_MC = 0x8848 ++ ETH_P_MPLS_UC = 0x8847 ++ ETH_P_MRP = 0x88e3 ++ ETH_P_MVRP = 0x88f5 ++ ETH_P_NCSI = 0x88f8 ++ ETH_P_NSH = 0x894f ++ ETH_P_PAE = 0x888e ++ ETH_P_PAUSE = 0x8808 ++ ETH_P_PHONET = 0xf5 ++ ETH_P_PPPTALK = 0x10 ++ ETH_P_PPP_DISC = 0x8863 ++ ETH_P_PPP_MP = 0x8 ++ ETH_P_PPP_SES = 0x8864 ++ ETH_P_PREAUTH = 0x88c7 ++ ETH_P_PRP = 0x88fb ++ ETH_P_PUP = 0x200 ++ ETH_P_PUPAT = 0x201 ++ ETH_P_QINQ1 = 0x9100 ++ ETH_P_QINQ2 = 0x9200 ++ ETH_P_QINQ3 = 0x9300 ++ ETH_P_RARP = 0x8035 ++ ETH_P_SCA = 0x6007 ++ ETH_P_SLOW = 0x8809 ++ ETH_P_SNAP = 0x5 ++ ETH_P_TDLS = 0x890d ++ ETH_P_TEB = 0x6558 ++ ETH_P_TIPC = 0x88ca ++ ETH_P_TRAILER = 0x1c ++ ETH_P_TR_802_2 = 0x11 ++ ETH_P_TSN = 0x22f0 ++ ETH_P_WAN_PPP = 0x7 ++ ETH_P_WCCP = 0x883e ++ ETH_P_X25 = 0x805 ++ ETH_P_XDSA = 0xf8 ++ EXTA = 0xe ++ EXTB = 0xf ++ FD_CLOEXEC = 0x1 ++ FD_SETSIZE = 0x400 ++ FLUSHO = 0x800000 ++ F_ADD_SEALS = 0x409 ++ F_DUPFD = 0x0 ++ F_DUPFD_CLOEXEC = 0x406 ++ F_EXLCK = 0x10 ++ F_GETFD = 0x1 ++ F_GETFL = 0x3 ++ F_GETLEASE = 0x401 ++ F_GETLK = 0x7 ++ F_GETLK64 = 0x7 ++ F_GETOWN = 0x6 ++ F_GETOWN_EX = 0x10 ++ F_GETPIPE_SZ = 0x408 ++ F_GETSIG = 0xb ++ F_GET_FILE_RW_HINT = 0x40d ++ F_GET_RW_HINT = 0x40b ++ F_GET_SEALS = 0x40a ++ F_LOCK = 0x1 ++ F_NOTIFY = 0x402 ++ F_OFD_GETLK = 0x24 ++ F_OFD_SETLK = 0x25 ++ F_OFD_SETLKW = 0x26 ++ F_OK = 0x0 ++ F_RDLCK = 0x1 ++ F_SEAL_FUTURE_WRITE = 0x10 ++ F_SEAL_GROW = 0x4 ++ F_SEAL_SEAL = 0x1 ++ F_SEAL_SHRINK = 0x2 ++ F_SEAL_WRITE = 0x8 ++ F_SETFD = 0x2 ++ F_SETFL = 0x4 ++ F_SETLEASE = 0x400 ++ F_SETLK = 0x8 ++ F_SETLK64 = 0x8 ++ F_SETLKW = 0x9 ++ F_SETLKW64 = 0x9 ++ F_SETOWN = 0x5 ++ F_SETOWN_EX = 0xf ++ F_SETPIPE_SZ = 0x407 ++ F_SETSIG = 0xa ++ F_SET_FILE_RW_HINT = 0x40e ++ F_SET_RW_HINT = 0x40c ++ F_SHLCK = 0x20 ++ F_TEST = 0x3 ++ F_TLOCK = 0x2 ++ F_ULOCK = 0x0 ++ F_UNLCK = 0x8 ++ F_WRLCK = 0x2 ++ HUPCL = 0x4000 ++ ICANON = 0x100 ++ ICMPV6_FILTER = 0x1 ++ ICRNL = 0x100 ++ IEXTEN = 0x400 ++ IFA_F_DADFAILED = 0x8 ++ IFA_F_DEPRECATED = 0x20 ++ IFA_F_HOMEADDRESS = 0x10 ++ IFA_F_MANAGETEMPADDR = 0x100 ++ IFA_F_MCAUTOJOIN = 0x400 ++ IFA_F_NODAD = 0x2 ++ IFA_F_NOPREFIXROUTE = 0x200 ++ IFA_F_OPTIMISTIC = 0x4 ++ IFA_F_PERMANENT = 0x80 ++ IFA_F_SECONDARY = 0x1 ++ IFA_F_STABLE_PRIVACY = 0x800 ++ IFA_F_TEMPORARY = 0x1 ++ IFA_F_TENTATIVE = 0x40 ++ IFA_MAX = 0xa ++ IFF_ALLMULTI = 0x200 ++ IFF_ATTACH_QUEUE = 0x200 ++ IFF_AUTOMEDIA = 0x4000 ++ IFF_BROADCAST = 0x2 ++ IFF_DEBUG = 0x4 ++ IFF_DETACH_QUEUE = 0x400 ++ IFF_DORMANT = 0x20000 ++ IFF_DYNAMIC = 0x8000 ++ IFF_ECHO = 0x40000 ++ IFF_LOOPBACK = 0x8 ++ IFF_LOWER_UP = 0x10000 ++ IFF_MASTER = 0x400 ++ IFF_MULTICAST = 0x1000 ++ IFF_MULTI_QUEUE = 0x100 ++ IFF_NAPI = 0x10 ++ IFF_NAPI_FRAGS = 0x20 ++ IFF_NOARP = 0x80 ++ IFF_NOFILTER = 0x1000 ++ IFF_NOTRAILERS = 0x20 ++ IFF_NO_PI = 0x1000 ++ IFF_ONE_QUEUE = 0x2000 ++ IFF_PERSIST = 0x800 ++ IFF_POINTOPOINT = 0x10 ++ IFF_PORTSEL = 0x2000 ++ IFF_PROMISC = 0x100 ++ IFF_RUNNING = 0x40 ++ IFF_SLAVE = 0x800 ++ IFF_TAP = 0x2 ++ IFF_TUN = 0x1 ++ IFF_TUN_EXCL = 0x8000 ++ IFF_UP = 0x1 ++ IFF_VNET_HDR = 0x4000 ++ IFF_VOLATILE = 0x70c5a ++ IFNAMSIZ = 0x10 ++ IGNBRK = 0x1 ++ IGNCR = 0x80 ++ IGNPAR = 0x4 ++ IMAXBEL = 0x2000 ++ INLCR = 0x40 ++ INPCK = 0x10 ++ IN_ACCESS = 0x1 ++ IN_ALL_EVENTS = 0xfff ++ IN_ATTRIB = 0x4 ++ IN_CLASSA_HOST = 0xffffff ++ IN_CLASSA_MAX = 0x80 ++ IN_CLASSA_NET = 0xff000000 ++ IN_CLASSA_NSHIFT = 0x18 ++ IN_CLASSB_HOST = 0xffff ++ IN_CLASSB_MAX = 0x10000 ++ IN_CLASSB_NET = 0xffff0000 ++ IN_CLASSB_NSHIFT = 0x10 ++ IN_CLASSC_HOST = 0xff ++ IN_CLASSC_NET = 0xffffff00 ++ IN_CLASSC_NSHIFT = 0x8 ++ IN_CLOEXEC = 0x200000 ++ IN_CLOSE = 0x18 ++ IN_CLOSE_NOWRITE = 0x10 ++ IN_CLOSE_WRITE = 0x8 ++ IN_CREATE = 0x100 ++ IN_DELETE = 0x200 ++ IN_DELETE_SELF = 0x400 ++ IN_DONT_FOLLOW = 0x2000000 ++ IN_EXCL_UNLINK = 0x4000000 ++ IN_IGNORED = 0x8000 ++ IN_ISDIR = 0x40000000 ++ IN_LOOPBACKNET = 0x7f ++ IN_MASK_ADD = 0x20000000 ++ IN_MASK_CREATE = 0x10000000 ++ IN_MODIFY = 0x2 ++ IN_MOVE = 0xc0 ++ IN_MOVED_FROM = 0x40 ++ IN_MOVED_TO = 0x80 ++ IN_MOVE_SELF = 0x800 ++ IN_NONBLOCK = 0x4 ++ IN_ONESHOT = 0x80000000 ++ IN_ONLYDIR = 0x1000000 ++ IN_OPEN = 0x20 ++ IN_Q_OVERFLOW = 0x4000 ++ IN_UNMOUNT = 0x2000 ++ IPPROTO_AH = 0x33 ++ IPPROTO_BEETPH = 0x5e ++ IPPROTO_COMP = 0x6c ++ IPPROTO_DCCP = 0x21 ++ IPPROTO_DSTOPTS = 0x3c ++ IPPROTO_EGP = 0x8 ++ IPPROTO_ENCAP = 0x62 ++ IPPROTO_ESP = 0x32 ++ IPPROTO_ETHERNET = 0x8f ++ IPPROTO_FRAGMENT = 0x2c ++ IPPROTO_GRE = 0x2f ++ IPPROTO_HOPOPTS = 0x0 ++ IPPROTO_ICMP = 0x1 ++ IPPROTO_ICMPV6 = 0x3a ++ IPPROTO_IDP = 0x16 ++ IPPROTO_IGMP = 0x2 ++ IPPROTO_IP = 0x0 ++ IPPROTO_IPIP = 0x4 ++ IPPROTO_IPV6 = 0x29 ++ IPPROTO_MH = 0x87 ++ IPPROTO_MPLS = 0x89 ++ IPPROTO_MPTCP = 0x106 ++ IPPROTO_MTP = 0x5c ++ IPPROTO_NONE = 0x3b ++ IPPROTO_PIM = 0x67 ++ IPPROTO_PUP = 0xc ++ IPPROTO_RAW = 0xff ++ IPPROTO_ROUTING = 0x2b ++ IPPROTO_RSVP = 0x2e ++ IPPROTO_SCTP = 0x84 ++ IPPROTO_TCP = 0x6 ++ IPPROTO_TP = 0x1d ++ IPPROTO_UDP = 0x11 ++ IPPROTO_UDPLITE = 0x88 ++ IPV6_2292DSTOPTS = 0x4 ++ IPV6_2292HOPLIMIT = 0x8 ++ IPV6_2292HOPOPTS = 0x3 ++ IPV6_2292PKTINFO = 0x2 ++ IPV6_2292PKTOPTIONS = 0x6 ++ IPV6_2292RTHDR = 0x5 ++ IPV6_ADDRFORM = 0x1 ++ IPV6_ADDR_PREFERENCES = 0x48 ++ IPV6_ADD_MEMBERSHIP = 0x14 ++ IPV6_AUTHHDR = 0xa ++ IPV6_AUTOFLOWLABEL = 0x46 ++ IPV6_CHECKSUM = 0x7 ++ IPV6_DONTFRAG = 0x3e ++ IPV6_DROP_MEMBERSHIP = 0x15 ++ IPV6_DSTOPTS = 0x3b ++ IPV6_FREEBIND = 0x4e ++ IPV6_HDRINCL = 0x24 ++ IPV6_HOPLIMIT = 0x34 ++ IPV6_HOPOPTS = 0x36 ++ IPV6_IPSEC_POLICY = 0x22 ++ IPV6_JOIN_ANYCAST = 0x1b ++ IPV6_JOIN_GROUP = 0x14 ++ IPV6_LEAVE_ANYCAST = 0x1c ++ IPV6_LEAVE_GROUP = 0x15 ++ IPV6_MINHOPCOUNT = 0x49 ++ IPV6_MTU = 0x18 ++ IPV6_MTU_DISCOVER = 0x17 ++ IPV6_MULTICAST_ALL = 0x1d ++ IPV6_MULTICAST_HOPS = 0x12 ++ IPV6_MULTICAST_IF = 0x11 ++ IPV6_MULTICAST_LOOP = 0x13 ++ IPV6_NEXTHOP = 0x9 ++ IPV6_ORIGDSTADDR = 0x4a ++ IPV6_PATHMTU = 0x3d ++ IPV6_PKTINFO = 0x32 ++ IPV6_PMTUDISC_DO = 0x2 ++ IPV6_PMTUDISC_DONT = 0x0 ++ IPV6_PMTUDISC_INTERFACE = 0x4 ++ IPV6_PMTUDISC_OMIT = 0x5 ++ IPV6_PMTUDISC_PROBE = 0x3 ++ IPV6_PMTUDISC_WANT = 0x1 ++ IPV6_RECVDSTOPTS = 0x3a ++ IPV6_RECVERR = 0x19 ++ IPV6_RECVERR_RFC4884 = 0x1f ++ IPV6_RECVFRAGSIZE = 0x4d ++ IPV6_RECVHOPLIMIT = 0x33 ++ IPV6_RECVHOPOPTS = 0x35 ++ IPV6_RECVORIGDSTADDR = 0x4a ++ IPV6_RECVPATHMTU = 0x3c ++ IPV6_RECVPKTINFO = 0x31 ++ IPV6_RECVRTHDR = 0x38 ++ IPV6_RECVTCLASS = 0x42 ++ IPV6_ROUTER_ALERT = 0x16 ++ IPV6_ROUTER_ALERT_ISOLATE = 0x1e ++ IPV6_RTHDR = 0x39 ++ IPV6_RTHDRDSTOPTS = 0x37 ++ IPV6_RTHDR_LOOSE = 0x0 ++ IPV6_RTHDR_STRICT = 0x1 ++ IPV6_RTHDR_TYPE_0 = 0x0 ++ IPV6_RXDSTOPTS = 0x3b ++ IPV6_RXHOPOPTS = 0x36 ++ IPV6_TCLASS = 0x43 ++ IPV6_TRANSPARENT = 0x4b ++ IPV6_UNICAST_HOPS = 0x10 ++ IPV6_UNICAST_IF = 0x4c ++ IPV6_V6ONLY = 0x1a ++ IPV6_XFRM_POLICY = 0x23 ++ IP_ADD_MEMBERSHIP = 0x23 ++ IP_ADD_SOURCE_MEMBERSHIP = 0x27 ++ IP_BIND_ADDRESS_NO_PORT = 0x18 ++ IP_BLOCK_SOURCE = 0x26 ++ IP_CHECKSUM = 0x17 ++ IP_DEFAULT_MULTICAST_LOOP = 0x1 ++ IP_DEFAULT_MULTICAST_TTL = 0x1 ++ IP_DF = 0x4000 ++ IP_DROP_MEMBERSHIP = 0x24 ++ IP_DROP_SOURCE_MEMBERSHIP = 0x28 ++ IP_FREEBIND = 0xf ++ IP_HDRINCL = 0x3 ++ IP_IPSEC_POLICY = 0x10 ++ IP_MAXPACKET = 0xffff ++ IP_MAX_MEMBERSHIPS = 0x14 ++ IP_MF = 0x2000 ++ IP_MINTTL = 0x15 ++ IP_MSFILTER = 0x29 ++ IP_MSS = 0x240 ++ IP_MTU = 0xe ++ IP_MTU_DISCOVER = 0xa ++ IP_MULTICAST_ALL = 0x31 ++ IP_MULTICAST_IF = 0x20 ++ IP_MULTICAST_LOOP = 0x22 ++ IP_MULTICAST_TTL = 0x21 ++ IP_NODEFRAG = 0x16 ++ IP_OFFMASK = 0x1fff ++ IP_OPTIONS = 0x4 ++ IP_ORIGDSTADDR = 0x14 ++ IP_PASSSEC = 0x12 ++ IP_PKTINFO = 0x8 ++ IP_PKTOPTIONS = 0x9 ++ IP_PMTUDISC = 0xa ++ IP_PMTUDISC_DO = 0x2 ++ IP_PMTUDISC_DONT = 0x0 ++ IP_PMTUDISC_INTERFACE = 0x4 ++ IP_PMTUDISC_OMIT = 0x5 ++ IP_PMTUDISC_PROBE = 0x3 ++ IP_PMTUDISC_WANT = 0x1 ++ IP_RECVERR = 0xb ++ IP_RECVERR_RFC4884 = 0x1a ++ IP_RECVFRAGSIZE = 0x19 ++ IP_RECVOPTS = 0x6 ++ IP_RECVORIGDSTADDR = 0x14 ++ IP_RECVRETOPTS = 0x7 ++ IP_RECVTOS = 0xd ++ IP_RECVTTL = 0xc ++ IP_RETOPTS = 0x7 ++ IP_RF = 0x8000 ++ IP_ROUTER_ALERT = 0x5 ++ IP_TOS = 0x1 ++ IP_TRANSPARENT = 0x13 ++ IP_TTL = 0x2 ++ IP_UNBLOCK_SOURCE = 0x25 ++ IP_UNICAST_IF = 0x32 ++ IP_XFRM_POLICY = 0x11 ++ ISIG = 0x80 ++ ISTRIP = 0x20 ++ IUTF8 = 0x4000 ++ IXANY = 0x800 ++ IXOFF = 0x400 ++ IXON = 0x200 ++ LINUX_REBOOT_CMD_CAD_OFF = 0x0 ++ LINUX_REBOOT_CMD_CAD_ON = 0x89abcdef ++ LINUX_REBOOT_CMD_HALT = 0xcdef0123 ++ LINUX_REBOOT_CMD_KEXEC = 0x45584543 ++ LINUX_REBOOT_CMD_POWER_OFF = 0x4321fedc ++ LINUX_REBOOT_CMD_RESTART = 0x1234567 ++ LINUX_REBOOT_CMD_RESTART2 = 0xa1b2c3d4 ++ LINUX_REBOOT_CMD_SW_SUSPEND = 0xd000fce2 ++ LINUX_REBOOT_MAGIC1 = 0xfee1dead ++ LINUX_REBOOT_MAGIC2 = 0x28121969 ++ LOCK_EX = 0x2 ++ LOCK_NB = 0x4 ++ LOCK_SH = 0x1 ++ LOCK_UN = 0x8 ++ MADV_COLD = 0x14 ++ MADV_DODUMP = 0x11 ++ MADV_DOFORK = 0xb ++ MADV_DONTDUMP = 0x10 ++ MADV_DONTFORK = 0xa ++ MADV_DONTNEED = 0x6 ++ MADV_FREE = 0x8 ++ MADV_HUGEPAGE = 0xe ++ MADV_HWPOISON = 0x64 ++ MADV_KEEPONFORK = 0x13 ++ MADV_MERGEABLE = 0xc ++ MADV_NOHUGEPAGE = 0xf ++ MADV_NORMAL = 0x0 ++ MADV_PAGEOUT = 0x15 ++ MADV_RANDOM = 0x1 ++ MADV_REMOVE = 0x9 ++ MADV_SEQUENTIAL = 0x2 ++ MADV_UNMERGEABLE = 0xd ++ MADV_WILLNEED = 0x3 ++ MADV_WIPEONFORK = 0x12 ++ MAP_ANON = 0x10 ++ MAP_ANONYMOUS = 0x10 ++ MAP_DENYWRITE = 0x2000 ++ MAP_EXECUTABLE = 0x4000 ++ MAP_FILE = 0x0 ++ MAP_FIXED = 0x100 ++ MAP_FIXED_NOREPLACE = 0x200000 ++ MAP_GROWSDOWN = 0x1000 ++ MAP_HUGETLB = 0x100000 ++ MAP_HUGE_MASK = 0x3f ++ MAP_HUGE_SHIFT = 0x1a ++ MAP_LOCKED = 0x8000 ++ MAP_NONBLOCK = 0x40000 ++ MAP_NORESERVE = 0x10000 ++ MAP_POPULATE = 0x20000 ++ MAP_PRIVATE = 0x2 ++ MAP_SHARED = 0x1 ++ MAP_SHARED_VALIDATE = 0x3 ++ MAP_STACK = 0x80000 ++ MAP_TYPE = 0xf ++ MCL_CURRENT = 0x2000 ++ MCL_FUTURE = 0x4000 ++ MCL_ONFAULT = 0x8000 ++ MNT_DETACH = 0x2 ++ MNT_EXPIRE = 0x4 ++ MNT_FORCE = 0x1 ++ MSG_BATCH = 0x40000 ++ MSG_CMSG_CLOEXEC = 0x40000000 ++ MSG_CONFIRM = 0x800 ++ MSG_CTRUNC = 0x8 ++ MSG_DONTROUTE = 0x4 ++ MSG_DONTWAIT = 0x40 ++ MSG_EOR = 0x80 ++ MSG_ERRQUEUE = 0x2000 ++ MSG_FASTOPEN = 0x20000000 ++ MSG_FIN = 0x200 ++ MSG_MORE = 0x8000 ++ MSG_NOSIGNAL = 0x4000 ++ MSG_OOB = 0x1 ++ MSG_PEEK = 0x2 ++ MSG_PROXY = 0x10 ++ MSG_RST = 0x1000 ++ MSG_SYN = 0x400 ++ MSG_TRUNC = 0x20 ++ MSG_TRYHARD = 0x4 ++ MSG_WAITALL = 0x100 ++ MSG_WAITFORONE = 0x10000 ++ MSG_ZEROCOPY = 0x4000000 ++ MS_ACTIVE = 0x40000000 ++ MS_ASYNC = 0x1 ++ MS_BIND = 0x1000 ++ MS_DIRSYNC = 0x80 ++ MS_INVALIDATE = 0x4 ++ MS_I_VERSION = 0x800000 ++ MS_KERNMOUNT = 0x400000 ++ MS_LAZYTIME = 0x2000000 ++ MS_MANDLOCK = 0x40 ++ MS_MGC_MSK = 0xffff0000 ++ MS_MGC_VAL = 0xc0ed0000 ++ MS_MOVE = 0x2000 ++ MS_NOATIME = 0x400 ++ MS_NODEV = 0x4 ++ MS_NODIRATIME = 0x800 ++ MS_NOEXEC = 0x8 ++ MS_NOSUID = 0x2 ++ MS_NOSYMFOLLOW = 0x100 ++ MS_NOUSER = -0x80000000 ++ MS_POSIXACL = 0x10000 ++ MS_PRIVATE = 0x40000 ++ MS_RDONLY = 0x1 ++ MS_REC = 0x4000 ++ MS_RELATIME = 0x200000 ++ MS_REMOUNT = 0x20 ++ MS_RMT_MASK = 0x2800051 ++ MS_SHARED = 0x100000 ++ MS_SILENT = 0x8000 ++ MS_SLAVE = 0x80000 ++ MS_STRICTATIME = 0x1000000 ++ MS_SYNC = 0x2 ++ MS_SYNCHRONOUS = 0x10 ++ MS_UNBINDABLE = 0x20000 ++ NAME_MAX = 0xff ++ NETLINK_ADD_MEMBERSHIP = 0x1 ++ NETLINK_AUDIT = 0x9 ++ NETLINK_BROADCAST_ERROR = 0x4 ++ NETLINK_CAP_ACK = 0xa ++ NETLINK_CONNECTOR = 0xb ++ NETLINK_CRYPTO = 0x15 ++ NETLINK_DNRTMSG = 0xe ++ NETLINK_DROP_MEMBERSHIP = 0x2 ++ NETLINK_ECRYPTFS = 0x13 ++ NETLINK_EXT_ACK = 0xb ++ NETLINK_FIB_LOOKUP = 0xa ++ NETLINK_FIREWALL = 0x3 ++ NETLINK_GENERIC = 0x10 ++ NETLINK_GET_STRICT_CHK = 0xc ++ NETLINK_INET_DIAG = 0x4 ++ NETLINK_IP6_FW = 0xd ++ NETLINK_ISCSI = 0x8 ++ NETLINK_KOBJECT_UEVENT = 0xf ++ NETLINK_LISTEN_ALL_NSID = 0x8 ++ NETLINK_LIST_MEMBERSHIPS = 0x9 ++ NETLINK_NETFILTER = 0xc ++ NETLINK_NFLOG = 0x5 ++ NETLINK_NO_ENOBUFS = 0x5 ++ NETLINK_PKTINFO = 0x3 ++ NETLINK_RDMA = 0x14 ++ NETLINK_ROUTE = 0x0 ++ NETLINK_RX_RING = 0x6 ++ NETLINK_SCSITRANSPORT = 0x12 ++ NETLINK_SELINUX = 0x7 ++ NETLINK_SMC = 0x16 ++ NETLINK_SOCK_DIAG = 0x4 ++ NETLINK_TX_RING = 0x7 ++ NETLINK_UNUSED = 0x1 ++ NETLINK_USERSOCK = 0x2 ++ NETLINK_XFRM = 0x6 ++ NLA_ALIGNTO = 0x4 ++ NLA_F_NESTED = 0x8000 ++ NLA_F_NET_BYTEORDER = 0x4000 ++ NLA_HDRLEN = 0x4 ++ NLMSG_ALIGNTO = 0x4 ++ NLMSG_DONE = 0x3 ++ NLMSG_ERROR = 0x2 ++ NLMSG_HDRLEN = 0x10 ++ NLMSG_MIN_TYPE = 0x10 ++ NLMSG_NOOP = 0x1 ++ NLMSG_OVERRUN = 0x4 ++ NLM_F_ACK = 0x4 ++ NLM_F_ACK_TLVS = 0x200 ++ NLM_F_APPEND = 0x800 ++ NLM_F_ATOMIC = 0x400 ++ NLM_F_CAPPED = 0x100 ++ NLM_F_CREATE = 0x400 ++ NLM_F_DUMP = 0x300 ++ NLM_F_DUMP_FILTERED = 0x20 ++ NLM_F_DUMP_INTR = 0x10 ++ NLM_F_ECHO = 0x8 ++ NLM_F_EXCL = 0x200 ++ NLM_F_MATCH = 0x200 ++ NLM_F_MULTI = 0x2 ++ NLM_F_NONREC = 0x100 ++ NLM_F_REPLACE = 0x100 ++ NLM_F_REQUEST = 0x1 ++ NLM_F_ROOT = 0x100 ++ NOFLSH = 0x80000000 ++ OCRNL = 0x8 ++ OFDEL = 0x80 ++ OFILL = 0x40 ++ ONLCR = 0x2 ++ ONLRET = 0x20 ++ ONOCR = 0x10 ++ OPOST = 0x1 ++ O_ACCMODE = 0x3 ++ O_APPEND = 0x8 ++ O_ASYNC = 0x2000 ++ O_CLOEXEC = 0x200000 ++ O_CREAT = 0x200 ++ O_DIRECT = 0x80000 ++ O_DIRECTORY = 0x8000 ++ O_DSYNC = 0x4000 ++ O_EXCL = 0x800 ++ O_FSYNC = 0x404000 ++ O_LARGEFILE = 0x0 ++ O_NDELAY = 0x4 ++ O_NOATIME = 0x100000 ++ O_NOCTTY = 0x1000 ++ O_NOFOLLOW = 0x10000 ++ O_NONBLOCK = 0x4 ++ O_PATH = 0x800000 ++ O_RDONLY = 0x0 ++ O_RDWR = 0x2 ++ O_RSYNC = 0x404000 ++ O_SYNC = 0x404000 ++ O_TMPFILE = 0x1008000 ++ O_TRUNC = 0x400 ++ O_WRONLY = 0x1 ++ PACKET_ADD_MEMBERSHIP = 0x1 ++ PACKET_AUXDATA = 0x8 ++ PACKET_BROADCAST = 0x1 ++ PACKET_COPY_THRESH = 0x7 ++ PACKET_DROP_MEMBERSHIP = 0x2 ++ PACKET_FANOUT = 0x12 ++ PACKET_FANOUT_CBPF = 0x6 ++ PACKET_FANOUT_CPU = 0x2 ++ PACKET_FANOUT_DATA = 0x16 ++ PACKET_FANOUT_EBPF = 0x7 ++ PACKET_FANOUT_FLAG_DEFRAG = 0x8000 ++ PACKET_FANOUT_FLAG_ROLLOVER = 0x1000 ++ PACKET_FANOUT_FLAG_UNIQUEID = 0x2000 ++ PACKET_FANOUT_HASH = 0x0 ++ PACKET_FANOUT_LB = 0x1 ++ PACKET_FANOUT_QM = 0x5 ++ PACKET_FANOUT_RND = 0x4 ++ PACKET_FANOUT_ROLLOVER = 0x3 ++ PACKET_FASTROUTE = 0x6 ++ PACKET_HDRLEN = 0xb ++ PACKET_HOST = 0x0 ++ PACKET_IGNORE_OUTGOING = 0x17 ++ PACKET_KERNEL = 0x7 ++ PACKET_LOOPBACK = 0x5 ++ PACKET_LOSS = 0xe ++ PACKET_MR_ALLMULTI = 0x2 ++ PACKET_MR_MULTICAST = 0x0 ++ PACKET_MR_PROMISC = 0x1 ++ PACKET_MR_UNICAST = 0x3 ++ PACKET_MULTICAST = 0x2 ++ PACKET_ORIGDEV = 0x9 ++ PACKET_OTHERHOST = 0x3 ++ PACKET_OUTGOING = 0x4 ++ PACKET_QDISC_BYPASS = 0x14 ++ PACKET_RECV_OUTPUT = 0x3 ++ PACKET_RESERVE = 0xc ++ PACKET_ROLLOVER_STATS = 0x15 ++ PACKET_RX_RING = 0x5 ++ PACKET_STATISTICS = 0x6 ++ PACKET_TIMESTAMP = 0x11 ++ PACKET_TX_HAS_OFF = 0x13 ++ PACKET_TX_RING = 0xd ++ PACKET_TX_TIMESTAMP = 0x10 ++ PACKET_USER = 0x6 ++ PACKET_VERSION = 0xa ++ PACKET_VNET_HDR = 0xf ++ PARENB = 0x1000 ++ PARITY_CRC16_PR0 = 0x2 ++ PARITY_CRC16_PR0_CCITT = 0x4 ++ PARITY_CRC16_PR1 = 0x3 ++ PARITY_CRC16_PR1_CCITT = 0x5 ++ PARITY_CRC32_PR0_CCITT = 0x6 ++ PARITY_CRC32_PR1_CCITT = 0x7 ++ PARITY_DEFAULT = 0x0 ++ PARITY_NONE = 0x1 ++ PARMRK = 0x8 ++ PARODD = 0x2000 ++ PENDIN = 0x20000000 ++ PRIO_PGRP = 0x1 ++ PRIO_PROCESS = 0x0 ++ PRIO_USER = 0x2 ++ PROT_EXEC = 0x4 ++ PROT_GROWSDOWN = 0x1000000 ++ PROT_GROWSUP = 0x2000000 ++ PROT_NONE = 0x0 ++ PROT_READ = 0x1 ++ PROT_WRITE = 0x2 ++ PR_CAPBSET_DROP = 0x18 ++ PR_CAPBSET_READ = 0x17 ++ PR_CAP_AMBIENT = 0x2f ++ PR_CAP_AMBIENT_CLEAR_ALL = 0x4 ++ PR_CAP_AMBIENT_IS_SET = 0x1 ++ PR_CAP_AMBIENT_LOWER = 0x3 ++ PR_CAP_AMBIENT_RAISE = 0x2 ++ PR_ENDIAN_BIG = 0x0 ++ PR_ENDIAN_LITTLE = 0x1 ++ PR_ENDIAN_PPC_LITTLE = 0x2 ++ PR_FPEMU_NOPRINT = 0x1 ++ PR_FPEMU_SIGFPE = 0x2 ++ PR_FP_EXC_ASYNC = 0x2 ++ PR_FP_EXC_DISABLED = 0x0 ++ PR_FP_EXC_DIV = 0x10000 ++ PR_FP_EXC_INV = 0x100000 ++ PR_FP_EXC_NONRECOV = 0x1 ++ PR_FP_EXC_OVF = 0x20000 ++ PR_FP_EXC_PRECISE = 0x3 ++ PR_FP_EXC_RES = 0x80000 ++ PR_FP_EXC_SW_ENABLE = 0x80 ++ PR_FP_EXC_UND = 0x40000 ++ PR_FP_MODE_FR = 0x1 ++ PR_FP_MODE_FRE = 0x2 ++ PR_GET_CHILD_SUBREAPER = 0x25 ++ PR_GET_DUMPABLE = 0x3 ++ PR_GET_ENDIAN = 0x13 ++ PR_GET_FPEMU = 0x9 ++ PR_GET_FPEXC = 0xb ++ PR_GET_FP_MODE = 0x2e ++ PR_GET_IO_FLUSHER = 0x3a ++ PR_GET_KEEPCAPS = 0x7 ++ PR_GET_NAME = 0x10 ++ PR_GET_NO_NEW_PRIVS = 0x27 ++ PR_GET_PDEATHSIG = 0x2 ++ PR_GET_SECCOMP = 0x15 ++ PR_GET_SECUREBITS = 0x1b ++ PR_GET_SPECULATION_CTRL = 0x34 ++ PR_GET_TAGGED_ADDR_CTRL = 0x38 ++ PR_GET_THP_DISABLE = 0x2a ++ PR_GET_TID_ADDRESS = 0x28 ++ PR_GET_TIMERSLACK = 0x1e ++ PR_GET_TIMING = 0xd ++ PR_GET_TSC = 0x19 ++ PR_GET_UNALIGN = 0x5 ++ PR_MCE_KILL = 0x21 ++ PR_MCE_KILL_CLEAR = 0x0 ++ PR_MCE_KILL_DEFAULT = 0x2 ++ PR_MCE_KILL_EARLY = 0x1 ++ PR_MCE_KILL_GET = 0x22 ++ PR_MCE_KILL_LATE = 0x0 ++ PR_MCE_KILL_SET = 0x1 ++ PR_MPX_DISABLE_MANAGEMENT = 0x2c ++ PR_MPX_ENABLE_MANAGEMENT = 0x2b ++ PR_MTE_TAG_MASK = 0x7fff8 ++ PR_MTE_TAG_SHIFT = 0x3 ++ PR_MTE_TCF_ASYNC = 0x4 ++ PR_MTE_TCF_MASK = 0x6 ++ PR_MTE_TCF_NONE = 0x0 ++ PR_MTE_TCF_SHIFT = 0x1 ++ PR_MTE_TCF_SYNC = 0x2 ++ PR_PAC_APDAKEY = 0x4 ++ PR_PAC_APDBKEY = 0x8 ++ PR_PAC_APGAKEY = 0x10 ++ PR_PAC_APIAKEY = 0x1 ++ PR_PAC_APIBKEY = 0x2 ++ PR_PAC_RESET_KEYS = 0x36 ++ PR_SET_CHILD_SUBREAPER = 0x24 ++ PR_SET_DUMPABLE = 0x4 ++ PR_SET_ENDIAN = 0x14 ++ PR_SET_FPEMU = 0xa ++ PR_SET_FPEXC = 0xc ++ PR_SET_FP_MODE = 0x2d ++ PR_SET_IO_FLUSHER = 0x39 ++ PR_SET_KEEPCAPS = 0x8 ++ PR_SET_MM = 0x23 ++ PR_SET_MM_ARG_END = 0x9 ++ PR_SET_MM_ARG_START = 0x8 ++ PR_SET_MM_AUXV = 0xc ++ PR_SET_MM_BRK = 0x7 ++ PR_SET_MM_END_CODE = 0x2 ++ PR_SET_MM_END_DATA = 0x4 ++ PR_SET_MM_ENV_END = 0xb ++ PR_SET_MM_ENV_START = 0xa ++ PR_SET_MM_EXE_FILE = 0xd ++ PR_SET_MM_MAP = 0xe ++ PR_SET_MM_MAP_SIZE = 0xf ++ PR_SET_MM_START_BRK = 0x6 ++ PR_SET_MM_START_CODE = 0x1 ++ PR_SET_MM_START_DATA = 0x3 ++ PR_SET_MM_START_STACK = 0x5 ++ PR_SET_NAME = 0xf ++ PR_SET_NO_NEW_PRIVS = 0x26 ++ PR_SET_PDEATHSIG = 0x1 ++ PR_SET_PTRACER = 0x59616d61 ++ PR_SET_PTRACER_ANY = 0xffffffffffffffff ++ PR_SET_SECCOMP = 0x16 ++ PR_SET_SECUREBITS = 0x1c ++ PR_SET_SPECULATION_CTRL = 0x35 ++ PR_SET_TAGGED_ADDR_CTRL = 0x37 ++ PR_SET_THP_DISABLE = 0x29 ++ PR_SET_TIMERSLACK = 0x1d ++ PR_SET_TIMING = 0xe ++ PR_SET_TSC = 0x1a ++ PR_SET_UNALIGN = 0x6 ++ PR_SPEC_DISABLE = 0x4 ++ PR_SPEC_DISABLE_NOEXEC = 0x10 ++ PR_SPEC_ENABLE = 0x2 ++ PR_SPEC_FORCE_DISABLE = 0x8 ++ PR_SPEC_INDIRECT_BRANCH = 0x1 ++ PR_SPEC_NOT_AFFECTED = 0x0 ++ PR_SPEC_PRCTL = 0x1 ++ PR_SPEC_STORE_BYPASS = 0x0 ++ PR_SVE_GET_VL = 0x33 ++ PR_SVE_SET_VL = 0x32 ++ PR_SVE_SET_VL_ONEXEC = 0x40000 ++ PR_SVE_VL_INHERIT = 0x20000 ++ PR_SVE_VL_LEN_MASK = 0xffff ++ PR_TAGGED_ADDR_ENABLE = 0x1 ++ PR_TASK_PERF_EVENTS_DISABLE = 0x1f ++ PR_TASK_PERF_EVENTS_ENABLE = 0x20 ++ PR_TIMING_STATISTICAL = 0x0 ++ PR_TIMING_TIMESTAMP = 0x1 ++ PR_TSC_ENABLE = 0x1 ++ PR_TSC_SIGSEGV = 0x2 ++ PR_UNALIGN_NOPRINT = 0x1 ++ PR_UNALIGN_SIGBUS = 0x2 ++ PTRACE_ATTACH = 0x10 ++ PTRACE_CONT = 0x7 ++ PTRACE_DETACH = 0x11 ++ PTRACE_EVENTMSG_SYSCALL_ENTRY = 0x1 ++ PTRACE_EVENTMSG_SYSCALL_EXIT = 0x2 ++ PTRACE_EVENT_CLONE = 0x3 ++ PTRACE_EVENT_EXEC = 0x4 ++ PTRACE_EVENT_EXIT = 0x6 ++ PTRACE_EVENT_FORK = 0x1 ++ PTRACE_EVENT_SECCOMP = 0x7 ++ PTRACE_EVENT_STOP = 0x80 ++ PTRACE_EVENT_VFORK = 0x2 ++ PTRACE_EVENT_VFORK_DONE = 0x5 ++ PTRACE_GETEVENTMSG = 0x4201 ++ PTRACE_GETREGS = 0xc ++ PTRACE_GETREGSET = 0x4204 ++ PTRACE_GETSIGINFO = 0x4202 ++ PTRACE_GETSIGMASK = 0x420a ++ PTRACE_GET_SYSCALL_INFO = 0x420e ++ PTRACE_INTERRUPT = 0x4207 ++ PTRACE_KILL = 0x8 ++ PTRACE_LISTEN = 0x4208 ++ PTRACE_O_EXITKILL = 0x100000 ++ PTRACE_O_MASK = 0x3000ff ++ PTRACE_O_SUSPEND_SECCOMP = 0x200000 ++ PTRACE_O_TRACECLONE = 0x8 ++ PTRACE_O_TRACEEXEC = 0x10 ++ PTRACE_O_TRACEEXIT = 0x40 ++ PTRACE_O_TRACEFORK = 0x2 ++ PTRACE_O_TRACESECCOMP = 0x80 ++ PTRACE_O_TRACESYSGOOD = 0x1 ++ PTRACE_O_TRACEVFORK = 0x4 ++ PTRACE_O_TRACEVFORKDONE = 0x20 ++ PTRACE_PEEKDATA = 0x2 ++ PTRACE_PEEKSIGINFO = 0x4209 ++ PTRACE_PEEKSIGINFO_SHARED = 0x1 ++ PTRACE_PEEKTEXT = 0x1 ++ PTRACE_PEEKUSR = 0x3 ++ PTRACE_POKEDATA = 0x5 ++ PTRACE_POKETEXT = 0x4 ++ PTRACE_POKEUSR = 0x6 ++ PTRACE_SECCOMP_GET_FILTER = 0x420c ++ PTRACE_SECCOMP_GET_METADATA = 0x420d ++ PTRACE_SEIZE = 0x4206 ++ PTRACE_SETOPTIONS = 0x4200 ++ PTRACE_SETREGS = 0xd ++ PTRACE_SETREGSET = 0x4205 ++ PTRACE_SETSIGINFO = 0x4203 ++ PTRACE_SETSIGMASK = 0x420b ++ PTRACE_SINGLESTEP = 0x9 ++ PTRACE_SYSCALL = 0x18 ++ PTRACE_SYSCALL_INFO_ENTRY = 0x1 ++ PTRACE_SYSCALL_INFO_EXIT = 0x2 ++ PTRACE_SYSCALL_INFO_NONE = 0x0 ++ PTRACE_SYSCALL_INFO_SECCOMP = 0x3 ++ PTRACE_TRACEME = 0x0 ++ PT_DA_MASK = 0xa4 ++ PT_DA_MATCH = 0xa3 ++ PT_DC_CTL = 0xa7 ++ PT_DV_MASK = 0xa6 ++ PT_DV_MATCH = 0xa5 ++ PT_F31_V1 = 0x62 ++ PT_F31_V2 = 0x82 ++ PT_FPCR = 0x3f ++ PT_FPREG_BASE = 0x20 ++ PT_FPREG_END = 0x3e ++ PT_PC = 0x40 ++ PT_REG_BASE = 0x0 ++ PT_REG_END = 0x1d ++ PT_TP = 0x41 ++ PT_UNIQUE = 0x41 ++ PT_USP = 0x1e ++ PT_VECREG_BASE = 0x43 ++ PT_VECREG_END = 0xa1 ++ RLIMIT_AS = 0x7 ++ RLIMIT_CORE = 0x4 ++ RLIMIT_CPU = 0x0 ++ RLIMIT_DATA = 0x2 ++ RLIMIT_FSIZE = 0x1 ++ RLIMIT_NOFILE = 0x6 ++ RLIMIT_STACK = 0x3 ++ RLIM_INFINITY = -0x1 ++ RTAX_ADVMSS = 0x8 ++ RTAX_CC_ALGO = 0x10 ++ RTAX_CWND = 0x7 ++ RTAX_FASTOPEN_NO_COOKIE = 0x11 ++ RTAX_FEATURES = 0xc ++ RTAX_FEATURE_ALLFRAG = 0x8 ++ RTAX_FEATURE_ECN = 0x1 ++ RTAX_FEATURE_MASK = 0xf ++ RTAX_FEATURE_SACK = 0x2 ++ RTAX_FEATURE_TIMESTAMP = 0x4 ++ RTAX_HOPLIMIT = 0xa ++ RTAX_INITCWND = 0xb ++ RTAX_INITRWND = 0xe ++ RTAX_LOCK = 0x1 ++ RTAX_MAX = 0x11 ++ RTAX_MTU = 0x2 ++ RTAX_QUICKACK = 0xf ++ RTAX_REORDERING = 0x9 ++ RTAX_RTO_MIN = 0xd ++ RTAX_RTT = 0x4 ++ RTAX_RTTVAR = 0x5 ++ RTAX_SSTHRESH = 0x6 ++ RTAX_UNSPEC = 0x0 ++ RTAX_WINDOW = 0x3 ++ RTA_ALIGNTO = 0x4 ++ RTA_MAX = 0x1e ++ RTCF_DIRECTSRC = 0x4000000 ++ RTCF_DOREDIRECT = 0x1000000 ++ RTCF_LOG = 0x2000000 ++ RTCF_MASQ = 0x400000 ++ RTCF_NAT = 0x800000 ++ RTCF_VALVE = 0x200000 ++ RTF_ADDRCLASSMASK = 0xf8000000 ++ RTF_ADDRCONF = 0x40000 ++ RTF_ALLONLINK = 0x20000 ++ RTF_BROADCAST = 0x10000000 ++ RTF_CACHE = 0x1000000 ++ RTF_DEFAULT = 0x10000 ++ RTF_DYNAMIC = 0x10 ++ RTF_FLOW = 0x2000000 ++ RTF_GATEWAY = 0x2 ++ RTF_HOST = 0x4 ++ RTF_INTERFACE = 0x40000000 ++ RTF_IRTT = 0x100 ++ RTF_LINKRT = 0x100000 ++ RTF_LOCAL = 0x80000000 ++ RTF_MODIFIED = 0x20 ++ RTF_MSS = 0x40 ++ RTF_MTU = 0x40 ++ RTF_MULTICAST = 0x20000000 ++ RTF_NAT = 0x8000000 ++ RTF_NOFORWARD = 0x1000 ++ RTF_NONEXTHOP = 0x200000 ++ RTF_NOPMTUDISC = 0x4000 ++ RTF_POLICY = 0x4000000 ++ RTF_REINSTATE = 0x8 ++ RTF_REJECT = 0x200 ++ RTF_STATIC = 0x400 ++ RTF_THROW = 0x2000 ++ RTF_UP = 0x1 ++ RTF_WINDOW = 0x80 ++ RTF_XRESOLVE = 0x800 ++ RTM_BASE = 0x10 ++ RTM_DELACTION = 0x31 ++ RTM_DELADDR = 0x15 ++ RTM_DELADDRLABEL = 0x49 ++ RTM_DELCHAIN = 0x65 ++ RTM_DELLINK = 0x11 ++ RTM_DELLINKPROP = 0x6d ++ RTM_DELMDB = 0x55 ++ RTM_DELNEIGH = 0x1d ++ RTM_DELNETCONF = 0x51 ++ RTM_DELNEXTHOP = 0x69 ++ RTM_DELNSID = 0x59 ++ RTM_DELQDISC = 0x25 ++ RTM_DELROUTE = 0x19 ++ RTM_DELRULE = 0x21 ++ RTM_DELTCLASS = 0x29 ++ RTM_DELTFILTER = 0x2d ++ RTM_DELVLAN = 0x71 ++ RTM_F_CLONED = 0x200 ++ RTM_F_EQUALIZE = 0x400 ++ RTM_F_FIB_MATCH = 0x2000 ++ RTM_F_LOOKUP_TABLE = 0x1000 ++ RTM_F_NOTIFY = 0x100 ++ RTM_F_OFFLOAD = 0x4000 ++ RTM_F_PREFIX = 0x800 ++ RTM_F_TRAP = 0x8000 ++ RTM_GETACTION = 0x32 ++ RTM_GETADDR = 0x16 ++ RTM_GETADDRLABEL = 0x4a ++ RTM_GETANYCAST = 0x3e ++ RTM_GETCHAIN = 0x66 ++ RTM_GETDCB = 0x4e ++ RTM_GETLINK = 0x12 ++ RTM_GETLINKPROP = 0x6e ++ RTM_GETMDB = 0x56 ++ RTM_GETMULTICAST = 0x3a ++ RTM_GETNEIGH = 0x1e ++ RTM_GETNEIGHTBL = 0x42 ++ RTM_GETNETCONF = 0x52 ++ RTM_GETNEXTHOP = 0x6a ++ RTM_GETNSID = 0x5a ++ RTM_GETQDISC = 0x26 ++ RTM_GETROUTE = 0x1a ++ RTM_GETRULE = 0x22 ++ RTM_GETSTATS = 0x5e ++ RTM_GETTCLASS = 0x2a ++ RTM_GETTFILTER = 0x2e ++ RTM_GETVLAN = 0x72 ++ RTM_MAX = 0x73 ++ RTM_NEWACTION = 0x30 ++ RTM_NEWADDR = 0x14 ++ RTM_NEWADDRLABEL = 0x48 ++ RTM_NEWCACHEREPORT = 0x60 ++ RTM_NEWCHAIN = 0x64 ++ RTM_NEWLINK = 0x10 ++ RTM_NEWLINKPROP = 0x6c ++ RTM_NEWMDB = 0x54 ++ RTM_NEWNDUSEROPT = 0x44 ++ RTM_NEWNEIGH = 0x1c ++ RTM_NEWNEIGHTBL = 0x40 ++ RTM_NEWNETCONF = 0x50 ++ RTM_NEWNEXTHOP = 0x68 ++ RTM_NEWNSID = 0x58 ++ RTM_NEWNVLAN = 0x70 ++ RTM_NEWPREFIX = 0x34 ++ RTM_NEWQDISC = 0x24 ++ RTM_NEWROUTE = 0x18 ++ RTM_NEWRULE = 0x20 ++ RTM_NEWSTATS = 0x5c ++ RTM_NEWTCLASS = 0x28 ++ RTM_NEWTFILTER = 0x2c ++ RTM_NR_FAMILIES = 0x19 ++ RTM_NR_MSGTYPES = 0x64 ++ RTM_SETDCB = 0x4f ++ RTM_SETLINK = 0x13 ++ RTM_SETNEIGHTBL = 0x43 ++ RTNH_ALIGNTO = 0x4 ++ RTNH_COMPARE_MASK = 0x19 ++ RTNH_F_DEAD = 0x1 ++ RTNH_F_LINKDOWN = 0x10 ++ RTNH_F_OFFLOAD = 0x8 ++ RTNH_F_ONLINK = 0x4 ++ RTNH_F_PERVASIVE = 0x2 ++ RTNH_F_UNRESOLVED = 0x20 ++ RTN_MAX = 0xb ++ RTPROT_BABEL = 0x2a ++ RTPROT_BGP = 0xba ++ RTPROT_BIRD = 0xc ++ RTPROT_BOOT = 0x3 ++ RTPROT_DHCP = 0x10 ++ RTPROT_DNROUTED = 0xd ++ RTPROT_EIGRP = 0xc0 ++ RTPROT_GATED = 0x8 ++ RTPROT_ISIS = 0xbb ++ RTPROT_KEEPALIVED = 0x12 ++ RTPROT_KERNEL = 0x2 ++ RTPROT_MROUTED = 0x11 ++ RTPROT_MRT = 0xa ++ RTPROT_NTK = 0xf ++ RTPROT_OSPF = 0xbc ++ RTPROT_RA = 0x9 ++ RTPROT_REDIRECT = 0x1 ++ RTPROT_RIP = 0xbd ++ RTPROT_STATIC = 0x4 ++ RTPROT_UNSPEC = 0x0 ++ RTPROT_XORP = 0xe ++ RTPROT_ZEBRA = 0xb ++ RT_CLASS_DEFAULT = 0xfd ++ RT_CLASS_LOCAL = 0xff ++ RT_CLASS_MAIN = 0xfe ++ RT_CLASS_MAX = 0xff ++ RT_CLASS_UNSPEC = 0x0 ++ RUSAGE_CHILDREN = -0x1 ++ RUSAGE_SELF = 0x0 ++ RUSAGE_THREAD = 0x1 ++ SCM_CREDENTIALS = 0x2 ++ SCM_RIGHTS = 0x1 ++ SCM_TIMESTAMP = 0x1d ++ SCM_TIMESTAMPING = 0x25 ++ SCM_TIMESTAMPING_OPT_STATS = 0x36 ++ SCM_TIMESTAMPING_PKTINFO = 0x3a ++ SCM_TIMESTAMPNS = 0x23 ++ SCM_TXTIME = 0x3d ++ SCM_WIFI_STATUS = 0x29 ++ SHUT_RD = 0x0 ++ SHUT_RDWR = 0x2 ++ SHUT_WR = 0x1 ++ SIOCADDDLCI = 0x8980 ++ SIOCADDMULTI = 0x8931 ++ SIOCADDRT = 0x890b ++ SIOCATMARK = 0x40047307 ++ SIOCBONDCHANGEACTIVE = 0x8995 ++ SIOCBONDENSLAVE = 0x8990 ++ SIOCBONDINFOQUERY = 0x8994 ++ SIOCBONDRELEASE = 0x8991 ++ SIOCBONDSETHWADDR = 0x8992 ++ SIOCBONDSLAVEINFOQUERY = 0x8993 ++ SIOCBRADDBR = 0x89a0 ++ SIOCBRADDIF = 0x89a2 ++ SIOCBRDELBR = 0x89a1 ++ SIOCBRDELIF = 0x89a3 ++ SIOCDARP = 0x8953 ++ SIOCDELDLCI = 0x8981 ++ SIOCDELMULTI = 0x8932 ++ SIOCDELRT = 0x890c ++ SIOCDEVPRIVATE = 0x89f0 ++ SIOCDIFADDR = 0x8936 ++ SIOCDRARP = 0x8960 ++ SIOCETHTOOL = 0x8946 ++ SIOCGARP = 0x8954 ++ SIOCGHWTSTAMP = 0x89b1 ++ SIOCGIFADDR = 0x8915 ++ SIOCGIFBR = 0x8940 ++ SIOCGIFBRDADDR = 0x8919 ++ SIOCGIFCONF = 0x8912 ++ SIOCGIFCOUNT = 0x8938 ++ SIOCGIFDSTADDR = 0x8917 ++ SIOCGIFENCAP = 0x8925 ++ SIOCGIFFLAGS = 0x8913 ++ SIOCGIFHWADDR = 0x8927 ++ SIOCGIFINDEX = 0x8933 ++ SIOCGIFMAP = 0x8970 ++ SIOCGIFMEM = 0x891f ++ SIOCGIFMETRIC = 0x891d ++ SIOCGIFMTU = 0x8921 ++ SIOCGIFNAME = 0x8910 ++ SIOCGIFNETMASK = 0x891b ++ SIOCGIFPFLAGS = 0x8935 ++ SIOCGIFSLAVE = 0x8929 ++ SIOCGIFTXQLEN = 0x8942 ++ SIOCGIFVLAN = 0x8982 ++ SIOCGMIIPHY = 0x8947 ++ SIOCGMIIREG = 0x8948 ++ SIOCGPGRP = 0x40047309 ++ SIOCGRARP = 0x8961 ++ SIOCGSKNS = 0x894c ++ SIOCGSTAMP = 0x8906 ++ SIOCGSTAMPNS = 0x8907 ++ SIOCGSTAMPNS_NEW = 0x40108907 ++ SIOCGSTAMPNS_OLD = 0x8907 ++ SIOCGSTAMP_NEW = 0x40108906 ++ SIOCGSTAMP_OLD = 0x8906 ++ SIOCINQ = 0x4004667f ++ SIOCOUTQ = 0x40047473 ++ SIOCOUTQNSD = 0x894b ++ SIOCPROTOPRIVATE = 0x89e0 ++ SIOCRTMSG = 0x890d ++ SIOCSARP = 0x8955 ++ SIOCSHWTSTAMP = 0x89b0 ++ SIOCSIFADDR = 0x8916 ++ SIOCSIFBR = 0x8941 ++ SIOCSIFBRDADDR = 0x891a ++ SIOCSIFDSTADDR = 0x8918 ++ SIOCSIFENCAP = 0x8926 ++ SIOCSIFFLAGS = 0x8914 ++ SIOCSIFHWADDR = 0x8924 ++ SIOCSIFHWBROADCAST = 0x8937 ++ SIOCSIFLINK = 0x8911 ++ SIOCSIFMAP = 0x8971 ++ SIOCSIFMEM = 0x8920 ++ SIOCSIFMETRIC = 0x891e ++ SIOCSIFMTU = 0x8922 ++ SIOCSIFNAME = 0x8923 ++ SIOCSIFNETMASK = 0x891c ++ SIOCSIFPFLAGS = 0x8934 ++ SIOCSIFSLAVE = 0x8930 ++ SIOCSIFTXQLEN = 0x8943 ++ SIOCSIFVLAN = 0x8983 ++ SIOCSMIIREG = 0x8949 ++ SIOCSPGRP = 0x80047308 ++ SIOCSRARP = 0x8962 ++ SIOCWANDEV = 0x894a ++ SOCK_CLOEXEC = 0x200000 ++ SOCK_DCCP = 0x6 ++ SOCK_DGRAM = 0x2 ++ SOCK_IOC_TYPE = 0x89 ++ SOCK_NONBLOCK = 0x40000000 ++ SOCK_PACKET = 0xa ++ SOCK_RAW = 0x3 ++ SOCK_RDM = 0x4 ++ SOCK_SEQPACKET = 0x5 ++ SOCK_STREAM = 0x1 ++ SOL_AAL = 0x109 ++ SOL_ALG = 0x117 ++ SOL_ATM = 0x108 ++ SOL_BLUETOOTH = 0x112 ++ SOL_CAIF = 0x116 ++ SOL_DCCP = 0x10d ++ SOL_DECNET = 0x105 ++ SOL_ICMPV6 = 0x3a ++ SOL_IP = 0x0 ++ SOL_IPV6 = 0x29 ++ SOL_IRDA = 0x10a ++ SOL_IUCV = 0x115 ++ SOL_KCM = 0x119 ++ SOL_LLC = 0x10c ++ SOL_NETBEUI = 0x10b ++ SOL_NETLINK = 0x10e ++ SOL_NFC = 0x118 ++ SOL_PACKET = 0x107 ++ SOL_PNPIPE = 0x113 ++ SOL_PPPOL2TP = 0x111 ++ SOL_RAW = 0xff ++ SOL_RDS = 0x114 ++ SOL_RXRPC = 0x110 ++ SOL_SOCKET = 0xffff ++ SOL_TCP = 0x6 ++ SOL_TIPC = 0x10f ++ SOL_TLS = 0x11a ++ SOL_X25 = 0x106 ++ SOL_XDP = 0x11b ++ SOMAXCONN = 0x1000 ++ SO_ACCEPTCONN = 0x1014 ++ SO_ATTACH_BPF = 0x32 ++ SO_ATTACH_FILTER = 0x1a ++ SO_ATTACH_REUSEPORT_CBPF = 0x33 ++ SO_ATTACH_REUSEPORT_EBPF = 0x34 ++ SO_BINDTODEVICE = 0x19 ++ SO_BINDTOIFINDEX = 0x3e ++ SO_BPF_EXTENSIONS = 0x30 ++ SO_BROADCAST = 0x20 ++ SO_BSDCOMPAT = 0xe ++ SO_BUSY_POLL = 0x2e ++ SO_CNX_ADVICE = 0x35 ++ SO_COOKIE = 0x39 ++ SO_DEBUG = 0x1 ++ SO_DETACH_BPF = 0x1b ++ SO_DETACH_FILTER = 0x1b ++ SO_DETACH_REUSEPORT_BPF = 0x44 ++ SO_DOMAIN = 0x1029 ++ SO_DONTROUTE = 0x10 ++ SO_ERROR = 0x1007 ++ SO_GET_FILTER = 0x1a ++ SO_INCOMING_CPU = 0x31 ++ SO_INCOMING_NAPI_ID = 0x38 ++ SO_KEEPALIVE = 0x8 ++ SO_LINGER = 0x80 ++ SO_LOCK_FILTER = 0x2c ++ SO_MARK = 0x24 ++ SO_MAX_PACING_RATE = 0x2f ++ SO_MEMINFO = 0x37 ++ SO_NOFCS = 0x2b ++ SO_NO_CHECK = 0xb ++ SO_OOBINLINE = 0x100 ++ SO_PASSCRED = 0x11 ++ SO_PASSSEC = 0x22 ++ SO_PEEK_OFF = 0x2a ++ SO_PEERCRED = 0x12 ++ SO_PEERGROUPS = 0x3b ++ SO_PEERNAME = 0x1c ++ SO_PEERSEC = 0x1e ++ SO_PRIORITY = 0xc ++ SO_PROTOCOL = 0x1028 ++ SO_RCVBUF = 0x1002 ++ SO_RCVBUFFORCE = 0x100b ++ SO_RCVLOWAT = 0x1010 ++ SO_RCVTIMEO = 0x1012 ++ SO_RCVTIMEO_NEW = 0x42 ++ SO_RCVTIMEO_OLD = 0x1012 ++ SO_REUSEADDR = 0x4 ++ SO_REUSEPORT = 0x200 ++ SO_RXQ_OVFL = 0x28 ++ SO_SECURITY_AUTHENTICATION = 0x13 ++ SO_SECURITY_ENCRYPTION_NETWORK = 0x15 ++ SO_SECURITY_ENCRYPTION_TRANSPORT = 0x14 ++ SO_SELECT_ERR_QUEUE = 0x2d ++ SO_SNDBUF = 0x1001 ++ SO_SNDBUFFORCE = 0x100a ++ SO_SNDLOWAT = 0x1011 ++ SO_SNDTIMEO = 0x1013 ++ SO_SNDTIMEO_NEW = 0x43 ++ SO_SNDTIMEO_OLD = 0x1013 ++ SO_TIMESTAMP = 0x1d ++ SO_TIMESTAMPING = 0x25 ++ SO_TIMESTAMPING_NEW = 0x41 ++ SO_TIMESTAMPING_OLD = 0x25 ++ SO_TIMESTAMPNS = 0x23 ++ SO_TIMESTAMPNS_NEW = 0x40 ++ SO_TIMESTAMPNS_OLD = 0x23 ++ SO_TIMESTAMP_NEW = 0x3f ++ SO_TIMESTAMP_OLD = 0x1d ++ SO_TXTIME = 0x3d ++ SO_TYPE = 0x1008 ++ SO_WIFI_STATUS = 0x29 ++ SO_ZEROCOPY = 0x3c ++ S_BLKSIZE = 0x200 ++ S_IEXEC = 0x40 ++ S_IFBLK = 0x6000 ++ S_IFCHR = 0x2000 ++ S_IFDIR = 0x4000 ++ S_IFIFO = 0x1000 ++ S_IFLNK = 0xa000 ++ S_IFMT = 0xf000 ++ S_IFREG = 0x8000 ++ S_IFSOCK = 0xc000 ++ S_IREAD = 0x100 ++ S_IRGRP = 0x20 ++ S_IROTH = 0x4 ++ S_IRUSR = 0x100 ++ S_IRWXG = 0x38 ++ S_IRWXO = 0x7 ++ S_IRWXU = 0x1c0 ++ S_ISGID = 0x400 ++ S_ISUID = 0x800 ++ S_ISVTX = 0x200 ++ S_IWGRP = 0x10 ++ S_IWOTH = 0x2 ++ S_IWRITE = 0x80 ++ S_IWUSR = 0x80 ++ S_IXGRP = 0x8 ++ S_IXOTH = 0x1 ++ S_IXUSR = 0x40 ++ TCFLSH = 0x2000741f ++ TCIFLUSH = 0x0 ++ TCIOFLUSH = 0x2 ++ TCOFLUSH = 0x1 ++ TCP_CC_INFO = 0x1a ++ TCP_CM_INQ = 0x24 ++ TCP_CONGESTION = 0xd ++ TCP_COOKIE_IN_ALWAYS = 0x1 ++ TCP_COOKIE_MAX = 0x10 ++ TCP_COOKIE_MIN = 0x8 ++ TCP_COOKIE_OUT_NEVER = 0x2 ++ TCP_COOKIE_PAIR_SIZE = 0x20 ++ TCP_COOKIE_TRANSACTIONS = 0xf ++ TCP_CORK = 0x3 ++ TCP_DEFER_ACCEPT = 0x9 ++ TCP_FASTOPEN = 0x17 ++ TCP_FASTOPEN_CONNECT = 0x1e ++ TCP_FASTOPEN_KEY = 0x21 ++ TCP_FASTOPEN_NO_COOKIE = 0x22 ++ TCP_INFO = 0xb ++ TCP_INQ = 0x24 ++ TCP_KEEPCNT = 0x6 ++ TCP_KEEPIDLE = 0x4 ++ TCP_KEEPINTVL = 0x5 ++ TCP_LINGER2 = 0x8 ++ TCP_MAXSEG = 0x2 ++ TCP_MAXWIN = 0xffff ++ TCP_MAX_WINSHIFT = 0xe ++ TCP_MD5SIG = 0xe ++ TCP_MD5SIG_EXT = 0x20 ++ TCP_MD5SIG_FLAG_PREFIX = 0x1 ++ TCP_MD5SIG_MAXKEYLEN = 0x50 ++ TCP_MSS = 0x200 ++ TCP_MSS_DEFAULT = 0x218 ++ TCP_MSS_DESIRED = 0x4c4 ++ TCP_NODELAY = 0x1 ++ TCP_NOTSENT_LOWAT = 0x19 ++ TCP_QUEUE_SEQ = 0x15 ++ TCP_QUICKACK = 0xc ++ TCP_REPAIR = 0x13 ++ TCP_REPAIR_OFF = 0x0 ++ TCP_REPAIR_OFF_NO_WP = -0x1 ++ TCP_REPAIR_ON = 0x1 ++ TCP_REPAIR_OPTIONS = 0x16 ++ TCP_REPAIR_QUEUE = 0x14 ++ TCP_REPAIR_WINDOW = 0x1d ++ TCP_SAVED_SYN = 0x1c ++ TCP_SAVE_SYN = 0x1b ++ TCP_SYNCNT = 0x7 ++ TCP_S_DATA_IN = 0x4 ++ TCP_S_DATA_OUT = 0x8 ++ TCP_THIN_DUPACK = 0x11 ++ TCP_THIN_LINEAR_TIMEOUTS = 0x10 ++ TCP_TIMESTAMP = 0x18 ++ TCP_TX_DELAY = 0x25 ++ TCP_ULP = 0x1f ++ TCP_USER_TIMEOUT = 0x12 ++ TCP_WINDOW_CLAMP = 0xa ++ TCP_ZEROCOPY_RECEIVE = 0x23 ++ TCSAFLUSH = 0x2 ++ TIOCCBRK = 0x5428 ++ TIOCCONS = 0x541d ++ TIOCEXCL = 0x540c ++ TIOCGDEV = 0x40045432 ++ TIOCGETD = 0x5424 ++ TIOCGEXCL = 0x40045440 ++ TIOCGICOUNT = 0x545d ++ TIOCGLCKTRMIOS = 0x5456 ++ TIOCGPGRP = 0x40047477 ++ TIOCGPKT = 0x40045438 ++ TIOCGPTLCK = 0x40045439 ++ TIOCGPTN = 0x40045430 ++ TIOCGPTPEER = 0x20005441 ++ TIOCGSERIAL = 0x541e ++ TIOCGSID = 0x5429 ++ TIOCGSOFTCAR = 0x5419 ++ TIOCLINUX = 0x541c ++ TIOCMBIC = 0x5417 ++ TIOCMBIS = 0x5416 ++ TIOCMGET = 0x5415 ++ TIOCMIWAIT = 0x545c ++ TIOCMSET = 0x5418 ++ TIOCM_CAR = 0x40 ++ TIOCM_CD = 0x40 ++ TIOCM_CTS = 0x20 ++ TIOCM_DSR = 0x100 ++ TIOCM_DTR = 0x2 ++ TIOCM_LE = 0x1 ++ TIOCM_LOOP = 0x8000 ++ TIOCM_OUT1 = 0x2000 ++ TIOCM_OUT2 = 0x4000 ++ TIOCM_RI = 0x80 ++ TIOCM_RNG = 0x80 ++ TIOCM_RTS = 0x4 ++ TIOCM_SR = 0x10 ++ TIOCM_ST = 0x8 ++ TIOCNOTTY = 0x5422 ++ TIOCNXCL = 0x540d ++ TIOCOUTQ = 0x40047473 ++ TIOCPKT = 0x5420 ++ TIOCPKT_DATA = 0x0 ++ TIOCPKT_DOSTOP = 0x20 ++ TIOCPKT_FLUSHREAD = 0x1 ++ TIOCPKT_FLUSHWRITE = 0x2 ++ TIOCPKT_IOCTL = 0x40 ++ TIOCPKT_NOSTOP = 0x10 ++ TIOCPKT_START = 0x8 ++ TIOCPKT_STOP = 0x4 ++ TIOCSBRK = 0x5427 ++ TIOCSCTTY = 0x540e ++ TIOCSERCONFIG = 0x5453 ++ TIOCSERGETLSR = 0x5459 ++ TIOCSERGETMULTI = 0x545a ++ TIOCSERGSTRUCT = 0x5458 ++ TIOCSERGWILD = 0x5454 ++ TIOCSERSETMULTI = 0x545b ++ TIOCSERSWILD = 0x5455 ++ TIOCSER_TEMT = 0x1 ++ TIOCSETD = 0x5423 ++ TIOCSIG = 0x80045436 ++ TIOCSLCKTRMIOS = 0x5457 ++ TIOCSPGRP = 0x80047476 ++ TIOCSPTLCK = 0x80045431 ++ TIOCSSERIAL = 0x541f ++ TIOCSSOFTCAR = 0x541a ++ TIOCSTART = 0x2000746e ++ TIOCSTI = 0x5412 ++ TIOCSTOP = 0x2000746f ++ TIOCVHANGUP = 0x5437 ++ TOSTOP = 0x400000 ++ TUNATTACHFILTER = 0x801054d5 ++ TUNDETACHFILTER = 0x801054d6 ++ TUNGETDEVNETNS = 0x200054e3 ++ TUNGETFEATURES = 0x400454cf ++ TUNGETFILTER = 0x401054db ++ TUNGETIFF = 0x400454d2 ++ TUNGETSNDBUF = 0x400454d3 ++ TUNGETVNETBE = 0x400454df ++ TUNGETVNETHDRSZ = 0x400454d7 ++ TUNGETVNETLE = 0x400454dd ++ TUNSETCARRIER = 0x800454e2 ++ TUNSETDEBUG = 0x800454c9 ++ TUNSETFILTEREBPF = 0x400454e1 ++ TUNSETGROUP = 0x800454ce ++ TUNSETIFF = 0x800454ca ++ TUNSETIFINDEX = 0x800454da ++ TUNSETLINK = 0x800454cd ++ TUNSETNOCSUM = 0x800454c8 ++ TUNSETOFFLOAD = 0x800454d0 ++ TUNSETOWNER = 0x800454cc ++ TUNSETPERSIST = 0x800454cb ++ TUNSETQUEUE = 0x800454d9 ++ TUNSETSNDBUF = 0x800454d4 ++ TUNSETSTEERINGEBPF = 0x400454e0 ++ TUNSETTXFILTER = 0x800454d1 ++ TUNSETVNETBE = 0x800454de ++ TUNSETVNETHDRSZ = 0x800454d8 ++ TUNSETVNETLE = 0x800454dc ++ VDISCARD = 0xf ++ VEOF = 0x0 ++ VEOL = 0x1 ++ VEOL2 = 0x2 ++ VERASE = 0x3 ++ VINTR = 0x8 ++ VKILL = 0x5 ++ VLNEXT = 0xe ++ VMIN = 0x10 ++ VQUIT = 0x9 ++ VREPRINT = 0x6 ++ VSTART = 0xc ++ VSTOP = 0xd ++ VSUSP = 0xa ++ VSWTC = 0x7 ++ VT0 = 0x0 ++ VT1 = 0x10000 ++ VTDLY = 0x10000 ++ VTIME = 0x11 ++ VWERASE = 0x4 ++ WALL = 0x40000000 ++ WCLONE = 0x80000000 ++ WCONTINUED = 0x8 ++ WEXITED = 0x4 ++ WNOHANG = 0x1 ++ WNOTHREAD = 0x20000000 ++ WNOWAIT = 0x1000000 ++ WORDSIZE = 0x40 ++ WSTOPPED = 0x2 ++ WUNTRACED = 0x2 ++) ++ ++// Errors ++const ( ++ E2BIG = Errno(0x7) ++ EACCES = Errno(0xd) ++ EADDRINUSE = Errno(0x30) ++ EADDRNOTAVAIL = Errno(0x31) ++ EADV = Errno(0x6b) ++ EAFNOSUPPORT = Errno(0x2f) ++ EAGAIN = Errno(0x23) ++ EALREADY = Errno(0x25) ++ EBADE = Errno(0x61) ++ EBADF = Errno(0x9) ++ EBADFD = Errno(0x72) ++ EBADMSG = Errno(0x54) ++ EBADR = Errno(0x62) ++ EBADRQC = Errno(0x65) ++ EBADSLT = Errno(0x66) ++ EBFONT = Errno(0x68) ++ EBUSY = Errno(0x10) ++ ECANCELED = Errno(0x83) ++ ECHILD = Errno(0xa) ++ ECHRNG = Errno(0x58) ++ ECOMM = Errno(0x6d) ++ ECONNABORTED = Errno(0x35) ++ ECONNREFUSED = Errno(0x3d) ++ ECONNRESET = Errno(0x36) ++ EDEADLK = Errno(0xb) ++ EDEADLOCK = Errno(0xb) ++ EDESTADDRREQ = Errno(0x27) ++ EDOM = Errno(0x21) ++ EDOTDOT = Errno(0x6f) ++ EDQUOT = Errno(0x45) ++ EEXIST = Errno(0x11) ++ EFAULT = Errno(0xe) ++ EFBIG = Errno(0x1b) ++ EHOSTDOWN = Errno(0x40) ++ EHOSTUNREACH = Errno(0x41) ++ EHWPOISON = Errno(0x8b) ++ EIDRM = Errno(0x51) ++ EILSEQ = Errno(0x74) ++ EINPROGRESS = Errno(0x24) ++ EINTR = Errno(0x4) ++ EINVAL = Errno(0x16) ++ EIO = Errno(0x5) ++ EISCONN = Errno(0x38) ++ EISDIR = Errno(0x15) ++ EISNAM = Errno(0x78) ++ EKEYEXPIRED = Errno(0x85) ++ EKEYREJECTED = Errno(0x87) ++ EKEYREVOKED = Errno(0x86) ++ EL2HLT = Errno(0x60) ++ EL2NSYNC = Errno(0x59) ++ EL3HLT = Errno(0x5a) ++ EL3RST = Errno(0x5b) ++ ELIBACC = Errno(0x7a) ++ ELIBBAD = Errno(0x7b) ++ ELIBEXEC = Errno(0x7e) ++ ELIBMAX = Errno(0x7d) ++ ELIBSCN = Errno(0x7c) ++ ELNRNG = Errno(0x5d) ++ ELOOP = Errno(0x3e) ++ EMEDIUMTYPE = Errno(0x82) ++ EMFILE = Errno(0x18) ++ EMLINK = Errno(0x1f) ++ EMSGSIZE = Errno(0x28) ++ EMULTIHOP = Errno(0x6e) ++ ENAMETOOLONG = Errno(0x3f) ++ ENAVAIL = Errno(0x77) ++ ENETDOWN = Errno(0x32) ++ ENETRESET = Errno(0x34) ++ ENETUNREACH = Errno(0x33) ++ ENFILE = Errno(0x17) ++ ENOANO = Errno(0x64) ++ ENOBUFS = Errno(0x37) ++ ENOCSI = Errno(0x5f) ++ ENODATA = Errno(0x56) ++ ENODEV = Errno(0x13) ++ ENOENT = Errno(0x2) ++ ENOEXEC = Errno(0x8) ++ ENOKEY = Errno(0x84) ++ ENOLCK = Errno(0x4d) ++ ENOLINK = Errno(0x6a) ++ ENOMEDIUM = Errno(0x81) ++ ENOMEM = Errno(0xc) ++ ENOMSG = Errno(0x50) ++ ENONET = Errno(0x69) ++ ENOPKG = Errno(0x5c) ++ ENOPROTOOPT = Errno(0x2a) ++ ENOSPC = Errno(0x1c) ++ ENOSR = Errno(0x52) ++ ENOSTR = Errno(0x57) ++ ENOSYS = Errno(0x4e) ++ ENOTBLK = Errno(0xf) ++ ENOTCONN = Errno(0x39) ++ ENOTDIR = Errno(0x14) ++ ENOTEMPTY = Errno(0x42) ++ ENOTNAM = Errno(0x76) ++ ENOTRECOVERABLE = Errno(0x89) ++ ENOTSOCK = Errno(0x26) ++ ENOTSUP = Errno(0x2d) ++ ENOTTY = Errno(0x19) ++ ENOTUNIQ = Errno(0x71) ++ ENXIO = Errno(0x6) ++ EOPNOTSUPP = Errno(0x2d) ++ EOVERFLOW = Errno(0x70) ++ EOWNERDEAD = Errno(0x88) ++ EPERM = Errno(0x1) ++ EPFNOSUPPORT = Errno(0x2e) ++ EPIPE = Errno(0x20) ++ EPROTO = Errno(0x55) ++ EPROTONOSUPPORT = Errno(0x2b) ++ EPROTOTYPE = Errno(0x29) ++ ERANGE = Errno(0x22) ++ EREMCHG = Errno(0x73) ++ EREMOTE = Errno(0x47) ++ EREMOTEIO = Errno(0x79) ++ ERESTART = Errno(0x7f) ++ ERFKILL = Errno(0x8a) ++ EROFS = Errno(0x1e) ++ ESHUTDOWN = Errno(0x3a) ++ ESOCKTNOSUPPORT = Errno(0x2c) ++ ESPIPE = Errno(0x1d) ++ ESRCH = Errno(0x3) ++ ESRMNT = Errno(0x6c) ++ ESTALE = Errno(0x46) ++ ESTRPIPE = Errno(0x80) ++ ETIME = Errno(0x53) ++ ETIMEDOUT = Errno(0x3c) ++ ETOOMANYREFS = Errno(0x3b) ++ ETXTBSY = Errno(0x1a) ++ EUCLEAN = Errno(0x75) ++ EUNATCH = Errno(0x5e) ++ EUSERS = Errno(0x44) ++ EWOULDBLOCK = Errno(0x23) ++ EXDEV = Errno(0x12) ++ EXFULL = Errno(0x63) ++) ++ ++// Signals ++const ( ++ SIGABRT = Signal(0x6) ++ SIGALRM = Signal(0xe) ++ SIGBUS = Signal(0xa) ++ SIGCHLD = Signal(0x14) ++ SIGCLD = Signal(0x14) ++ SIGCONT = Signal(0x13) ++ SIGEMT = Signal(0x7) ++ SIGFPE = Signal(0x8) ++ SIGHUP = Signal(0x1) ++ SIGILL = Signal(0x4) ++ SIGINFO = Signal(0x1d) ++ SIGINT = Signal(0x2) ++ SIGIO = Signal(0x17) ++ SIGIOT = Signal(0x6) ++ SIGKILL = Signal(0x9) ++ SIGPIPE = Signal(0xd) ++ SIGPOLL = Signal(0x17) ++ SIGPROF = Signal(0x1b) ++ SIGPWR = Signal(0x1d) ++ SIGQUIT = Signal(0x3) ++ SIGSEGV = Signal(0xb) ++ SIGSTOP = Signal(0x11) ++ SIGSYS = Signal(0xc) ++ SIGTERM = Signal(0xf) ++ SIGTRAP = Signal(0x5) ++ SIGTSTP = Signal(0x12) ++ SIGTTIN = Signal(0x15) ++ SIGTTOU = Signal(0x16) ++ SIGURG = Signal(0x10) ++ SIGUSR1 = Signal(0x1e) ++ SIGUSR2 = Signal(0x1f) ++ SIGVTALRM = Signal(0x1a) ++ SIGWINCH = Signal(0x1c) ++ SIGXCPU = Signal(0x18) ++ SIGXFSZ = Signal(0x19) ++) ++ ++// Error table ++var errors = [...]string{ ++ 1: "operation not permitted", ++ 2: "no such file or directory", ++ 3: "no such process", ++ 4: "interrupted system call", ++ 5: "input/output error", ++ 6: "no such device or address", ++ 7: "argument list too long", ++ 8: "exec format error", ++ 9: "bad file descriptor", ++ 10: "no child processes", ++ 11: "resource deadlock avoided", ++ 12: "cannot allocate memory", ++ 13: "permission denied", ++ 14: "bad address", ++ 15: "block device required", ++ 16: "device or resource busy", ++ 17: "file exists", ++ 18: "invalid cross-device link", ++ 19: "no such device", ++ 20: "not a directory", ++ 21: "is a directory", ++ 22: "invalid argument", ++ 23: "too many open files in system", ++ 24: "too many open files", ++ 25: "inappropriate ioctl for device", ++ 26: "text file busy", ++ 27: "file too large", ++ 28: "no space left on device", ++ 29: "illegal seek", ++ 30: "read-only file system", ++ 31: "too many links", ++ 32: "broken pipe", ++ 33: "numerical argument out of domain", ++ 34: "numerical result out of range", ++ 35: "resource temporarily unavailable", ++ 36: "operation now in progress", ++ 37: "operation already in progress", ++ 38: "socket operation on non-socket", ++ 39: "destination address required", ++ 40: "message too long", ++ 41: "protocol wrong type for socket", ++ 42: "protocol not available", ++ 43: "protocol not supported", ++ 44: "socket type not supported", ++ 45: "operation not supported", ++ 46: "protocol family not supported", ++ 47: "address family not supported by protocol", ++ 48: "address already in use", ++ 49: "cannot assign requested address", ++ 50: "network is down", ++ 51: "network is unreachable", ++ 52: "network dropped connection on reset", ++ 53: "software caused connection abort", ++ 54: "connection reset by peer", ++ 55: "no buffer space available", ++ 56: "transport endpoint is already connected", ++ 57: "transport endpoint is not connected", ++ 58: "cannot send after transport endpoint shutdown", ++ 59: "too many references: cannot splice", ++ 60: "connection timed out", ++ 61: "connection refused", ++ 62: "too many levels of symbolic links", ++ 63: "file name too long", ++ 64: "host is down", ++ 65: "no route to host", ++ 66: "directory not empty", ++ 68: "too many users", ++ 69: "disk quota exceeded", ++ 70: "stale file handle", ++ 71: "object is remote", ++ 77: "no locks available", ++ 78: "function not implemented", ++ 80: "no message of desired type", ++ 81: "identifier removed", ++ 82: "out of streams resources", ++ 83: "timer expired", ++ 84: "bad message", ++ 85: "protocol error", ++ 86: "no data available", ++ 87: "device not a stream", ++ 88: "channel number out of range", ++ 89: "level 2 not synchronized", ++ 90: "level 3 halted", ++ 91: "level 3 reset", ++ 92: "package not installed", ++ 93: "link number out of range", ++ 94: "protocol driver not attached", ++ 95: "no CSI structure available", ++ 96: "level 2 halted", ++ 97: "invalid exchange", ++ 98: "invalid request descriptor", ++ 99: "exchange full", ++ 100: "no anode", ++ 101: "invalid request code", ++ 102: "invalid slot", ++ 104: "bad font file format", ++ 105: "machine is not on the network", ++ 106: "link has been severed", ++ 107: "advertise error", ++ 108: "srmount error", ++ 109: "communication error on send", ++ 110: "multihop attempted", ++ 111: "RFS specific error", ++ 112: "value too large for defined data type", ++ 113: "name not unique on network", ++ 114: "file descriptor in bad state", ++ 115: "remote address changed", ++ 116: "invalid or incomplete multibyte or wide character", ++ 117: "structure needs cleaning", ++ 118: "not a XENIX named type file", ++ 119: "no XENIX semaphores available", ++ 120: "is a named type file", ++ 121: "remote I/O error", ++ 122: "can not access a needed shared library", ++ 123: "accessing a corrupted shared library", ++ 124: ".lib section in a.out corrupted", ++ 125: "attempting to link in too many shared libraries", ++ 126: "cannot exec a shared library directly", ++ 127: "interrupted system call should be restarted", ++ 128: "streams pipe error", ++ 129: "no medium found", ++ 130: "wrong medium type", ++ 131: "operation canceled", ++ 132: "required key not available", ++ 133: "key has expired", ++ 134: "key has been revoked", ++ 135: "key was rejected by service", ++ 136: "owner died", ++ 137: "state not recoverable", ++ 138: "operation not possible due to RF-kill", ++ 139: "memory page has hardware error", ++} ++ ++// Signal table ++var signals = [...]string{ ++ 1: "hangup", ++ 2: "interrupt", ++ 3: "quit", ++ 4: "illegal instruction", ++ 5: "trace/breakpoint trap", ++ 6: "aborted", ++ 7: "EMT trap", ++ 8: "floating point exception", ++ 9: "killed", ++ 10: "bus error", ++ 11: "segmentation fault", ++ 12: "bad system call", ++ 13: "broken pipe", ++ 14: "alarm clock", ++ 15: "terminated", ++ 16: "urgent I/O condition", ++ 17: "stopped (signal)", ++ 18: "stopped", ++ 19: "continued", ++ 20: "child exited", ++ 21: "stopped (tty input)", ++ 22: "stopped (tty output)", ++ 23: "I/O possible", ++ 24: "CPU time limit exceeded", ++ 25: "file size limit exceeded", ++ 26: "virtual timer expired", ++ 27: "profiling timer expired", ++ 28: "window changed", ++ 29: "power failure", ++ 30: "user defined signal 1", ++ 31: "user defined signal 2", ++} +diff --git a/src/syscall/zsyscall_linux_sw64.go b/src/syscall/zsyscall_linux_sw64.go +new file mode 100644 +index 0000000000..d617aa07fd +--- /dev/null ++++ b/src/syscall/zsyscall_linux_sw64.go +@@ -0,0 +1,1647 @@ ++// mksyscall.pl -tags linux,sw64 syscall_linux.go syscall_linux_sw64.go ++// Code generated by the command above; DO NOT EDIT. ++ ++//go:build linux && sw64 ++ ++package syscall ++ ++import "unsafe" ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func faccessat(dirfd int, path string, mode uint32) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode)) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func faccessat2(dirfd int, path string, mode uint32, flags int) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall6(_SYS_faccessat2, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func fchmodat(dirfd int, path string, mode uint32) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode)) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func fchmodat2(dirfd int, path string, mode uint32, flags int) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall6(_SYS_fchmodat2, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(oldpath) ++ if err != nil { ++ return ++ } ++ var _p1 *byte ++ _p1, err = BytePtrFromString(newpath) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall6(SYS_LINKAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ r0, _, e1 := Syscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mode), 0, 0) ++ fd = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func pipe2(p *[2]_C_int, flags int) (err error) { ++ _, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func readlinkat(dirfd int, path string, buf []byte) (n int, err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ var _p1 unsafe.Pointer ++ if len(buf) > 0 { ++ _p1 = unsafe.Pointer(&buf[0]) ++ } else { ++ _p1 = unsafe.Pointer(&_zero) ++ } ++ r0, _, e1 := Syscall6(SYS_READLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0) ++ n = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func symlinkat(oldpath string, newdirfd int, newpath string) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(oldpath) ++ if err != nil { ++ return ++ } ++ var _p1 *byte ++ _p1, err = BytePtrFromString(newpath) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall(SYS_SYMLINKAT, uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1))) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func unlinkat(dirfd int, path string, flags int) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall(SYS_UNLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags)) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flag), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Getcwd(buf []byte) (n int, err error) { ++ var _p0 unsafe.Pointer ++ if len(buf) > 0 { ++ _p0 = unsafe.Pointer(&buf[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ r0, _, e1 := Syscall(SYS_GETCWD, uintptr(_p0), uintptr(len(buf)), 0) ++ n = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) { ++ r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0) ++ wpid = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) { ++ _, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func ptracePtr(request int, pid int, addr uintptr, data unsafe.Pointer) (err error) { ++ _, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(arg) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall6(SYS_REBOOT, uintptr(magic1), uintptr(magic2), uintptr(cmd), uintptr(unsafe.Pointer(_p0)), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func mount(source string, target string, fstype string, flags uintptr, data *byte) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(source) ++ if err != nil { ++ return ++ } ++ var _p1 *byte ++ _p1, err = BytePtrFromString(target) ++ if err != nil { ++ return ++ } ++ var _p2 *byte ++ _p2, err = BytePtrFromString(fstype) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall6(SYS_MOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(_p2)), uintptr(flags), uintptr(unsafe.Pointer(data)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Acct(path string) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall(SYS_ACCT, uintptr(unsafe.Pointer(_p0)), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Adjtimex(buf *Timex) (state int, err error) { ++ r0, _, e1 := Syscall(SYS_ADJTIMEX, uintptr(unsafe.Pointer(buf)), 0, 0) ++ state = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Chdir(path string) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Chroot(path string) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Close(fd int) (err error) { ++ _, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Dup(oldfd int) (fd int, err error) { ++ r0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), 0, 0) ++ fd = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Dup3(oldfd int, newfd int, flags int) (err error) { ++ _, _, e1 := Syscall(SYS_DUP3, uintptr(oldfd), uintptr(newfd), uintptr(flags)) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func EpollCreate1(flag int) (fd int, err error) { ++ r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE1, uintptr(flag), 0, 0) ++ fd = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) { ++ _, _, e1 := RawSyscall6(SYS_EPOLL_CTL, uintptr(epfd), uintptr(op), uintptr(fd), uintptr(unsafe.Pointer(event)), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Fallocate(fd int, mode uint32, off int64, len int64) (err error) { ++ _, _, e1 := Syscall6(SYS_FALLOCATE, uintptr(fd), uintptr(mode), uintptr(off), uintptr(len), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Fchdir(fd int) (err error) { ++ _, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Fchmod(fd int, mode uint32) (err error) { ++ _, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall6(SYS_FCHOWNAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func fcntl(fd int, cmd int, arg int) (val int, err error) { ++ r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg)) ++ val = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Fdatasync(fd int) (err error) { ++ _, _, e1 := Syscall(SYS_FDATASYNC, uintptr(fd), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Flock(fd int, how int) (err error) { ++ _, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Fsync(fd int) (err error) { ++ _, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Getdents(fd int, buf []byte) (n int, err error) { ++ var _p0 unsafe.Pointer ++ if len(buf) > 0 { ++ _p0 = unsafe.Pointer(&buf[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ r0, _, e1 := Syscall(SYS_GETDENTS64, uintptr(fd), uintptr(_p0), uintptr(len(buf))) ++ n = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Getpgid(pid int) (pgid int, err error) { ++ r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0) ++ pgid = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Getpid() (pid int) { ++ r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0) ++ pid = int(r0) ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Getppid() (ppid int) { ++ r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0) ++ ppid = int(r0) ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Getpriority(which int, who int) (prio int, err error) { ++ r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0) ++ prio = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Getrusage(who int, rusage *Rusage) (err error) { ++ _, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Gettid() (tid int) { ++ r0, _, _ := RawSyscall(SYS_GETTID, 0, 0, 0) ++ tid = int(r0) ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Getxattr(path string, attr string, dest []byte) (sz int, err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ var _p1 *byte ++ _p1, err = BytePtrFromString(attr) ++ if err != nil { ++ return ++ } ++ var _p2 unsafe.Pointer ++ if len(dest) > 0 { ++ _p2 = unsafe.Pointer(&dest[0]) ++ } else { ++ _p2 = unsafe.Pointer(&_zero) ++ } ++ r0, _, e1 := Syscall6(SYS_GETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(dest)), 0, 0) ++ sz = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(pathname) ++ if err != nil { ++ return ++ } ++ r0, _, e1 := Syscall(SYS_INOTIFY_ADD_WATCH, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(mask)) ++ watchdesc = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func InotifyInit1(flags int) (fd int, err error) { ++ r0, _, e1 := RawSyscall(SYS_INOTIFY_INIT1, uintptr(flags), 0, 0) ++ fd = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func InotifyRmWatch(fd int, watchdesc uint32) (success int, err error) { ++ r0, _, e1 := RawSyscall(SYS_INOTIFY_RM_WATCH, uintptr(fd), uintptr(watchdesc), 0) ++ success = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Kill(pid int, sig Signal) (err error) { ++ _, _, e1 := RawSyscall(SYS_KILL, uintptr(pid), uintptr(sig), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Klogctl(typ int, buf []byte) (n int, err error) { ++ var _p0 unsafe.Pointer ++ if len(buf) > 0 { ++ _p0 = unsafe.Pointer(&buf[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ r0, _, e1 := Syscall(SYS_SYSLOG, uintptr(typ), uintptr(_p0), uintptr(len(buf))) ++ n = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Listxattr(path string, dest []byte) (sz int, err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ var _p1 unsafe.Pointer ++ if len(dest) > 0 { ++ _p1 = unsafe.Pointer(&dest[0]) ++ } else { ++ _p1 = unsafe.Pointer(&_zero) ++ } ++ r0, _, e1 := Syscall(SYS_LISTXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest))) ++ sz = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Mkdirat(dirfd int, path string, mode uint32) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall(SYS_MKDIRAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode)) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Mknodat(dirfd int, path string, mode uint32, dev int) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall6(SYS_MKNODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Nanosleep(time *Timespec, leftover *Timespec) (err error) { ++ _, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func PivotRoot(newroot string, putold string) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(newroot) ++ if err != nil { ++ return ++ } ++ var _p1 *byte ++ _p1, err = BytePtrFromString(putold) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall(SYS_PIVOT_ROOT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func prlimit1(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) { ++ _, _, e1 := RawSyscall6(SYS_PRLIMIT64, uintptr(pid), uintptr(resource), uintptr(unsafe.Pointer(newlimit)), uintptr(unsafe.Pointer(old)), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func read(fd int, p []byte) (n int, err error) { ++ var _p0 unsafe.Pointer ++ if len(p) > 0 { ++ _p0 = unsafe.Pointer(&p[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p))) ++ n = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Removexattr(path string, attr string) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ var _p1 *byte ++ _p1, err = BytePtrFromString(attr) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall(SYS_REMOVEXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Setdomainname(p []byte) (err error) { ++ var _p0 unsafe.Pointer ++ if len(p) > 0 { ++ _p0 = unsafe.Pointer(&p[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ _, _, e1 := Syscall(SYS_SETDOMAINNAME, uintptr(_p0), uintptr(len(p)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Sethostname(p []byte) (err error) { ++ var _p0 unsafe.Pointer ++ if len(p) > 0 { ++ _p0 = unsafe.Pointer(&p[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ _, _, e1 := Syscall(SYS_SETHOSTNAME, uintptr(_p0), uintptr(len(p)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Setpgid(pid int, pgid int) (err error) { ++ _, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Setsid() (pid int, err error) { ++ r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0) ++ pid = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Settimeofday(tv *Timeval) (err error) { ++ _, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Setpriority(which int, who int, prio int) (err error) { ++ _, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio)) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Setxattr(path string, attr string, data []byte, flags int) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ var _p1 *byte ++ _p1, err = BytePtrFromString(attr) ++ if err != nil { ++ return ++ } ++ var _p2 unsafe.Pointer ++ if len(data) > 0 { ++ _p2 = unsafe.Pointer(&data[0]) ++ } else { ++ _p2 = unsafe.Pointer(&_zero) ++ } ++ _, _, e1 := Syscall6(SYS_SETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(data)), uintptr(flags), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Sync() { ++ Syscall(SYS_SYNC, 0, 0, 0) ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Sysinfo(info *Sysinfo_t) (err error) { ++ _, _, e1 := RawSyscall(SYS_SYSINFO, uintptr(unsafe.Pointer(info)), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) { ++ r0, _, e1 := Syscall6(SYS_TEE, uintptr(rfd), uintptr(wfd), uintptr(len), uintptr(flags), 0, 0) ++ n = int64(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Tgkill(tgid int, tid int, sig Signal) (err error) { ++ _, _, e1 := RawSyscall(SYS_TGKILL, uintptr(tgid), uintptr(tid), uintptr(sig)) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Times(tms *Tms) (ticks uintptr, err error) { ++ r0, _, e1 := RawSyscall(SYS_TIMES, uintptr(unsafe.Pointer(tms)), 0, 0) ++ ticks = uintptr(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Umask(mask int) (oldmask int) { ++ r0, _, _ := RawSyscall(SYS_UMASK, uintptr(mask), 0, 0) ++ oldmask = int(r0) ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Uname(buf *Utsname) (err error) { ++ _, _, e1 := RawSyscall(SYS_UNAME, uintptr(unsafe.Pointer(buf)), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Unmount(target string, flags int) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(target) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall(SYS_UMOUNT2, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Unshare(flags int) (err error) { ++ _, _, e1 := Syscall(SYS_UNSHARE, uintptr(flags), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func write(fd int, p []byte) (n int, err error) { ++ var _p0 unsafe.Pointer ++ if len(p) > 0 { ++ _p0 = unsafe.Pointer(&p[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p))) ++ n = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func exitThread(code int) (err error) { ++ _, _, e1 := Syscall(SYS_EXIT, uintptr(code), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func readlen(fd int, p *byte, np int) (n int, err error) { ++ r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(p)), uintptr(np)) ++ n = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func munmap(addr uintptr, length uintptr) (err error) { ++ _, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Madvise(b []byte, advice int) (err error) { ++ var _p0 unsafe.Pointer ++ if len(b) > 0 { ++ _p0 = unsafe.Pointer(&b[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ _, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(advice)) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Mprotect(b []byte, prot int) (err error) { ++ var _p0 unsafe.Pointer ++ if len(b) > 0 { ++ _p0 = unsafe.Pointer(&b[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot)) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Mlock(b []byte) (err error) { ++ var _p0 unsafe.Pointer ++ if len(b) > 0 { ++ _p0 = unsafe.Pointer(&b[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Munlock(b []byte) (err error) { ++ var _p0 unsafe.Pointer ++ if len(b) > 0 { ++ _p0 = unsafe.Pointer(&b[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Mlockall(flags int) (err error) { ++ _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Munlockall() (err error) { ++ _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func getxpid() (pid int, ppid int) { ++ r0, r1, _ := RawSyscall(SYS_GETXPID, 0, 0, 0) ++ pid = int(r0) ++ ppid = int(r1) ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Fstat64(fd int, st *Stat_t) (err error) { ++ _, _, e1 := Syscall(SYS_FSTAT64, uintptr(fd), uintptr(unsafe.Pointer(st)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Lstat64(path string, st *Stat_t) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall(SYS_LSTAT64, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(st)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Stat64(path string, st *Stat_t) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall(SYS_STAT64, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(st)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func getxuid() (uid int, euid int) { ++ r0, r1, _ := Syscall(SYS_GETXUID, 0, 0, 0) ++ uid = int(r0) ++ euid = int(r1) ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func getxgid() (gid int, egid int) { ++ r0, r1, _ := Syscall(SYS_GETXGID, 0, 0, 0) ++ gid = int(r0) ++ egid = int(r1) ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Statfs(path string, buf *Statfs_t) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(buf)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Fstatfs(fd int, buf *Statfs_t) (err error) { ++ _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(buf)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Dup2(oldfd int, newfd int) (err error) { ++ _, _, e1 := Syscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Fchown(fd int, uid int, gid int) (err error) { ++ _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Ftruncate(fd int, length int64) (err error) { ++ _, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), uintptr(length), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func InotifyInit() (fd int, err error) { ++ r0, _, e1 := RawSyscall(SYS_INOTIFY_INIT, 0, 0, 0) ++ fd = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Lchown(path string, uid int, gid int) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid)) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Listen(s int, n int) (err error) { ++ _, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(n), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func pread(fd int, p []byte, offset int64) (n int, err error) { ++ var _p0 unsafe.Pointer ++ if len(p) > 0 { ++ _p0 = unsafe.Pointer(&p[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ r0, _, e1 := Syscall6(SYS_PREAD64, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0) ++ n = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func pwrite(fd int, p []byte, offset int64) (n int, err error) { ++ var _p0 unsafe.Pointer ++ if len(p) > 0 { ++ _p0 = unsafe.Pointer(&p[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ r0, _, e1 := Syscall6(SYS_PWRITE64, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0) ++ n = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Seek(fd int, offset int64, whence int) (off int64, err error) { ++ r0, _, e1 := Syscall(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(whence)) ++ off = int64(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { ++ r0, _, e1 := Syscall6(SYS_SENDFILE, uintptr(outfd), uintptr(infd), uintptr(unsafe.Pointer(offset)), uintptr(count), 0, 0) ++ written = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Setfsgid(gid int) (err error) { ++ _, _, e1 := Syscall(SYS_SETFSGID, uintptr(gid), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Setfsuid(uid int) (err error) { ++ _, _, e1 := Syscall(SYS_SETFSUID, uintptr(uid), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Shutdown(fd int, how int) (err error) { ++ _, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) { ++ r0, _, e1 := Syscall6(SYS_SPLICE, uintptr(rfd), uintptr(unsafe.Pointer(roff)), uintptr(wfd), uintptr(unsafe.Pointer(woff)), uintptr(len), uintptr(flags)) ++ n = int64(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func SyncFileRange(fd int, off int64, n int64, flags int) (err error) { ++ _, _, e1 := Syscall6(SYS_SYNC_FILE_RANGE, uintptr(fd), uintptr(off), uintptr(n), uintptr(flags), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Truncate(path string, length int64) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), uintptr(length), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) { ++ r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0) ++ fd = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { ++ _, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen)) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { ++ _, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen)) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func getgroups(n int, list *_Gid_t) (nn int, err error) { ++ r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(n), uintptr(unsafe.Pointer(list)), 0) ++ nn = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) { ++ _, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) { ++ _, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func socket(domain int, typ int, proto int) (fd int, err error) { ++ r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto)) ++ fd = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) { ++ _, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { ++ _, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { ++ _, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) { ++ var _p0 unsafe.Pointer ++ if len(p) > 0 { ++ _p0 = unsafe.Pointer(&p[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen))) ++ n = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) { ++ var _p0 unsafe.Pointer ++ if len(buf) > 0 { ++ _p0 = unsafe.Pointer(&buf[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ _, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen)) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) { ++ r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags)) ++ n = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) { ++ r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags)) ++ n = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) { ++ r0, _, e1 := Syscall6(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flags), uintptr(fd), uintptr(offset)) ++ xaddr = uintptr(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *sigset_t) (n int, err error) { ++ r0, _, e1 := Syscall6(SYS_PSELECT6, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask))) ++ n = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Gettimeofday(tv *Timeval) (err error) { ++ _, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(oldpath) ++ if err != nil { ++ return ++ } ++ var _p1 *byte ++ _p1, err = BytePtrFromString(newpath) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Ustat(dev int, ubuf *Ustat_t) (err error) { ++ _, _, e1 := Syscall(SYS_USTAT, uintptr(dev), uintptr(unsafe.Pointer(ubuf)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func futimesat(dirfd int, path string, times *[2]Timeval) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall(SYS_FUTIMESAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times))) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func utimes(path string, times *[2]Timeval) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall6(SYS_FSTATAT64, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { ++ var _p0 unsafe.Pointer ++ if len(events) > 0 { ++ _p0 = unsafe.Pointer(&events[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ r0, _, e1 := Syscall6(SYS_EPOLL_WAIT, uintptr(epfd), uintptr(_p0), uintptr(len(events)), uintptr(msec), 0, 0) ++ n = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} +diff --git a/src/syscall/zsysnum_linux_sw64.go b/src/syscall/zsysnum_linux_sw64.go +new file mode 100644 +index 0000000000..ab5bc966b6 +--- /dev/null ++++ b/src/syscall/zsysnum_linux_sw64.go +@@ -0,0 +1,370 @@ ++// mksysnum_linux.pl /usr/include/asm/unistd.h ++// Code generated by the command above; DO NOT EDIT. ++ ++package syscall ++ ++const ( ++ SYS_EXIT = 1 ++ SYS_FORK = 2 ++ SYS_READ = 3 ++ SYS_WRITE = 4 ++ SYS_CLOSE = 6 ++ SYS_LINK = 9 ++ SYS_UNLINK = 10 ++ SYS_CHDIR = 12 ++ SYS_FCHDIR = 13 ++ SYS_MKNOD = 14 ++ SYS_CHMOD = 15 ++ SYS_CHOWN = 16 ++ SYS_BRK = 17 ++ SYS_LSEEK = 19 ++ SYS_GETXPID = 20 ++ SYS_UMOUNT2 = 22 ++ SYS_SETUID = 23 ++ SYS_GETXUID = 24 ++ SYS_PTRACE = 26 ++ SYS_ACCESS = 33 ++ SYS_SYNC = 36 ++ SYS_KILL = 37 ++ SYS_SETPGID = 39 ++ SYS_DUP = 41 ++ SYS_PIPE = 42 ++ SYS_OPEN = 45 ++ SYS_GETXGID = 47 ++ SYS_ODD_SIGPROCMASK = 48 ++ SYS_ACCT = 51 ++ SYS_SIGPENDING = 52 ++ SYS_IOCTL = 54 ++ SYS_SYMLINK = 57 ++ SYS_READLINK = 58 ++ SYS_EXECVE = 59 ++ SYS_UMASK = 60 ++ SYS_CHROOT = 61 ++ SYS_GETPGRP = 63 ++ SYS_VFORK = 66 ++ SYS_STAT = 67 ++ SYS_LSTAT = 68 ++ SYS_MMAP = 71 ++ SYS_MUNMAP = 73 ++ SYS_MPROTECT = 74 ++ SYS_MADVISE = 75 ++ SYS_VHANGUP = 76 ++ SYS_GETGROUPS = 79 ++ SYS_SETGROUPS = 80 ++ SYS_SETPGRP = 82 ++ SYS_GETHOSTNAME = 87 ++ SYS_SETHOSTNAME = 88 ++ SYS_DUP2 = 90 ++ SYS_FSTAT = 91 ++ SYS_FCNTL = 92 ++ SYS_POLL = 94 ++ SYS_FSYNC = 95 ++ SYS_SETPRIORITY = 96 ++ SYS_SOCKET = 97 ++ SYS_CONNECT = 98 ++ SYS_ACCEPT = 99 ++ SYS_ODD_GETPRIORITY = 100 ++ SYS_SEND = 101 ++ SYS_RECV = 102 ++ SYS_SIGRETURN = 103 ++ SYS_BIND = 104 ++ SYS_SETSOCKOPT = 105 ++ SYS_LISTEN = 106 ++ SYS_SIGSUSPEND = 111 ++ SYS_RECVMSG = 113 ++ SYS_SENDMSG = 114 ++ SYS_GETSOCKOPT = 118 ++ SYS_SOCKETCALL = 119 ++ SYS_READV = 120 ++ SYS_WRITEV = 121 ++ SYS_FCHOWN = 123 ++ SYS_FCHMOD = 124 ++ SYS_RECVFROM = 125 ++ SYS_SETREUID = 126 ++ SYS_SETREGID = 127 ++ SYS_RENAME = 128 ++ SYS_TRUNCATE = 129 ++ SYS_FTRUNCATE = 130 ++ SYS_FLOCK = 131 ++ SYS_SETGID = 132 ++ SYS_SENDTO = 133 ++ SYS_SHUTDOWN = 134 ++ SYS_SOCKETPAIR = 135 ++ SYS_MKDIR = 136 ++ SYS_RMDIR = 137 ++ SYS_GETPEERNAME = 141 ++ SYS_GETRLIMIT = 144 ++ SYS_SETRLIMIT = 145 ++ SYS_SETSID = 147 ++ SYS_QUOTACTL = 148 ++ SYS_GETSOCKNAME = 150 ++ SYS_SIGACTION = 156 ++ SYS_SETDOMAINNAME = 166 ++ SYS_BPF = 170 ++ SYS_USERFAULTFD = 171 ++ SYS_MEMBARRIER = 172 ++ SYS_MLOCK2 = 173 ++ SYS_GETPID = 174 ++ SYS_GETPPID = 175 ++ SYS_GETUID = 176 ++ SYS_GETEUID = 177 ++ SYS_GETGID = 178 ++ SYS_GETEGID = 179 ++ SYS_MSGCTL = 200 ++ SYS_MSGGET = 201 ++ SYS_MSGRCV = 202 ++ SYS_MSGSND = 203 ++ SYS_SEMCTL = 204 ++ SYS_SEMGET = 205 ++ SYS_SEMOP = 206 ++ SYS_LCHOWN = 208 ++ SYS_SHMAT = 209 ++ SYS_SHMCTL = 210 ++ SYS_SHMDT = 211 ++ SYS_SHMGET = 212 ++ SYS_MSYNC = 217 ++ SYS_STATFS64 = 229 ++ SYS_FSTATFS64 = 230 ++ SYS_GETPGID = 233 ++ SYS_GETSID = 234 ++ SYS_SIGALTSTACK = 235 ++ SYS_SYSFS = 254 ++ SYS_GETSYSINFO = 256 ++ SYS_SETSYSINFO = 257 ++ SYS_PIDFD_SEND_SIGNAL = 271 ++ SYS_IO_URING_SETUP = 272 ++ SYS_IO_URING_ENTER = 273 ++ SYS_IO_URING_REGISTER = 274 ++ SYS_OPEN_TREE = 275 ++ SYS_MOVE_MOUNT = 276 ++ SYS_FSOPEN = 277 ++ SYS_FSCONFIG = 278 ++ SYS_FSMOUNT = 279 ++ SYS_FSPICK = 280 ++ SYS_PIDFD_OPEN = 281 ++ SYS_CLONE3 = 282 ++ SYS_CLOSE_RANGE = 283 ++ SYS_OPENAT2 = 284 ++ SYS_PIDFD_GETFD = 285 ++ SYS_FACCESSAT2 = 286 ++ SYS_PROCESS_MADVISE = 287 ++ SYS_PKEY_MPROTECT = 288 ++ SYS_PKEY_ALLOC = 289 ++ SYS_PKEY_FREE = 290 ++ SYS_GETPRIORITY = 298 ++ SYS_SIGPROCMASK = 299 ++ SYS_BDFLUSH = 300 ++ SYS_MOUNT = 302 ++ SYS_SWAPOFF = 304 ++ SYS_GETDENTS = 305 ++ SYS_CREATE_MODULE = 306 ++ SYS_INIT_MODULE = 307 ++ SYS_DELETE_MODULE = 308 ++ SYS_GET_KERNEL_SYMS = 309 ++ SYS_SYSLOG = 310 ++ SYS_REBOOT = 311 ++ SYS_CLONE = 312 ++ SYS_USELIB = 313 ++ SYS_MLOCK = 314 ++ SYS_MUNLOCK = 315 ++ SYS_MLOCKALL = 316 ++ SYS_MUNLOCKALL = 317 ++ SYS_SYSINFO = 318 ++ SYS_OLDUMOUNT = 321 ++ SYS_SWAPON = 322 ++ SYS_TIMES = 323 ++ SYS_PERSONALITY = 324 ++ SYS_SETFSUID = 325 ++ SYS_SETFSGID = 326 ++ SYS_USTAT = 327 ++ SYS_STATFS = 328 ++ SYS_FSTATFS = 329 ++ SYS_SCHED_SETPARAM = 330 ++ SYS_SCHED_GETPARAM = 331 ++ SYS_SCHED_SETSCHEDULER = 332 ++ SYS_SCHED_GETSCHEDULER = 333 ++ SYS_SCHED_YIELD = 334 ++ SYS_SCHED_GET_PRIORITY_MAX = 335 ++ SYS_SCHED_GET_PRIORITY_MIN = 336 ++ SYS_SCHED_RR_GET_INTERVAL = 337 ++ SYS_AFS_SYSCALL = 338 ++ SYS_UNAME = 339 ++ SYS_NANOSLEEP = 340 ++ SYS_MREMAP = 341 ++ SYS_NFSSERVCTL = 342 ++ SYS_SETRESUID = 343 ++ SYS_GETRESUID = 344 ++ SYS_PCICONFIG_READ = 345 ++ SYS_PCICONFIG_WRITE = 346 ++ SYS_QUERY_MODULE = 347 ++ SYS_PRCTL = 348 ++ SYS_PREAD64 = 349 ++ SYS_PWRITE64 = 350 ++ SYS_RT_SIGRETURN = 351 ++ SYS_RT_SIGACTION = 352 ++ SYS_RT_SIGPROCMASK = 353 ++ SYS_RT_SIGPENDING = 354 ++ SYS_RT_SIGTIMEDWAIT = 355 ++ SYS_RT_SIGQUEUEINFO = 356 ++ SYS_RT_SIGSUSPEND = 357 ++ SYS_SELECT = 358 ++ SYS_GETTIMEOFDAY = 359 ++ SYS_SETTIMEOFDAY = 360 ++ SYS_GETITIMER = 361 ++ SYS_SETITIMER = 362 ++ SYS_UTIMES = 363 ++ SYS_GETRUSAGE = 364 ++ SYS_WAIT4 = 365 ++ SYS_ADJTIMEX = 366 ++ SYS_GETCWD = 367 ++ SYS_CAPGET = 368 ++ SYS_CAPSET = 369 ++ SYS_SENDFILE = 370 ++ SYS_SETRESGID = 371 ++ SYS_GETRESGID = 372 ++ SYS_DIPC = 373 ++ SYS_PIVOT_ROOT = 374 ++ SYS_MINCORE = 375 ++ SYS_PCICONFIG_IOBASE = 376 ++ SYS_GETDENTS64 = 377 ++ SYS_GETTID = 378 ++ SYS_READAHEAD = 379 ++ SYS_TKILL = 381 ++ SYS_SETXATTR = 382 ++ SYS_LSETXATTR = 383 ++ SYS_FSETXATTR = 384 ++ SYS_GETXATTR = 385 ++ SYS_LGETXATTR = 386 ++ SYS_FGETXATTR = 387 ++ SYS_LISTXATTR = 388 ++ SYS_LLISTXATTR = 389 ++ SYS_FLISTXATTR = 390 ++ SYS_REMOVEXATTR = 391 ++ SYS_LREMOVEXATTR = 392 ++ SYS_FREMOVEXATTR = 393 ++ SYS_FUTEX = 394 ++ SYS_SCHED_SETAFFINITY = 395 ++ SYS_SCHED_GETAFFINITY = 396 ++ SYS_TUXCALL = 397 ++ SYS_IO_SETUP = 398 ++ SYS_IO_DESTROY = 399 ++ SYS_IO_GETEVENTS = 400 ++ SYS_IO_SUBMIT = 401 ++ SYS_IO_CANCEL = 402 ++ SYS_IO_PGETEVENTS = 403 ++ SYS_RSEQ = 404 ++ SYS_EXIT_GROUP = 405 ++ SYS_LOOKUP_DCOOKIE = 406 ++ SYS_EPOLL_CREATE = 407 ++ SYS_EPOLL_CTL = 408 ++ SYS_EPOLL_WAIT = 409 ++ SYS_REMAP_FILE_PAGES = 410 ++ SYS_SET_TID_ADDRESS = 411 ++ SYS_RESTART_SYSCALL = 412 ++ SYS_FADVISE64 = 413 ++ SYS_TIMER_CREATE = 414 ++ SYS_TIMER_SETTIME = 415 ++ SYS_TIMER_GETTIME = 416 ++ SYS_TIMER_GETOVERRUN = 417 ++ SYS_TIMER_DELETE = 418 ++ SYS_CLOCK_SETTIME = 419 ++ SYS_CLOCK_GETTIME = 420 ++ SYS_CLOCK_GETRES = 421 ++ SYS_CLOCK_NANOSLEEP = 422 ++ SYS_SEMTIMEDOP = 423 ++ SYS_TGKILL = 424 ++ SYS_STAT64 = 425 ++ SYS_LSTAT64 = 426 ++ SYS_FSTAT64 = 427 ++ SYS_VSERVER = 428 ++ SYS_MBIND = 429 ++ SYS_GET_MEMPOLICY = 430 ++ SYS_SET_MEMPOLICY = 431 ++ SYS_MQ_OPEN = 432 ++ SYS_MQ_UNLINK = 433 ++ SYS_MQ_TIMEDSEND = 434 ++ SYS_MQ_TIMEDRECEIVE = 435 ++ SYS_MQ_NOTIFY = 436 ++ SYS_MQ_GETSETATTR = 437 ++ SYS_WAITID = 438 ++ SYS_ADD_KEY = 439 ++ SYS_REQUEST_KEY = 440 ++ SYS_KEYCTL = 441 ++ SYS_IOPRIO_SET = 442 ++ SYS_IOPRIO_GET = 443 ++ SYS_INOTIFY_INIT = 444 ++ SYS_INOTIFY_ADD_WATCH = 445 ++ SYS_INOTIFY_RM_WATCH = 446 ++ SYS_FDATASYNC = 447 ++ SYS_KEXEC_LOAD = 448 ++ SYS_MIGRATE_PAGES = 449 ++ SYS_OPENAT = 450 ++ SYS_MKDIRAT = 451 ++ SYS_MKNODAT = 452 ++ SYS_FCHOWNAT = 453 ++ SYS_FUTIMESAT = 454 ++ SYS_FSTATAT64 = 455 ++ SYS_UNLINKAT = 456 ++ SYS_RENAMEAT = 457 ++ SYS_LINKAT = 458 ++ SYS_SYMLINKAT = 459 ++ SYS_READLINKAT = 460 ++ SYS_FCHMODAT = 461 ++ SYS_FACCESSAT = 462 ++ SYS_PSELECT6 = 463 ++ SYS_PPOLL = 464 ++ SYS_UNSHARE = 465 ++ SYS_SET_ROBUST_LIST = 466 ++ SYS_GET_ROBUST_LIST = 467 ++ SYS_SPLICE = 468 ++ SYS_SYNC_FILE_RANGE = 469 ++ SYS_TEE = 470 ++ SYS_VMSPLICE = 471 ++ SYS_MOVE_PAGES = 472 ++ SYS_GETCPU = 473 ++ SYS_EPOLL_PWAIT = 474 ++ SYS_UTIMENSAT = 475 ++ SYS_SIGNALFD = 476 ++ SYS_TIMERFD = 477 ++ SYS_EVENTFD = 478 ++ SYS_RECVMMSG = 479 ++ SYS_FALLOCATE = 480 ++ SYS_TIMERFD_CREATE = 481 ++ SYS_TIMERFD_SETTIME = 482 ++ SYS_TIMERFD_GETTIME = 483 ++ SYS_SIGNALFD4 = 484 ++ SYS_EVENTFD2 = 485 ++ SYS_EPOLL_CREATE1 = 486 ++ SYS_DUP3 = 487 ++ SYS_PIPE2 = 488 ++ SYS_INOTIFY_INIT1 = 489 ++ SYS_PREADV = 490 ++ SYS_PWRITEV = 491 ++ SYS_RT_TGSIGQUEUEINFO = 492 ++ SYS_PERF_EVENT_OPEN = 493 ++ SYS_FANOTIFY_INIT = 494 ++ SYS_FANOTIFY_MARK = 495 ++ SYS_PRLIMIT64 = 496 ++ SYS_NAME_TO_HANDLE_AT = 497 ++ SYS_OPEN_BY_HANDLE_AT = 498 ++ SYS_CLOCK_ADJTIME = 499 ++ SYS_SYNCFS = 500 ++ SYS_SETNS = 501 ++ SYS_ACCEPT4 = 502 ++ SYS_SENDMMSG = 503 ++ SYS_PROCESS_VM_READV = 504 ++ SYS_PROCESS_VM_WRITEV = 505 ++ SYS_KCMP = 506 ++ SYS_FINIT_MODULE = 507 ++ SYS_SCHED_SETATTR = 508 ++ SYS_SCHED_GETATTR = 509 ++ SYS_RENAMEAT2 = 510 ++ SYS_GETRANDOM = 511 ++ SYS_MEMFD_CREATE = 512 ++ SYS_EXECVEAT = 513 ++ SYS_SECCOMP = 514 ++ SYS_COPY_FILE_RANGE = 515 ++ SYS_PREADV2 = 516 ++ SYS_PWRITEV2 = 517 ++ SYS_STATX = 518 ++) +diff --git a/src/syscall/ztypes_linux_sw64.go b/src/syscall/ztypes_linux_sw64.go +new file mode 100644 +index 0000000000..7b3531279e +--- /dev/null ++++ b/src/syscall/ztypes_linux_sw64.go +@@ -0,0 +1,628 @@ ++// Code generated by cmd/cgo -godefs; DO NOT EDIT. ++// cgo -godefs /home/zhangjh/golang/src/syscall/types_linux.go ++ ++package syscall ++ ++const ( ++ sizeofPtr = 0x8 ++ sizeofShort = 0x2 ++ sizeofInt = 0x4 ++ sizeofLong = 0x8 ++ sizeofLongLong = 0x8 ++ PathMax = 0x1000 ++) ++ ++type ( ++ _C_short int16 ++ _C_int int32 ++ _C_long int64 ++ _C_long_long int64 ++) ++ ++type Timespec struct { ++ Sec int64 ++ Nsec int64 ++} ++ ++type Timeval struct { ++ Sec int64 ++ Usec int64 ++} ++ ++type Timex struct { ++ Modes uint32 ++ Offset int64 ++ Freq int64 ++ Maxerror int64 ++ Esterror int64 ++ Status int32 ++ Constant int64 ++ Precision int64 ++ Tolerance int64 ++ Time Timeval ++ Tick int64 ++ Ppsfreq int64 ++ Jitter int64 ++ Shift int32 ++ Stabil int64 ++ Jitcnt int64 ++ Calcnt int64 ++ Errcnt int64 ++ Stbcnt int64 ++ Tai int32 ++ Pad_cgo_0 [44]byte ++} ++ ++type Time_t int64 ++ ++type Tms struct { ++ Utime int64 ++ Stime int64 ++ Cutime int64 ++ Cstime int64 ++} ++ ++type Utimbuf struct { ++ Actime int64 ++ Modtime int64 ++} ++ ++type Rusage struct { ++ Utime Timeval ++ Stime Timeval ++ Maxrss int64 ++ Ixrss int64 ++ Idrss int64 ++ Isrss int64 ++ Minflt int64 ++ Majflt int64 ++ Nswap int64 ++ Inblock int64 ++ Oublock int64 ++ Msgsnd int64 ++ Msgrcv int64 ++ Nsignals int64 ++ Nvcsw int64 ++ Nivcsw int64 ++} ++ ++type Rlimit struct { ++ Cur uint64 ++ Max uint64 ++} ++ ++type _Gid_t uint32 ++ ++type Stat_t struct { ++ Dev uint64 ++ Ino uint64 ++ Rdev uint64 ++ Size int64 ++ Blocks int64 ++ Mode uint32 ++ Uid uint32 ++ Gid uint32 ++ Blksize uint32 ++ Nlink uint32 ++ X__pad2 int32 ++ Atim Timespec ++ Mtim Timespec ++ Ctim Timespec ++ X__glibc_reserved [3]int64 ++} ++ ++type statxTimestamp struct { ++ Sec int64 ++ Nsec uint32 ++ X__reserved int32 ++} ++ ++type statx_t struct { ++ Mask uint32 ++ Blksize uint32 ++ Attributes uint64 ++ Nlink uint32 ++ Uid uint32 ++ Gid uint32 ++ Mode uint16 ++ X__spare0 [1]uint16 ++ Ino uint64 ++ Size uint64 ++ Blocks uint64 ++ Attributes_mask uint64 ++ Atime statxTimestamp ++ Btime statxTimestamp ++ Ctime statxTimestamp ++ Mtime statxTimestamp ++ Rdev_major uint32 ++ Rdev_minor uint32 ++ Dev_major uint32 ++ Dev_minor uint32 ++ Mnt_id uint64 ++ X__spare2 uint64 ++ X__spare3 [12]uint64 ++} ++ ++type Statfs_t struct { ++ Type int64 ++ Bsize int64 ++ Blocks uint64 ++ Bfree uint64 ++ Bavail uint64 ++ Files uint64 ++ Ffree uint64 ++ Fsid Fsid ++ Namelen int64 ++ Frsize int64 ++ Flags int64 ++ Spare [4]int64 ++} ++ ++type Dirent struct { ++ Ino uint64 ++ Off int64 ++ Reclen uint16 ++ Type uint8 ++ Name [256]int8 ++ Pad_cgo_0 [5]byte ++} ++ ++type Fsid struct { ++ X__val [2]int32 ++} ++ ++type Flock_t struct { ++ Type int16 ++ Whence int16 ++ Start int64 ++ Len int64 ++ Pid int32 ++ Pad_cgo_0 [4]byte ++} ++ ++type RawSockaddrInet4 struct { ++ Family uint16 ++ Port uint16 ++ Addr [4]byte /* in_addr */ ++ Zero [8]uint8 ++} ++ ++type RawSockaddrInet6 struct { ++ Family uint16 ++ Port uint16 ++ Flowinfo uint32 ++ Addr [16]byte /* in6_addr */ ++ Scope_id uint32 ++} ++ ++type RawSockaddrUnix struct { ++ Family uint16 ++ Path [108]int8 ++} ++ ++type RawSockaddrLinklayer struct { ++ Family uint16 ++ Protocol uint16 ++ Ifindex int32 ++ Hatype uint16 ++ Pkttype uint8 ++ Halen uint8 ++ Addr [8]uint8 ++} ++ ++type RawSockaddrNetlink struct { ++ Family uint16 ++ Pad uint16 ++ Pid uint32 ++ Groups uint32 ++} ++ ++type RawSockaddr struct { ++ Family uint16 ++ Data [14]int8 ++} ++ ++type RawSockaddrAny struct { ++ Addr RawSockaddr ++ Pad [96]int8 ++} ++ ++type _Socklen uint32 ++ ++type Linger struct { ++ Onoff int32 ++ Linger int32 ++} ++ ++type Iovec struct { ++ Base *byte ++ Len uint64 ++} ++ ++type IPMreq struct { ++ Multiaddr [4]byte /* in_addr */ ++ Interface [4]byte /* in_addr */ ++} ++ ++type IPMreqn struct { ++ Multiaddr [4]byte /* in_addr */ ++ Address [4]byte /* in_addr */ ++ Ifindex int32 ++} ++ ++type IPv6Mreq struct { ++ Multiaddr [16]byte /* in6_addr */ ++ Interface uint32 ++} ++ ++type Msghdr struct { ++ Name *byte ++ Namelen uint32 ++ Iov *Iovec ++ Iovlen uint64 ++ Control *byte ++ Controllen uint64 ++ Flags int32 ++ Pad_cgo_0 [4]byte ++} ++ ++type Cmsghdr struct { ++ Len uint64 ++ Level int32 ++ Type int32 ++} ++ ++type Inet4Pktinfo struct { ++ Ifindex int32 ++ Spec_dst [4]byte /* in_addr */ ++ Addr [4]byte /* in_addr */ ++} ++ ++type Inet6Pktinfo struct { ++ Addr [16]byte /* in6_addr */ ++ Ifindex uint32 ++} ++ ++type IPv6MTUInfo struct { ++ Addr RawSockaddrInet6 ++ Mtu uint32 ++} ++ ++type ICMPv6Filter struct { ++ Data [8]uint32 ++} ++ ++type Ucred struct { ++ Pid int32 ++ Uid uint32 ++ Gid uint32 ++} ++ ++type TCPInfo struct { ++ State uint8 ++ Ca_state uint8 ++ Retransmits uint8 ++ Probes uint8 ++ Backoff uint8 ++ Options uint8 ++ Rto uint32 ++ Ato uint32 ++ Snd_mss uint32 ++ Rcv_mss uint32 ++ Unacked uint32 ++ Sacked uint32 ++ Lost uint32 ++ Retrans uint32 ++ Fackets uint32 ++ Last_data_sent uint32 ++ Last_ack_sent uint32 ++ Last_data_recv uint32 ++ Last_ack_recv uint32 ++ Pmtu uint32 ++ Rcv_ssthresh uint32 ++ Rtt uint32 ++ Rttvar uint32 ++ Snd_ssthresh uint32 ++ Snd_cwnd uint32 ++ Advmss uint32 ++ Reordering uint32 ++ Rcv_rtt uint32 ++ Rcv_space uint32 ++ Total_retrans uint32 ++} ++ ++const ( ++ SizeofSockaddrInet4 = 0x10 ++ SizeofSockaddrInet6 = 0x1c ++ SizeofSockaddrAny = 0x70 ++ SizeofSockaddrUnix = 0x6e ++ SizeofSockaddrLinklayer = 0x14 ++ SizeofSockaddrNetlink = 0xc ++ SizeofLinger = 0x8 ++ SizeofIPMreq = 0x8 ++ SizeofIPMreqn = 0xc ++ SizeofIPv6Mreq = 0x14 ++ SizeofMsghdr = 0x38 ++ SizeofCmsghdr = 0x10 ++ SizeofInet4Pktinfo = 0xc ++ SizeofInet6Pktinfo = 0x14 ++ SizeofIPv6MTUInfo = 0x20 ++ SizeofICMPv6Filter = 0x20 ++ SizeofUcred = 0xc ++ SizeofTCPInfo = 0x68 ++) ++ ++const ( ++ IFA_UNSPEC = 0x0 ++ IFA_ADDRESS = 0x1 ++ IFA_LOCAL = 0x2 ++ IFA_LABEL = 0x3 ++ IFA_BROADCAST = 0x4 ++ IFA_ANYCAST = 0x5 ++ IFA_CACHEINFO = 0x6 ++ IFA_MULTICAST = 0x7 ++ IFLA_UNSPEC = 0x0 ++ IFLA_ADDRESS = 0x1 ++ IFLA_BROADCAST = 0x2 ++ IFLA_IFNAME = 0x3 ++ IFLA_MTU = 0x4 ++ IFLA_LINK = 0x5 ++ IFLA_QDISC = 0x6 ++ IFLA_STATS = 0x7 ++ IFLA_COST = 0x8 ++ IFLA_PRIORITY = 0x9 ++ IFLA_MASTER = 0xa ++ IFLA_WIRELESS = 0xb ++ IFLA_PROTINFO = 0xc ++ IFLA_TXQLEN = 0xd ++ IFLA_MAP = 0xe ++ IFLA_WEIGHT = 0xf ++ IFLA_OPERSTATE = 0x10 ++ IFLA_LINKMODE = 0x11 ++ IFLA_LINKINFO = 0x12 ++ IFLA_NET_NS_PID = 0x13 ++ IFLA_IFALIAS = 0x14 ++ IFLA_MAX = 0x37 ++ RT_SCOPE_UNIVERSE = 0x0 ++ RT_SCOPE_SITE = 0xc8 ++ RT_SCOPE_LINK = 0xfd ++ RT_SCOPE_HOST = 0xfe ++ RT_SCOPE_NOWHERE = 0xff ++ RT_TABLE_UNSPEC = 0x0 ++ RT_TABLE_COMPAT = 0xfc ++ RT_TABLE_DEFAULT = 0xfd ++ RT_TABLE_MAIN = 0xfe ++ RT_TABLE_LOCAL = 0xff ++ RT_TABLE_MAX = 0xffffffff ++ RTA_UNSPEC = 0x0 ++ RTA_DST = 0x1 ++ RTA_SRC = 0x2 ++ RTA_IIF = 0x3 ++ RTA_OIF = 0x4 ++ RTA_GATEWAY = 0x5 ++ RTA_PRIORITY = 0x6 ++ RTA_PREFSRC = 0x7 ++ RTA_METRICS = 0x8 ++ RTA_MULTIPATH = 0x9 ++ RTA_FLOW = 0xb ++ RTA_CACHEINFO = 0xc ++ RTA_TABLE = 0xf ++ RTN_UNSPEC = 0x0 ++ RTN_UNICAST = 0x1 ++ RTN_LOCAL = 0x2 ++ RTN_BROADCAST = 0x3 ++ RTN_ANYCAST = 0x4 ++ RTN_MULTICAST = 0x5 ++ RTN_BLACKHOLE = 0x6 ++ RTN_UNREACHABLE = 0x7 ++ RTN_PROHIBIT = 0x8 ++ RTN_THROW = 0x9 ++ RTN_NAT = 0xa ++ RTN_XRESOLVE = 0xb ++ RTNLGRP_NONE = 0x0 ++ RTNLGRP_LINK = 0x1 ++ RTNLGRP_NOTIFY = 0x2 ++ RTNLGRP_NEIGH = 0x3 ++ RTNLGRP_TC = 0x4 ++ RTNLGRP_IPV4_IFADDR = 0x5 ++ RTNLGRP_IPV4_MROUTE = 0x6 ++ RTNLGRP_IPV4_ROUTE = 0x7 ++ RTNLGRP_IPV4_RULE = 0x8 ++ RTNLGRP_IPV6_IFADDR = 0x9 ++ RTNLGRP_IPV6_MROUTE = 0xa ++ RTNLGRP_IPV6_ROUTE = 0xb ++ RTNLGRP_IPV6_IFINFO = 0xc ++ RTNLGRP_IPV6_PREFIX = 0x12 ++ RTNLGRP_IPV6_RULE = 0x13 ++ RTNLGRP_ND_USEROPT = 0x14 ++ SizeofNlMsghdr = 0x10 ++ SizeofNlMsgerr = 0x14 ++ SizeofRtGenmsg = 0x1 ++ SizeofNlAttr = 0x4 ++ SizeofRtAttr = 0x4 ++ SizeofIfInfomsg = 0x10 ++ SizeofIfAddrmsg = 0x8 ++ SizeofRtMsg = 0xc ++ SizeofRtNexthop = 0x8 ++) ++ ++type NlMsghdr struct { ++ Len uint32 ++ Type uint16 ++ Flags uint16 ++ Seq uint32 ++ Pid uint32 ++} ++ ++type NlMsgerr struct { ++ Error int32 ++ Msg NlMsghdr ++} ++ ++type RtGenmsg struct { ++ Family uint8 ++} ++ ++type NlAttr struct { ++ Len uint16 ++ Type uint16 ++} ++ ++type RtAttr struct { ++ Len uint16 ++ Type uint16 ++} ++ ++type IfInfomsg struct { ++ Family uint8 ++ X__ifi_pad uint8 ++ Type uint16 ++ Index int32 ++ Flags uint32 ++ Change uint32 ++} ++ ++type IfAddrmsg struct { ++ Family uint8 ++ Prefixlen uint8 ++ Flags uint8 ++ Scope uint8 ++ Index uint32 ++} ++ ++type RtMsg struct { ++ Family uint8 ++ Dst_len uint8 ++ Src_len uint8 ++ Tos uint8 ++ Table uint8 ++ Protocol uint8 ++ Scope uint8 ++ Type uint8 ++ Flags uint32 ++} ++ ++type RtNexthop struct { ++ Len uint16 ++ Flags uint8 ++ Hops uint8 ++ Ifindex int32 ++} ++ ++const ( ++ SizeofSockFilter = 0x8 ++ SizeofSockFprog = 0x10 ++) ++ ++type SockFilter struct { ++ Code uint16 ++ Jt uint8 ++ Jf uint8 ++ K uint32 ++} ++ ++type SockFprog struct { ++ Len uint16 ++ Filter *SockFilter ++} ++ ++type InotifyEvent struct { ++ Wd int32 ++ Mask uint32 ++ Cookie uint32 ++ Len uint32 ++} ++ ++const SizeofInotifyEvent = 0x10 ++ ++type PtraceRegs struct{} ++ ++type ptracePsw struct { ++} ++ ++type ptraceFpregs struct { ++} ++ ++type ptracePer struct { ++} ++ ++type FdSet struct { ++ Bits [16]int64 ++} ++ ++type Sysinfo_t struct { ++ Uptime int64 ++ Loads [3]uint64 ++ Totalram uint64 ++ Freeram uint64 ++ Sharedram uint64 ++ Bufferram uint64 ++ Totalswap uint64 ++ Freeswap uint64 ++ Procs uint16 ++ Pad uint16 ++ Totalhigh uint64 ++ Freehigh uint64 ++ Unit uint32 ++ X_f [0]int8 ++ Pad_cgo_0 [4]byte ++} ++ ++type Utsname struct { ++ Sysname [65]int8 ++ Nodename [65]int8 ++ Release [65]int8 ++ Version [65]int8 ++ Machine [65]int8 ++ Domainname [65]int8 ++} ++ ++type Ustat_t struct { ++ Tfree int32 ++ Tinode uint64 ++ Fname [6]int8 ++ Fpack [6]int8 ++ Pad_cgo_0 [4]byte ++} ++ ++type EpollEvent struct { ++ Events uint32 ++ _ int32 ++ Fd int32 ++ Pad int32 ++} ++ ++const ( ++ _AT_FDCWD = -0x64 ++ _AT_REMOVEDIR = 0x200 ++ _AT_SYMLINK_NOFOLLOW = 0x100 ++ _AT_EACCESS = 0x200 ++ _AT_EMPTY_PATH = 0x1000 ++ _AT_NO_AUTOMOUNT = 0x800 ++ _STATX_BASIC_STATS = 0x7ff ++) ++ ++type pollFd struct { ++ Fd int32 ++ Events int16 ++ Revents int16 ++} ++ ++type Termios struct { ++ Iflag uint32 ++ Oflag uint32 ++ Cflag uint32 ++ Lflag uint32 ++ Cc [32]uint8 ++ Line uint8 ++ Ispeed uint32 ++ Ospeed uint32 ++} ++ ++const ( ++ IUCLC = 0x1000 ++ OLCUC = 0x4 ++ TCGETS = 0x402c7413 ++ TCSETS = 0x802c7414 ++ XCASE = 0x4000 ++) diff --git a/0007-cmd-dist-Add-sw64-port.patch b/0007-cmd-dist-Add-sw64-port.patch new file mode 100644 index 0000000000000000000000000000000000000000..291e8d95c192c964b4c550cb39cc2ffc514a83f6 --- /dev/null +++ b/0007-cmd-dist-Add-sw64-port.patch @@ -0,0 +1,222 @@ +diff --git a/src/cmd/dist/build.go b/src/cmd/dist/build.go +index 1f467647f5..64487ed1ed 100644 +--- a/src/cmd/dist/build.go ++++ b/src/cmd/dist/build.go +@@ -41,6 +41,7 @@ var ( + gomips64 string + goppc64 string + goriscv64 string ++ gosw64 string + goroot string + goextlinkenabled string + gogcflags string // For running built compiler +@@ -82,6 +83,7 @@ var okgoarch = []string{ + "s390x", + "sparc64", + "wasm", ++ "sw64", + } + + // The known operating systems. +@@ -192,6 +194,12 @@ func xinit() { + } + gofips140 = b + ++ b = os.Getenv("GOSW64") ++ if b == "" { ++ b = xgetgosw64() ++ } ++ gosw64 = b ++ + if p := pathf("%s/src/all.bash", goroot); !isfile(p) { + fatalf("$GOROOT is not set correctly or not exported\n"+ + "\tGOROOT=%s\n"+ +@@ -253,6 +261,7 @@ func xinit() { + os.Setenv("GOMIPS64", gomips64) + os.Setenv("GOPPC64", goppc64) + os.Setenv("GORISCV64", goriscv64) ++ os.Setenv("GOSW64", gosw64) + os.Setenv("GOROOT", goroot) + os.Setenv("GOFIPS140", gofips140) + +@@ -624,7 +633,7 @@ func setup() { + func mustLinkExternal(goos, goarch string, cgoEnabled bool) bool { + if cgoEnabled { + switch goarch { +- case "mips", "mipsle", "mips64", "mips64le": ++ case "mips", "mipsle", "mips64", "mips64le", "sw64": + // Internally linking cgo is incomplete on some architectures. + // https://golang.org/issue/14449 + return true +@@ -1309,6 +1318,9 @@ func cmdenv() { + if goarch == "riscv64" { + xprintf(format, "GORISCV64", goriscv64) + } ++ if goarch == "sw64" { ++ xprintf(format, "GOSW64", gosw64) ++ } + xprintf(format, "GOWORK", "off") + + if *path { +@@ -1790,6 +1802,7 @@ var cgoEnabled = map[string]bool{ + "linux/riscv64": true, + "linux/s390x": true, + "linux/sparc64": true, ++ "linux/sw64": true, + "android/386": true, + "android/amd64": true, + "android/arm": true, +diff --git a/src/cmd/dist/buildruntime.go b/src/cmd/dist/buildruntime.go +index 04b5b45410..ea8829de9b 100644 +--- a/src/cmd/dist/buildruntime.go ++++ b/src/cmd/dist/buildruntime.go +@@ -59,6 +59,7 @@ func mkbuildcfg(file string) { + fmt.Fprintf(&buf, "const DefaultGOMIPS64 = `%s`\n", gomips64) + fmt.Fprintf(&buf, "const DefaultGOPPC64 = `%s`\n", goppc64) + fmt.Fprintf(&buf, "const DefaultGORISCV64 = `%s`\n", goriscv64) ++ fmt.Fprintf(&buf, "const defaultGOSW64 = `%s`\n", gosw64) + fmt.Fprintf(&buf, "const defaultGOEXPERIMENT = `%s`\n", goexperiment) + fmt.Fprintf(&buf, "const defaultGO_EXTLINK_ENABLED = `%s`\n", goextlinkenabled) + fmt.Fprintf(&buf, "const defaultGO_LDSO = `%s`\n", defaultldso) +diff --git a/src/cmd/dist/main.go b/src/cmd/dist/main.go +index f3425a9dd8..3b687ad871 100644 +--- a/src/cmd/dist/main.go ++++ b/src/cmd/dist/main.go +@@ -130,6 +130,8 @@ func main() { + gohostarch = "riscv64" + case strings.Contains(out, "s390x"): + gohostarch = "s390x" ++ case strings.Contains(out, "sw_64"), strings.Contains(out, "sw64"): ++ gohostarch = "sw64" + case gohostos == "darwin", gohostos == "ios": + if strings.Contains(run("", CheckExit, "uname", "-v"), "RELEASE_ARM64_") { + gohostarch = "arm64" +@@ -168,6 +170,12 @@ func main() { + os.Exit(0) + } + ++ if len(os.Args) > 1 && os.Args[1] == "-check-gosw64" { ++ useUIDVv1() // might fail with SIGILL ++ println("UDIVv1 OK.") ++ os.Exit(0) ++ } ++ + xinit() + xmain() + xexit(0) +diff --git a/src/cmd/dist/test.go b/src/cmd/dist/test.go +index 0c992118f4..7974cbb635 100644 +--- a/src/cmd/dist/test.go ++++ b/src/cmd/dist/test.go +@@ -1164,7 +1164,7 @@ func (t *tester) internalLink() bool { + // Internally linking cgo is incomplete on some architectures. + // https://golang.org/issue/10373 + // https://golang.org/issue/14449 +- if goarch == "mips64" || goarch == "mips64le" || goarch == "mips" || goarch == "mipsle" || goarch == "riscv64" { ++ if goarch == "mips64" || goarch == "mips64le" || goarch == "mips" || goarch == "mipsle" || goarch == "riscv64" || goarch == "sw64" { + return false + } + if goos == "aix" { +@@ -1704,7 +1704,7 @@ func buildModeSupported(compiler, buildmode, goos, goarch string) bool { + return true + case "linux": + switch goarch { +- case "386", "amd64", "arm", "armbe", "arm64", "arm64be", "loong64", "ppc64le", "riscv64", "s390x": ++ case "386", "amd64", "arm", "armbe", "arm64", "arm64be", "loong64", "ppc64le", "riscv64", "s390x", "sw64": + // linux/ppc64 not supported because it does + // not support external linking mode yet. + return true +@@ -1724,7 +1724,7 @@ func buildModeSupported(compiler, buildmode, goos, goarch string) bool { + + case "c-shared": + switch platform { +- case "linux/amd64", "linux/arm", "linux/arm64", "linux/loong64", "linux/386", "linux/ppc64le", "linux/riscv64", "linux/s390x", ++ case "linux/amd64", "linux/arm", "linux/arm64", "linux/loong64", "linux/386", "linux/ppc64le", "linux/riscv64", "linux/s390x", "linux/sw64", + "android/amd64", "android/arm", "android/arm64", "android/386", + "freebsd/amd64", + "darwin/amd64", "darwin/arm64", +@@ -1763,7 +1763,7 @@ func buildModeSupported(compiler, buildmode, goos, goarch string) bool { + + case "plugin": + switch platform { +- case "linux/amd64", "linux/arm", "linux/arm64", "linux/386", "linux/loong64", "linux/s390x", "linux/ppc64le", ++ case "linux/amd64", "linux/arm", "linux/arm64", "linux/386", "linux/loong64", "linux/s390x", "linux/ppc64le", "linux/sw64", + "android/amd64", "android/386", + "darwin/amd64", "darwin/arm64", + "freebsd/amd64": +diff --git a/src/cmd/dist/udiv_default.s b/src/cmd/dist/udiv_default.s +new file mode 100644 +index 0000000000..371dcd9690 +--- /dev/null ++++ b/src/cmd/dist/udiv_default.s +@@ -0,0 +1,10 @@ ++// 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. ++ ++// +build !sw64,gc ++ ++#include "textflag.h" ++ ++TEXT ·useUIDVv1(SB),NOSPLIT,$0 ++ RET +diff --git a/src/cmd/dist/udiv_sw64.s b/src/cmd/dist/udiv_sw64.s +new file mode 100644 +index 0000000000..8d7155fdf8 +--- /dev/null ++++ b/src/cmd/dist/udiv_sw64.s +@@ -0,0 +1,12 @@ ++// 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. ++ ++// +build sw64,gc ++ ++#include "textflag.h" ++ ++// try to run "vmov.f64 d0, d0" instruction ++TEXT ·useUIDVv1(SB),NOSPLIT,$0 ++ WORD $0x400003E0 // vmov.f64 d0, d0 ++ RET +diff --git a/src/cmd/dist/util.go b/src/cmd/dist/util.go +index 4d5e3589dc..bcb9f5f935 100644 +--- a/src/cmd/dist/util.go ++++ b/src/cmd/dist/util.go +@@ -405,6 +405,23 @@ func xgetgoarm() string { + return "7" + } + ++func xgetgosw64() string { ++ if gohostarch != "sw64" || goos != gohostos { ++ // Conservative default for cross-compilation. ++ return "swv3" ++ } ++ // Try to exec ourselves in a mode to detect DIV,REM support. ++ // Seeing how far it gets determines which instructions failed. ++ // The test is OS-agnostic. ++ out := run("", 0, os.Args[0], "-check-gosw64") ++ v1ok := strings.Contains(out, "UDIVv1 OK.") ++ ++ if v1ok { ++ return "swv4" ++ } ++ return "swv3" ++} ++ + // elfIsLittleEndian detects if the ELF file is little endian. + func elfIsLittleEndian(fn string) bool { + // read the ELF file header to determine the endianness without using the +diff --git a/src/cmd/dist/util_gc.go b/src/cmd/dist/util_gc.go +index 6efdf23e60..f6e917abcd 100644 +--- a/src/cmd/dist/util_gc.go ++++ b/src/cmd/dist/util_gc.go +@@ -18,3 +18,8 @@ func useVFPv3() + // It will crash the current process if it doesn't implement + // ARMv6K or above. + func useARMv6K() ++ ++// useUIDVv1 tries to run core4 instructions on SW64. ++// It will crash the current process if it doesn't implement ++// Core4 or above. ++func useUIDVv1() + diff --git a/0007-internal-bytealg-optimize-memequal-and-memequal_varl.patch b/0007-internal-bytealg-optimize-memequal-and-memequal_varl.patch new file mode 100644 index 0000000000000000000000000000000000000000..7e97b4ae39bffab8dbc8df201de06e31b71fee74 --- /dev/null +++ b/0007-internal-bytealg-optimize-memequal-and-memequal_varl.patch @@ -0,0 +1,142 @@ +From 83f497423050707a8cd27152256699ccd7819456 Mon Sep 17 00:00:00 2001 +From: Huang Qiqi +Date: Sat, 18 May 2024 11:00:57 +0800 +Subject: [PATCH 07/44] internal/bytealg: optimize memequal and memequal_varlen + function for loong64 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +goos: linux +goarch: loong64 +pkg: bytes +cpu: Loongson-3C5000 @ 2200.00MHz + │ test/old_3c5000_equal.log │ test/new_3c5000_equal.log │ + │ sec/op │ sec/op vs base │ +Equal/0 0.6824n ± 0% 0.6837n ± 0% +0.20% (p=0.000 n=20) +Equal/1 10.46n ± 0% 12.71n ± 0% +21.46% (p=0.000 n=20) +Equal/6 17.29n ± 0% 19.57n ± 0% +13.22% (p=0.000 n=20) +Equal/9 21.38n ± 0% 13.19n ± 0% -38.31% (p=0.000 n=20) +Equal/15 29.57n ± 0% 21.39n ± 0% -27.68% (p=0.000 n=20) +Equal/16 30.94n ± 0% 10.46n ± 0% -66.19% (p=0.000 n=20) +Equal/20 36.40n ± 0% 16.83n ± 0% -53.76% (p=0.000 n=20) +Equal/32 52.78n ± 0% 12.28n ± 0% -76.73% (p=0.000 n=20) +Equal/4K 5606.0n ± 0% 385.8n ± 0% -93.12% (p=0.000 n=20) +Equal/4M 5728.9µ ± 0% 746.4µ ± 0% -86.97% (p=0.000 n=20) +Equal/64M 92.02m ± 0% 14.13m ± 5% -84.65% (p=0.000 n=20) +EqualBothUnaligned/64_0 98.73n ± 0% 10.04n ± 0% -89.83% (p=0.000 n=20) +EqualBothUnaligned/64_1 98.73n ± 0% 10.29n ± 0% -89.58% (p=0.000 n=20) +EqualBothUnaligned/64_4 98.73n ± 0% 10.29n ± 0% -89.58% (p=0.000 n=20) +EqualBothUnaligned/64_7 98.73n ± 0% 10.28n ± 0% -89.59% (p=0.000 n=20) +EqualBothUnaligned/4096_0 5602.0n ± 0% 365.8n ± 0% -93.47% (p=0.000 n=20) +EqualBothUnaligned/4096_1 5602.0n ± 0% 437.2n ± 0% -92.19% (p=0.000 n=20) +EqualBothUnaligned/4096_4 5602.0n ± 0% 436.4n ± 0% -92.21% (p=0.000 n=20) +EqualBothUnaligned/4096_7 5602.0n ± 0% 439.2n ± 0% -92.16% (p=0.000 n=20) +EqualBothUnaligned/4194304_0 5729.0µ ± 0% 732.4µ ± 0% -87.22% (p=0.000 n=20) +EqualBothUnaligned/4194304_1 5729.2µ ± 0% 781.8µ ± 1% -86.35% (p=0.000 n=20) +EqualBothUnaligned/4194304_4 5729.3µ ± 0% 773.9µ ± 0% -86.49% (p=0.000 n=20) +EqualBothUnaligned/4194304_7 5729.3µ ± 0% 773.9µ ± 5% -86.49% (p=0.000 n=20) +EqualBothUnaligned/67108864_0 92.38m ± 0% 34.61m ± 38% -62.53% (p=0.000 n=20) +EqualBothUnaligned/67108864_1 92.38m ± 0% 33.07m ± 23% -64.20% (p=0.000 n=20) +EqualBothUnaligned/67108864_4 92.38m ± 0% 82.09m ± 32% -11.14% (p=0.000 n=20) +EqualBothUnaligned/67108864_7 92.39m ± 0% 61.47m ± 16% -33.46% (p=0.000 n=20) +geomean 11.86µ 2.654µ -77.62% + +Change-Id: Ib181f532238e6f6d82a3e9e6987abe121688b6eb +--- + src/internal/bytealg/equal_loong64.s | 72 +++++++++++++++++++--------- + 1 file changed, 49 insertions(+), 23 deletions(-) + +diff --git a/src/internal/bytealg/equal_loong64.s b/src/internal/bytealg/equal_loong64.s +index 830b09bd2c..4cc31d5e46 100644 +--- a/src/internal/bytealg/equal_loong64.s ++++ b/src/internal/bytealg/equal_loong64.s +@@ -9,36 +9,62 @@ + + // memequal(a, b unsafe.Pointer, size uintptr) bool + TEXT runtime·memequal(SB),NOSPLIT|NOFRAME,$0-25 +- BEQ R4, R5, eq +- ADDV R4, R6, R7 +- PCALIGN $16 +-loop: +- BNE R4, R7, test +- MOVV $1, R4 ++ // R4 = a_base ++ // R5 = b_base ++ // R6 = size ++ JMP equalbody<>(SB) ++ ++// memequal_varlen(a, b unsafe.Pointer) bool ++TEXT runtime·memequal_varlen(SB),NOSPLIT,$0-17 ++ // R4 = a_base ++ // R5 = b_base ++ MOVV 8(REGCTXT), R6 // compiler stores size at offset 8 in the closure ++ JMP equalbody<>(SB) ++ ++TEXT equalbody<>(SB),NOSPLIT|NOFRAME,$0 ++ BEQ R4, R5, eq ++ ADDV R4, R6, R6 // end ++ ++loop_16byte: ++ ADDV $16, R4, R9 ++ BLT R6, R9, load8byte ++ MOVV (R4), R7 ++ MOVV (R5), R8 ++ MOVV 8(R4), R10 ++ MOVV 8(R5), R11 ++ MOVV R9, R4 ++ XOR R7, R8, R7 ++ XOR R10, R11, R10 ++ OR R10, R7, R7 ++ ADDV $16, R5 ++ BEQ R7, loop_16byte ++ ++ MOVB R0, R4 + RET +-test: +- MOVBU (R4), R9 ++ ++load8byte: ++ ADDV $8, R4, R9 ++ BLT R6, R9, tail ++ MOVV (R4), R7 ++ MOVV (R5), R8 ++ MOVV R9, R4 ++ ADDV $8, R5 ++ BEQ R7, R8, tail ++ ++ MOVB R0, R4 ++ RET ++ ++tail: ++ BEQ R4, R6, eq ++ MOVBU (R4), R7 ++ MOVBU (R5), R8 + ADDV $1, R4 +- MOVBU (R5), R10 + ADDV $1, R5 +- BEQ R9, R10, loop ++ BEQ R7, R8, tail + + MOVB R0, R4 + RET +-eq: +- MOVV $1, R4 +- RET + +-// memequal_varlen(a, b unsafe.Pointer) bool +-TEXT runtime·memequal_varlen(SB),NOSPLIT,$40-17 +- 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 +- RET + eq: + MOVV $1, R4 + RET +-- +2.38.1 + diff --git a/0008-cmd-cgo-Add-sw64-port.patch b/0008-cmd-cgo-Add-sw64-port.patch new file mode 100644 index 0000000000000000000000000000000000000000..5670feae0c81e9d9ebd373181aae6c5027616349 --- /dev/null +++ b/0008-cmd-cgo-Add-sw64-port.patch @@ -0,0 +1,78 @@ +diff --git a/src/cmd/cgo/internal/test/issue9400/asm_sw64.s b/src/cmd/cgo/internal/test/issue9400/asm_sw64.s +new file mode 100644 +index 0000000000..05eab55361 +--- /dev/null ++++ b/src/cmd/cgo/internal/test/issue9400/asm_sw64.s +@@ -0,0 +1,30 @@ ++// 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. ++ ++// +build sw64 ++// +build !gccgo ++ ++#include "textflag.h" ++ ++TEXT ·RewindAndSetgid(SB), NOSPLIT|NOFRAME, $0-0 ++ // Rewind stack pointer so anything that happens on the stack ++ // will clobber the test pattern created by the caller ++ LDI SP, $(1024*8)(SP) ++ ++ // Ask signaller to setgid ++ LDI R1, $1 ++ MEMB ++ STW R1, ·Baton(SB) ++ MEMB ++ ++ // Wait for setgid completion ++loop: ++ MEMB ++ LDW R1, ·Baton(SB) ++ NOOP // hint that we're in a spin loop ++ BNE R1, loop ++ MEMB ++ ++ LDI SP, $-(1024*8)(SP) ++ RET +diff --git a/src/cmd/cgo/internal/testsanitizers/cc_test.go b/src/cmd/cgo/internal/testsanitizers/cc_test.go +index 96a9e71cd7..5ca898faa2 100644 +--- a/src/cmd/cgo/internal/testsanitizers/cc_test.go ++++ b/src/cmd/cgo/internal/testsanitizers/cc_test.go +@@ -22,6 +22,7 @@ import ( + "os/user" + "path/filepath" + "regexp" ++ "runtime" + "strconv" + "strings" + "sync" +@@ -445,6 +446,9 @@ int LLVMFuzzerTestOneInput(char *data, size_t size) { + `) + + func (c *config) checkCSanitizer() (skip bool, err error) { ++ if runtime.GOARCH == "sw64" { ++ return true, fmt.Errorf("skip sw64 gcc sanitizer because of some known issue") ++ } + dir, err := os.MkdirTemp("", c.sanitizer) + if err != nil { + return false, fmt.Errorf("failed to create temp directory: %v", err) +diff --git a/src/cmd/cgo/main.go b/src/cmd/cgo/main.go +index 939e282ff0..b45de2f2c0 100644 +--- a/src/cmd/cgo/main.go ++++ b/src/cmd/cgo/main.go +@@ -223,6 +223,7 @@ var ptrSizeMap = map[string]int64{ + "shbe": 4, + "sparc": 4, + "sparc64": 8, ++ "sw64": 8, + } + + var intSizeMap = map[string]int64{ +@@ -249,6 +250,7 @@ var intSizeMap = map[string]int64{ + "shbe": 4, + "sparc": 4, + "sparc64": 8, ++ "sw64": 8, + } + + var cPrefix string diff --git a/0008-internal-bytealg-optimize-Index-and-IndexString-func.patch b/0008-internal-bytealg-optimize-Index-and-IndexString-func.patch new file mode 100644 index 0000000000000000000000000000000000000000..4fb2113d1dc87b193fc7af7c42f2ab6d9a4a6047 --- /dev/null +++ b/0008-internal-bytealg-optimize-Index-and-IndexString-func.patch @@ -0,0 +1,299 @@ +From 89d740fe5889c558dbb69b6ac3a80ec38cd5765c Mon Sep 17 00:00:00 2001 +From: Huang Qiqi +Date: Thu, 23 May 2024 16:25:06 +0800 +Subject: [PATCH 08/44] internal/bytealg: optimize Index and IndexString + function for loong64 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +goos: linux +goarch: loong64 +pkg: bytes +cpu: Loongson-3C5000 @ 2200.00MHz + │ test/old_3c5000_index.log │ test/new_3c5000_index.log │ + │ sec/op │ sec/op vs base │ +Index/10 66.42n ± 0% 20.47n ± 0% -69.18% (p=0.000 n=20) +Index/32 196.1n ± 0% 105.7n ± 0% -46.12% (p=0.000 n=20) +Index/4K 13.622µ ± 0% 5.673µ ± 0% -58.35% (p=0.000 n=20) +Index/4M 14.005m ± 0% 5.734m ± 0% -59.06% (p=0.000 n=20) +Index/64M 224.50m ± 0% 91.94m ± 0% -59.05% (p=0.000 n=20) +IndexEasy/10 21.30n ± 0% 18.66n ± 0% -12.41% (p=0.000 n=20) +IndexEasy/32 41.40n ± 0% 33.91n ± 1% -18.09% (p=0.000 n=20) +IndexEasy/4K 4.141µ ± 4% 2.373µ ± 1% -42.70% (p=0.000 n=20) +IndexEasy/4M 3.830m ± 0% 2.392m ± 0% -37.55% (p=0.000 n=20) +IndexEasy/64M 62.54m ± 1% 39.86m ± 0% -36.26% (p=0.000 n=20) +geomean 29.43µ 15.73µ -46.57% + +goos: linux +goarch: loong64 +pkg: strings +cpu: Loongson-3C5000 @ 2200.00MHz + │ test/old_3c5000_indexstring.log │ test/new_3c5000_indexstring.log │ + │ sec/op │ sec/op vs base │ +Index 30.54n ± 0% 16.91n ± 0% -44.64% (p=0.000 n=20) + +Change-Id: I92739ada1637356c6d42761a8a596b0bffec405d +--- + src/internal/bytealg/index_generic.go | 2 +- + src/internal/bytealg/index_loong64.go | 23 ++++ + src/internal/bytealg/index_loong64.s | 190 ++++++++++++++++++++++++++ + src/internal/bytealg/index_native.go | 2 +- + 4 files changed, 215 insertions(+), 2 deletions(-) + create mode 100644 src/internal/bytealg/index_loong64.go + create mode 100644 src/internal/bytealg/index_loong64.s + +diff --git a/src/internal/bytealg/index_generic.go b/src/internal/bytealg/index_generic.go +index a59e32938e..2d89c41825 100644 +--- a/src/internal/bytealg/index_generic.go ++++ b/src/internal/bytealg/index_generic.go +@@ -2,7 +2,7 @@ + // 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 ++//go:build !amd64 && !arm64 && !s390x && !ppc64le && !ppc64 && !loong64 + + package bytealg + +diff --git a/src/internal/bytealg/index_loong64.go b/src/internal/bytealg/index_loong64.go +new file mode 100644 +index 0000000000..d6f43eb32c +--- /dev/null ++++ b/src/internal/bytealg/index_loong64.go +@@ -0,0 +1,23 @@ ++// 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 ++ ++// Empirical data shows that using Index can get better ++// performance when len(s) <= 16. ++const MaxBruteForce = 16 ++ ++func init() { ++ // Optimize cases where the length of the substring is less than 32 bytes ++ 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/src/internal/bytealg/index_loong64.s b/src/internal/bytealg/index_loong64.s +new file mode 100644 +index 0000000000..221d0332a4 +--- /dev/null ++++ b/src/internal/bytealg/index_loong64.s +@@ -0,0 +1,190 @@ ++// 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 ·Index(SB),NOSPLIT,$0-56 ++ MOVV R7, R6 // R6 = separator pointer ++ MOVV R8, R7 // R7 = separator length ++ JMP indexbody<>(SB) ++ ++TEXT ·IndexString(SB),NOSPLIT,$0-40 ++ JMP indexbody<>(SB) ++ ++// input: ++// R4 = string ++// R5 = length ++// R6 = separator pointer ++// R7 = separator length (2 <= len <= 32) ++TEXT indexbody<>(SB),NOSPLIT,$0 ++ // main idea is to load 'sep' into separate register(s) ++ // to avoid repeatedly re-load it again and again ++ // for sebsequent substring comparisons ++ SUBV R7, R5, R8 ++ ADDV $1, R4, R9 // store base for later ++ MOVV $8, R5 ++ ADDV R4, R8 // end ++ BLT R5, R7, len_gt_8 ++ ++len_le_8: ++ AND $0x8, R7, R5 ++ BNE R5, len_8 ++ AND $0x4, R7, R5 ++ BNE R5, len_4_7 ++ ++len_2_3: ++ AND $0x1, R7, R5 ++ BNE R5, len_3 ++ ++len_2: ++ MOVHU (R6), R10 ++loop_2: ++ BLT R8, R4, not_found ++ MOVHU (R4), R11 ++ ADDV $1, R4 ++ BNE R10, R11, loop_2 ++ JMP found ++ ++len_3: ++ MOVHU (R6), R10 ++ MOVBU 2(R6), R11 ++loop_3: ++ BLT R8, R4, not_found ++ MOVHU (R4), R12 ++ ADDV $1, R4 ++ BNE R10, R12, loop_3 ++ MOVBU 1(R4), R12 ++ BNE R11, R12, loop_3 ++ JMP found ++ ++len_4_7: ++ AND $0x2, R7, R5 ++ BNE R5, len_6_7 ++ AND $0x1, R7, R5 ++ BNE R5, len_5 ++ ++len_4: ++ MOVWU (R6), R10 ++loop_4: ++ BLT R8, R4, not_found ++ MOVWU (R4), R11 ++ ADDV $1, R4 ++ BNE R10, R11, loop_4 ++ JMP found ++len_5: ++ MOVWU (R6), R10 ++ MOVBU 4(R6), R11 ++loop_5: ++ BLT R8, R4, not_found ++ MOVWU (R4), R12 ++ ADDV $1, R4 ++ BNE R10, R12, loop_5 ++ MOVBU 3(R4), R12 ++ BNE R11, R12, loop_5 ++ JMP found ++ ++len_6_7: ++ AND $0x1, R7, R5 ++ BNE R5, len_7 ++ ++len_6: ++ MOVWU (R6), R10 ++ MOVHU 4(R6), R11 ++loop_6: ++ BLT R8, R4, not_found ++ MOVWU (R4), R12 ++ ADDV $1, R4 ++ BNE R10, R12, loop_6 ++ MOVHU 3(R4), R12 ++ BNE R11, R12, loop_6 ++ JMP found ++ ++len_7: ++ MOVWU (R6), R10 ++ MOVWU 3(R6), R11 ++loop_7: ++ BLT R8, R4, not_found ++ MOVWU (R4), R12 ++ ADDV $1, R4 ++ BNE R10, R12, loop_7 ++ MOVWU 2(R4), R12 ++ BNE R11, R12, loop_7 ++ JMP found ++ ++len_8: ++ MOVV (R6), R10 ++loop_8: ++ BLT R8, R4, not_found ++ MOVV (R4), R11 ++ ADDV $1, R4 ++ BNE R10, R11, loop_8 ++ JMP found ++ ++len_gt_8: ++ MOVV $16, R5 ++ BLT R5, R7, len_gt_16 ++ ++len_9_16: ++ MOVV (R6), R10 ++ SUBV $8, R7 ++ MOVV (R6)(R7), R11 ++ SUBV $1, R7 ++loop_9_16: ++ BLT R8, R4, not_found ++ MOVV (R4), R12 ++ ADDV $1, R4 ++ BNE R10, R12, loop_9_16 ++ MOVV (R4)(R7), R12 ++ BNE R11, R12, loop_9_16 ++ JMP found ++ ++len_gt_16: ++ MOVV $24, R5 ++ BLT R5, R7, len_25_32 ++ ++len_17_24: ++ MOVV (R6), R10 ++ SUBV $8, R7 ++ MOVV 8(R6), R11 ++ MOVV (R6)(R7), R12 ++ SUBV $1, R7 ++loop_17_24: ++ BLT R8, R4, not_found ++ MOVV (R4), R13 ++ ADDV $1, R4 ++ BNE R10, R13, loop_17_24 ++ MOVV 7(R4), R13 ++ BNE R11, R13, loop_17_24 ++ MOVV (R4)(R7), R13 ++ BNE R12, R13, loop_17_24 ++ JMP found ++ ++len_25_32: ++ MOVV (R6), R10 ++ SUBV $8, R7 ++ MOVV 8(R6), R11 ++ MOVV 16(R6), R12 ++ MOVV (R6)(R7), R13 ++ SUBV $1, R7 ++loop_25_32: ++ BLT R8, R4, not_found ++ MOVV (R4), R14 ++ ADDV $1, R4 ++ BNE R10, R14, loop_25_32 ++ MOVV 7(R4), R14 ++ BNE R11, R14, loop_25_32 ++ MOVV 15(R4), R14 ++ BNE R12, R14, loop_25_32 ++ MOVV (R4)(R7), R14 ++ BNE R13, R14, loop_25_32 ++ JMP found ++ ++found: ++ SUBV R9, R4 ++ RET ++ ++not_found: ++ MOVV $-1, R4 ++ RET +diff --git a/src/internal/bytealg/index_native.go b/src/internal/bytealg/index_native.go +index 59c93f9d12..7aadaabe4e 100644 +--- a/src/internal/bytealg/index_native.go ++++ b/src/internal/bytealg/index_native.go +@@ -2,7 +2,7 @@ + // 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 ++//go:build amd64 || arm64 || s390x || ppc64le || ppc64 || loong64 + + package bytealg + +-- +2.38.1 + diff --git a/0009-internal-bytealg-optimize-Count-and-CountString-func.patch b/0009-internal-bytealg-optimize-Count-and-CountString-func.patch new file mode 100644 index 0000000000000000000000000000000000000000..9b99d37cca346311046f3085e4133441b5f321ae --- /dev/null +++ b/0009-internal-bytealg-optimize-Count-and-CountString-func.patch @@ -0,0 +1,153 @@ +From 37c73e45ea537b7e8662b968b630a2566b25ae59 Mon Sep 17 00:00:00 2001 +From: Huang Qiqi +Date: Wed, 29 May 2024 10:49:41 +0800 +Subject: [PATCH 09/44] internal/bytealg: optimize Count and CountString + function for loong64 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Benchmark results on Loongson 3C5000 (which is an LA464 implementation): + +goos: linux +goarch: loong64 +pkg: bytes +cpu: Loongson-3C5000 @ 2200.00MHz + │ test/old_3c5000_count.log │ test/new_3c5000_count.log │ + │ sec/op │ sec/op vs base │ +CountSingle/10 16.26n ± 0% 16.26n ± 0% ~ (p=0.653 n=20) +CountSingle/32 41.48n ± 0% 27.48n ± 0% -33.75% (p=0.000 n=20) +CountSingle/4K 4.998µ ± 0% 2.961µ ± 0% -40.76% (p=0.000 n=20) +CountSingle/4M 5.076m ± 0% 3.510m ± 8% -30.84% (p=0.000 n=20) +CountSingle/64M 88.70m ± 0% 58.15m ± 1% -34.45% (p=0.000 n=20) +geomean 17.23µ 12.20µ -29.19% + +Change-Id: Ic60d49fea83c9cf4f9b02bae3ce69b81206c7017 +--- + src/internal/bytealg/count_generic.go | 2 +- + src/internal/bytealg/count_loong64.s | 86 +++++++++++++++++++++++++++ + src/internal/bytealg/count_native.go | 2 +- + 3 files changed, 88 insertions(+), 2 deletions(-) + create mode 100644 src/internal/bytealg/count_loong64.s + +diff --git a/src/internal/bytealg/count_generic.go b/src/internal/bytealg/count_generic.go +index 932a7c584c..16f974539c 100644 +--- a/src/internal/bytealg/count_generic.go ++++ b/src/internal/bytealg/count_generic.go +@@ -2,7 +2,7 @@ + // 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 ++//go:build !amd64 && !arm && !arm64 && !loong64 && !ppc64le && !ppc64 && !riscv64 && !s390x + + package bytealg + +diff --git a/src/internal/bytealg/count_loong64.s b/src/internal/bytealg/count_loong64.s +new file mode 100644 +index 0000000000..ca19c5f343 +--- /dev/null ++++ b/src/internal/bytealg/count_loong64.s +@@ -0,0 +1,86 @@ ++// 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(SB),NOSPLIT,$0-40 ++ // R4 = b_base ++ // R5 = b_len ++ // R6 = b_cap (unused) ++ // R7 = byte to count (want in R6) ++ AND $0xff, R7, R6 ++ JMP countbody<>(SB) ++ ++TEXT ·CountString(SB),NOSPLIT,$0-32 ++ // R4 = s_base ++ // R5 = s_len ++ // R6 = byte to count ++ AND $0xff, R6 ++ JMP countbody<>(SB) ++ ++// input: ++// R4 = s_base ++// R5 = s_len ++// R6 = byte to count ++TEXT countbody<>(SB),NOSPLIT,$0 ++ MOVV R0, R7 // count ++ ADDV R4, R5 // end ++ MOVV $1, R17 ++ ++loop: ++ ADDV $8, R4, R9 ++ BLT R5, R9, tail ++ MOVV (R4), R8 ++ ++ AND $0xff, R8, R10 ++ WORD $0xcf210b // bstrpick.w r11, r8, 15, 8 ++ XOR R6, R10, R10 ++ XOR R6, R11, R11 ++ MASKNEZ R10, R17, R12 ++ MASKNEZ R11, R17, R13 ++ ADDV R7, R12, R7 ++ ADDV R7, R13, R7 ++ ++ WORD $0xd7410a // bstrpick.w r10, r8, 23, 16 ++ WORD $0xdf610b // bstrpick.w r11, r8, 31, 24 ++ XOR R6, R10, R10 ++ XOR R6, R11, R11 ++ MASKNEZ R10, R17, R12 ++ MASKNEZ R11, R17, R13 ++ ADDV R7, R12, R7 ++ ADDV R7, R13, R7 ++ ++ WORD $0xe7810a // bstrpick.w r10, r8, 39, 32 ++ WORD $0xefa10b // bstrpick.w r11, r8, 47, 40 ++ XOR R6, R10, R10 ++ XOR R6, R11, R11 ++ MASKNEZ R10, R17, R12 ++ MASKNEZ R11, R17, R13 ++ ADDV R7, R12, R7 ++ ADDV R7, R13, R7 ++ ++ WORD $0xf7c10a // bstrpick.w r10, r8, 55, 48 ++ WORD $0xffe10b // bstrpick.w r11, r8, 63, 56 ++ XOR R6, R10, R10 ++ XOR R6, R11, R11 ++ MASKNEZ R10, R17, R12 ++ MASKNEZ R11, R17, R13 ++ ADDV R7, R12, R7 ++ ADDV R7, R13, R7 ++ ++ MOVV R9, R4 ++ JMP loop ++ ++tail: ++ BEQ R4, R5, done ++ MOVBU (R4), R8 ++ ADDV $1, R4 ++ BNE R6, R8, tail ++ ADDV $1, R7 ++ JMP tail ++ ++done: ++ MOVV R7, R4 ++ RET +diff --git a/src/internal/bytealg/count_native.go b/src/internal/bytealg/count_native.go +index 90189c9fe0..eab64e8950 100644 +--- a/src/internal/bytealg/count_native.go ++++ b/src/internal/bytealg/count_native.go +@@ -2,7 +2,7 @@ + // 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 ++//go:build amd64 || arm || arm64 || loong64 || ppc64le || ppc64 || riscv64 || s390x + + package bytealg + +-- +2.38.1 + diff --git a/0009-reflect-Add-sw64-port.patch b/0009-reflect-Add-sw64-port.patch new file mode 100644 index 0000000000000000000000000000000000000000..955b5e4264ba069e9b65255e58820c72590341ed --- /dev/null +++ b/0009-reflect-Add-sw64-port.patch @@ -0,0 +1,144 @@ +diff --git a/src/reflect/asm_sw64.s b/src/reflect/asm_sw64.s +new file mode 100644 +index 0000000000..3df3001526 +--- /dev/null ++++ b/src/reflect/asm_sw64.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 "textflag.h" ++#include "funcdata.h" ++ ++// The frames of each of the two functions below contain two locals, at offsets ++// that are known to the runtime. ++// ++// The first local is a bool called retValid with a whole pointer-word reserved ++// for it on the stack. The purpose of this word is so that the runtime knows ++// whether the stack-allocated return space contains valid values for stack ++// scanning. ++// ++// The second local is an abi.RegArgs value whose offset is also known to the ++// runtime, so that a stack map for it can be constructed, since it contains ++// pointers visible to the GC. ++#define LOCAL_RETVALID 40 ++#define LOCAL_REGARGS 48 ++ ++// The frame size of the functions below is ++// 32 (args of callReflect/callMethod) + (8 bool with padding) + 224 (abi.RegArgs) = 264. ++ ++// makeFuncStub is the code half of the function returned by MakeFunc. ++// See the comment on the declaration of makeFuncStub in makefunc.go ++// for more details. ++// No arg size here, runtime pulls arg map out of the func value. ++//TEXT ·makeFuncStub(SB), (NOSPLIT|WRAPPER), $40 ++TEXT ·makeFuncStub(SB), (NOSPLIT|WRAPPER), $264 ++ NO_LOCAL_POINTERS ++ ADDL SP, $LOCAL_REGARGS, R9 // spillArgs using R9 ++ CALL runtime·spillArgs(SB) ++ STL REGCTXT, 32(SP) // save CTXT > args of moveMakeFuncArgPtrs < LOCAL_REGARGS ++ STL REGCTXT, 8(SP) ++ STL R9, 16(SP) ++ CALL ·moveMakeFuncArgPtrs(SB) ++ LDL REGCTXT, 32(SP) // restore CTXT ++ STL REGCTXT, 8(SP) ++ LDI R1, $argframe+0(FP) ++ STL R1, 16(SP) ++ STB ZERO, $LOCAL_RETVALID(SP) ++ ADDL SP, $LOCAL_RETVALID, R1 ++ STL R1, 24(SP) ++ ADDL SP, $LOCAL_REGARGS, R1 ++ STL R1, 32(SP) ++ CALL ·callReflect(SB) ++ ADDL SP, $LOCAL_REGARGS, R9 // unspillArgs using R9 ++ CALL runtime·unspillArgs(SB) ++ RET ++ ++// methodValueCall is the code half of the function returned by makeMethodValue. ++// See the comment on the declaration of methodValueCall in makefunc.go ++// for more details. ++// No arg size here; runtime pulls arg map out of the func value. ++//TEXT ·methodValueCall(SB), (NOSPLIT|WRAPPER), $40 ++TEXT ·methodValueCall(SB), (NOSPLIT|WRAPPER), $264 ++ NO_LOCAL_POINTERS ++ ADDL SP, $LOCAL_REGARGS, R9 // spillArgs using R9 ++ CALL runtime·spillArgs(SB) ++ STL REGCTXT, 32(SP) // save CTXT ++ STL REGCTXT, 8(SP) ++ STL R9, 16(SP) ++ CALL ·moveMakeFuncArgPtrs(SB) ++ LDL REGCTXT, 32(SP) // restore CTXT ++ STL REGCTXT, 8(SP) ++ LDI R1, $argframe+0(FP) ++ STL R1, 16(SP) ++ STB ZERO, $LOCAL_RETVALID(SP) ++ ADDL SP, $LOCAL_RETVALID, R1 ++ STL R1, 24(SP) ++ ADDL SP, $LOCAL_REGARGS, R1 ++ STL R1, 32(SP) // frame size to 32+SP as callreflect args ++ CALL ·callMethod(SB) ++ ADDL SP, $LOCAL_REGARGS, R9 // unspillArgs using R9 ++ CALL runtime·unspillArgs(SB) ++ RET +diff --git a/src/reflect/float32reg_generic.go b/src/reflect/float32reg_generic.go +index 23ad4bf285..2643babd7f 100644 +--- a/src/reflect/float32reg_generic.go ++++ b/src/reflect/float32reg_generic.go +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build !ppc64 && !ppc64le && !riscv64 ++//go:build !ppc64 && !ppc64le && !riscv64 && !sw64 + + package reflect + +diff --git a/src/reflect/float32reg_sw64.s b/src/reflect/float32reg_sw64.s +new file mode 100644 +index 0000000000..5168fb191f +--- /dev/null ++++ b/src/reflect/float32reg_sw64.s +@@ -0,0 +1,28 @@ ++// 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. ++ ++#include "textflag.h" ++ ++// On SW64, the float32 has 35 valid bits ++// when loaded in a register, different from ++// other platforms. These functions are ++// needed to ensure correct conversions on SW64. ++ ++// Convert float32->uint64 ++TEXT ·archFloat32ToReg(SB),NOSPLIT,$0-16 ++ FLDS F1, val+0(FP) ++ FSTD F1, ret+8(FP) ++ RET ++ ++// Convert uint64->float32 ++TEXT ·archFloat32FromReg(SB),NOSPLIT,$0-12 ++ FLDD F1, reg+0(FP) ++ // Normally a float64->float32 conversion ++ // would need rounding, but that is not needed ++ // here since the uint64 was originally converted ++ // from float32, and should be avoided to ++ // preserve SNaN values. ++ FSTS F1, ret+8(FP) ++ RET ++ +diff --git a/src/reflect/stubs_sw64.go b/src/reflect/stubs_sw64.go +new file mode 100644 +index 0000000000..a72ebab970 +--- /dev/null ++++ b/src/reflect/stubs_sw64.go +@@ -0,0 +1,8 @@ ++// 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 reflect ++ ++func archFloat32FromReg(reg uint64) float32 ++func archFloat32ToReg(val float32) uint64 diff --git a/0010-cmd-vendor-vendor-Add-sw64-port.patch b/0010-cmd-vendor-vendor-Add-sw64-port.patch new file mode 100644 index 0000000000000000000000000000000000000000..0de4cde32388768defa4b29600691f7933c08fde --- /dev/null +++ b/0010-cmd-vendor-vendor-Add-sw64-port.patch @@ -0,0 +1,15542 @@ +diff --git a/src/cmd/vendor/golang.org/x/arch/sw64/sw64asm/gnu.go b/src/cmd/vendor/golang.org/x/arch/sw64/sw64asm/gnu.go +new file mode 100644 +index 0000000000..618a7422db +--- /dev/null ++++ b/src/cmd/vendor/golang.org/x/arch/sw64/sw64asm/gnu.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. ++ ++package sw64asm ++ ++import ( ++ "strings" ++) ++ ++// GNUSyntax returns the GNU assembler syntax for the instruction, as defined by GNU binutils. ++// This form typically matches the syntax defined in the ARM Reference Manual. ++func GNUSyntax(inst Inst) string { ++ /*switch inst.Op { ++ case RET: ++ if r, ok := inst.Args[0].(Reg); ok && r == X30 { ++ return "ret" ++ } ++ case B: ++ if _, ok := inst.Args[0].(Cond); ok { ++ return strings.ToLower("b." + inst.Args[0].String() + " " + inst.Args[1].String()) ++ } ++ case SYSL: ++ result := strings.ToLower(inst.String()) ++ return strings.Replace(result, "c", "C", -1) ++ case DCPS1, DCPS2, DCPS3, CLREX: ++ return strings.ToLower(strings.TrimSpace(inst.String())) ++ case ISB: ++ if strings.Contains(inst.String(), "SY") { ++ result := strings.TrimSuffix(inst.String(), " SY") ++ return strings.ToLower(result) ++ } ++ }*/ ++ return strings.ToLower("sw64 is not implement") ++} +diff --git a/src/cmd/vendor/golang.org/x/arch/sw64/sw64asm/main.go b/src/cmd/vendor/golang.org/x/arch/sw64/sw64asm/main.go +new file mode 100644 +index 0000000000..2cf3b5ff2f +--- /dev/null ++++ b/src/cmd/vendor/golang.org/x/arch/sw64/sw64asm/main.go +@@ -0,0 +1,101 @@ ++package sw64asm ++ ++import ( ++ "encoding/binary" ++ "fmt" ++ "io" ++) ++ ++// An Inst is a single instruction. ++type Inst struct { ++ Op OP // Opcode mnemonic ++ Enc uint32 // Raw encoding bits. ++ Args []string // Instruction arguments, in native SW64 order. ++} ++ ++func immName(v uint32) string { ++ return fmt.Sprintf("$0x%x", v) ++} ++ ++func memory(rno uint32, offset uint32) string { ++ return fmt.Sprintf("$%d(%s)", offset, iRegName(rno)) ++} ++ ++func targetName(pc uint64, name string, base int64) string { ++ if base == 0 { ++ return fmt.Sprintf("%x <%s>", pc, name) ++ } else { ++ return fmt.Sprintf("%x <%s+0x%x>", pc, name, base) ++ } ++} ++ ++// Decode decodes the 4 bytes in src as a single instruction. ++func Decode(src []byte) (inst Inst, err error) { ++ if len(src) < 4 { ++ return Inst{}, nil ++ } ++ v := binary.LittleEndian.Uint32(src) ++ i := Inst{ ++ Op: ParseOPtable(v), ++ Enc: v, ++ Args: make([]string, 0, 4), ++ } ++ return i, nil ++} ++ ++func GoSyntax(i Inst, pc uint64, symname func(uint64) (string, uint64), text io.ReaderAt) string { ++ switch i.Op.Class { ++ case OPC_SYSCALL: ++ i.AddArg(immName(fetchBit(i.Enc, 0, 25))) ++ case OPC_CONTROL: ++ i.AddArg(i.RegNameAt(0)(fetchRa(i.Enc))) ++ pc_t := uint64(fetchBit(i.Enc, 0, 21)) + 4 + pc ++ name, base := symname(pc_t) ++ i.AddArg(targetName(pc_t, name, int64(pc_t-base))) ++ case OPC_MEMORY: ++ i.AddArg(i.RegNameAt(0)(fetchRa(i.Enc))) ++ i.AddArg(memory(fetchRb(i.Enc), fetchDisp(i.Enc))) ++ case OPC_FUNC_MEMORY: ++ i.AddArg(i.RegNameAt(0)(fetchRa(i.Enc))) ++ i.AddArg(memory(fetchRb(i.Enc), fetchDisp(i.Enc))) ++ case OPC_MISI_MEMORY: ++ i.AddArg(i.RegNameAt(0)(fetchRa(i.Enc))) ++ case OPC_ARITHMETIC: ++ i.AddArg(i.RegNameAt(0)(fetchRa(i.Enc))) ++ i.AddArg(i.RegNameAt(1)(fetchRb(i.Enc))) ++ i.AddArg(i.RegNameAt(2)(fetchBit(i.Enc, 0, 5))) ++ case OPC_ARITHMETIC_I: ++ i.AddArg(i.RegNameAt(0)(fetchRa(i.Enc))) ++ i.AddArg(immName(fetchBit(i.Enc, 13, 8))) ++ i.AddArg(i.RegNameAt(0)(fetchBit(i.Enc, 0, 5))) ++ case OPC_COMPLEX_ARITHMETIC: ++ i.AddArg(i.RegNameAt(0)(fetchRa(i.Enc))) ++ i.AddArg(i.RegNameAt(1)(fetchRb(i.Enc))) ++ i.AddArg(i.RegNameAt(2)(fetchBit(i.Enc, 5, 5))) ++ i.AddArg(i.RegNameAt(3)(fetchBit(i.Enc, 0, 5))) ++ case OPC_COMPLEX_ARITHMETIC_I: ++ i.AddArg(i.RegNameAt(0)(fetchRa(i.Enc))) ++ i.AddArg(immName(fetchBit(i.Enc, 13, 8))) ++ i.AddArg(i.RegNameAt(2)(fetchBit(i.Enc, 5, 5))) ++ i.AddArg(i.RegNameAt(3)(fetchBit(i.Enc, 0, 5))) ++ } ++ ++ switch len(i.Args) { ++ case 0: ++ return fmt.Sprintf("%7s", i.Op.Name) ++ case 1: ++ return fmt.Sprintf("%7s %3s", i.Op.Name, i.Args[0]) ++ case 2: ++ return fmt.Sprintf("%7s %3s, %v", i.Op.Name, i.Args[0], i.Args[1]) ++ case 3: ++ return fmt.Sprintf("%7s %3s, %v, %v", i.Op.Name, i.Args[0], i.Args[1], i.Args[2]) ++ default: ++ return fmt.Sprintf("%7s %3s, %v, %v", i.Op.Name, "?", "?", "?") ++ } ++} ++func (i *Inst) AddArg(arg string) { ++ if arg == "" { ++ return ++ } ++ i.Args = append(i.Args, arg) ++} +diff --git a/src/cmd/vendor/golang.org/x/arch/sw64/sw64asm/op2str.go b/src/cmd/vendor/golang.org/x/arch/sw64/sw64asm/op2str.go +new file mode 100644 +index 0000000000..8f97b44dac +--- /dev/null ++++ b/src/cmd/vendor/golang.org/x/arch/sw64/sw64asm/op2str.go +@@ -0,0 +1,377 @@ ++package sw64asm ++ ++import ( ++ "fmt" ++ "strings" ++) ++ ++var classTabs = map[int]int{ ++ 0x00: OPC_SYSCALL, ++ 0x01: OPC_MEMORY, ++ 0x02: OPC_MEMORY, ++ 0x03: OPC_MEMORY, ++ 0x04: OPC_CONTROL, ++ 0x05: OPC_CONTROL, ++ 0x06: OPC_MISI_MEMORY, ++ 0x08: OPC_FUNC_MEMORY, ++ 0x10: OPC_ARITHMETIC, ++ 0x11: OPC_ARITHMETIC, ++ 0x12: OPC_ARITHMETIC_I, ++ 0x13: OPC_ARITHMETIC_I, ++ 0x20: OPC_MEMORY, ++ 0x21: OPC_MEMORY, ++ 0x22: OPC_MEMORY, ++ 0x23: OPC_MEMORY, ++ 0x24: OPC_MEMORY, ++ 0x25: OPC_MEMORY, ++ 0x26: OPC_MEMORY, ++ 0x27: OPC_MEMORY, ++ 0x28: OPC_MEMORY, ++ 0x29: OPC_MEMORY, ++ 0x2A: OPC_MEMORY, ++ 0x2B: OPC_MEMORY, ++ 0x2C: OPC_MEMORY, ++ 0x2D: OPC_MEMORY, ++ 0x2E: OPC_MEMORY, ++ 0x2F: OPC_MEMORY, ++ 0x30: OPC_CONTROL, ++ 0x31: OPC_CONTROL, ++ 0x32: OPC_CONTROL, ++ 0x33: OPC_CONTROL, ++ 0x34: OPC_CONTROL, ++ 0x35: OPC_CONTROL, ++ 0x36: OPC_CONTROL, ++ 0x37: OPC_CONTROL, ++ 0x38: OPC_CONTROL, ++ 0x39: OPC_CONTROL, ++ 0x3A: OPC_CONTROL, ++ 0x3B: OPC_CONTROL, ++ 0x3C: OPC_CONTROL, ++ 0x3D: OPC_CONTROL, ++ 0x3e: OPC_MEMORY, ++ 0x3f: OPC_MEMORY, ++ 0x18: OPC_ARITHMETIC, ++ 0x19: OPC_COMPLEX_ARITHMETIC, ++} ++ ++// op fn name ++var nameTabs = map[int]map[int]string{ ++ 0x00: {0x0: "SYSCALL/B", 0x1: "SYSCALL"}, ++ 0x01: {0x0: "CALL"}, ++ 0x02: {0x0: "RET"}, ++ 0x03: {0x0: "JMP"}, ++ 0x04: {0x0: "BR"}, ++ 0x05: {0x0: "BSR"}, ++ 0x06: { ++ 0x0000: "MEMB", ++ 0x0001: "IMEMB", ++ 0x1000: "RD_F", ++ 0x1020: "WR_F", ++ }, ++ 0x08: { ++ 0x0: "LLDW", ++ 0x1: "LLDL", ++ 0x8: "LSTW", ++ 0x9: "LSTL", ++ }, ++ 0x10: { ++ 0x00: "ADDW", ++ 0x01: "SUBW", ++ 0x02: "S4ADDW", ++ 0x03: "S4SUBW", ++ 0x04: "S8ADDW", ++ 0x05: "S8SUBW", ++ 0x08: "ADDL", ++ 0x09: "SUBL", ++ 0x0a: "S4ADDL", ++ 0x0b: "S4SUBL", ++ 0x0c: "S8ADDL", ++ 0x0d: "S8SUBL", ++ 0x10: "MULW", ++ 0x18: "MULL", ++ 0x19: "UMULH", ++ 0x28: "CMPEQ", ++ 0x29: "CMPLT", ++ 0x2a: "CMPLE", ++ 0x2b: "CMPULT", ++ 0x2c: "CMPULE", ++ 0x38: "AND", ++ 0x39: "BIC", ++ 0x3a: "BIS", ++ 0x3b: "ORNOT", ++ 0x3c: "XOR", ++ 0x3d: "EQV", ++ 0x40: "INSLB", ++ 0x41: "INSLH", ++ 0x42: "INSLW", ++ 0x43: "INSLL", ++ 0x44: "INSHB", ++ 0x45: "INSHH", ++ 0x46: "INSHW", ++ 0x47: "INSHL", ++ 0x48: "SLL", ++ 0x49: "SRL", ++ 0x4a: "SRA", ++ 0x50: "EXTLB", ++ 0x51: "EXTLH", ++ 0x52: "EXTLW", ++ 0x53: "EXTLL", ++ 0x54: "EXTHB", ++ 0x55: "EXTHH", ++ 0x56: "EXTHW", ++ 0x57: "EXTHL", ++ 0x58: "CTPOP", ++ 0x59: "CTLZ", ++ 0x5a: "CTTZ", ++ 0x60: "MASKLB", ++ 0x61: "MASKLH", ++ 0x62: "MASKLW", ++ 0x63: "MASKLL", ++ 0x64: "MASKHB", ++ 0x65: "MASKHH", ++ 0x66: "MASKHW", ++ 0x67: "MASKHL", ++ 0x68: "ZAP", ++ 0x69: "ZAPNOT", ++ 0x6a: "SEXTB", ++ 0x6b: "SEXTH", ++ 0x6c: "CMPGEB", ++ 0x70: "FIMOVS", ++ 0x78: "FIMOVD", ++ }, ++ 0x11: { ++ 0x0: "SELEQ", ++ 0x1: "SELGE", ++ 0x2: "SELGT", ++ 0x3: "SELLE", ++ 0x4: "SELLT", ++ 0x5: "SELNE", ++ 0x6: "SELLBC", ++ 0x7: "SELLBS", ++ }, ++ 0x12: { ++ 0x00: "ADDW", ++ 0x01: "SUBW", ++ 0x02: "S4ADDW", ++ 0x03: "S4SUBW", ++ 0x04: "S8ADDW", ++ 0x05: "S8SUBW", ++ 0x08: "ADDL", ++ 0x09: "SUBL", ++ 0x0a: "S4ADDL", ++ 0x0b: "S4SUBL", ++ 0x0c: "S8ADDL", ++ 0x0d: "S8SUBL", ++ 0x10: "MULW", ++ 0x18: "MULL", ++ 0x19: "UMULH", ++ 0x28: "CMPEQ", ++ 0x29: "CMPLT", ++ 0x2a: "CMPLE", ++ 0x2b: "CMPULT", ++ 0x2c: "CMPULE", ++ 0x38: "AND", ++ 0x39: "BIC", ++ 0x3a: "BIS", ++ 0x3b: "ORNOT", ++ 0x3c: "XOR", ++ 0x3d: "EQV", ++ 0x40: "INSLB", ++ 0x41: "INSLH", ++ 0x42: "INSLW", ++ 0x43: "INSLL", ++ 0x44: "INSHB", ++ 0x45: "INSHH", ++ 0x46: "INSHW", ++ 0x47: "INSHL", ++ 0x48: "SLL", ++ 0x49: "SRL", ++ 0x4a: "SRA", ++ 0x50: "EXTLB", ++ 0x51: "EXTLH", ++ 0x52: "EXTLW", ++ 0x53: "EXTLL", ++ 0x54: "EXTHB", ++ 0x55: "EXTHH", ++ 0x56: "EXTHW", ++ 0x57: "EXTHL", ++ 0x60: "MASKLB", ++ 0x61: "MASKLH", ++ 0x62: "MASKLW", ++ 0x63: "MASKLL", ++ 0x64: "MASKHB", ++ 0x65: "MASKHH", ++ 0x66: "MASKHW", ++ 0x67: "MASKHL", ++ 0x68: "ZAP", ++ 0x69: "ZAPNOT", ++ 0x6a: "SEXTB", ++ 0x6b: "SEXTH", ++ 0x6c: "CMPGEB", ++ }, ++ 0x13: { ++ 0x0: "SELEQ", ++ 0x1: "SELGE", ++ 0x2: "SELGT", ++ 0x3: "SELLE", ++ 0x4: "SELLT", ++ 0x5: "SELNE", ++ 0x6: "SELLBC", ++ 0x7: "SELLBS", ++ }, ++ 0x20: {0: "LDBU"}, ++ 0x21: {0: "LDHU"}, ++ 0x22: {0: "LDW"}, ++ 0x23: {0: "LDL"}, ++ 0x24: {0: "LDL_U"}, ++ 0x25: {0: "PRI_LD"}, ++ 0x26: {0: "FLDS"}, ++ 0x27: {0: "FLDD"}, ++ 0x28: {0: "STB"}, ++ 0x29: {0: "STH"}, ++ 0x2A: {0: "STW"}, ++ 0x2B: {0: "STL"}, ++ 0x2C: {0: "STL_U"}, ++ 0x2D: {0: "PRI_ST"}, ++ 0x2E: {0: "FSTS"}, ++ 0x2F: {0: "FSTD"}, ++ 0x30: {0: "BEQ"}, ++ 0x31: {0: "BNE"}, ++ 0x32: {0: "BLT"}, ++ 0x33: {0: "BLE"}, ++ 0x34: {0: "BGT"}, ++ 0x35: {0: "BGE"}, ++ 0x36: {0: "BLBC"}, ++ 0x37: {0: "BLBS"}, ++ 0x38: {0: "FBEQ"}, ++ 0x39: {0: "FBNE"}, ++ 0x3A: {0: "FBLT"}, ++ 0x3B: {0: "FBLE"}, ++ 0x3C: {0: "FBGT"}, ++ 0x3D: {0: "FBGE"}, ++ 0x3e: {0: "LDI"}, ++ 0x3f: {0: "LDIH"}, ++ 0x18: { ++ 0x00: "FADDS", ++ 0x01: "FADDD", ++ 0x02: "FSUBS", ++ 0x03: "FSUBD", ++ 0x04: "FMULS", ++ 0x05: "FMULD", ++ 0x06: "FDIVS", ++ 0x07: "FDIVD", ++ 0x08: "FSQRTS", ++ 0x09: "FSQRTD", ++ 0x10: "FCMPEQ", ++ 0x11: "FCMPLE", ++ 0x12: "FCMPLT", ++ 0x13: "FCMPUN", ++ 0x20: "FCVTSD", ++ 0x21: "FCVTDS", ++ 0x22: "FCVTDL_G", ++ 0x23: "FCVTDL_P", ++ 0x24: "FCVTDL_Z", ++ 0x25: "FCVTDL_N", ++ 0x27: "FCVTDL", ++ 0x28: "FCVTWL", ++ 0x29: "FCVTLW", ++ 0x2D: "FCVTLS", ++ 0x2F: "FCVTLD", ++ 0x30: "FCPYS", ++ 0x31: "FCPYSE", ++ 0x32: "FCPYSN", ++ 0x40: "IFMOVS", ++ 0x41: "IFMOVD", ++ 0x50: "RFPCR", ++ 0x51: "WFPCR", ++ 0x54: "SETFPEC0", ++ 0x55: "SETFPEC1", ++ 0x56: "SETFPEC2", ++ 0x57: "SETFPEC3", ++ }, ++ 0x19: { ++ 0x00: "FMAS", ++ 0x01: "FMAD", ++ 0x02: "FMSS", ++ 0x03: "FMSD", ++ 0x04: "FNMAS", ++ 0x05: "FNMAD", ++ 0x06: "FNMSS", ++ 0x07: "FNMSD", ++ }, ++} ++ ++var __iRegName = make(map[uint32]string) ++ ++func iRegName(v uint32) string { ++ if len(__iRegName) == 0 { ++ for i := uint32(0); i < 32; i++ { ++ switch i { ++ case 15: ++ __iRegName[i] = fmt.Sprintf("G") ++ case 25: ++ __iRegName[i] = fmt.Sprintf("CTXT") ++ case 26: ++ __iRegName[i] = fmt.Sprintf("RA") ++ case 28: ++ __iRegName[i] = fmt.Sprintf("TMP") ++ case 29: ++ __iRegName[i] = fmt.Sprintf("GP") ++ case 30: ++ __iRegName[i] = fmt.Sprintf("SP") ++ case 31: ++ __iRegName[i] = fmt.Sprintf("ZERO") ++ default: ++ __iRegName[i] = fmt.Sprintf("R%d", i) ++ } ++ } ++ } ++ return __iRegName[v] ++} ++ ++var __fRegName = make(map[uint32]string) ++ ++func fRegName(v uint32) string { ++ if len(__fRegName) == 0 { ++ for i := uint32(0); i < 32; i++ { ++ __fRegName[i] = fmt.Sprintf("F%d", i) ++ } ++ } ++ return __fRegName[v] ++} ++func nullName(_ uint32) string { return "" } ++ ++func (i Inst) RegNameAt(pos int) func(uint32) string { ++ name := i.Op.Name ++ ++ switch { ++ case name == "MEMB", ++ name == "IMEMB", ++ strings.HasPrefix(name, "SETFPEC"): ++ return nullName ++ case strings.HasPrefix(name, "FIMOV"): ++ switch pos { ++ case 0: ++ return fRegName ++ case 1: ++ return nullName ++ case 2: ++ return iRegName ++ } ++ case strings.HasPrefix(name, "IFMOV"): ++ switch pos { ++ case 0: ++ return iRegName ++ case 1: ++ return nullName ++ case 2: ++ return fRegName ++ } ++ default: ++ if name[0] == 'F' { ++ return fRegName ++ } ++ } ++ ++ return iRegName ++} +diff --git a/src/cmd/vendor/golang.org/x/arch/sw64/sw64asm/rawinst.go b/src/cmd/vendor/golang.org/x/arch/sw64/sw64asm/rawinst.go +new file mode 100644 +index 0000000000..94a2745e77 +--- /dev/null ++++ b/src/cmd/vendor/golang.org/x/arch/sw64/sw64asm/rawinst.go +@@ -0,0 +1,88 @@ ++package sw64asm ++ ++import ( ++ "fmt" ++) ++ ++func ParseOPtable(raw uint32) OP { ++ op := fetchOpcode(raw) ++ class, ok := classTabs[int(op)] ++ if !ok { ++ return OP{ ++ OPcode: int(op), ++ Name: fmt.Sprintf("?0x%x", op), ++ } ++ } ++ fn := fetchFncode(raw, class) ++ name, ok := nameTabs[int(op)][int(fn)] ++ if !ok { ++ name = fmt.Sprintf("?0x%x:0x%x?", op, fn) ++ } ++ return OP{ ++ OPcode: int(op), ++ Fncode: int(fn), ++ Name: name, ++ Class: class, ++ IsFloat: name[1] == 'F', ++ } ++} ++ ++func fetchBit(v uint32, begin, width uint32) uint32 { ++ t := v >> begin ++ mask := (uint32(1) << width) - 1 ++ return t & mask ++} ++ ++func fetchOpcode(v uint32) uint32 { return fetchBit(v, 26, 6) } ++func fetchRa(v uint32) uint32 { return fetchBit(v, 21, 5) } ++func fetchRb(v uint32) uint32 { return fetchBit(v, 16, 5) } ++func fetchDisp(v uint32) uint32 { return fetchBit(v, 0, 16) } ++ ++func fetchFncode(v uint32, c int) uint32 { ++ switch c { ++ case OPC_SYSCALL: ++ return fetchBit(v, 25, 1) ++ case OPC_ARITHMETIC, ++ OPC_ARITHMETIC_I: ++ return fetchBit(v, 5, 8) ++ case OPC_COMPLEX_ARITHMETIC, ++ OPC_COMPLEX_ARITHMETIC_I: ++ return fetchBit(v, 10, 6) ++ case OPC_MISI_MEMORY: ++ return fetchBit(v, 0, 16) ++ case OPC_FUNC_MEMORY: ++ return fetchBit(v, 12, 4) ++ case OPC_CONTROL, ++ OPC_MEMORY: ++ return 0 ++ default: ++ panic(fmt.Sprintf("Invalid instruction for %v %v", v, c)) ++ } ++} ++ ++const ( ++ OPC_NULL = iota // 类别 |31 26|25 21|20 16|15 5|4 0| ++ OPC_SYSCALL //系统调用指令, |Opcode| Function | ++ OPC_CONTROL //转移控制指令, |Opcode| Ra | disp | ++ OPC_MEMORY //存储器指令, |Opcode| Ra | Rb | disp | ++ ++ OPC_MISI_MEMORY // 杂项指令 |Opcode| Ra | Rb | Function | ++ ++ OPC_FUNC_MEMORY //带功能域的存 |Opcode| Ra | Rb | Function | disp | ++ ++ OPC_ARITHMETIC //简单运算指令, |Opcode| Ra | Rb | Function | RC | ++ OPC_ARITHMETIC_I //简单运算指令, |Opcode| Ra | Ib |Function| RC | ++ // |31 26|25 21|20 13|12 5|4 0| ++ ++ OPC_COMPLEX_ARITHMETIC // 浮点复合运算指令格式 |Opcode| Fa | Fb |Function | Fc |Fd | ++ OPC_COMPLEX_ARITHMETIC_I // 浮点复合运算指令格式 |Opcode| Fa | Fb |Function | Ib |Fd | ++ // |31 26|25 21|20 16|15 10|9 5|4 0| ++) ++ ++type OP struct { ++ OPcode int ++ Fncode int ++ Name string ++ Class int ++ IsFloat bool ++} +diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_sw64.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_sw64.s +new file mode 100644 +index 0000000000..4afa6ff5cc +--- /dev/null ++++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_linux_sw64.s +@@ -0,0 +1,55 @@ ++// 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 linux && sw64 && gc ++ ++#include "textflag.h" ++ ++// ++// System calls for sw64, Linux ++// ++// Just jump to package syscall's implementation for all these functions. ++// The runtime may know about them. ++ ++#define SYSCALL SYS_CALL_B $131 ++ ++TEXT ·Syscall(SB),NOSPLIT|NOFRAME,$0-56 ++ JMP syscall·Syscall(SB) ++ ++TEXT ·Syscall6(SB),NOSPLIT|NOFRAME,$0-80 ++ JMP syscall·Syscall6(SB) ++ ++TEXT ·SyscallNoError(SB),NOSPLIT,$0-48 ++ CALL runtime·entersyscall(SB) ++ LDL R16, a1+8(FP) ++ LDL R17, a2+16(FP) ++ LDL R18, a3+24(FP) ++ LDI R19, ZERO ++ LDI R20, ZERO ++ LDI R21, ZERO ++ LDL R0, trap+0(FP) // syscall entry ++ SYSCALL ++ STL R0, r1+32(FP) ++ STL R20, r2+40(FP) ++ CALL runtime·exitsyscall(SB) ++ RET ++ ++TEXT ·RawSyscall(SB),NOSPLIT|NOFRAME,$0-56 ++ JMP syscall·RawSyscall(SB) ++ ++TEXT ·RawSyscall6(SB),NOSPLIT|NOFRAME,$0-80 ++ JMP syscall·RawSyscall6(SB) ++ ++TEXT ·RawSyscallNoError(SB),NOSPLIT|NOFRAME,$0-48 ++ LDL R16, a1+8(FP) ++ LDL R17, a2+16(FP) ++ LDL R18, a3+24(FP) ++ LDI R19, ZERO ++ LDI R20, ZERO ++ LDI R21, ZERO ++ LDL R0, trap+0(FP) // syscall entry ++ SYSCALL ++ STL R0, r1+32(FP) ++ STL R20, r2+40(FP) ++ RET +diff --git a/src/cmd/vendor/golang.org/x/sys/unix/endian_little.go b/src/cmd/vendor/golang.org/x/sys/unix/endian_little.go +index b9f0e277b1..4b20b0a3d0 100644 +--- a/src/cmd/vendor/golang.org/x/sys/unix/endian_little.go ++++ b/src/cmd/vendor/golang.org/x/sys/unix/endian_little.go +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + // +-//go:build 386 || amd64 || amd64p32 || alpha || arm || arm64 || loong64 || mipsle || mips64le || mips64p32le || nios2 || ppc64le || riscv || riscv64 || sh ++//go:build 386 || amd64 || amd64p32 || alpha || arm || arm64 || loong64 || mipsle || mips64le || mips64p32le || nios2 || ppc64le || riscv || riscv64 || sh || sw64 + + package unix + +diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_sw64.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_sw64.go +new file mode 100644 +index 0000000000..d764637396 +--- /dev/null ++++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_sw64.go +@@ -0,0 +1,159 @@ ++// 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 linux && sw64 ++ ++package unix ++ ++ ++const ( ++ //generate by handle in zerrors_linux_sw64.go ++ //_snyh_TODO: this should be generate by improving build script ++ TIOCGWINSZ = 0x40087468 ++) ++ ++const ( ++ //ALL OF THIS constants are WORKAROUND, and should be removing ++ SYS_NEWFSTATAT = SYS_FSTATAT64 ++) ++ ++//sysnb getxpid() (pid int, ppid int) ++// TODO(snyh): correct handle Getppid and Getpid ++// currently manually remove the implements of Getpid and Getppid ++// in zsyscall_linux_sw64.go ++func Getpid() (pid int) { pid, _ = getxpid(); return } ++func Getppid() (ppid int) { _, ppid = getxpid(); return } ++ ++// TODO(snyh): correct handle Utime ++func Utime(path string, buf *Utimbuf) error { ++ tv := [2]Timeval{ ++ {Sec: buf.Actime}, ++ {Sec: buf.Modtime}, ++ } ++ return utimes(path, &tv) ++} ++ ++//sys Fstat64(fd int, st *Stat_t) (err error) ++//sys Lstat64(path string, st *Stat_t) (err error) ++//sys Stat64(path string, st *Stat_t) (err error) ++func Fstat(fd int, st *Stat_t) (err error) { return Fstat64(fd, st) } ++func Lstat(path string, st *Stat_t) (err error) { return Lstat64(path, st) } ++func Stat(path string, st *Stat_t) (err error) { return Stat64(path, st) } ++ ++//sys getxuid() (uid int, euid int) ++func Getuid() (uid int) { uid, _ = getxuid(); return } ++func Geteuid() (euid int) { _, euid = getxuid(); return } ++ ++//sys getxgid() (gid int, egid int) ++func Getgid() (gid int) { gid, _ = getxgid(); return } ++func Getegid() (egid int) { _, egid = getxgid(); return } ++ ++//sys Statfs(path string, buf *Statfs_t) (err error) ++//sys Fstatfs(fd int, buf *Statfs_t) (err error) ++//sys Fchown(fd int, uid int, gid int) (err error) ++//sys Ftruncate(fd int, length int64) (err error) ++//sysnb Getrlimit(resource int, rlim *Rlimit) (err error) ++//sys Lchown(path string, uid int, gid int) (err error) ++//sys Listen(s int, n int) (err error) ++//sys pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64 ++//sys pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64 ++//sys Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK ++//sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) ++//sys setfsgid(gid int) (prev int, err error) ++//sys setfsuid(uid int) (prev int, err error) ++//sys Shutdown(fd int, how int) (err error) ++//sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) ++ ++//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error) ++//sys Truncate(path string, length int64) (err error) ++//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) ++//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) ++//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) ++//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) ++//sysnb getgroups(n int, list *_Gid_t) (nn int, err error) ++//sysnb setgroups(n int, list *_Gid_t) (err error) ++//sys getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) ++//sys setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) ++//sysnb socket(domain int, typ int, proto int) (fd int, err error) ++//sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) ++//sysnb getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) ++//sysnb getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) ++//sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) ++//sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) ++//sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error) ++//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) ++//sys mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) ++ ++//sysnb Gettimeofday(tv *Timeval) (err error) ++ ++func Time(t *Time_t) (tt Time_t, err error) { ++ var tv Timeval ++ err = Gettimeofday(&tv) ++ if err != nil { ++ return 0, err ++ } ++ if t != nil { ++ *t = Time_t(tv.Sec) ++ } ++ return Time_t(tv.Sec), nil ++} ++ ++func setTimespec(sec, nsec int64) Timespec { ++ return Timespec{Sec: sec, Nsec: nsec} ++} ++ ++func setTimeval(sec, usec int64) Timeval { ++ return Timeval{Sec: sec, Usec: usec} ++} ++ ++func Ioperm(from int, num int, on int) (err error) { ++ return ENOSYS ++} ++ ++func Iopl(level int) (err error) { ++ return ENOSYS ++} ++ ++// func (r *PtraceRegs) PC() uint64 { return r.Epc } ++// func (r *PtraceRegs) SetPC(pc uint64) { r.Epc = pc } ++ ++func (iov *Iovec) SetLen(length int) { ++ iov.Len = uint64(length) ++} ++ ++func (msghdr *Msghdr) SetControllen(length int) { ++ msghdr.Controllen = uint64(length) ++} ++ ++func (msghdr *Msghdr) SetIovlen(length int) { ++ msghdr.Iovlen = uint64(length) ++} ++ ++func (cmsg *Cmsghdr) SetLen(length int) { ++ cmsg.Len = uint64(length) ++} ++ ++ ++//sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) ++//sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64 ++//sys Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_NEWFSTATAT ++func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) { ++ var ts *Timespec ++ if timeout != nil { ++ ts = &Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000} ++ } ++ return Pselect(nfd, r, w, e, ts, nil) ++} ++ ++//sys Ustat(dev int, ubuf *Ustat_t) (err error) ++//sys futimesat(dirfd int, path string, times *[2]Timeval) (err error) ++//sys utimes(path string, times *[2]Timeval) (err error) ++ ++//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) ++ ++func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) { ++ rsa.Service_name_len = uint64(length) ++} ++ ++const SYS_FSTATAT = SYS_NEWFSTATAT +diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux.go +index 6ebc48b3fe..a88ddb1413 100644 +--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux.go ++++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux.go +@@ -1,6 +1,6 @@ + // Code generated by mkmerge; DO NOT EDIT. + +-//go:build linux ++//go:build linux && !sw64 + + package unix + +diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_sw64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_sw64.go +new file mode 100644 +index 0000000000..0a8433e906 +--- /dev/null ++++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_sw64.go +@@ -0,0 +1,4486 @@ ++// mkerrors.sh -Wall -Werror -static -I/tmp/sw64/include ++// Code generated by the command above; see README.md. DO NOT EDIT. ++ ++//go:build sw64 && linux ++ ++// Code generated by cmd/cgo -godefs; DO NOT EDIT. ++// cgo -godefs -- -Wall -Werror -static -I/tmp/sw64/include /home/zhangjh/git-source/go/sys-1.24/unix/_const.go ++ ++package unix ++ ++import "syscall" ++ ++const ( ++ AAFS_MAGIC = 0x5a3c69f0 ++ ADFS_SUPER_MAGIC = 0xadf5 ++ AFFS_SUPER_MAGIC = 0xadff ++ AFS_FS_MAGIC = 0x6b414653 ++ AFS_SUPER_MAGIC = 0x5346414f ++ AF_ALG = 0x26 ++ AF_APPLETALK = 0x5 ++ AF_ASH = 0x12 ++ AF_ATMPVC = 0x8 ++ AF_ATMSVC = 0x14 ++ AF_AX25 = 0x3 ++ AF_BLUETOOTH = 0x1f ++ AF_BRIDGE = 0x7 ++ AF_CAIF = 0x25 ++ AF_CAN = 0x1d ++ AF_DECnet = 0xc ++ AF_ECONET = 0x13 ++ AF_FILE = 0x1 ++ AF_IB = 0x1b ++ AF_IEEE802154 = 0x24 ++ AF_INET = 0x2 ++ AF_INET6 = 0xa ++ AF_IPX = 0x4 ++ AF_IRDA = 0x17 ++ AF_ISDN = 0x22 ++ AF_IUCV = 0x20 ++ AF_KCM = 0x29 ++ AF_KEY = 0xf ++ AF_LLC = 0x1a ++ AF_LOCAL = 0x1 ++ AF_MAX = 0x2e ++ AF_MCTP = 0x2d ++ AF_MPLS = 0x1c ++ AF_NETBEUI = 0xd ++ AF_NETLINK = 0x10 ++ AF_NETROM = 0x6 ++ AF_NFC = 0x27 ++ AF_PACKET = 0x11 ++ AF_PHONET = 0x23 ++ AF_PPPOX = 0x18 ++ AF_QIPCRTR = 0x2a ++ AF_RDS = 0x15 ++ AF_ROSE = 0xb ++ AF_ROUTE = 0x10 ++ AF_RXRPC = 0x21 ++ AF_SECURITY = 0xe ++ AF_SMC = 0x2b ++ AF_SNA = 0x16 ++ AF_TIPC = 0x1e ++ AF_UNIX = 0x1 ++ AF_UNSPEC = 0x0 ++ AF_VSOCK = 0x28 ++ AF_WANPIPE = 0x19 ++ AF_X25 = 0x9 ++ AF_XDP = 0x2c ++ ALG_OP_DECRYPT = 0x0 ++ ALG_OP_ENCRYPT = 0x1 ++ ALG_SET_AEAD_ASSOCLEN = 0x4 ++ ALG_SET_AEAD_AUTHSIZE = 0x5 ++ ALG_SET_DRBG_ENTROPY = 0x6 ++ ALG_SET_IV = 0x2 ++ ALG_SET_KEY = 0x1 ++ ALG_SET_KEY_BY_KEY_SERIAL = 0x7 ++ ALG_SET_OP = 0x3 ++ ANON_INODE_FS_MAGIC = 0x9041934 ++ ARPHRD_6LOWPAN = 0x339 ++ ARPHRD_ADAPT = 0x108 ++ ARPHRD_APPLETLK = 0x8 ++ ARPHRD_ARCNET = 0x7 ++ ARPHRD_ASH = 0x30d ++ ARPHRD_ATM = 0x13 ++ ARPHRD_AX25 = 0x3 ++ ARPHRD_BIF = 0x307 ++ ARPHRD_CAIF = 0x336 ++ ARPHRD_CAN = 0x118 ++ ARPHRD_CHAOS = 0x5 ++ ARPHRD_CISCO = 0x201 ++ ARPHRD_CSLIP = 0x101 ++ ARPHRD_CSLIP6 = 0x103 ++ ARPHRD_DDCMP = 0x205 ++ ARPHRD_DLCI = 0xf ++ ARPHRD_ECONET = 0x30e ++ ARPHRD_EETHER = 0x2 ++ ARPHRD_ETHER = 0x1 ++ ARPHRD_EUI64 = 0x1b ++ ARPHRD_FCAL = 0x311 ++ ARPHRD_FCFABRIC = 0x313 ++ ARPHRD_FCPL = 0x312 ++ ARPHRD_FCPP = 0x310 ++ ARPHRD_FDDI = 0x306 ++ ARPHRD_FRAD = 0x302 ++ ARPHRD_HDLC = 0x201 ++ ARPHRD_HIPPI = 0x30c ++ ARPHRD_HWX25 = 0x110 ++ ARPHRD_IEEE1394 = 0x18 ++ ARPHRD_IEEE802 = 0x6 ++ ARPHRD_IEEE80211 = 0x321 ++ ARPHRD_IEEE80211_PRISM = 0x322 ++ ARPHRD_IEEE80211_RADIOTAP = 0x323 ++ ARPHRD_IEEE802154 = 0x324 ++ ARPHRD_IEEE802154_MONITOR = 0x325 ++ ARPHRD_IEEE802_TR = 0x320 ++ ARPHRD_INFINIBAND = 0x20 ++ ARPHRD_IP6GRE = 0x337 ++ ARPHRD_IPDDP = 0x309 ++ ARPHRD_IPGRE = 0x30a ++ ARPHRD_IRDA = 0x30f ++ ARPHRD_LAPB = 0x204 ++ ARPHRD_LOCALTLK = 0x305 ++ ARPHRD_LOOPBACK = 0x304 ++ ARPHRD_MCTP = 0x122 ++ ARPHRD_METRICOM = 0x17 ++ ARPHRD_NETLINK = 0x338 ++ ARPHRD_NETROM = 0x0 ++ ARPHRD_NONE = 0xfffe ++ ARPHRD_PHONET = 0x334 ++ ARPHRD_PHONET_PIPE = 0x335 ++ ARPHRD_PIMREG = 0x30b ++ ARPHRD_PPP = 0x200 ++ ARPHRD_PRONET = 0x4 ++ ARPHRD_RAWHDLC = 0x206 ++ ARPHRD_RAWIP = 0x207 ++ ARPHRD_ROSE = 0x10e ++ ARPHRD_RSRVD = 0x104 ++ ARPHRD_SIT = 0x308 ++ ARPHRD_SKIP = 0x303 ++ ARPHRD_SLIP = 0x100 ++ ARPHRD_SLIP6 = 0x102 ++ ARPHRD_TUNNEL = 0x300 ++ ARPHRD_TUNNEL6 = 0x301 ++ ARPHRD_VOID = 0xffff ++ ARPHRD_VSOCKMON = 0x33a ++ ARPHRD_X25 = 0x10f ++ AUDIT_ADD = 0x3eb ++ AUDIT_ADD_RULE = 0x3f3 ++ AUDIT_ALWAYS = 0x2 ++ AUDIT_ANOM_ABEND = 0x6a5 ++ AUDIT_ANOM_CREAT = 0x6a7 ++ AUDIT_ANOM_LINK = 0x6a6 ++ AUDIT_ANOM_PROMISCUOUS = 0x6a4 ++ AUDIT_ARCH = 0xb ++ AUDIT_ARCH_AARCH64 = 0xc00000b7 ++ AUDIT_ARCH_ALPHA = 0xc0009026 ++ AUDIT_ARCH_ARCOMPACT = 0x4000005d ++ AUDIT_ARCH_ARCOMPACTBE = 0x5d ++ AUDIT_ARCH_ARCV2 = 0x400000c3 ++ AUDIT_ARCH_ARCV2BE = 0xc3 ++ AUDIT_ARCH_ARM = 0x40000028 ++ AUDIT_ARCH_ARMEB = 0x28 ++ AUDIT_ARCH_C6X = 0x4000008c ++ AUDIT_ARCH_C6XBE = 0x8c ++ AUDIT_ARCH_CRIS = 0x4000004c ++ AUDIT_ARCH_CSKY = 0x400000fc ++ AUDIT_ARCH_FRV = 0x5441 ++ AUDIT_ARCH_H8300 = 0x2e ++ AUDIT_ARCH_HEXAGON = 0xa4 ++ AUDIT_ARCH_I386 = 0x40000003 ++ AUDIT_ARCH_IA64 = 0xc0000032 ++ AUDIT_ARCH_LOONGARCH32 = 0x40000102 ++ AUDIT_ARCH_LOONGARCH64 = 0xc0000102 ++ AUDIT_ARCH_M32R = 0x58 ++ AUDIT_ARCH_M68K = 0x4 ++ AUDIT_ARCH_MICROBLAZE = 0xbd ++ AUDIT_ARCH_MIPS = 0x8 ++ AUDIT_ARCH_MIPS64 = 0x80000008 ++ AUDIT_ARCH_MIPS64N32 = 0xa0000008 ++ AUDIT_ARCH_MIPSEL = 0x40000008 ++ AUDIT_ARCH_MIPSEL64 = 0xc0000008 ++ AUDIT_ARCH_MIPSEL64N32 = 0xe0000008 ++ AUDIT_ARCH_NDS32 = 0x400000a7 ++ AUDIT_ARCH_NDS32BE = 0xa7 ++ AUDIT_ARCH_NIOS2 = 0x40000071 ++ AUDIT_ARCH_OPENRISC = 0x5c ++ AUDIT_ARCH_PARISC = 0xf ++ AUDIT_ARCH_PARISC64 = 0x8000000f ++ AUDIT_ARCH_PPC = 0x14 ++ AUDIT_ARCH_PPC64 = 0x80000015 ++ AUDIT_ARCH_PPC64LE = 0xc0000015 ++ AUDIT_ARCH_RISCV32 = 0x400000f3 ++ AUDIT_ARCH_RISCV64 = 0xc00000f3 ++ AUDIT_ARCH_S390 = 0x16 ++ AUDIT_ARCH_S390X = 0x80000016 ++ AUDIT_ARCH_SH = 0x2a ++ AUDIT_ARCH_SH64 = 0x8000002a ++ AUDIT_ARCH_SHEL = 0x4000002a ++ AUDIT_ARCH_SHEL64 = 0xc000002a ++ AUDIT_ARCH_SPARC = 0x2 ++ AUDIT_ARCH_SPARC64 = 0x8000002b ++ AUDIT_ARCH_SW64 = 0xc0009916 ++ AUDIT_ARCH_TILEGX = 0xc00000bf ++ AUDIT_ARCH_TILEGX32 = 0x400000bf ++ AUDIT_ARCH_TILEPRO = 0x400000bc ++ AUDIT_ARCH_UNICORE = 0x4000006e ++ AUDIT_ARCH_X86_64 = 0xc000003e ++ AUDIT_ARCH_XTENSA = 0x5e ++ AUDIT_ARG0 = 0xc8 ++ AUDIT_ARG1 = 0xc9 ++ AUDIT_ARG2 = 0xca ++ AUDIT_ARG3 = 0xcb ++ AUDIT_AVC = 0x578 ++ AUDIT_AVC_PATH = 0x57a ++ AUDIT_BITMASK_SIZE = 0x40 ++ AUDIT_BIT_MASK = 0x8000000 ++ AUDIT_BIT_TEST = 0x48000000 ++ AUDIT_BPF = 0x536 ++ AUDIT_BPRM_FCAPS = 0x529 ++ AUDIT_CAPSET = 0x52a ++ AUDIT_CLASS_CHATTR = 0x2 ++ AUDIT_CLASS_CHATTR_32 = 0x3 ++ AUDIT_CLASS_DIR_WRITE = 0x0 ++ AUDIT_CLASS_DIR_WRITE_32 = 0x1 ++ AUDIT_CLASS_READ = 0x4 ++ AUDIT_CLASS_READ_32 = 0x5 ++ AUDIT_CLASS_SIGNAL = 0x8 ++ AUDIT_CLASS_SIGNAL_32 = 0x9 ++ AUDIT_CLASS_WRITE = 0x6 ++ AUDIT_CLASS_WRITE_32 = 0x7 ++ AUDIT_COMPARE_AUID_TO_EUID = 0x10 ++ AUDIT_COMPARE_AUID_TO_FSUID = 0xe ++ AUDIT_COMPARE_AUID_TO_OBJ_UID = 0x5 ++ AUDIT_COMPARE_AUID_TO_SUID = 0xf ++ AUDIT_COMPARE_EGID_TO_FSGID = 0x17 ++ AUDIT_COMPARE_EGID_TO_OBJ_GID = 0x4 ++ AUDIT_COMPARE_EGID_TO_SGID = 0x18 ++ AUDIT_COMPARE_EUID_TO_FSUID = 0x12 ++ AUDIT_COMPARE_EUID_TO_OBJ_UID = 0x3 ++ AUDIT_COMPARE_EUID_TO_SUID = 0x11 ++ AUDIT_COMPARE_FSGID_TO_OBJ_GID = 0x9 ++ AUDIT_COMPARE_FSUID_TO_OBJ_UID = 0x8 ++ AUDIT_COMPARE_GID_TO_EGID = 0x14 ++ AUDIT_COMPARE_GID_TO_FSGID = 0x15 ++ AUDIT_COMPARE_GID_TO_OBJ_GID = 0x2 ++ AUDIT_COMPARE_GID_TO_SGID = 0x16 ++ AUDIT_COMPARE_SGID_TO_FSGID = 0x19 ++ AUDIT_COMPARE_SGID_TO_OBJ_GID = 0x7 ++ AUDIT_COMPARE_SUID_TO_FSUID = 0x13 ++ AUDIT_COMPARE_SUID_TO_OBJ_UID = 0x6 ++ AUDIT_COMPARE_UID_TO_AUID = 0xa ++ AUDIT_COMPARE_UID_TO_EUID = 0xb ++ AUDIT_COMPARE_UID_TO_FSUID = 0xc ++ AUDIT_COMPARE_UID_TO_OBJ_UID = 0x1 ++ AUDIT_COMPARE_UID_TO_SUID = 0xd ++ AUDIT_CONFIG_CHANGE = 0x519 ++ AUDIT_CWD = 0x51b ++ AUDIT_DAEMON_ABORT = 0x4b2 ++ AUDIT_DAEMON_CONFIG = 0x4b3 ++ AUDIT_DAEMON_END = 0x4b1 ++ AUDIT_DAEMON_START = 0x4b0 ++ AUDIT_DEL = 0x3ec ++ AUDIT_DEL_RULE = 0x3f4 ++ AUDIT_DEVMAJOR = 0x64 ++ AUDIT_DEVMINOR = 0x65 ++ AUDIT_DIR = 0x6b ++ AUDIT_DM_CTRL = 0x53a ++ AUDIT_DM_EVENT = 0x53b ++ AUDIT_EGID = 0x6 ++ AUDIT_EOE = 0x528 ++ AUDIT_EQUAL = 0x40000000 ++ AUDIT_EUID = 0x2 ++ AUDIT_EVENT_LISTENER = 0x537 ++ AUDIT_EXE = 0x70 ++ AUDIT_EXECVE = 0x51d ++ AUDIT_EXIT = 0x67 ++ AUDIT_FAIL_PANIC = 0x2 ++ AUDIT_FAIL_PRINTK = 0x1 ++ AUDIT_FAIL_SILENT = 0x0 ++ AUDIT_FANOTIFY = 0x533 ++ AUDIT_FD_PAIR = 0x525 ++ AUDIT_FEATURE_BITMAP_ALL = 0x7f ++ AUDIT_FEATURE_BITMAP_BACKLOG_LIMIT = 0x1 ++ AUDIT_FEATURE_BITMAP_BACKLOG_WAIT_TIME = 0x2 ++ AUDIT_FEATURE_BITMAP_EXCLUDE_EXTEND = 0x8 ++ AUDIT_FEATURE_BITMAP_EXECUTABLE_PATH = 0x4 ++ AUDIT_FEATURE_BITMAP_FILTER_FS = 0x40 ++ AUDIT_FEATURE_BITMAP_LOST_RESET = 0x20 ++ AUDIT_FEATURE_BITMAP_SESSIONID_FILTER = 0x10 ++ AUDIT_FEATURE_CHANGE = 0x530 ++ AUDIT_FEATURE_LOGINUID_IMMUTABLE = 0x1 ++ AUDIT_FEATURE_ONLY_UNSET_LOGINUID = 0x0 ++ AUDIT_FEATURE_VERSION = 0x1 ++ AUDIT_FIELD_COMPARE = 0x6f ++ AUDIT_FILETYPE = 0x6c ++ AUDIT_FILTERKEY = 0xd2 ++ AUDIT_FILTER_ENTRY = 0x2 ++ AUDIT_FILTER_EXCLUDE = 0x5 ++ AUDIT_FILTER_EXIT = 0x4 ++ AUDIT_FILTER_FS = 0x6 ++ AUDIT_FILTER_PREPEND = 0x10 ++ AUDIT_FILTER_TASK = 0x1 ++ AUDIT_FILTER_TYPE = 0x5 ++ AUDIT_FILTER_URING_EXIT = 0x7 ++ AUDIT_FILTER_USER = 0x0 ++ AUDIT_FILTER_WATCH = 0x3 ++ AUDIT_FIRST_KERN_ANOM_MSG = 0x6a4 ++ AUDIT_FIRST_USER_MSG = 0x44c ++ AUDIT_FIRST_USER_MSG2 = 0x834 ++ AUDIT_FSGID = 0x8 ++ AUDIT_FSTYPE = 0x1a ++ AUDIT_FSUID = 0x4 ++ AUDIT_GET = 0x3e8 ++ AUDIT_GET_FEATURE = 0x3fb ++ AUDIT_GID = 0x5 ++ AUDIT_GREATER_THAN = 0x20000000 ++ AUDIT_GREATER_THAN_OR_EQUAL = 0x60000000 ++ AUDIT_INODE = 0x66 ++ AUDIT_INTEGRITY_DATA = 0x708 ++ AUDIT_INTEGRITY_EVM_XATTR = 0x70e ++ AUDIT_INTEGRITY_HASH = 0x70b ++ AUDIT_INTEGRITY_METADATA = 0x709 ++ AUDIT_INTEGRITY_PCR = 0x70c ++ AUDIT_INTEGRITY_POLICY_RULE = 0x70f ++ AUDIT_INTEGRITY_RULE = 0x70d ++ AUDIT_INTEGRITY_STATUS = 0x70a ++ AUDIT_IPC = 0x517 ++ AUDIT_IPC_SET_PERM = 0x51f ++ AUDIT_KERNEL = 0x7d0 ++ AUDIT_KERNEL_OTHER = 0x524 ++ AUDIT_KERN_MODULE = 0x532 ++ AUDIT_LAST_FEATURE = 0x1 ++ AUDIT_LAST_KERN_ANOM_MSG = 0x707 ++ AUDIT_LAST_USER_MSG = 0x4af ++ AUDIT_LAST_USER_MSG2 = 0xbb7 ++ AUDIT_LESS_THAN = 0x10000000 ++ AUDIT_LESS_THAN_OR_EQUAL = 0x50000000 ++ AUDIT_LIST = 0x3ea ++ AUDIT_LIST_RULES = 0x3f5 ++ AUDIT_LOGIN = 0x3ee ++ AUDIT_LOGINUID = 0x9 ++ AUDIT_LOGINUID_SET = 0x18 ++ AUDIT_MAC_CALIPSO_ADD = 0x58a ++ AUDIT_MAC_CALIPSO_DEL = 0x58b ++ AUDIT_MAC_CIPSOV4_ADD = 0x57f ++ AUDIT_MAC_CIPSOV4_DEL = 0x580 ++ AUDIT_MAC_CONFIG_CHANGE = 0x57d ++ AUDIT_MAC_IPSEC_ADDSA = 0x583 ++ AUDIT_MAC_IPSEC_ADDSPD = 0x585 ++ AUDIT_MAC_IPSEC_DELSA = 0x584 ++ AUDIT_MAC_IPSEC_DELSPD = 0x586 ++ AUDIT_MAC_IPSEC_EVENT = 0x587 ++ AUDIT_MAC_MAP_ADD = 0x581 ++ AUDIT_MAC_MAP_DEL = 0x582 ++ AUDIT_MAC_POLICY_LOAD = 0x57b ++ AUDIT_MAC_STATUS = 0x57c ++ AUDIT_MAC_UNLBL_ALLOW = 0x57e ++ AUDIT_MAC_UNLBL_STCADD = 0x588 ++ AUDIT_MAC_UNLBL_STCDEL = 0x589 ++ AUDIT_MAKE_EQUIV = 0x3f7 ++ AUDIT_MAX_FIELDS = 0x40 ++ AUDIT_MAX_FIELD_COMPARE = 0x19 ++ AUDIT_MAX_KEY_LEN = 0x100 ++ AUDIT_MESSAGE_TEXT_MAX = 0x2170 ++ AUDIT_MMAP = 0x52b ++ AUDIT_MQ_GETSETATTR = 0x523 ++ AUDIT_MQ_NOTIFY = 0x522 ++ AUDIT_MQ_OPEN = 0x520 ++ AUDIT_MQ_SENDRECV = 0x521 ++ AUDIT_MSGTYPE = 0xc ++ AUDIT_NEGATE = 0x80000000 ++ AUDIT_NETFILTER_CFG = 0x52d ++ AUDIT_NETFILTER_PKT = 0x52c ++ AUDIT_NEVER = 0x0 ++ AUDIT_NLGRP_MAX = 0x1 ++ AUDIT_NOT_EQUAL = 0x30000000 ++ AUDIT_NR_FILTERS = 0x8 ++ AUDIT_OBJ_GID = 0x6e ++ AUDIT_OBJ_LEV_HIGH = 0x17 ++ AUDIT_OBJ_LEV_LOW = 0x16 ++ AUDIT_OBJ_PID = 0x526 ++ AUDIT_OBJ_ROLE = 0x14 ++ AUDIT_OBJ_TYPE = 0x15 ++ AUDIT_OBJ_UID = 0x6d ++ AUDIT_OBJ_USER = 0x13 ++ AUDIT_OPENAT2 = 0x539 ++ AUDIT_OPERATORS = 0x78000000 ++ AUDIT_PATH = 0x516 ++ AUDIT_PERM = 0x6a ++ AUDIT_PERM_ATTR = 0x8 ++ AUDIT_PERM_EXEC = 0x1 ++ AUDIT_PERM_READ = 0x4 ++ AUDIT_PERM_WRITE = 0x2 ++ AUDIT_PERS = 0xa ++ AUDIT_PID = 0x0 ++ AUDIT_POSSIBLE = 0x1 ++ AUDIT_PPID = 0x12 ++ AUDIT_PROCTITLE = 0x52f ++ AUDIT_REPLACE = 0x531 ++ AUDIT_SADDR_FAM = 0x71 ++ AUDIT_SECCOMP = 0x52e ++ AUDIT_SELINUX_ERR = 0x579 ++ AUDIT_SESSIONID = 0x19 ++ AUDIT_SET = 0x3e9 ++ AUDIT_SET_FEATURE = 0x3fa ++ AUDIT_SGID = 0x7 ++ AUDIT_SID_UNSET = 0xffffffff ++ AUDIT_SIGNAL_INFO = 0x3f2 ++ AUDIT_SOCKADDR = 0x51a ++ AUDIT_SOCKETCALL = 0x518 ++ AUDIT_STATUS_BACKLOG_LIMIT = 0x10 ++ AUDIT_STATUS_BACKLOG_WAIT_TIME = 0x20 ++ AUDIT_STATUS_BACKLOG_WAIT_TIME_ACTUAL = 0x80 ++ AUDIT_STATUS_ENABLED = 0x1 ++ AUDIT_STATUS_FAILURE = 0x2 ++ AUDIT_STATUS_LOST = 0x40 ++ AUDIT_STATUS_PID = 0x4 ++ AUDIT_STATUS_RATE_LIMIT = 0x8 ++ AUDIT_SUBJ_CLR = 0x11 ++ AUDIT_SUBJ_ROLE = 0xe ++ AUDIT_SUBJ_SEN = 0x10 ++ AUDIT_SUBJ_TYPE = 0xf ++ AUDIT_SUBJ_USER = 0xd ++ AUDIT_SUCCESS = 0x68 ++ AUDIT_SUID = 0x3 ++ AUDIT_SYSCALL = 0x514 ++ AUDIT_SYSCALL_CLASSES = 0x10 ++ AUDIT_TIME_ADJNTPVAL = 0x535 ++ AUDIT_TIME_INJOFFSET = 0x534 ++ AUDIT_TRIM = 0x3f6 ++ AUDIT_TTY = 0x527 ++ AUDIT_TTY_GET = 0x3f8 ++ AUDIT_TTY_SET = 0x3f9 ++ AUDIT_UID = 0x1 ++ AUDIT_UID_UNSET = 0xffffffff ++ AUDIT_UNUSED_BITS = 0x7fffc00 ++ AUDIT_URINGOP = 0x538 ++ AUDIT_USER = 0x3ed ++ AUDIT_USER_AVC = 0x453 ++ AUDIT_USER_TTY = 0x464 ++ AUDIT_VERSION_BACKLOG_LIMIT = 0x1 ++ AUDIT_VERSION_BACKLOG_WAIT_TIME = 0x2 ++ AUDIT_VERSION_LATEST = 0x7f ++ AUDIT_WATCH = 0x69 ++ AUDIT_WATCH_INS = 0x3ef ++ AUDIT_WATCH_LIST = 0x3f1 ++ AUDIT_WATCH_REM = 0x3f0 ++ AUTOFS_SUPER_MAGIC = 0x187 ++ B0 = 0x0 ++ B1000000 = 0x17 ++ B110 = 0x3 ++ B115200 = 0x11 ++ B1152000 = 0x18 ++ B1200 = 0x9 ++ B134 = 0x4 ++ B150 = 0x5 ++ B1500000 = 0x19 ++ B1800 = 0xa ++ B19200 = 0xe ++ B200 = 0x6 ++ B2000000 = 0x1a ++ B230400 = 0x12 ++ B2400 = 0xb ++ B2500000 = 0x1b ++ B300 = 0x7 ++ B3000000 = 0x1c ++ B3500000 = 0x1d ++ B38400 = 0xf ++ B4000000 = 0x1e ++ B460800 = 0x13 ++ B4800 = 0xc ++ B50 = 0x1 ++ B500000 = 0x14 ++ B57600 = 0x10 ++ B576000 = 0x15 ++ B600 = 0x8 ++ B75 = 0x2 ++ B921600 = 0x16 ++ B9600 = 0xd ++ BDEVFS_MAGIC = 0x62646576 ++ BINDERFS_SUPER_MAGIC = 0x6c6f6f70 ++ BINFMTFS_MAGIC = 0x42494e4d ++ BLKALIGNOFF = 0x2000127a ++ BLKBSZGET = 0x40081270 ++ BLKBSZSET = 0x80081271 ++ BLKDISCARD = 0x20001277 ++ BLKDISCARDZEROES = 0x2000127c ++ BLKFLSBUF = 0x20001261 ++ BLKFRAGET = 0x20001265 ++ BLKFRASET = 0x20001264 ++ BLKGETDISKSEQ = 0x40081280 ++ BLKGETSIZE = 0x20001260 ++ BLKGETSIZE64 = 0x40081272 ++ BLKIOMIN = 0x20001278 ++ BLKIOOPT = 0x20001279 ++ BLKPBSZGET = 0x2000127b ++ BLKRAGET = 0x20001263 ++ BLKRASET = 0x20001262 ++ BLKROGET = 0x2000125e ++ BLKROSET = 0x2000125d ++ BLKROTATIONAL = 0x2000127e ++ BLKRRPART = 0x2000125f ++ BLKSECDISCARD = 0x2000127d ++ BLKSECTGET = 0x20001267 ++ BLKSECTSET = 0x20001266 ++ BLKSSZGET = 0x20001268 ++ BLKZEROOUT = 0x2000127f ++ BOTHER = 0x1f ++ BPF_A = 0x10 ++ BPF_ABS = 0x20 ++ BPF_ADD = 0x0 ++ BPF_ALU = 0x4 ++ BPF_ALU64 = 0x7 ++ BPF_AND = 0x50 ++ BPF_ARSH = 0xc0 ++ BPF_ATOMIC = 0xc0 ++ BPF_B = 0x10 ++ BPF_BUILD_ID_SIZE = 0x14 ++ BPF_CALL = 0x80 ++ BPF_CMPXCHG = 0xf1 ++ BPF_DIV = 0x30 ++ BPF_DW = 0x18 ++ BPF_END = 0xd0 ++ BPF_EXIT = 0x90 ++ BPF_FETCH = 0x1 ++ BPF_FROM_BE = 0x8 ++ BPF_FROM_LE = 0x0 ++ BPF_FS_MAGIC = 0xcafe4a11 ++ BPF_F_AFTER = 0x10 ++ BPF_F_ALLOW_MULTI = 0x2 ++ BPF_F_ALLOW_OVERRIDE = 0x1 ++ BPF_F_ANY_ALIGNMENT = 0x2 ++ BPF_F_BEFORE = 0x8 ++ BPF_F_ID = 0x20 ++ BPF_F_NETFILTER_IP_DEFRAG = 0x1 ++ BPF_F_QUERY_EFFECTIVE = 0x1 ++ BPF_F_REPLACE = 0x4 ++ BPF_F_SLEEPABLE = 0x10 ++ BPF_F_STRICT_ALIGNMENT = 0x1 ++ BPF_F_TEST_RND_HI32 = 0x4 ++ BPF_F_TEST_RUN_ON_CPU = 0x1 ++ BPF_F_TEST_STATE_FREQ = 0x8 ++ BPF_F_TEST_XDP_LIVE_FRAMES = 0x2 ++ BPF_F_XDP_DEV_BOUND_ONLY = 0x40 ++ BPF_F_XDP_HAS_FRAGS = 0x20 ++ BPF_H = 0x8 ++ BPF_IMM = 0x0 ++ BPF_IND = 0x40 ++ BPF_JA = 0x0 ++ BPF_JEQ = 0x10 ++ BPF_JGE = 0x30 ++ BPF_JGT = 0x20 ++ BPF_JLE = 0xb0 ++ BPF_JLT = 0xa0 ++ BPF_JMP = 0x5 ++ BPF_JMP32 = 0x6 ++ BPF_JNE = 0x50 ++ BPF_JSET = 0x40 ++ BPF_JSGE = 0x70 ++ BPF_JSGT = 0x60 ++ BPF_JSLE = 0xd0 ++ BPF_JSLT = 0xc0 ++ BPF_K = 0x0 ++ BPF_LD = 0x0 ++ BPF_LDX = 0x1 ++ BPF_LEN = 0x80 ++ BPF_LL_OFF = -0x200000 ++ BPF_LSH = 0x60 ++ BPF_MAJOR_VERSION = 0x1 ++ BPF_MAXINSNS = 0x1000 ++ BPF_MEM = 0x60 ++ BPF_MEMSX = 0x80 ++ BPF_MEMWORDS = 0x10 ++ BPF_MINOR_VERSION = 0x1 ++ BPF_MISC = 0x7 ++ BPF_MOD = 0x90 ++ BPF_MOV = 0xb0 ++ BPF_MSH = 0xa0 ++ BPF_MUL = 0x20 ++ BPF_NEG = 0x80 ++ BPF_NET_OFF = -0x100000 ++ BPF_OBJ_NAME_LEN = 0x10 ++ BPF_OR = 0x40 ++ BPF_PSEUDO_BTF_ID = 0x3 ++ BPF_PSEUDO_CALL = 0x1 ++ BPF_PSEUDO_FUNC = 0x4 ++ BPF_PSEUDO_KFUNC_CALL = 0x2 ++ BPF_PSEUDO_MAP_FD = 0x1 ++ BPF_PSEUDO_MAP_IDX = 0x5 ++ BPF_PSEUDO_MAP_IDX_VALUE = 0x6 ++ BPF_PSEUDO_MAP_VALUE = 0x2 ++ BPF_RET = 0x6 ++ BPF_RSH = 0x70 ++ BPF_ST = 0x2 ++ BPF_STX = 0x3 ++ BPF_SUB = 0x10 ++ BPF_TAG_SIZE = 0x8 ++ BPF_TAX = 0x0 ++ BPF_TO_BE = 0x8 ++ BPF_TO_LE = 0x0 ++ BPF_TXA = 0x80 ++ BPF_W = 0x0 ++ BPF_X = 0x8 ++ BPF_XADD = 0xc0 ++ BPF_XCHG = 0xe1 ++ BPF_XOR = 0xa0 ++ BRKINT = 0x2 ++ BS0 = 0x0 ++ BS1 = 0x8000 ++ BSDLY = 0x8000 ++ BTRFS_SUPER_MAGIC = 0x9123683e ++ BTRFS_TEST_MAGIC = 0x73727279 ++ BUS_BLUETOOTH = 0x5 ++ BUS_HIL = 0x4 ++ BUS_USB = 0x3 ++ BUS_VIRTUAL = 0x6 ++ CAN_BCM = 0x2 ++ CAN_BUS_OFF_THRESHOLD = 0x100 ++ CAN_CTRLMODE_3_SAMPLES = 0x4 ++ CAN_CTRLMODE_BERR_REPORTING = 0x10 ++ CAN_CTRLMODE_CC_LEN8_DLC = 0x100 ++ CAN_CTRLMODE_FD = 0x20 ++ CAN_CTRLMODE_FD_NON_ISO = 0x80 ++ CAN_CTRLMODE_LISTENONLY = 0x2 ++ CAN_CTRLMODE_LOOPBACK = 0x1 ++ CAN_CTRLMODE_ONE_SHOT = 0x8 ++ CAN_CTRLMODE_PRESUME_ACK = 0x40 ++ CAN_CTRLMODE_TDC_AUTO = 0x200 ++ CAN_CTRLMODE_TDC_MANUAL = 0x400 ++ CAN_EFF_FLAG = 0x80000000 ++ CAN_EFF_ID_BITS = 0x1d ++ CAN_EFF_MASK = 0x1fffffff ++ CAN_ERROR_PASSIVE_THRESHOLD = 0x80 ++ CAN_ERROR_WARNING_THRESHOLD = 0x60 ++ CAN_ERR_ACK = 0x20 ++ CAN_ERR_BUSERROR = 0x80 ++ CAN_ERR_BUSOFF = 0x40 ++ CAN_ERR_CNT = 0x200 ++ CAN_ERR_CRTL = 0x4 ++ CAN_ERR_CRTL_ACTIVE = 0x40 ++ CAN_ERR_CRTL_RX_OVERFLOW = 0x1 ++ CAN_ERR_CRTL_RX_PASSIVE = 0x10 ++ CAN_ERR_CRTL_RX_WARNING = 0x4 ++ CAN_ERR_CRTL_TX_OVERFLOW = 0x2 ++ CAN_ERR_CRTL_TX_PASSIVE = 0x20 ++ CAN_ERR_CRTL_TX_WARNING = 0x8 ++ CAN_ERR_CRTL_UNSPEC = 0x0 ++ CAN_ERR_DLC = 0x8 ++ CAN_ERR_FLAG = 0x20000000 ++ CAN_ERR_LOSTARB = 0x2 ++ CAN_ERR_LOSTARB_UNSPEC = 0x0 ++ CAN_ERR_MASK = 0x1fffffff ++ CAN_ERR_PROT = 0x8 ++ CAN_ERR_PROT_ACTIVE = 0x40 ++ CAN_ERR_PROT_BIT = 0x1 ++ CAN_ERR_PROT_BIT0 = 0x8 ++ CAN_ERR_PROT_BIT1 = 0x10 ++ CAN_ERR_PROT_FORM = 0x2 ++ CAN_ERR_PROT_LOC_ACK = 0x19 ++ CAN_ERR_PROT_LOC_ACK_DEL = 0x1b ++ CAN_ERR_PROT_LOC_CRC_DEL = 0x18 ++ CAN_ERR_PROT_LOC_CRC_SEQ = 0x8 ++ CAN_ERR_PROT_LOC_DATA = 0xa ++ CAN_ERR_PROT_LOC_DLC = 0xb ++ CAN_ERR_PROT_LOC_EOF = 0x1a ++ CAN_ERR_PROT_LOC_ID04_00 = 0xe ++ CAN_ERR_PROT_LOC_ID12_05 = 0xf ++ CAN_ERR_PROT_LOC_ID17_13 = 0x7 ++ CAN_ERR_PROT_LOC_ID20_18 = 0x6 ++ CAN_ERR_PROT_LOC_ID28_21 = 0x2 ++ CAN_ERR_PROT_LOC_IDE = 0x5 ++ CAN_ERR_PROT_LOC_INTERM = 0x12 ++ CAN_ERR_PROT_LOC_RES0 = 0x9 ++ CAN_ERR_PROT_LOC_RES1 = 0xd ++ CAN_ERR_PROT_LOC_RTR = 0xc ++ CAN_ERR_PROT_LOC_SOF = 0x3 ++ CAN_ERR_PROT_LOC_SRTR = 0x4 ++ CAN_ERR_PROT_LOC_UNSPEC = 0x0 ++ CAN_ERR_PROT_OVERLOAD = 0x20 ++ CAN_ERR_PROT_STUFF = 0x4 ++ CAN_ERR_PROT_TX = 0x80 ++ CAN_ERR_PROT_UNSPEC = 0x0 ++ CAN_ERR_RESTARTED = 0x100 ++ CAN_ERR_TRX = 0x10 ++ CAN_ERR_TRX_CANH_NO_WIRE = 0x4 ++ CAN_ERR_TRX_CANH_SHORT_TO_BAT = 0x5 ++ CAN_ERR_TRX_CANH_SHORT_TO_GND = 0x7 ++ CAN_ERR_TRX_CANH_SHORT_TO_VCC = 0x6 ++ CAN_ERR_TRX_CANL_NO_WIRE = 0x40 ++ CAN_ERR_TRX_CANL_SHORT_TO_BAT = 0x50 ++ CAN_ERR_TRX_CANL_SHORT_TO_CANH = 0x80 ++ CAN_ERR_TRX_CANL_SHORT_TO_GND = 0x70 ++ CAN_ERR_TRX_CANL_SHORT_TO_VCC = 0x60 ++ CAN_ERR_TRX_UNSPEC = 0x0 ++ CAN_ERR_TX_TIMEOUT = 0x1 ++ CAN_INV_FILTER = 0x20000000 ++ CAN_ISOTP = 0x6 ++ CAN_J1939 = 0x7 ++ CAN_MAX_DLC = 0x8 ++ CAN_MAX_DLEN = 0x8 ++ CAN_MAX_RAW_DLC = 0xf ++ CAN_MCNET = 0x5 ++ CAN_MTU = 0x10 ++ CAN_NPROTO = 0x8 ++ CAN_RAW = 0x1 ++ CAN_RAW_FILTER_MAX = 0x200 ++ CAN_RTR_FLAG = 0x40000000 ++ CAN_SFF_ID_BITS = 0xb ++ CAN_SFF_MASK = 0x7ff ++ CAN_TERMINATION_DISABLED = 0x0 ++ CAN_TP16 = 0x3 ++ CAN_TP20 = 0x4 ++ CAP_AUDIT_CONTROL = 0x1e ++ CAP_AUDIT_READ = 0x25 ++ CAP_AUDIT_WRITE = 0x1d ++ CAP_BLOCK_SUSPEND = 0x24 ++ CAP_BPF = 0x27 ++ CAP_CHECKPOINT_RESTORE = 0x28 ++ CAP_CHOWN = 0x0 ++ CAP_DAC_OVERRIDE = 0x1 ++ CAP_DAC_READ_SEARCH = 0x2 ++ CAP_FOWNER = 0x3 ++ CAP_FSETID = 0x4 ++ CAP_IPC_LOCK = 0xe ++ CAP_IPC_OWNER = 0xf ++ CAP_KILL = 0x5 ++ CAP_LAST_CAP = 0x28 ++ CAP_LEASE = 0x1c ++ CAP_LINUX_IMMUTABLE = 0x9 ++ CAP_MAC_ADMIN = 0x21 ++ CAP_MAC_OVERRIDE = 0x20 ++ CAP_MKNOD = 0x1b ++ CAP_NET_ADMIN = 0xc ++ CAP_NET_BIND_SERVICE = 0xa ++ CAP_NET_BROADCAST = 0xb ++ CAP_NET_RAW = 0xd ++ CAP_PERFMON = 0x26 ++ CAP_SETFCAP = 0x1f ++ CAP_SETGID = 0x6 ++ CAP_SETPCAP = 0x8 ++ CAP_SETUID = 0x7 ++ CAP_SYSLOG = 0x22 ++ CAP_SYS_ADMIN = 0x15 ++ CAP_SYS_BOOT = 0x16 ++ CAP_SYS_CHROOT = 0x12 ++ CAP_SYS_MODULE = 0x10 ++ CAP_SYS_NICE = 0x17 ++ CAP_SYS_PACCT = 0x14 ++ CAP_SYS_PTRACE = 0x13 ++ CAP_SYS_RAWIO = 0x11 ++ CAP_SYS_RESOURCE = 0x18 ++ CAP_SYS_TIME = 0x19 ++ CAP_SYS_TTY_CONFIG = 0x1a ++ CAP_WAKE_ALARM = 0x23 ++ CBAUD = 0x1f ++ CBAUDEX = 0x0 ++ CEPH_SUPER_MAGIC = 0xc36400 ++ CFLUSH = 0xf ++ CGROUP2_SUPER_MAGIC = 0x63677270 ++ CGROUP_SUPER_MAGIC = 0x27e0eb ++ CIBAUD = 0x1f0000 ++ CIFS_SUPER_MAGIC = 0xff534d42 ++ CLOCAL = 0x8000 ++ CLOCK_BOOTTIME = 0x7 ++ CLOCK_BOOTTIME_ALARM = 0x9 ++ CLOCK_DEFAULT = 0x0 ++ CLOCK_EXT = 0x1 ++ CLOCK_INT = 0x2 ++ CLOCK_MONOTONIC = 0x1 ++ CLOCK_MONOTONIC_COARSE = 0x6 ++ CLOCK_MONOTONIC_RAW = 0x4 ++ CLOCK_PROCESS_CPUTIME_ID = 0x2 ++ CLOCK_REALTIME = 0x0 ++ CLOCK_REALTIME_ALARM = 0x8 ++ CLOCK_REALTIME_COARSE = 0x5 ++ CLOCK_TAI = 0xb ++ CLOCK_THREAD_CPUTIME_ID = 0x3 ++ CLOCK_TXFROMRX = 0x4 ++ CLOCK_TXINT = 0x3 ++ CLONE_ARGS_SIZE_VER0 = 0x40 ++ CLONE_ARGS_SIZE_VER1 = 0x50 ++ CLONE_ARGS_SIZE_VER2 = 0x58 ++ CLONE_CHILD_CLEARTID = 0x200000 ++ CLONE_CHILD_SETTID = 0x1000000 ++ CLONE_CLEAR_SIGHAND = 0x100000000 ++ CLONE_DETACHED = 0x400000 ++ CLONE_FILES = 0x400 ++ CLONE_FS = 0x200 ++ CLONE_INTO_CGROUP = 0x200000000 ++ CLONE_IO = 0x80000000 ++ CLONE_NEWCGROUP = 0x2000000 ++ CLONE_NEWIPC = 0x8000000 ++ CLONE_NEWNET = 0x40000000 ++ CLONE_NEWNS = 0x20000 ++ CLONE_NEWPID = 0x20000000 ++ CLONE_NEWTIME = 0x80 ++ CLONE_NEWUSER = 0x10000000 ++ CLONE_NEWUTS = 0x4000000 ++ CLONE_PARENT = 0x8000 ++ CLONE_PARENT_SETTID = 0x100000 ++ CLONE_PIDFD = 0x1000 ++ CLONE_PTRACE = 0x2000 ++ CLONE_SETTLS = 0x80000 ++ CLONE_SIGHAND = 0x800 ++ CLONE_SYSVSEM = 0x40000 ++ CLONE_THREAD = 0x10000 ++ CLONE_UNTRACED = 0x800000 ++ CLONE_VFORK = 0x4000 ++ CLONE_VM = 0x100 ++ CMSPAR = 0x40000000 ++ CODA_SUPER_MAGIC = 0x73757245 ++ CR0 = 0x0 ++ CR1 = 0x1000 ++ CR2 = 0x2000 ++ CR3 = 0x3000 ++ CRAMFS_MAGIC = 0x28cd3d45 ++ CRDLY = 0x3000 ++ CREAD = 0x800 ++ CRTSCTS = 0x80000000 ++ CRYPTO_MAX_NAME = 0x40 ++ CRYPTO_MSG_MAX = 0x15 ++ CRYPTO_NR_MSGTYPES = 0x6 ++ CRYPTO_REPORT_MAXSIZE = 0x160 ++ CS5 = 0x0 ++ CS6 = 0x100 ++ CS7 = 0x200 ++ CS8 = 0x300 ++ CSIGNAL = 0xff ++ CSIZE = 0x300 ++ CSTART = 0x11 ++ CSTATUS = 0x0 ++ CSTOP = 0x13 ++ CSTOPB = 0x400 ++ CSUSP = 0x1a ++ DAXFS_MAGIC = 0x64646178 ++ DEBUGFS_MAGIC = 0x64626720 ++ DEVLINK_CMD_ESWITCH_MODE_GET = 0x1d ++ DEVLINK_CMD_ESWITCH_MODE_SET = 0x1e ++ DEVLINK_FLASH_OVERWRITE_IDENTIFIERS = 0x2 ++ DEVLINK_FLASH_OVERWRITE_SETTINGS = 0x1 ++ DEVLINK_GENL_MCGRP_CONFIG_NAME = "config" ++ DEVLINK_GENL_NAME = "devlink" ++ DEVLINK_GENL_VERSION = 0x1 ++ DEVLINK_PORT_FN_CAP_IPSEC_CRYPTO = 0x4 ++ DEVLINK_PORT_FN_CAP_IPSEC_PACKET = 0x8 ++ DEVLINK_PORT_FN_CAP_MIGRATABLE = 0x2 ++ DEVLINK_PORT_FN_CAP_ROCE = 0x1 ++ DEVLINK_SB_THRESHOLD_TO_ALPHA_MAX = 0x14 ++ DEVLINK_SUPPORTED_FLASH_OVERWRITE_SECTIONS = 0x3 ++ DEVMEM_MAGIC = 0x454d444d ++ DEVPTS_SUPER_MAGIC = 0x1cd1 ++ DMA_BUF_MAGIC = 0x444d4142 ++ DM_ACTIVE_PRESENT_FLAG = 0x20 ++ DM_BUFFER_FULL_FLAG = 0x100 ++ DM_CONTROL_NODE = "control" ++ DM_DATA_OUT_FLAG = 0x10000 ++ DM_DEFERRED_REMOVE = 0x20000 ++ DM_DEV_ARM_POLL = 0xc138fd10 ++ DM_DEV_CREATE = 0xc138fd03 ++ DM_DEV_REMOVE = 0xc138fd04 ++ DM_DEV_RENAME = 0xc138fd05 ++ DM_DEV_SET_GEOMETRY = 0xc138fd0f ++ DM_DEV_STATUS = 0xc138fd07 ++ DM_DEV_SUSPEND = 0xc138fd06 ++ DM_DEV_WAIT = 0xc138fd08 ++ DM_DIR = "mapper" ++ DM_GET_TARGET_VERSION = 0xc138fd11 ++ DM_IMA_MEASUREMENT_FLAG = 0x80000 ++ DM_INACTIVE_PRESENT_FLAG = 0x40 ++ DM_INTERNAL_SUSPEND_FLAG = 0x40000 ++ DM_IOCTL = 0xfd ++ DM_LIST_DEVICES = 0xc138fd02 ++ DM_LIST_VERSIONS = 0xc138fd0d ++ DM_MAX_TYPE_NAME = 0x10 ++ DM_NAME_LEN = 0x80 ++ DM_NAME_LIST_FLAG_DOESNT_HAVE_UUID = 0x2 ++ DM_NAME_LIST_FLAG_HAS_UUID = 0x1 ++ DM_NOFLUSH_FLAG = 0x800 ++ DM_PERSISTENT_DEV_FLAG = 0x8 ++ DM_QUERY_INACTIVE_TABLE_FLAG = 0x1000 ++ DM_READONLY_FLAG = 0x1 ++ DM_REMOVE_ALL = 0xc138fd01 ++ DM_SECURE_DATA_FLAG = 0x8000 ++ DM_SKIP_BDGET_FLAG = 0x200 ++ DM_SKIP_LOCKFS_FLAG = 0x400 ++ DM_STATUS_TABLE_FLAG = 0x10 ++ DM_SUSPEND_FLAG = 0x2 ++ DM_TABLE_CLEAR = 0xc138fd0a ++ DM_TABLE_DEPS = 0xc138fd0b ++ DM_TABLE_LOAD = 0xc138fd09 ++ DM_TABLE_STATUS = 0xc138fd0c ++ DM_TARGET_MSG = 0xc138fd0e ++ DM_UEVENT_GENERATED_FLAG = 0x2000 ++ DM_UUID_FLAG = 0x4000 ++ DM_UUID_LEN = 0x81 ++ DM_VERSION = 0xc138fd00 ++ DM_VERSION_EXTRA = "-ioctl (2023-03-01)" ++ DM_VERSION_MAJOR = 0x4 ++ DM_VERSION_MINOR = 0x30 ++ DM_VERSION_PATCHLEVEL = 0x0 ++ DT_BLK = 0x6 ++ DT_CHR = 0x2 ++ DT_DIR = 0x4 ++ DT_FIFO = 0x1 ++ DT_LNK = 0xa ++ DT_REG = 0x8 ++ DT_SOCK = 0xc ++ DT_UNKNOWN = 0x0 ++ DT_WHT = 0xe ++ ECCGETLAYOUT = 0x41484d11 ++ ECCGETSTATS = 0x40104d12 ++ ECHO = 0x8 ++ ECHOCTL = 0x40 ++ ECHOE = 0x2 ++ ECHOK = 0x4 ++ ECHOKE = 0x1 ++ ECHONL = 0x10 ++ ECHOPRT = 0x20 ++ ECRYPTFS_SUPER_MAGIC = 0xf15f ++ EFD_CLOEXEC = 0x200000 ++ EFD_NONBLOCK = 0x4 ++ EFD_SEMAPHORE = 0x1 ++ EFIVARFS_MAGIC = 0xde5e81e4 ++ EFS_SUPER_MAGIC = 0x414a53 ++ EM_386 = 0x3 ++ EM_486 = 0x6 ++ EM_68K = 0x4 ++ EM_860 = 0x7 ++ EM_88K = 0x5 ++ EM_AARCH64 = 0xb7 ++ EM_ALPHA = 0x9026 ++ EM_ALTERA_NIOS2 = 0x71 ++ EM_ARCOMPACT = 0x5d ++ EM_ARCV2 = 0xc3 ++ EM_ARM = 0x28 ++ EM_BLACKFIN = 0x6a ++ EM_BPF = 0xf7 ++ EM_CRIS = 0x4c ++ EM_CSKY = 0xfc ++ EM_CYGNUS_M32R = 0x9041 ++ EM_CYGNUS_MN10300 = 0xbeef ++ EM_FRV = 0x5441 ++ EM_H8_300 = 0x2e ++ EM_HEXAGON = 0xa4 ++ EM_IA_64 = 0x32 ++ EM_LOONGARCH = 0x102 ++ EM_M32 = 0x1 ++ EM_M32R = 0x58 ++ EM_MICROBLAZE = 0xbd ++ EM_MIPS = 0x8 ++ EM_MIPS_RS3_LE = 0xa ++ EM_MIPS_RS4_BE = 0xa ++ EM_MN10300 = 0x59 ++ EM_NDS32 = 0xa7 ++ EM_NONE = 0x0 ++ EM_OPENRISC = 0x5c ++ EM_PARISC = 0xf ++ EM_PPC = 0x14 ++ EM_PPC64 = 0x15 ++ EM_RISCV = 0xf3 ++ EM_S390 = 0x16 ++ EM_S390_OLD = 0xa390 ++ EM_SH = 0x2a ++ EM_SPARC = 0x2 ++ EM_SPARC32PLUS = 0x12 ++ EM_SPARCV9 = 0x2b ++ EM_SPU = 0x17 ++ EM_SW64 = 0x9916 ++ EM_TILEGX = 0xbf ++ EM_TILEPRO = 0xbc ++ EM_TI_C6000 = 0x8c ++ EM_UNICORE = 0x6e ++ EM_X86_64 = 0x3e ++ EM_XTENSA = 0x5e ++ ENCODING_DEFAULT = 0x0 ++ ENCODING_FM_MARK = 0x3 ++ ENCODING_FM_SPACE = 0x4 ++ ENCODING_MANCHESTER = 0x5 ++ ENCODING_NRZ = 0x1 ++ ENCODING_NRZI = 0x2 ++ EPOLLERR = 0x8 ++ EPOLLET = 0x80000000 ++ EPOLLEXCLUSIVE = 0x10000000 ++ EPOLLHUP = 0x10 ++ EPOLLIN = 0x1 ++ EPOLLMSG = 0x400 ++ EPOLLONESHOT = 0x40000000 ++ EPOLLOUT = 0x4 ++ EPOLLPRI = 0x2 ++ EPOLLRDBAND = 0x80 ++ EPOLLRDHUP = 0x2000 ++ EPOLLRDNORM = 0x40 ++ EPOLLWAKEUP = 0x20000000 ++ EPOLLWRBAND = 0x200 ++ EPOLLWRNORM = 0x100 ++ EPOLL_CLOEXEC = 0x200000 ++ EPOLL_CTL_ADD = 0x1 ++ EPOLL_CTL_DEL = 0x2 ++ EPOLL_CTL_MOD = 0x3 ++ EROFS_SUPER_MAGIC_V1 = 0xe0f5e1e2 ++ ESP_V4_FLOW = 0xa ++ ESP_V6_FLOW = 0xc ++ ETHER_FLOW = 0x12 ++ ETHTOOL_BUSINFO_LEN = 0x20 ++ ETHTOOL_EROMVERS_LEN = 0x20 ++ ETHTOOL_FEC_AUTO = 0x2 ++ ETHTOOL_FEC_BASER = 0x10 ++ ETHTOOL_FEC_LLRS = 0x20 ++ ETHTOOL_FEC_NONE = 0x1 ++ ETHTOOL_FEC_OFF = 0x4 ++ ETHTOOL_FEC_RS = 0x8 ++ ETHTOOL_FLAG_ALL = 0x7 ++ ETHTOOL_FLASHDEV = 0x33 ++ ETHTOOL_FLASH_MAX_FILENAME = 0x80 ++ ETHTOOL_FWVERS_LEN = 0x20 ++ ETHTOOL_F_COMPAT = 0x4 ++ ETHTOOL_F_UNSUPPORTED = 0x1 ++ ETHTOOL_F_WISH = 0x2 ++ ETHTOOL_GCHANNELS = 0x3c ++ ETHTOOL_GCOALESCE = 0xe ++ ETHTOOL_GDRVINFO = 0x3 ++ ETHTOOL_GEEE = 0x44 ++ ETHTOOL_GEEPROM = 0xb ++ ETHTOOL_GENL_NAME = "ethtool" ++ ETHTOOL_GENL_VERSION = 0x1 ++ ETHTOOL_GET_DUMP_DATA = 0x40 ++ ETHTOOL_GET_DUMP_FLAG = 0x3f ++ ETHTOOL_GET_TS_INFO = 0x41 ++ ETHTOOL_GFEATURES = 0x3a ++ ETHTOOL_GFECPARAM = 0x50 ++ ETHTOOL_GFLAGS = 0x25 ++ ETHTOOL_GGRO = 0x2b ++ ETHTOOL_GGSO = 0x23 ++ ETHTOOL_GLINK = 0xa ++ ETHTOOL_GLINKSETTINGS = 0x4c ++ ETHTOOL_GMODULEEEPROM = 0x43 ++ ETHTOOL_GMODULEINFO = 0x42 ++ ETHTOOL_GMSGLVL = 0x7 ++ ETHTOOL_GPAUSEPARAM = 0x12 ++ ETHTOOL_GPERMADDR = 0x20 ++ ETHTOOL_GPFLAGS = 0x27 ++ ETHTOOL_GPHYSTATS = 0x4a ++ ETHTOOL_GREGS = 0x4 ++ ETHTOOL_GRINGPARAM = 0x10 ++ ETHTOOL_GRSSH = 0x46 ++ ETHTOOL_GRXCLSRLALL = 0x30 ++ ETHTOOL_GRXCLSRLCNT = 0x2e ++ ETHTOOL_GRXCLSRULE = 0x2f ++ ETHTOOL_GRXCSUM = 0x14 ++ ETHTOOL_GRXFH = 0x29 ++ ETHTOOL_GRXFHINDIR = 0x38 ++ ETHTOOL_GRXNTUPLE = 0x36 ++ ETHTOOL_GRXRINGS = 0x2d ++ ETHTOOL_GSET = 0x1 ++ ETHTOOL_GSG = 0x18 ++ ETHTOOL_GSSET_INFO = 0x37 ++ ETHTOOL_GSTATS = 0x1d ++ ETHTOOL_GSTRINGS = 0x1b ++ ETHTOOL_GTSO = 0x1e ++ ETHTOOL_GTUNABLE = 0x48 ++ ETHTOOL_GTXCSUM = 0x16 ++ ETHTOOL_GUFO = 0x21 ++ ETHTOOL_GWOL = 0x5 ++ ETHTOOL_MCGRP_MONITOR_NAME = "monitor" ++ ETHTOOL_NWAY_RST = 0x9 ++ ETHTOOL_PERQUEUE = 0x4b ++ ETHTOOL_PHYS_ID = 0x1c ++ ETHTOOL_PHY_EDPD_DFLT_TX_MSECS = 0xffff ++ ETHTOOL_PHY_EDPD_DISABLE = 0x0 ++ ETHTOOL_PHY_EDPD_NO_TX = 0xfffe ++ ETHTOOL_PHY_FAST_LINK_DOWN_OFF = 0xff ++ ETHTOOL_PHY_FAST_LINK_DOWN_ON = 0x0 ++ ETHTOOL_PHY_GTUNABLE = 0x4e ++ ETHTOOL_PHY_STUNABLE = 0x4f ++ ETHTOOL_RESET = 0x34 ++ ETHTOOL_RXNTUPLE_ACTION_CLEAR = -0x2 ++ ETHTOOL_RXNTUPLE_ACTION_DROP = -0x1 ++ ETHTOOL_RX_FLOW_SPEC_RING = 0xffffffff ++ ETHTOOL_RX_FLOW_SPEC_RING_VF = 0xff00000000 ++ ETHTOOL_RX_FLOW_SPEC_RING_VF_OFF = 0x20 ++ ETHTOOL_SCHANNELS = 0x3d ++ ETHTOOL_SCOALESCE = 0xf ++ ETHTOOL_SEEE = 0x45 ++ ETHTOOL_SEEPROM = 0xc ++ ETHTOOL_SET_DUMP = 0x3e ++ ETHTOOL_SFEATURES = 0x3b ++ ETHTOOL_SFECPARAM = 0x51 ++ ETHTOOL_SFLAGS = 0x26 ++ ETHTOOL_SGRO = 0x2c ++ ETHTOOL_SGSO = 0x24 ++ ETHTOOL_SLINKSETTINGS = 0x4d ++ ETHTOOL_SMSGLVL = 0x8 ++ ETHTOOL_SPAUSEPARAM = 0x13 ++ ETHTOOL_SPFLAGS = 0x28 ++ ETHTOOL_SRINGPARAM = 0x11 ++ ETHTOOL_SRSSH = 0x47 ++ ETHTOOL_SRXCLSRLDEL = 0x31 ++ ETHTOOL_SRXCLSRLINS = 0x32 ++ ETHTOOL_SRXCSUM = 0x15 ++ ETHTOOL_SRXFH = 0x2a ++ ETHTOOL_SRXFHINDIR = 0x39 ++ ETHTOOL_SRXNTUPLE = 0x35 ++ ETHTOOL_SSET = 0x2 ++ ETHTOOL_SSG = 0x19 ++ ETHTOOL_STSO = 0x1f ++ ETHTOOL_STUNABLE = 0x49 ++ ETHTOOL_STXCSUM = 0x17 ++ ETHTOOL_SUFO = 0x22 ++ ETHTOOL_SWOL = 0x6 ++ ETHTOOL_TEST = 0x1a ++ ETH_P_1588 = 0x88f7 ++ ETH_P_8021AD = 0x88a8 ++ ETH_P_8021AH = 0x88e7 ++ ETH_P_8021Q = 0x8100 ++ ETH_P_80221 = 0x8917 ++ ETH_P_802_2 = 0x4 ++ ETH_P_802_3 = 0x1 ++ ETH_P_802_3_MIN = 0x600 ++ ETH_P_802_EX1 = 0x88b5 ++ ETH_P_AARP = 0x80f3 ++ ETH_P_AF_IUCV = 0xfbfb ++ ETH_P_ALL = 0x3 ++ ETH_P_AOE = 0x88a2 ++ ETH_P_ARCNET = 0x1a ++ ETH_P_ARP = 0x806 ++ ETH_P_ATALK = 0x809b ++ ETH_P_ATMFATE = 0x8884 ++ ETH_P_ATMMPOA = 0x884c ++ ETH_P_AX25 = 0x2 ++ ETH_P_BATMAN = 0x4305 ++ ETH_P_BPQ = 0x8ff ++ ETH_P_CAIF = 0xf7 ++ ETH_P_CAN = 0xc ++ ETH_P_CANFD = 0xd ++ ETH_P_CANXL = 0xe ++ ETH_P_CFM = 0x8902 ++ ETH_P_CONTROL = 0x16 ++ ETH_P_CUST = 0x6006 ++ ETH_P_DDCMP = 0x6 ++ ETH_P_DEC = 0x6000 ++ ETH_P_DIAG = 0x6005 ++ ETH_P_DNA_DL = 0x6001 ++ ETH_P_DNA_RC = 0x6002 ++ ETH_P_DNA_RT = 0x6003 ++ ETH_P_DSA = 0x1b ++ ETH_P_DSA_8021Q = 0xdadb ++ ETH_P_DSA_A5PSW = 0xe001 ++ ETH_P_ECONET = 0x18 ++ ETH_P_EDSA = 0xdada ++ ETH_P_ERSPAN = 0x88be ++ ETH_P_ERSPAN2 = 0x22eb ++ ETH_P_ETHERCAT = 0x88a4 ++ ETH_P_FCOE = 0x8906 ++ ETH_P_FIP = 0x8914 ++ ETH_P_HDLC = 0x19 ++ ETH_P_HSR = 0x892f ++ ETH_P_IBOE = 0x8915 ++ ETH_P_IEEE802154 = 0xf6 ++ ETH_P_IEEEPUP = 0xa00 ++ ETH_P_IEEEPUPAT = 0xa01 ++ ETH_P_IFE = 0xed3e ++ ETH_P_IP = 0x800 ++ ETH_P_IPV6 = 0x86dd ++ ETH_P_IPX = 0x8137 ++ ETH_P_IRDA = 0x17 ++ ETH_P_LAT = 0x6004 ++ ETH_P_LINK_CTL = 0x886c ++ ETH_P_LLDP = 0x88cc ++ ETH_P_LOCALTALK = 0x9 ++ ETH_P_LOOP = 0x60 ++ ETH_P_LOOPBACK = 0x9000 ++ ETH_P_MACSEC = 0x88e5 ++ ETH_P_MAP = 0xf9 ++ ETH_P_MCTP = 0xfa ++ ETH_P_MOBITEX = 0x15 ++ ETH_P_MPLS_MC = 0x8848 ++ ETH_P_MPLS_UC = 0x8847 ++ ETH_P_MRP = 0x88e3 ++ ETH_P_MVRP = 0x88f5 ++ ETH_P_NCSI = 0x88f8 ++ ETH_P_NSH = 0x894f ++ ETH_P_PAE = 0x888e ++ ETH_P_PAUSE = 0x8808 ++ ETH_P_PHONET = 0xf5 ++ ETH_P_PPPTALK = 0x10 ++ ETH_P_PPP_DISC = 0x8863 ++ ETH_P_PPP_MP = 0x8 ++ ETH_P_PPP_SES = 0x8864 ++ ETH_P_PREAUTH = 0x88c7 ++ ETH_P_PROFINET = 0x8892 ++ ETH_P_PRP = 0x88fb ++ ETH_P_PUP = 0x200 ++ ETH_P_PUPAT = 0x201 ++ ETH_P_QINQ1 = 0x9100 ++ ETH_P_QINQ2 = 0x9200 ++ ETH_P_QINQ3 = 0x9300 ++ ETH_P_RARP = 0x8035 ++ ETH_P_REALTEK = 0x8899 ++ ETH_P_SCA = 0x6007 ++ ETH_P_SLOW = 0x8809 ++ ETH_P_SNAP = 0x5 ++ ETH_P_TDLS = 0x890d ++ ETH_P_TEB = 0x6558 ++ ETH_P_TIPC = 0x88ca ++ ETH_P_TRAILER = 0x1c ++ ETH_P_TR_802_2 = 0x11 ++ ETH_P_TSN = 0x22f0 ++ ETH_P_WAN_PPP = 0x7 ++ ETH_P_WCCP = 0x883e ++ ETH_P_X25 = 0x805 ++ ETH_P_XDSA = 0xf8 ++ EV_ABS = 0x3 ++ EV_CNT = 0x20 ++ EV_FF = 0x15 ++ EV_FF_STATUS = 0x17 ++ EV_KEY = 0x1 ++ EV_LED = 0x11 ++ EV_MAX = 0x1f ++ EV_MSC = 0x4 ++ EV_PWR = 0x16 ++ EV_REL = 0x2 ++ EV_REP = 0x14 ++ EV_SND = 0x12 ++ EV_SW = 0x5 ++ EV_SYN = 0x0 ++ EV_VERSION = 0x10001 ++ EXABYTE_ENABLE_NEST = 0xf0 ++ EXFAT_SUPER_MAGIC = 0x2011bab0 ++ EXT2_SUPER_MAGIC = 0xef53 ++ EXT3_SUPER_MAGIC = 0xef53 ++ EXT4_SUPER_MAGIC = 0xef53 ++ EXTA = 0xe ++ EXTB = 0xf ++ EXTPROC = 0x10000000 ++ F2FS_SUPER_MAGIC = 0xf2f52010 ++ FALLOC_FL_COLLAPSE_RANGE = 0x8 ++ FALLOC_FL_INSERT_RANGE = 0x20 ++ FALLOC_FL_KEEP_SIZE = 0x1 ++ FALLOC_FL_NO_HIDE_STALE = 0x4 ++ FALLOC_FL_PUNCH_HOLE = 0x2 ++ FALLOC_FL_UNSHARE_RANGE = 0x40 ++ FALLOC_FL_ZERO_RANGE = 0x10 ++ FANOTIFY_METADATA_VERSION = 0x3 ++ FAN_ACCESS = 0x1 ++ FAN_ACCESS_PERM = 0x20000 ++ FAN_ALLOW = 0x1 ++ FAN_ALL_CLASS_BITS = 0xc ++ FAN_ALL_EVENTS = 0x3b ++ FAN_ALL_INIT_FLAGS = 0x3f ++ FAN_ALL_MARK_FLAGS = 0xff ++ FAN_ALL_OUTGOING_EVENTS = 0x3403b ++ FAN_ALL_PERM_EVENTS = 0x30000 ++ FAN_ATTRIB = 0x4 ++ FAN_AUDIT = 0x10 ++ FAN_CLASS_CONTENT = 0x4 ++ FAN_CLASS_NOTIF = 0x0 ++ FAN_CLASS_PRE_CONTENT = 0x8 ++ FAN_CLOEXEC = 0x1 ++ FAN_CLOSE = 0x18 ++ FAN_CLOSE_NOWRITE = 0x10 ++ FAN_CLOSE_WRITE = 0x8 ++ FAN_CREATE = 0x100 ++ FAN_DELETE = 0x200 ++ FAN_DELETE_SELF = 0x400 ++ FAN_DENY = 0x2 ++ FAN_ENABLE_AUDIT = 0x40 ++ FAN_EPIDFD = -0x2 ++ FAN_EVENT_INFO_TYPE_DFID = 0x3 ++ FAN_EVENT_INFO_TYPE_DFID_NAME = 0x2 ++ FAN_EVENT_INFO_TYPE_ERROR = 0x5 ++ FAN_EVENT_INFO_TYPE_FID = 0x1 ++ FAN_EVENT_INFO_TYPE_NEW_DFID_NAME = 0xc ++ FAN_EVENT_INFO_TYPE_OLD_DFID_NAME = 0xa ++ FAN_EVENT_INFO_TYPE_PIDFD = 0x4 ++ FAN_EVENT_METADATA_LEN = 0x18 ++ FAN_EVENT_ON_CHILD = 0x8000000 ++ FAN_FS_ERROR = 0x8000 ++ FAN_INFO = 0x20 ++ FAN_MARK_ADD = 0x1 ++ FAN_MARK_DONT_FOLLOW = 0x4 ++ FAN_MARK_EVICTABLE = 0x200 ++ FAN_MARK_FILESYSTEM = 0x100 ++ FAN_MARK_FLUSH = 0x80 ++ FAN_MARK_IGNORE = 0x400 ++ FAN_MARK_IGNORED_MASK = 0x20 ++ FAN_MARK_IGNORED_SURV_MODIFY = 0x40 ++ FAN_MARK_IGNORE_SURV = 0x440 ++ FAN_MARK_INODE = 0x0 ++ FAN_MARK_MOUNT = 0x10 ++ FAN_MARK_ONLYDIR = 0x8 ++ FAN_MARK_REMOVE = 0x2 ++ FAN_MODIFY = 0x2 ++ FAN_MOVE = 0xc0 ++ FAN_MOVED_FROM = 0x40 ++ FAN_MOVED_TO = 0x80 ++ FAN_MOVE_SELF = 0x800 ++ FAN_NOFD = -0x1 ++ FAN_NONBLOCK = 0x2 ++ FAN_NOPIDFD = -0x1 ++ FAN_ONDIR = 0x40000000 ++ FAN_OPEN = 0x20 ++ FAN_OPEN_EXEC = 0x1000 ++ FAN_OPEN_EXEC_PERM = 0x40000 ++ FAN_OPEN_PERM = 0x10000 ++ FAN_Q_OVERFLOW = 0x4000 ++ FAN_RENAME = 0x10000000 ++ FAN_REPORT_DFID_NAME = 0xc00 ++ FAN_REPORT_DFID_NAME_TARGET = 0x1e00 ++ FAN_REPORT_DIR_FID = 0x400 ++ FAN_REPORT_FID = 0x200 ++ FAN_REPORT_NAME = 0x800 ++ FAN_REPORT_PIDFD = 0x80 ++ FAN_REPORT_TARGET_FID = 0x1000 ++ FAN_REPORT_TID = 0x100 ++ FAN_RESPONSE_INFO_AUDIT_RULE = 0x1 ++ FAN_RESPONSE_INFO_NONE = 0x0 ++ FAN_UNLIMITED_MARKS = 0x20 ++ FAN_UNLIMITED_QUEUE = 0x10 ++ FD_CLOEXEC = 0x1 ++ FD_SETSIZE = 0x400 ++ FF0 = 0x0 ++ FF1 = 0x4000 ++ FFDLY = 0x4000 ++ FIB_RULE_DEV_DETACHED = 0x8 ++ FIB_RULE_FIND_SADDR = 0x10000 ++ FIB_RULE_IIF_DETACHED = 0x8 ++ FIB_RULE_INVERT = 0x2 ++ FIB_RULE_OIF_DETACHED = 0x10 ++ FIB_RULE_PERMANENT = 0x1 ++ FIB_RULE_UNRESOLVED = 0x4 ++ FICLONE = 0x80049409 ++ FICLONERANGE = 0x8020940d ++ FIDEDUPERANGE = 0xc0189436 ++ FLUSHO = 0x800000 ++ FSCRYPT_KEY_DESCRIPTOR_SIZE = 0x8 ++ FSCRYPT_KEY_DESC_PREFIX = "fscrypt:" ++ FSCRYPT_KEY_DESC_PREFIX_SIZE = 0x8 ++ FSCRYPT_KEY_IDENTIFIER_SIZE = 0x10 ++ FSCRYPT_KEY_REMOVAL_STATUS_FLAG_FILES_BUSY = 0x1 ++ FSCRYPT_KEY_REMOVAL_STATUS_FLAG_OTHER_USERS = 0x2 ++ FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR = 0x1 ++ FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER = 0x2 ++ FSCRYPT_KEY_STATUS_ABSENT = 0x1 ++ FSCRYPT_KEY_STATUS_FLAG_ADDED_BY_SELF = 0x1 ++ FSCRYPT_KEY_STATUS_INCOMPLETELY_REMOVED = 0x3 ++ FSCRYPT_KEY_STATUS_PRESENT = 0x2 ++ FSCRYPT_MAX_KEY_SIZE = 0x40 ++ FSCRYPT_MODE_ADIANTUM = 0x9 ++ FSCRYPT_MODE_AES_128_CBC = 0x5 ++ FSCRYPT_MODE_AES_128_CTS = 0x6 ++ FSCRYPT_MODE_AES_256_CTS = 0x4 ++ FSCRYPT_MODE_AES_256_HCTR2 = 0xa ++ FSCRYPT_MODE_AES_256_XTS = 0x1 ++ FSCRYPT_MODE_SM4_CTS = 0x8 ++ FSCRYPT_MODE_SM4_XTS = 0x7 ++ FSCRYPT_POLICY_FLAGS_PAD_16 = 0x2 ++ FSCRYPT_POLICY_FLAGS_PAD_32 = 0x3 ++ FSCRYPT_POLICY_FLAGS_PAD_4 = 0x0 ++ FSCRYPT_POLICY_FLAGS_PAD_8 = 0x1 ++ FSCRYPT_POLICY_FLAGS_PAD_MASK = 0x3 ++ FSCRYPT_POLICY_FLAG_DIRECT_KEY = 0x4 ++ FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32 = 0x10 ++ FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64 = 0x8 ++ FSCRYPT_POLICY_V1 = 0x0 ++ FSCRYPT_POLICY_V2 = 0x2 ++ FS_ENCRYPTION_MODE_ADIANTUM = 0x9 ++ FS_ENCRYPTION_MODE_AES_128_CBC = 0x5 ++ FS_ENCRYPTION_MODE_AES_128_CTS = 0x6 ++ FS_ENCRYPTION_MODE_AES_256_CBC = 0x3 ++ FS_ENCRYPTION_MODE_AES_256_CTS = 0x4 ++ FS_ENCRYPTION_MODE_AES_256_GCM = 0x2 ++ FS_ENCRYPTION_MODE_AES_256_XTS = 0x1 ++ FS_ENCRYPTION_MODE_INVALID = 0x0 ++ FS_IOC_ADD_ENCRYPTION_KEY = 0xc0506617 ++ FS_IOC_ENABLE_VERITY = 0x80806685 ++ FS_IOC_GETFLAGS = 0x40086601 ++ FS_IOC_GET_ENCRYPTION_KEY_STATUS = 0xc080661a ++ FS_IOC_GET_ENCRYPTION_NONCE = 0x4010661b ++ FS_IOC_GET_ENCRYPTION_POLICY = 0x800c6615 ++ FS_IOC_GET_ENCRYPTION_POLICY_EX = 0xc0096616 ++ FS_IOC_GET_ENCRYPTION_PWSALT = 0x80106614 ++ FS_IOC_MEASURE_VERITY = 0xc0046686 ++ FS_IOC_READ_VERITY_METADATA = 0xc0286687 ++ FS_IOC_REMOVE_ENCRYPTION_KEY = 0xc0406618 ++ FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS = 0xc0406619 ++ FS_IOC_SETFLAGS = 0x80086602 ++ FS_IOC_SET_ENCRYPTION_POLICY = 0x400c6613 ++ FS_KEY_DESCRIPTOR_SIZE = 0x8 ++ FS_KEY_DESC_PREFIX = "fscrypt:" ++ FS_KEY_DESC_PREFIX_SIZE = 0x8 ++ FS_MAX_KEY_SIZE = 0x40 ++ FS_POLICY_FLAGS_PAD_16 = 0x2 ++ FS_POLICY_FLAGS_PAD_32 = 0x3 ++ FS_POLICY_FLAGS_PAD_4 = 0x0 ++ FS_POLICY_FLAGS_PAD_8 = 0x1 ++ FS_POLICY_FLAGS_PAD_MASK = 0x3 ++ FS_POLICY_FLAGS_VALID = 0x7 ++ FS_VERITY_FL = 0x100000 ++ FS_VERITY_HASH_ALG_SHA256 = 0x1 ++ FS_VERITY_HASH_ALG_SHA512 = 0x2 ++ FS_VERITY_METADATA_TYPE_DESCRIPTOR = 0x2 ++ FS_VERITY_METADATA_TYPE_MERKLE_TREE = 0x1 ++ FS_VERITY_METADATA_TYPE_SIGNATURE = 0x3 ++ FUSE_SUPER_MAGIC = 0x65735546 ++ FUTEXFS_SUPER_MAGIC = 0xbad1dea ++ F_ADD_SEALS = 0x409 ++ F_DUPFD = 0x0 ++ F_DUPFD_CLOEXEC = 0x406 ++ F_EXLCK = 0x10 ++ F_GETFD = 0x1 ++ F_GETFL = 0x3 ++ F_GETLEASE = 0x401 ++ F_GETLK = 0x7 ++ F_GETLK64 = 0x7 ++ F_GETOWN = 0x6 ++ F_GETOWN_EX = 0x10 ++ F_GETPIPE_SZ = 0x408 ++ F_GETSIG = 0xb ++ F_GET_FILE_RW_HINT = 0x40d ++ F_GET_RW_HINT = 0x40b ++ F_GET_SEALS = 0x40a ++ F_LOCK = 0x1 ++ F_NOTIFY = 0x402 ++ F_OFD_GETLK = 0x24 ++ F_OFD_SETLK = 0x25 ++ F_OFD_SETLKW = 0x26 ++ F_OK = 0x0 ++ F_RDLCK = 0x1 ++ F_SEAL_FUTURE_WRITE = 0x10 ++ F_SEAL_GROW = 0x4 ++ F_SEAL_SEAL = 0x1 ++ F_SEAL_SHRINK = 0x2 ++ F_SEAL_WRITE = 0x8 ++ F_SETFD = 0x2 ++ F_SETFL = 0x4 ++ F_SETLEASE = 0x400 ++ F_SETLK = 0x8 ++ F_SETLK64 = 0x8 ++ F_SETLKW = 0x9 ++ F_SETLKW64 = 0x9 ++ F_SETOWN = 0x5 ++ F_SETOWN_EX = 0xf ++ F_SETPIPE_SZ = 0x407 ++ F_SETSIG = 0xa ++ F_SET_FILE_RW_HINT = 0x40e ++ F_SET_RW_HINT = 0x40c ++ F_SHLCK = 0x20 ++ F_TEST = 0x3 ++ F_TLOCK = 0x2 ++ F_ULOCK = 0x0 ++ F_UNLCK = 0x8 ++ F_WRLCK = 0x2 ++ GENL_ADMIN_PERM = 0x1 ++ GENL_CMD_CAP_DO = 0x2 ++ GENL_CMD_CAP_DUMP = 0x4 ++ GENL_CMD_CAP_HASPOL = 0x8 ++ GENL_HDRLEN = 0x4 ++ GENL_ID_CTRL = 0x10 ++ GENL_ID_PMCRAID = 0x12 ++ GENL_ID_VFS_DQUOT = 0x11 ++ GENL_MAX_ID = 0x3ff ++ GENL_MIN_ID = 0x10 ++ GENL_NAMSIZ = 0x10 ++ GENL_START_ALLOC = 0x13 ++ GENL_UNS_ADMIN_PERM = 0x10 ++ GRND_INSECURE = 0x4 ++ GRND_NONBLOCK = 0x1 ++ GRND_RANDOM = 0x2 ++ HDIO_DRIVE_CMD = 0x31f ++ HDIO_DRIVE_CMD_AEB = 0x31e ++ HDIO_DRIVE_CMD_HDR_SIZE = 0x4 ++ HDIO_DRIVE_HOB_HDR_SIZE = 0x8 ++ HDIO_DRIVE_RESET = 0x31c ++ HDIO_DRIVE_TASK = 0x31e ++ HDIO_DRIVE_TASKFILE = 0x31d ++ HDIO_DRIVE_TASK_HDR_SIZE = 0x8 ++ HDIO_GETGEO = 0x301 ++ HDIO_GET_32BIT = 0x309 ++ HDIO_GET_ACOUSTIC = 0x30f ++ HDIO_GET_ADDRESS = 0x310 ++ HDIO_GET_BUSSTATE = 0x31a ++ HDIO_GET_DMA = 0x30b ++ HDIO_GET_IDENTITY = 0x30d ++ HDIO_GET_KEEPSETTINGS = 0x308 ++ HDIO_GET_MULTCOUNT = 0x304 ++ HDIO_GET_NICE = 0x30c ++ HDIO_GET_NOWERR = 0x30a ++ HDIO_GET_QDMA = 0x305 ++ HDIO_GET_UNMASKINTR = 0x302 ++ HDIO_GET_WCACHE = 0x30e ++ HDIO_OBSOLETE_IDENTITY = 0x307 ++ HDIO_SCAN_HWIF = 0x328 ++ HDIO_SET_32BIT = 0x324 ++ HDIO_SET_ACOUSTIC = 0x32c ++ HDIO_SET_ADDRESS = 0x32f ++ HDIO_SET_BUSSTATE = 0x32d ++ HDIO_SET_DMA = 0x326 ++ HDIO_SET_KEEPSETTINGS = 0x323 ++ HDIO_SET_MULTCOUNT = 0x321 ++ HDIO_SET_NICE = 0x329 ++ HDIO_SET_NOWERR = 0x325 ++ HDIO_SET_PIO_MODE = 0x327 ++ HDIO_SET_QDMA = 0x32e ++ HDIO_SET_UNMASKINTR = 0x322 ++ HDIO_SET_WCACHE = 0x32b ++ HDIO_SET_XFER = 0x306 ++ HDIO_TRISTATE_HWIF = 0x31b ++ HDIO_UNREGISTER_HWIF = 0x32a ++ HIDIOCGRAWINFO = 0x40084803 ++ HIDIOCGRDESC = 0x50044802 ++ HIDIOCGRDESCSIZE = 0x40044801 ++ HID_MAX_DESCRIPTOR_SIZE = 0x1000 ++ HOSTFS_SUPER_MAGIC = 0xc0ffee ++ HPFS_SUPER_MAGIC = 0xf995e849 ++ HUGETLBFS_MAGIC = 0x958458f6 ++ HUPCL = 0x4000 ++ IBSHIFT = 0x10 ++ ICANON = 0x100 ++ ICRNL = 0x100 ++ IEXTEN = 0x400 ++ IFA_F_DADFAILED = 0x8 ++ IFA_F_DEPRECATED = 0x20 ++ IFA_F_HOMEADDRESS = 0x10 ++ IFA_F_MANAGETEMPADDR = 0x100 ++ IFA_F_MCAUTOJOIN = 0x400 ++ IFA_F_NODAD = 0x2 ++ IFA_F_NOPREFIXROUTE = 0x200 ++ IFA_F_OPTIMISTIC = 0x4 ++ IFA_F_PERMANENT = 0x80 ++ IFA_F_SECONDARY = 0x1 ++ IFA_F_STABLE_PRIVACY = 0x800 ++ IFA_F_TEMPORARY = 0x1 ++ IFA_F_TENTATIVE = 0x40 ++ IFA_MAX = 0xb ++ IFF_ALLMULTI = 0x200 ++ IFF_ATTACH_QUEUE = 0x200 ++ IFF_AUTOMEDIA = 0x4000 ++ IFF_BROADCAST = 0x2 ++ IFF_DEBUG = 0x4 ++ IFF_DETACH_QUEUE = 0x400 ++ IFF_DORMANT = 0x20000 ++ IFF_DYNAMIC = 0x8000 ++ IFF_ECHO = 0x40000 ++ IFF_LOOPBACK = 0x8 ++ IFF_LOWER_UP = 0x10000 ++ IFF_MASTER = 0x400 ++ IFF_MULTICAST = 0x1000 ++ IFF_MULTI_QUEUE = 0x100 ++ IFF_NAPI = 0x10 ++ IFF_NAPI_FRAGS = 0x20 ++ IFF_NOARP = 0x80 ++ IFF_NOFILTER = 0x1000 ++ IFF_NOTRAILERS = 0x20 ++ IFF_NO_CARRIER = 0x40 ++ IFF_NO_PI = 0x1000 ++ IFF_ONE_QUEUE = 0x2000 ++ IFF_PERSIST = 0x800 ++ IFF_POINTOPOINT = 0x10 ++ IFF_PORTSEL = 0x2000 ++ IFF_PROMISC = 0x100 ++ IFF_RUNNING = 0x40 ++ IFF_SLAVE = 0x800 ++ IFF_TAP = 0x2 ++ IFF_TUN = 0x1 ++ IFF_TUN_EXCL = 0x8000 ++ IFF_UP = 0x1 ++ IFF_VNET_HDR = 0x4000 ++ IFF_VOLATILE = 0x70c5a ++ IFNAMSIZ = 0x10 ++ IGNBRK = 0x1 ++ IGNCR = 0x80 ++ IGNPAR = 0x4 ++ IMAXBEL = 0x2000 ++ INLCR = 0x40 ++ INPCK = 0x10 ++ IN_ACCESS = 0x1 ++ IN_ALL_EVENTS = 0xfff ++ IN_ATTRIB = 0x4 ++ IN_CLASSA_HOST = 0xffffff ++ IN_CLASSA_MAX = 0x80 ++ IN_CLASSA_NET = 0xff000000 ++ IN_CLASSA_NSHIFT = 0x18 ++ IN_CLASSB_HOST = 0xffff ++ IN_CLASSB_MAX = 0x10000 ++ IN_CLASSB_NET = 0xffff0000 ++ IN_CLASSB_NSHIFT = 0x10 ++ IN_CLASSC_HOST = 0xff ++ IN_CLASSC_NET = 0xffffff00 ++ IN_CLASSC_NSHIFT = 0x8 ++ IN_CLOEXEC = 0x200000 ++ IN_CLOSE = 0x18 ++ IN_CLOSE_NOWRITE = 0x10 ++ IN_CLOSE_WRITE = 0x8 ++ IN_CREATE = 0x100 ++ IN_DELETE = 0x200 ++ IN_DELETE_SELF = 0x400 ++ IN_DONT_FOLLOW = 0x2000000 ++ IN_EXCL_UNLINK = 0x4000000 ++ IN_IGNORED = 0x8000 ++ IN_ISDIR = 0x40000000 ++ IN_LOOPBACKNET = 0x7f ++ IN_MASK_ADD = 0x20000000 ++ IN_MASK_CREATE = 0x10000000 ++ IN_MODIFY = 0x2 ++ IN_MOVE = 0xc0 ++ IN_MOVED_FROM = 0x40 ++ IN_MOVED_TO = 0x80 ++ IN_MOVE_SELF = 0x800 ++ IN_NONBLOCK = 0x4 ++ IN_ONESHOT = 0x80000000 ++ IN_ONLYDIR = 0x1000000 ++ IN_OPEN = 0x20 ++ IN_Q_OVERFLOW = 0x4000 ++ IN_UNMOUNT = 0x2000 ++ IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 ++ IPPROTO_AH = 0x33 ++ IPPROTO_BEETPH = 0x5e ++ IPPROTO_COMP = 0x6c ++ IPPROTO_DCCP = 0x21 ++ IPPROTO_DSTOPTS = 0x3c ++ IPPROTO_EGP = 0x8 ++ IPPROTO_ENCAP = 0x62 ++ IPPROTO_ESP = 0x32 ++ IPPROTO_ETHERNET = 0x8f ++ IPPROTO_FRAGMENT = 0x2c ++ IPPROTO_GRE = 0x2f ++ IPPROTO_HOPOPTS = 0x0 ++ IPPROTO_ICMP = 0x1 ++ IPPROTO_ICMPV6 = 0x3a ++ IPPROTO_IDP = 0x16 ++ IPPROTO_IGMP = 0x2 ++ IPPROTO_IP = 0x0 ++ IPPROTO_IPIP = 0x4 ++ IPPROTO_IPV6 = 0x29 ++ IPPROTO_L2TP = 0x73 ++ IPPROTO_MH = 0x87 ++ IPPROTO_MPLS = 0x89 ++ IPPROTO_MPTCP = 0x106 ++ IPPROTO_MTP = 0x5c ++ IPPROTO_NONE = 0x3b ++ IPPROTO_PIM = 0x67 ++ IPPROTO_PUP = 0xc ++ IPPROTO_RAW = 0xff ++ IPPROTO_ROUTING = 0x2b ++ IPPROTO_RSVP = 0x2e ++ IPPROTO_SCTP = 0x84 ++ IPPROTO_TCP = 0x6 ++ IPPROTO_TP = 0x1d ++ IPPROTO_UDP = 0x11 ++ IPPROTO_UDPLITE = 0x88 ++ IPV6_2292DSTOPTS = 0x4 ++ IPV6_2292HOPLIMIT = 0x8 ++ IPV6_2292HOPOPTS = 0x3 ++ IPV6_2292PKTINFO = 0x2 ++ IPV6_2292PKTOPTIONS = 0x6 ++ IPV6_2292RTHDR = 0x5 ++ IPV6_ADDRFORM = 0x1 ++ IPV6_ADDR_PREFERENCES = 0x48 ++ IPV6_ADD_MEMBERSHIP = 0x14 ++ IPV6_AUTHHDR = 0xa ++ IPV6_AUTOFLOWLABEL = 0x46 ++ IPV6_CHECKSUM = 0x7 ++ IPV6_DONTFRAG = 0x3e ++ IPV6_DROP_MEMBERSHIP = 0x15 ++ IPV6_DSTOPTS = 0x3b ++ IPV6_FLOW = 0x11 ++ IPV6_FREEBIND = 0x4e ++ IPV6_HDRINCL = 0x24 ++ IPV6_HOPLIMIT = 0x34 ++ IPV6_HOPOPTS = 0x36 ++ IPV6_IPSEC_POLICY = 0x22 ++ IPV6_JOIN_ANYCAST = 0x1b ++ IPV6_JOIN_GROUP = 0x14 ++ IPV6_LEAVE_ANYCAST = 0x1c ++ IPV6_LEAVE_GROUP = 0x15 ++ IPV6_MINHOPCOUNT = 0x49 ++ IPV6_MTU = 0x18 ++ IPV6_MTU_DISCOVER = 0x17 ++ IPV6_MULTICAST_ALL = 0x1d ++ IPV6_MULTICAST_HOPS = 0x12 ++ IPV6_MULTICAST_IF = 0x11 ++ IPV6_MULTICAST_LOOP = 0x13 ++ IPV6_NEXTHOP = 0x9 ++ IPV6_ORIGDSTADDR = 0x4a ++ IPV6_PATHMTU = 0x3d ++ IPV6_PKTINFO = 0x32 ++ IPV6_PMTUDISC_DO = 0x2 ++ IPV6_PMTUDISC_DONT = 0x0 ++ IPV6_PMTUDISC_INTERFACE = 0x4 ++ IPV6_PMTUDISC_OMIT = 0x5 ++ IPV6_PMTUDISC_PROBE = 0x3 ++ IPV6_PMTUDISC_WANT = 0x1 ++ IPV6_RECVDSTOPTS = 0x3a ++ IPV6_RECVERR = 0x19 ++ IPV6_RECVERR_RFC4884 = 0x1f ++ IPV6_RECVFRAGSIZE = 0x4d ++ IPV6_RECVHOPLIMIT = 0x33 ++ IPV6_RECVHOPOPTS = 0x35 ++ IPV6_RECVORIGDSTADDR = 0x4a ++ IPV6_RECVPATHMTU = 0x3c ++ IPV6_RECVPKTINFO = 0x31 ++ IPV6_RECVRTHDR = 0x38 ++ IPV6_RECVTCLASS = 0x42 ++ IPV6_ROUTER_ALERT = 0x16 ++ IPV6_ROUTER_ALERT_ISOLATE = 0x1e ++ IPV6_RTHDR = 0x39 ++ IPV6_RTHDRDSTOPTS = 0x37 ++ IPV6_RTHDR_LOOSE = 0x0 ++ IPV6_RTHDR_STRICT = 0x1 ++ IPV6_RTHDR_TYPE_0 = 0x0 ++ IPV6_RXDSTOPTS = 0x3b ++ IPV6_RXHOPOPTS = 0x36 ++ IPV6_TCLASS = 0x43 ++ IPV6_TRANSPARENT = 0x4b ++ IPV6_UNICAST_HOPS = 0x10 ++ IPV6_UNICAST_IF = 0x4c ++ IPV6_USER_FLOW = 0xe ++ IPV6_V6ONLY = 0x1a ++ IPV6_XFRM_POLICY = 0x23 ++ IP_ADD_MEMBERSHIP = 0x23 ++ IP_ADD_SOURCE_MEMBERSHIP = 0x27 ++ IP_BIND_ADDRESS_NO_PORT = 0x18 ++ IP_BLOCK_SOURCE = 0x26 ++ IP_CHECKSUM = 0x17 ++ IP_DEFAULT_MULTICAST_LOOP = 0x1 ++ IP_DEFAULT_MULTICAST_TTL = 0x1 ++ IP_DF = 0x4000 ++ IP_DROP_MEMBERSHIP = 0x24 ++ IP_DROP_SOURCE_MEMBERSHIP = 0x28 ++ IP_FREEBIND = 0xf ++ IP_HDRINCL = 0x3 ++ IP_IPSEC_POLICY = 0x10 ++ IP_LOCAL_PORT_RANGE = 0x33 ++ IP_MAXPACKET = 0xffff ++ IP_MAX_MEMBERSHIPS = 0x14 ++ IP_MF = 0x2000 ++ IP_MINTTL = 0x15 ++ IP_MSFILTER = 0x29 ++ IP_MSS = 0x240 ++ IP_MTU = 0xe ++ IP_MTU_DISCOVER = 0xa ++ IP_MULTICAST_ALL = 0x31 ++ IP_MULTICAST_IF = 0x20 ++ IP_MULTICAST_LOOP = 0x22 ++ IP_MULTICAST_TTL = 0x21 ++ IP_NODEFRAG = 0x16 ++ IP_OFFMASK = 0x1fff ++ IP_OPTIONS = 0x4 ++ IP_ORIGDSTADDR = 0x14 ++ IP_PASSSEC = 0x12 ++ IP_PKTINFO = 0x8 ++ IP_PKTOPTIONS = 0x9 ++ IP_PMTUDISC = 0xa ++ IP_PMTUDISC_DO = 0x2 ++ IP_PMTUDISC_DONT = 0x0 ++ IP_PMTUDISC_INTERFACE = 0x4 ++ IP_PMTUDISC_OMIT = 0x5 ++ IP_PMTUDISC_PROBE = 0x3 ++ IP_PMTUDISC_WANT = 0x1 ++ IP_RECVERR = 0xb ++ IP_RECVERR_RFC4884 = 0x1a ++ IP_RECVFRAGSIZE = 0x19 ++ IP_RECVOPTS = 0x6 ++ IP_RECVORIGDSTADDR = 0x14 ++ IP_RECVRETOPTS = 0x7 ++ IP_RECVTOS = 0xd ++ IP_RECVTTL = 0xc ++ IP_RETOPTS = 0x7 ++ IP_RF = 0x8000 ++ IP_ROUTER_ALERT = 0x5 ++ IP_TOS = 0x1 ++ IP_TRANSPARENT = 0x13 ++ IP_TTL = 0x2 ++ IP_UNBLOCK_SOURCE = 0x25 ++ IP_UNICAST_IF = 0x32 ++ IP_USER_FLOW = 0xd ++ IP_XFRM_POLICY = 0x11 ++ ISIG = 0x80 ++ ISOFS_SUPER_MAGIC = 0x9660 ++ ISTRIP = 0x20 ++ ITIMER_PROF = 0x2 ++ ITIMER_REAL = 0x0 ++ ITIMER_VIRTUAL = 0x1 ++ IUCLC = 0x1000 ++ IUTF8 = 0x4000 ++ IXANY = 0x800 ++ IXOFF = 0x400 ++ IXON = 0x200 ++ JFFS2_SUPER_MAGIC = 0x72b6 ++ KCMPROTO_CONNECTED = 0x0 ++ KCM_RECV_DISABLE = 0x1 ++ KEXEC_ARCH_386 = 0x30000 ++ KEXEC_ARCH_68K = 0x40000 ++ KEXEC_ARCH_AARCH64 = 0xb70000 ++ KEXEC_ARCH_ARM = 0x280000 ++ KEXEC_ARCH_DEFAULT = 0x0 ++ KEXEC_ARCH_IA_64 = 0x320000 ++ KEXEC_ARCH_LOONGARCH = 0x1020000 ++ KEXEC_ARCH_MASK = 0xffff0000 ++ KEXEC_ARCH_MIPS = 0x80000 ++ KEXEC_ARCH_MIPS_LE = 0xa0000 ++ KEXEC_ARCH_PARISC = 0xf0000 ++ KEXEC_ARCH_PPC = 0x140000 ++ KEXEC_ARCH_PPC64 = 0x150000 ++ KEXEC_ARCH_RISCV = 0xf30000 ++ KEXEC_ARCH_S390 = 0x160000 ++ KEXEC_ARCH_SH = 0x2a0000 ++ KEXEC_ARCH_SW64 = 0x99160000 ++ KEXEC_ARCH_X86_64 = 0x3e0000 ++ KEXEC_FILE_NO_INITRAMFS = 0x4 ++ KEXEC_FILE_ON_CRASH = 0x2 ++ KEXEC_FILE_UNLOAD = 0x1 ++ KEXEC_ON_CRASH = 0x1 ++ KEXEC_PRESERVE_CONTEXT = 0x2 ++ KEXEC_SEGMENT_MAX = 0x10 ++ KEXEC_UPDATE_ELFCOREHDR = 0x4 ++ KEYCTL_ASSUME_AUTHORITY = 0x10 ++ KEYCTL_CAPABILITIES = 0x1f ++ KEYCTL_CAPS0_BIG_KEY = 0x10 ++ KEYCTL_CAPS0_CAPABILITIES = 0x1 ++ KEYCTL_CAPS0_DIFFIE_HELLMAN = 0x4 ++ KEYCTL_CAPS0_INVALIDATE = 0x20 ++ KEYCTL_CAPS0_MOVE = 0x80 ++ KEYCTL_CAPS0_PERSISTENT_KEYRINGS = 0x2 ++ KEYCTL_CAPS0_PUBLIC_KEY = 0x8 ++ KEYCTL_CAPS0_RESTRICT_KEYRING = 0x40 ++ KEYCTL_CAPS1_NOTIFICATIONS = 0x4 ++ KEYCTL_CAPS1_NS_KEYRING_NAME = 0x1 ++ KEYCTL_CAPS1_NS_KEY_TAG = 0x2 ++ KEYCTL_CHOWN = 0x4 ++ KEYCTL_CLEAR = 0x7 ++ KEYCTL_DESCRIBE = 0x6 ++ KEYCTL_DH_COMPUTE = 0x17 ++ KEYCTL_GET_KEYRING_ID = 0x0 ++ KEYCTL_GET_PERSISTENT = 0x16 ++ KEYCTL_GET_SECURITY = 0x11 ++ KEYCTL_INSTANTIATE = 0xc ++ KEYCTL_INSTANTIATE_IOV = 0x14 ++ KEYCTL_INVALIDATE = 0x15 ++ KEYCTL_JOIN_SESSION_KEYRING = 0x1 ++ KEYCTL_LINK = 0x8 ++ KEYCTL_MOVE = 0x1e ++ KEYCTL_MOVE_EXCL = 0x1 ++ KEYCTL_NEGATE = 0xd ++ KEYCTL_PKEY_DECRYPT = 0x1a ++ KEYCTL_PKEY_ENCRYPT = 0x19 ++ KEYCTL_PKEY_QUERY = 0x18 ++ KEYCTL_PKEY_SIGN = 0x1b ++ KEYCTL_PKEY_VERIFY = 0x1c ++ KEYCTL_READ = 0xb ++ KEYCTL_REJECT = 0x13 ++ KEYCTL_RESTRICT_KEYRING = 0x1d ++ KEYCTL_REVOKE = 0x3 ++ KEYCTL_SEARCH = 0xa ++ KEYCTL_SESSION_TO_PARENT = 0x12 ++ KEYCTL_SETPERM = 0x5 ++ KEYCTL_SET_REQKEY_KEYRING = 0xe ++ KEYCTL_SET_TIMEOUT = 0xf ++ KEYCTL_SUPPORTS_DECRYPT = 0x2 ++ KEYCTL_SUPPORTS_ENCRYPT = 0x1 ++ KEYCTL_SUPPORTS_SIGN = 0x4 ++ KEYCTL_SUPPORTS_VERIFY = 0x8 ++ KEYCTL_UNLINK = 0x9 ++ KEYCTL_UPDATE = 0x2 ++ KEYCTL_WATCH_KEY = 0x20 ++ KEY_REQKEY_DEFL_DEFAULT = 0x0 ++ KEY_REQKEY_DEFL_GROUP_KEYRING = 0x6 ++ KEY_REQKEY_DEFL_NO_CHANGE = -0x1 ++ KEY_REQKEY_DEFL_PROCESS_KEYRING = 0x2 ++ KEY_REQKEY_DEFL_REQUESTOR_KEYRING = 0x7 ++ KEY_REQKEY_DEFL_SESSION_KEYRING = 0x3 ++ KEY_REQKEY_DEFL_THREAD_KEYRING = 0x1 ++ KEY_REQKEY_DEFL_USER_KEYRING = 0x4 ++ KEY_REQKEY_DEFL_USER_SESSION_KEYRING = 0x5 ++ KEY_SPEC_GROUP_KEYRING = -0x6 ++ KEY_SPEC_PROCESS_KEYRING = -0x2 ++ KEY_SPEC_REQKEY_AUTH_KEY = -0x7 ++ KEY_SPEC_REQUESTOR_KEYRING = -0x8 ++ KEY_SPEC_SESSION_KEYRING = -0x3 ++ KEY_SPEC_THREAD_KEYRING = -0x1 ++ KEY_SPEC_USER_KEYRING = -0x4 ++ KEY_SPEC_USER_SESSION_KEYRING = -0x5 ++ LINUX_REBOOT_CMD_CAD_OFF = 0x0 ++ LINUX_REBOOT_CMD_CAD_ON = 0x89abcdef ++ LINUX_REBOOT_CMD_HALT = 0xcdef0123 ++ LINUX_REBOOT_CMD_KEXEC = 0x45584543 ++ LINUX_REBOOT_CMD_POWER_OFF = 0x4321fedc ++ LINUX_REBOOT_CMD_RESTART = 0x1234567 ++ LINUX_REBOOT_CMD_RESTART2 = 0xa1b2c3d4 ++ LINUX_REBOOT_CMD_SW_SUSPEND = 0xd000fce2 ++ LINUX_REBOOT_MAGIC1 = 0xfee1dead ++ LINUX_REBOOT_MAGIC2 = 0x28121969 ++ LOCK_EX = 0x2 ++ LOCK_NB = 0x4 ++ LOCK_SH = 0x1 ++ LOCK_UN = 0x8 ++ LOOP_CLR_FD = 0x4c01 ++ LOOP_CONFIGURE = 0x4c0a ++ LOOP_CTL_ADD = 0x4c80 ++ LOOP_CTL_GET_FREE = 0x4c82 ++ LOOP_CTL_REMOVE = 0x4c81 ++ LOOP_GET_STATUS = 0x4c03 ++ LOOP_GET_STATUS64 = 0x4c05 ++ LOOP_SET_BLOCK_SIZE = 0x4c09 ++ LOOP_SET_CAPACITY = 0x4c07 ++ LOOP_SET_DIRECT_IO = 0x4c08 ++ LOOP_SET_FD = 0x4c00 ++ LOOP_SET_STATUS = 0x4c02 ++ LOOP_SET_STATUS64 = 0x4c04 ++ LOOP_SET_STATUS_CLEARABLE_FLAGS = 0x4 ++ LOOP_SET_STATUS_SETTABLE_FLAGS = 0xc ++ LO_KEY_SIZE = 0x20 ++ LO_NAME_SIZE = 0x40 ++ LWTUNNEL_IP6_MAX = 0x8 ++ LWTUNNEL_IP_MAX = 0x8 ++ LWTUNNEL_IP_OPTS_MAX = 0x3 ++ LWTUNNEL_IP_OPT_ERSPAN_MAX = 0x4 ++ LWTUNNEL_IP_OPT_GENEVE_MAX = 0x3 ++ LWTUNNEL_IP_OPT_VXLAN_MAX = 0x1 ++ MADV_COLD = 0x14 ++ MADV_COLLAPSE = 0x19 ++ MADV_DODUMP = 0x11 ++ MADV_DOFORK = 0xb ++ MADV_DONTDUMP = 0x10 ++ MADV_DONTFORK = 0xa ++ MADV_DONTNEED = 0x6 ++ MADV_DONTNEED_LOCKED = 0x18 ++ MADV_FREE = 0x8 ++ MADV_HUGEPAGE = 0xe ++ MADV_HWPOISON = 0x64 ++ MADV_KEEPONFORK = 0x13 ++ MADV_MERGEABLE = 0xc ++ MADV_NOHUGEPAGE = 0xf ++ MADV_NORMAL = 0x0 ++ MADV_PAGEOUT = 0x15 ++ MADV_POPULATE_READ = 0x16 ++ MADV_POPULATE_WRITE = 0x17 ++ MADV_RANDOM = 0x1 ++ MADV_REMOVE = 0x9 ++ MADV_SEQUENTIAL = 0x2 ++ MADV_UNMERGEABLE = 0xd ++ MADV_WILLNEED = 0x3 ++ MADV_WIPEONFORK = 0x12 ++ MAP_ANON = 0x10 ++ MAP_ANONYMOUS = 0x10 ++ MAP_DENYWRITE = 0x2000 ++ MAP_EXECUTABLE = 0x4000 ++ MAP_FILE = 0x0 ++ MAP_FIXED = 0x100 ++ MAP_FIXED_NOREPLACE = 0x200000 ++ MAP_GROWSDOWN = 0x1000 ++ MAP_HUGETLB = 0x100000 ++ MAP_HUGE_MASK = 0x3f ++ MAP_HUGE_SHIFT = 0x1a ++ MAP_LOCKED = 0x8000 ++ MAP_NONBLOCK = 0x40000 ++ MAP_NORESERVE = 0x10000 ++ MAP_POPULATE = 0x20000 ++ MAP_PRIVATE = 0x2 ++ MAP_SHARED = 0x1 ++ MAP_SHARED_VALIDATE = 0x3 ++ MAP_STACK = 0x80000 ++ MAP_TYPE = 0xf ++ MCAST_BLOCK_SOURCE = 0x2b ++ MCAST_EXCLUDE = 0x0 ++ MCAST_INCLUDE = 0x1 ++ MCAST_JOIN_GROUP = 0x2a ++ MCAST_JOIN_SOURCE_GROUP = 0x2e ++ MCAST_LEAVE_GROUP = 0x2d ++ MCAST_LEAVE_SOURCE_GROUP = 0x2f ++ MCAST_MSFILTER = 0x30 ++ MCAST_UNBLOCK_SOURCE = 0x2c ++ MCL_CURRENT = 0x2000 ++ MCL_FUTURE = 0x4000 ++ MCL_ONFAULT = 0x8000 ++ MEMERASE = 0x80084d02 ++ MEMERASE64 = 0x80104d14 ++ MEMGETBADBLOCK = 0x80084d0b ++ MEMGETINFO = 0x40204d01 ++ MEMGETOOBSEL = 0x40c84d0a ++ MEMGETREGIONCOUNT = 0x40044d07 ++ MEMGETREGIONINFO = 0xc0104d08 ++ MEMISLOCKED = 0x40084d17 ++ MEMLOCK = 0x80084d05 ++ MEMREAD = 0xc0404d1a ++ MEMREADOOB = 0xc0104d04 ++ MEMREADOOB64 = 0xc0184d16 ++ MEMSETBADBLOCK = 0x80084d0c ++ MEMUNLOCK = 0x80084d06 ++ MEMWRITE = 0xc0304d18 ++ MEMWRITEOOB = 0xc0104d03 ++ MEMWRITEOOB64 = 0xc0184d15 ++ MFD_ALLOW_SEALING = 0x2 ++ MFD_CLOEXEC = 0x1 ++ MFD_EXEC = 0x10 ++ MFD_HUGETLB = 0x4 ++ MFD_HUGE_16GB = 0x88000000 ++ MFD_HUGE_16MB = 0x60000000 ++ MFD_HUGE_1GB = 0x78000000 ++ MFD_HUGE_1MB = 0x50000000 ++ MFD_HUGE_256MB = 0x70000000 ++ MFD_HUGE_2GB = 0x7c000000 ++ MFD_HUGE_2MB = 0x54000000 ++ MFD_HUGE_32MB = 0x64000000 ++ MFD_HUGE_512KB = 0x4c000000 ++ MFD_HUGE_512MB = 0x74000000 ++ MFD_HUGE_64KB = 0x40000000 ++ MFD_HUGE_8MB = 0x5c000000 ++ MFD_HUGE_MASK = 0x3f ++ MFD_HUGE_SHIFT = 0x1a ++ MFD_NOEXEC_SEAL = 0x8 ++ MINIX2_SUPER_MAGIC = 0x2468 ++ MINIX2_SUPER_MAGIC2 = 0x2478 ++ MINIX3_SUPER_MAGIC = 0x4d5a ++ MINIX_SUPER_MAGIC = 0x137f ++ MINIX_SUPER_MAGIC2 = 0x138f ++ MNT_DETACH = 0x2 ++ MNT_EXPIRE = 0x4 ++ MNT_FORCE = 0x1 ++ MODULE_INIT_COMPRESSED_FILE = 0x4 ++ MODULE_INIT_IGNORE_MODVERSIONS = 0x1 ++ MODULE_INIT_IGNORE_VERMAGIC = 0x2 ++ MOUNT_ATTR_IDMAP = 0x100000 ++ MOUNT_ATTR_NOATIME = 0x10 ++ MOUNT_ATTR_NODEV = 0x4 ++ MOUNT_ATTR_NODIRATIME = 0x80 ++ MOUNT_ATTR_NOEXEC = 0x8 ++ MOUNT_ATTR_NOSUID = 0x2 ++ MOUNT_ATTR_NOSYMFOLLOW = 0x200000 ++ MOUNT_ATTR_RDONLY = 0x1 ++ MOUNT_ATTR_RELATIME = 0x0 ++ MOUNT_ATTR_SIZE_VER0 = 0x20 ++ MOUNT_ATTR_STRICTATIME = 0x20 ++ MOUNT_ATTR__ATIME = 0x70 ++ MREMAP_DONTUNMAP = 0x4 ++ MREMAP_FIXED = 0x2 ++ MREMAP_MAYMOVE = 0x1 ++ MSDOS_SUPER_MAGIC = 0x4d44 ++ MSG_BATCH = 0x40000 ++ MSG_CMSG_CLOEXEC = 0x40000000 ++ MSG_CONFIRM = 0x800 ++ MSG_CTRUNC = 0x8 ++ MSG_DONTROUTE = 0x4 ++ MSG_DONTWAIT = 0x40 ++ MSG_EOR = 0x80 ++ MSG_ERRQUEUE = 0x2000 ++ MSG_FASTOPEN = 0x20000000 ++ MSG_FIN = 0x200 ++ MSG_MORE = 0x8000 ++ MSG_NOSIGNAL = 0x4000 ++ MSG_OOB = 0x1 ++ MSG_PEEK = 0x2 ++ MSG_PROXY = 0x10 ++ MSG_RST = 0x1000 ++ MSG_SYN = 0x400 ++ MSG_TRUNC = 0x20 ++ MSG_TRYHARD = 0x4 ++ MSG_WAITALL = 0x100 ++ MSG_WAITFORONE = 0x10000 ++ MSG_ZEROCOPY = 0x4000000 ++ MS_ACTIVE = 0x40000000 ++ MS_ASYNC = 0x1 ++ MS_BIND = 0x1000 ++ MS_BORN = 0x20000000 ++ MS_DIRSYNC = 0x80 ++ MS_INVALIDATE = 0x4 ++ MS_I_VERSION = 0x800000 ++ MS_KERNMOUNT = 0x400000 ++ MS_LAZYTIME = 0x2000000 ++ MS_MANDLOCK = 0x40 ++ MS_MGC_MSK = 0xffff0000 ++ MS_MGC_VAL = 0xc0ed0000 ++ MS_MOVE = 0x2000 ++ MS_NOATIME = 0x400 ++ MS_NODEV = 0x4 ++ MS_NODIRATIME = 0x800 ++ MS_NOEXEC = 0x8 ++ MS_NOREMOTELOCK = 0x8000000 ++ MS_NOSEC = 0x10000000 ++ MS_NOSUID = 0x2 ++ MS_NOSYMFOLLOW = 0x100 ++ MS_NOUSER = -0x80000000 ++ MS_POSIXACL = 0x10000 ++ MS_PRIVATE = 0x40000 ++ MS_RDONLY = 0x1 ++ MS_REC = 0x4000 ++ MS_RELATIME = 0x200000 ++ MS_REMOUNT = 0x20 ++ MS_RMT_MASK = 0x2800051 ++ MS_SHARED = 0x100000 ++ MS_SILENT = 0x8000 ++ MS_SLAVE = 0x80000 ++ MS_STRICTATIME = 0x1000000 ++ MS_SUBMOUNT = 0x4000000 ++ MS_SYNC = 0x2 ++ MS_SYNCHRONOUS = 0x10 ++ MS_UNBINDABLE = 0x20000 ++ MS_VERBOSE = 0x8000 ++ MTDFILEMODE = 0x20004d13 ++ MTD_ABSENT = 0x0 ++ MTD_BIT_WRITEABLE = 0x800 ++ MTD_CAP_NANDFLASH = 0x400 ++ MTD_CAP_NORFLASH = 0xc00 ++ MTD_CAP_NVRAM = 0x1c00 ++ MTD_CAP_RAM = 0x1c00 ++ MTD_CAP_ROM = 0x0 ++ MTD_DATAFLASH = 0x6 ++ MTD_INODE_FS_MAGIC = 0x11307854 ++ MTD_MAX_ECCPOS_ENTRIES = 0x40 ++ MTD_MAX_OOBFREE_ENTRIES = 0x8 ++ MTD_MLCNANDFLASH = 0x8 ++ MTD_NANDECC_AUTOPLACE = 0x2 ++ MTD_NANDECC_AUTOPL_USR = 0x4 ++ MTD_NANDECC_OFF = 0x0 ++ MTD_NANDECC_PLACE = 0x1 ++ MTD_NANDECC_PLACEONLY = 0x3 ++ MTD_NANDFLASH = 0x4 ++ MTD_NORFLASH = 0x3 ++ MTD_NO_ERASE = 0x1000 ++ MTD_OTP_FACTORY = 0x1 ++ MTD_OTP_OFF = 0x0 ++ MTD_OTP_USER = 0x2 ++ MTD_POWERUP_LOCK = 0x2000 ++ MTD_RAM = 0x1 ++ MTD_ROM = 0x2 ++ MTD_SLC_ON_MLC_EMULATION = 0x4000 ++ MTD_UBIVOLUME = 0x7 ++ MTD_WRITEABLE = 0x400 ++ NAME_MAX = 0xff ++ NCP_SUPER_MAGIC = 0x564c ++ NETLINK_ADD_MEMBERSHIP = 0x1 ++ NETLINK_AUDIT = 0x9 ++ NETLINK_BROADCAST_ERROR = 0x4 ++ NETLINK_CAP_ACK = 0xa ++ NETLINK_CONNECTOR = 0xb ++ NETLINK_CRYPTO = 0x15 ++ NETLINK_DNRTMSG = 0xe ++ NETLINK_DROP_MEMBERSHIP = 0x2 ++ NETLINK_ECRYPTFS = 0x13 ++ NETLINK_EXT_ACK = 0xb ++ NETLINK_FIB_LOOKUP = 0xa ++ NETLINK_FIREWALL = 0x3 ++ NETLINK_GENERIC = 0x10 ++ NETLINK_GET_STRICT_CHK = 0xc ++ NETLINK_INET_DIAG = 0x4 ++ NETLINK_IP6_FW = 0xd ++ NETLINK_ISCSI = 0x8 ++ NETLINK_KOBJECT_UEVENT = 0xf ++ NETLINK_LISTEN_ALL_NSID = 0x8 ++ NETLINK_LIST_MEMBERSHIPS = 0x9 ++ NETLINK_NETFILTER = 0xc ++ NETLINK_NFLOG = 0x5 ++ NETLINK_NO_ENOBUFS = 0x5 ++ NETLINK_PKTINFO = 0x3 ++ NETLINK_RDMA = 0x14 ++ NETLINK_ROUTE = 0x0 ++ NETLINK_RX_RING = 0x6 ++ NETLINK_SCSITRANSPORT = 0x12 ++ NETLINK_SELINUX = 0x7 ++ NETLINK_SMC = 0x16 ++ NETLINK_SOCK_DIAG = 0x4 ++ NETLINK_TX_RING = 0x7 ++ NETLINK_UNUSED = 0x1 ++ NETLINK_USERSOCK = 0x2 ++ NETLINK_XFRM = 0x6 ++ NETNSA_MAX = 0x5 ++ NETNSA_NSID_NOT_ASSIGNED = -0x1 ++ NFC_ATR_REQ_GB_MAXSIZE = 0x30 ++ NFC_ATR_REQ_MAXSIZE = 0x40 ++ NFC_ATR_RES_GB_MAXSIZE = 0x2f ++ NFC_ATR_RES_MAXSIZE = 0x40 ++ NFC_COMM_ACTIVE = 0x0 ++ NFC_COMM_PASSIVE = 0x1 ++ NFC_DEVICE_NAME_MAXSIZE = 0x8 ++ NFC_DIRECTION_RX = 0x0 ++ NFC_DIRECTION_TX = 0x1 ++ NFC_FIRMWARE_NAME_MAXSIZE = 0x20 ++ NFC_GB_MAXSIZE = 0x30 ++ NFC_GENL_MCAST_EVENT_NAME = "events" ++ NFC_GENL_NAME = "nfc" ++ NFC_GENL_VERSION = 0x1 ++ NFC_HEADER_SIZE = 0x1 ++ NFC_ISO15693_UID_MAXSIZE = 0x8 ++ NFC_LLCP_MAX_SERVICE_NAME = 0x3f ++ NFC_LLCP_MIUX = 0x1 ++ NFC_LLCP_REMOTE_LTO = 0x3 ++ NFC_LLCP_REMOTE_MIU = 0x2 ++ NFC_LLCP_REMOTE_RW = 0x4 ++ NFC_LLCP_RW = 0x0 ++ NFC_NFCID1_MAXSIZE = 0xa ++ NFC_NFCID2_MAXSIZE = 0x8 ++ NFC_NFCID3_MAXSIZE = 0xa ++ NFC_PROTO_FELICA = 0x3 ++ NFC_PROTO_FELICA_MASK = 0x8 ++ NFC_PROTO_ISO14443 = 0x4 ++ NFC_PROTO_ISO14443_B = 0x6 ++ NFC_PROTO_ISO14443_B_MASK = 0x40 ++ NFC_PROTO_ISO14443_MASK = 0x10 ++ NFC_PROTO_ISO15693 = 0x7 ++ NFC_PROTO_ISO15693_MASK = 0x80 ++ NFC_PROTO_JEWEL = 0x1 ++ NFC_PROTO_JEWEL_MASK = 0x2 ++ NFC_PROTO_MAX = 0x8 ++ NFC_PROTO_MIFARE = 0x2 ++ NFC_PROTO_MIFARE_MASK = 0x4 ++ NFC_PROTO_NFC_DEP = 0x5 ++ NFC_PROTO_NFC_DEP_MASK = 0x20 ++ NFC_RAW_HEADER_SIZE = 0x2 ++ NFC_RF_INITIATOR = 0x0 ++ NFC_RF_NONE = 0x2 ++ NFC_RF_TARGET = 0x1 ++ NFC_SENSB_RES_MAXSIZE = 0xc ++ NFC_SENSF_RES_MAXSIZE = 0x12 ++ NFC_SE_DISABLED = 0x0 ++ NFC_SE_EMBEDDED = 0x2 ++ NFC_SE_ENABLED = 0x1 ++ NFC_SE_UICC = 0x1 ++ NFC_SOCKPROTO_LLCP = 0x1 ++ NFC_SOCKPROTO_MAX = 0x2 ++ NFC_SOCKPROTO_RAW = 0x0 ++ NFDBITS = 0x40 ++ NFNETLINK_V0 = 0x0 ++ NFNLGRP_ACCT_QUOTA = 0x8 ++ NFNLGRP_CONNTRACK_DESTROY = 0x3 ++ NFNLGRP_CONNTRACK_EXP_DESTROY = 0x6 ++ NFNLGRP_CONNTRACK_EXP_NEW = 0x4 ++ NFNLGRP_CONNTRACK_EXP_UPDATE = 0x5 ++ NFNLGRP_CONNTRACK_NEW = 0x1 ++ NFNLGRP_CONNTRACK_UPDATE = 0x2 ++ NFNLGRP_MAX = 0x9 ++ NFNLGRP_NFTABLES = 0x7 ++ NFNLGRP_NFTRACE = 0x9 ++ NFNLGRP_NONE = 0x0 ++ NFNL_BATCH_MAX = 0x1 ++ NFNL_MSG_BATCH_BEGIN = 0x10 ++ NFNL_MSG_BATCH_END = 0x11 ++ NFNL_NFA_NEST = 0x8000 ++ NFNL_SUBSYS_ACCT = 0x7 ++ NFNL_SUBSYS_COUNT = 0xd ++ NFNL_SUBSYS_CTHELPER = 0x9 ++ NFNL_SUBSYS_CTNETLINK = 0x1 ++ NFNL_SUBSYS_CTNETLINK_EXP = 0x2 ++ NFNL_SUBSYS_CTNETLINK_TIMEOUT = 0x8 ++ NFNL_SUBSYS_HOOK = 0xc ++ NFNL_SUBSYS_IPSET = 0x6 ++ NFNL_SUBSYS_NFTABLES = 0xa ++ NFNL_SUBSYS_NFT_COMPAT = 0xb ++ NFNL_SUBSYS_NONE = 0x0 ++ NFNL_SUBSYS_OSF = 0x5 ++ NFNL_SUBSYS_QUEUE = 0x3 ++ NFNL_SUBSYS_ULOG = 0x4 ++ NFS_SUPER_MAGIC = 0x6969 ++ NFT_CHAIN_FLAGS = 0x7 ++ NFT_CHAIN_MAXNAMELEN = 0x100 ++ NFT_CT_MAX = 0x17 ++ NFT_DATA_RESERVED_MASK = 0xffffff00 ++ NFT_DATA_VALUE_MAXLEN = 0x40 ++ NFT_EXTHDR_OP_MAX = 0x4 ++ NFT_FIB_RESULT_MAX = 0x3 ++ NFT_INNER_MASK = 0xf ++ NFT_LOGLEVEL_MAX = 0x8 ++ NFT_NAME_MAXLEN = 0x100 ++ NFT_NG_MAX = 0x1 ++ NFT_OBJECT_CONNLIMIT = 0x5 ++ NFT_OBJECT_COUNTER = 0x1 ++ NFT_OBJECT_CT_EXPECT = 0x9 ++ NFT_OBJECT_CT_HELPER = 0x3 ++ NFT_OBJECT_CT_TIMEOUT = 0x7 ++ NFT_OBJECT_LIMIT = 0x4 ++ NFT_OBJECT_MAX = 0xa ++ NFT_OBJECT_QUOTA = 0x2 ++ NFT_OBJECT_SECMARK = 0x8 ++ NFT_OBJECT_SYNPROXY = 0xa ++ NFT_OBJECT_TUNNEL = 0x6 ++ NFT_OBJECT_UNSPEC = 0x0 ++ NFT_OBJ_MAXNAMELEN = 0x100 ++ NFT_OSF_MAXGENRELEN = 0x10 ++ NFT_QUEUE_FLAG_BYPASS = 0x1 ++ NFT_QUEUE_FLAG_CPU_FANOUT = 0x2 ++ NFT_QUEUE_FLAG_MASK = 0x3 ++ NFT_REG32_COUNT = 0x10 ++ NFT_REG32_SIZE = 0x4 ++ NFT_REG_MAX = 0x4 ++ NFT_REG_SIZE = 0x10 ++ NFT_REJECT_ICMPX_MAX = 0x3 ++ NFT_RT_MAX = 0x4 ++ NFT_SECMARK_CTX_MAXLEN = 0x100 ++ NFT_SET_MAXNAMELEN = 0x100 ++ NFT_SOCKET_MAX = 0x3 ++ NFT_TABLE_F_MASK = 0x3 ++ NFT_TABLE_MAXNAMELEN = 0x100 ++ NFT_TRACETYPE_MAX = 0x3 ++ NFT_TUNNEL_F_MASK = 0x7 ++ NFT_TUNNEL_MAX = 0x1 ++ NFT_TUNNEL_MODE_MAX = 0x2 ++ NFT_USERDATA_MAXLEN = 0x100 ++ NFT_XFRM_KEY_MAX = 0x6 ++ NF_NAT_RANGE_MAP_IPS = 0x1 ++ NF_NAT_RANGE_MASK = 0x7f ++ NF_NAT_RANGE_NETMAP = 0x40 ++ NF_NAT_RANGE_PERSISTENT = 0x8 ++ NF_NAT_RANGE_PROTO_OFFSET = 0x20 ++ NF_NAT_RANGE_PROTO_RANDOM = 0x4 ++ NF_NAT_RANGE_PROTO_RANDOM_ALL = 0x14 ++ NF_NAT_RANGE_PROTO_RANDOM_FULLY = 0x10 ++ NF_NAT_RANGE_PROTO_SPECIFIED = 0x2 ++ NILFS_SUPER_MAGIC = 0x3434 ++ NL0 = 0x0 ++ NL1 = 0x100 ++ NL2 = 0x200 ++ NL3 = 0x300 ++ NLA_ALIGNTO = 0x4 ++ NLA_F_NESTED = 0x8000 ++ NLA_F_NET_BYTEORDER = 0x4000 ++ NLA_HDRLEN = 0x4 ++ NLDLY = 0x300 ++ NLMSG_ALIGNTO = 0x4 ++ NLMSG_DONE = 0x3 ++ NLMSG_ERROR = 0x2 ++ NLMSG_HDRLEN = 0x10 ++ NLMSG_MIN_TYPE = 0x10 ++ NLMSG_NOOP = 0x1 ++ NLMSG_OVERRUN = 0x4 ++ NLM_F_ACK = 0x4 ++ NLM_F_ACK_TLVS = 0x200 ++ NLM_F_APPEND = 0x800 ++ NLM_F_ATOMIC = 0x400 ++ NLM_F_BULK = 0x200 ++ NLM_F_CAPPED = 0x100 ++ NLM_F_CREATE = 0x400 ++ NLM_F_DUMP = 0x300 ++ NLM_F_DUMP_FILTERED = 0x20 ++ NLM_F_DUMP_INTR = 0x10 ++ NLM_F_ECHO = 0x8 ++ NLM_F_EXCL = 0x200 ++ NLM_F_MATCH = 0x200 ++ NLM_F_MULTI = 0x2 ++ NLM_F_NONREC = 0x100 ++ NLM_F_REPLACE = 0x100 ++ NLM_F_REQUEST = 0x1 ++ NLM_F_ROOT = 0x100 ++ NOFLSH = 0x80000000 ++ NSFS_MAGIC = 0x6e736673 ++ NS_GET_NSTYPE = 0x2000b703 ++ NS_GET_OWNER_UID = 0x2000b704 ++ NS_GET_PARENT = 0x2000b702 ++ NS_GET_USERNS = 0x2000b701 ++ OCFS2_SUPER_MAGIC = 0x7461636f ++ OCRNL = 0x8 ++ OFDEL = 0x80 ++ OFILL = 0x40 ++ OLCUC = 0x4 ++ ONLCR = 0x2 ++ ONLRET = 0x20 ++ ONOCR = 0x10 ++ OPENPROM_SUPER_MAGIC = 0x9fa1 ++ OPOST = 0x1 ++ OTPERASE = 0x800c4d19 ++ OTPGETREGIONCOUNT = 0x80044d0e ++ OTPGETREGIONINFO = 0x800c4d0f ++ OTPLOCK = 0x400c4d10 ++ OTPSELECT = 0x40044d0d ++ OVERLAYFS_SUPER_MAGIC = 0x794c7630 ++ O_ACCMODE = 0x3 ++ O_APPEND = 0x8 ++ O_ASYNC = 0x2000 ++ O_CLOEXEC = 0x200000 ++ O_CREAT = 0x200 ++ O_DIRECT = 0x80000 ++ O_DIRECTORY = 0x8000 ++ O_DSYNC = 0x4000 ++ O_EXCL = 0x800 ++ O_FSYNC = 0x404000 ++ O_LARGEFILE = 0x0 ++ O_NDELAY = 0x4 ++ O_NOATIME = 0x100000 ++ O_NOCTTY = 0x1000 ++ O_NOFOLLOW = 0x10000 ++ O_NONBLOCK = 0x4 ++ O_PATH = 0x800000 ++ O_RDONLY = 0x0 ++ O_RDWR = 0x2 ++ O_RSYNC = 0x404000 ++ O_SYNC = 0x404000 ++ O_TMPFILE = 0x1008000 ++ O_TRUNC = 0x400 ++ O_WRONLY = 0x1 ++ PACKET_ADD_MEMBERSHIP = 0x1 ++ PACKET_AUXDATA = 0x8 ++ PACKET_BROADCAST = 0x1 ++ PACKET_COPY_THRESH = 0x7 ++ PACKET_DROP_MEMBERSHIP = 0x2 ++ PACKET_FANOUT = 0x12 ++ PACKET_FANOUT_CBPF = 0x6 ++ PACKET_FANOUT_CPU = 0x2 ++ PACKET_FANOUT_DATA = 0x16 ++ PACKET_FANOUT_EBPF = 0x7 ++ PACKET_FANOUT_FLAG_DEFRAG = 0x8000 ++ PACKET_FANOUT_FLAG_IGNORE_OUTGOING = 0x4000 ++ PACKET_FANOUT_FLAG_ROLLOVER = 0x1000 ++ PACKET_FANOUT_FLAG_UNIQUEID = 0x2000 ++ PACKET_FANOUT_HASH = 0x0 ++ PACKET_FANOUT_LB = 0x1 ++ PACKET_FANOUT_QM = 0x5 ++ PACKET_FANOUT_RND = 0x4 ++ PACKET_FANOUT_ROLLOVER = 0x3 ++ PACKET_FASTROUTE = 0x6 ++ PACKET_HDRLEN = 0xb ++ PACKET_HOST = 0x0 ++ PACKET_IGNORE_OUTGOING = 0x17 ++ PACKET_KERNEL = 0x7 ++ PACKET_LOOPBACK = 0x5 ++ PACKET_LOSS = 0xe ++ PACKET_MR_ALLMULTI = 0x2 ++ PACKET_MR_MULTICAST = 0x0 ++ PACKET_MR_PROMISC = 0x1 ++ PACKET_MR_UNICAST = 0x3 ++ PACKET_MULTICAST = 0x2 ++ PACKET_ORIGDEV = 0x9 ++ PACKET_OTHERHOST = 0x3 ++ PACKET_OUTGOING = 0x4 ++ PACKET_QDISC_BYPASS = 0x14 ++ PACKET_RECV_OUTPUT = 0x3 ++ PACKET_RESERVE = 0xc ++ PACKET_ROLLOVER_STATS = 0x15 ++ PACKET_RX_RING = 0x5 ++ PACKET_STATISTICS = 0x6 ++ PACKET_TIMESTAMP = 0x11 ++ PACKET_TX_HAS_OFF = 0x13 ++ PACKET_TX_RING = 0xd ++ PACKET_TX_TIMESTAMP = 0x10 ++ PACKET_USER = 0x6 ++ PACKET_VERSION = 0xa ++ PACKET_VNET_HDR = 0xf ++ PACKET_VNET_HDR_SZ = 0x18 ++ PARENB = 0x1000 ++ PARITY_CRC16_PR0 = 0x2 ++ PARITY_CRC16_PR0_CCITT = 0x4 ++ PARITY_CRC16_PR1 = 0x3 ++ PARITY_CRC16_PR1_CCITT = 0x5 ++ PARITY_CRC32_PR0_CCITT = 0x6 ++ PARITY_CRC32_PR1_CCITT = 0x7 ++ PARITY_DEFAULT = 0x0 ++ PARITY_NONE = 0x1 ++ PARMRK = 0x8 ++ PARODD = 0x2000 ++ PENDIN = 0x20000000 ++ PERF_ATTR_SIZE_VER0 = 0x40 ++ PERF_ATTR_SIZE_VER1 = 0x48 ++ PERF_ATTR_SIZE_VER2 = 0x50 ++ PERF_ATTR_SIZE_VER3 = 0x60 ++ PERF_ATTR_SIZE_VER4 = 0x68 ++ PERF_ATTR_SIZE_VER5 = 0x70 ++ PERF_ATTR_SIZE_VER6 = 0x78 ++ PERF_ATTR_SIZE_VER7 = 0x80 ++ PERF_ATTR_SIZE_VER8 = 0x88 ++ PERF_AUX_FLAG_COLLISION = 0x8 ++ PERF_AUX_FLAG_CORESIGHT_FORMAT_CORESIGHT = 0x0 ++ PERF_AUX_FLAG_CORESIGHT_FORMAT_RAW = 0x100 ++ PERF_AUX_FLAG_OVERWRITE = 0x2 ++ PERF_AUX_FLAG_PARTIAL = 0x4 ++ PERF_AUX_FLAG_PMU_FORMAT_TYPE_MASK = 0xff00 ++ PERF_AUX_FLAG_TRUNCATED = 0x1 ++ PERF_BR_ARM64_DEBUG_DATA = 0x7 ++ PERF_BR_ARM64_DEBUG_EXIT = 0x5 ++ PERF_BR_ARM64_DEBUG_HALT = 0x4 ++ PERF_BR_ARM64_DEBUG_INST = 0x6 ++ PERF_BR_ARM64_FIQ = 0x3 ++ PERF_EVENT_IOC_DISABLE = 0x20002401 ++ PERF_EVENT_IOC_ENABLE = 0x20002400 ++ PERF_EVENT_IOC_ID = 0x40082407 ++ PERF_EVENT_IOC_MODIFY_ATTRIBUTES = 0x8008240b ++ PERF_EVENT_IOC_PAUSE_OUTPUT = 0x80042409 ++ PERF_EVENT_IOC_PERIOD = 0x80082404 ++ PERF_EVENT_IOC_QUERY_BPF = 0xc008240a ++ PERF_EVENT_IOC_REFRESH = 0x20002402 ++ PERF_EVENT_IOC_RESET = 0x20002403 ++ PERF_EVENT_IOC_SET_BPF = 0x80042408 ++ PERF_EVENT_IOC_SET_FILTER = 0x80082406 ++ PERF_EVENT_IOC_SET_OUTPUT = 0x20002405 ++ PERF_FLAG_FD_CLOEXEC = 0x8 ++ PERF_FLAG_FD_NO_GROUP = 0x1 ++ PERF_FLAG_FD_OUTPUT = 0x2 ++ PERF_FLAG_PID_CGROUP = 0x4 ++ PERF_HW_EVENT_MASK = 0xffffffff ++ PERF_MAX_CONTEXTS_PER_STACK = 0x8 ++ PERF_MAX_STACK_DEPTH = 0x7f ++ PERF_MEM_BLK_ADDR = 0x4 ++ PERF_MEM_BLK_DATA = 0x2 ++ PERF_MEM_BLK_NA = 0x1 ++ PERF_MEM_BLK_SHIFT = 0x28 ++ PERF_MEM_HOPS_0 = 0x1 ++ PERF_MEM_HOPS_1 = 0x2 ++ PERF_MEM_HOPS_2 = 0x3 ++ PERF_MEM_HOPS_3 = 0x4 ++ PERF_MEM_HOPS_SHIFT = 0x2b ++ PERF_MEM_LOCK_LOCKED = 0x2 ++ PERF_MEM_LOCK_NA = 0x1 ++ PERF_MEM_LOCK_SHIFT = 0x18 ++ PERF_MEM_LVLNUM_ANY_CACHE = 0xb ++ PERF_MEM_LVLNUM_CXL = 0x9 ++ PERF_MEM_LVLNUM_IO = 0xa ++ PERF_MEM_LVLNUM_L1 = 0x1 ++ PERF_MEM_LVLNUM_L2 = 0x2 ++ PERF_MEM_LVLNUM_L3 = 0x3 ++ PERF_MEM_LVLNUM_L4 = 0x4 ++ PERF_MEM_LVLNUM_LFB = 0xc ++ PERF_MEM_LVLNUM_NA = 0xf ++ PERF_MEM_LVLNUM_PMEM = 0xe ++ PERF_MEM_LVLNUM_RAM = 0xd ++ PERF_MEM_LVLNUM_SHIFT = 0x21 ++ PERF_MEM_LVLNUM_UNC = 0x8 ++ PERF_MEM_LVL_HIT = 0x2 ++ PERF_MEM_LVL_IO = 0x1000 ++ PERF_MEM_LVL_L1 = 0x8 ++ PERF_MEM_LVL_L2 = 0x20 ++ PERF_MEM_LVL_L3 = 0x40 ++ PERF_MEM_LVL_LFB = 0x10 ++ PERF_MEM_LVL_LOC_RAM = 0x80 ++ PERF_MEM_LVL_MISS = 0x4 ++ PERF_MEM_LVL_NA = 0x1 ++ PERF_MEM_LVL_REM_CCE1 = 0x400 ++ PERF_MEM_LVL_REM_CCE2 = 0x800 ++ PERF_MEM_LVL_REM_RAM1 = 0x100 ++ PERF_MEM_LVL_REM_RAM2 = 0x200 ++ PERF_MEM_LVL_SHIFT = 0x5 ++ PERF_MEM_LVL_UNC = 0x2000 ++ PERF_MEM_OP_EXEC = 0x10 ++ PERF_MEM_OP_LOAD = 0x2 ++ PERF_MEM_OP_NA = 0x1 ++ PERF_MEM_OP_PFETCH = 0x8 ++ PERF_MEM_OP_SHIFT = 0x0 ++ PERF_MEM_OP_STORE = 0x4 ++ PERF_MEM_REMOTE_REMOTE = 0x1 ++ PERF_MEM_REMOTE_SHIFT = 0x25 ++ PERF_MEM_SNOOPX_FWD = 0x1 ++ PERF_MEM_SNOOPX_PEER = 0x2 ++ PERF_MEM_SNOOPX_SHIFT = 0x26 ++ PERF_MEM_SNOOP_HIT = 0x4 ++ PERF_MEM_SNOOP_HITM = 0x10 ++ PERF_MEM_SNOOP_MISS = 0x8 ++ PERF_MEM_SNOOP_NA = 0x1 ++ PERF_MEM_SNOOP_NONE = 0x2 ++ PERF_MEM_SNOOP_SHIFT = 0x13 ++ PERF_MEM_TLB_HIT = 0x2 ++ PERF_MEM_TLB_L1 = 0x8 ++ PERF_MEM_TLB_L2 = 0x10 ++ PERF_MEM_TLB_MISS = 0x4 ++ PERF_MEM_TLB_NA = 0x1 ++ PERF_MEM_TLB_OS = 0x40 ++ PERF_MEM_TLB_SHIFT = 0x1a ++ PERF_MEM_TLB_WK = 0x20 ++ PERF_PMU_TYPE_SHIFT = 0x20 ++ PERF_RECORD_KSYMBOL_FLAGS_UNREGISTER = 0x1 ++ PERF_RECORD_MISC_COMM_EXEC = 0x2000 ++ PERF_RECORD_MISC_CPUMODE_MASK = 0x7 ++ PERF_RECORD_MISC_CPUMODE_UNKNOWN = 0x0 ++ PERF_RECORD_MISC_EXACT_IP = 0x4000 ++ PERF_RECORD_MISC_EXT_RESERVED = 0x8000 ++ PERF_RECORD_MISC_FORK_EXEC = 0x2000 ++ PERF_RECORD_MISC_GUEST_KERNEL = 0x4 ++ PERF_RECORD_MISC_GUEST_USER = 0x5 ++ PERF_RECORD_MISC_HYPERVISOR = 0x3 ++ PERF_RECORD_MISC_KERNEL = 0x1 ++ PERF_RECORD_MISC_MMAP_BUILD_ID = 0x4000 ++ PERF_RECORD_MISC_MMAP_DATA = 0x2000 ++ PERF_RECORD_MISC_PROC_MAP_PARSE_TIMEOUT = 0x1000 ++ PERF_RECORD_MISC_SWITCH_OUT = 0x2000 ++ PERF_RECORD_MISC_SWITCH_OUT_PREEMPT = 0x4000 ++ PERF_RECORD_MISC_USER = 0x2 ++ PERF_SAMPLE_BRANCH_PLM_ALL = 0x7 ++ PERF_SAMPLE_WEIGHT_TYPE = 0x1004000 ++ PIPEFS_MAGIC = 0x50495045 ++ PPPIOCATTACH = 0x8004743d ++ PPPIOCATTCHAN = 0x80047438 ++ PPPIOCBRIDGECHAN = 0x80047435 ++ PPPIOCCONNECT = 0x8004743a ++ PPPIOCDETACH = 0x8004743c ++ PPPIOCDISCONN = 0x20007439 ++ PPPIOCGASYNCMAP = 0x40047458 ++ PPPIOCGCHAN = 0x40047437 ++ PPPIOCGDEBUG = 0x40047441 ++ PPPIOCGFLAGS = 0x4004745a ++ PPPIOCGIDLE = 0x4010743f ++ PPPIOCGIDLE32 = 0x4008743f ++ PPPIOCGIDLE64 = 0x4010743f ++ PPPIOCGL2TPSTATS = 0x40487436 ++ PPPIOCGMRU = 0x40047453 ++ PPPIOCGNPMODE = 0xc008744c ++ PPPIOCGRASYNCMAP = 0x40047455 ++ PPPIOCGUNIT = 0x40047456 ++ PPPIOCGXASYNCMAP = 0x40207450 ++ PPPIOCNEWUNIT = 0xc004743e ++ PPPIOCSACTIVE = 0x80107446 ++ PPPIOCSASYNCMAP = 0x80047457 ++ PPPIOCSCOMPRESS = 0x8010744d ++ PPPIOCSDEBUG = 0x80047440 ++ PPPIOCSFLAGS = 0x80047459 ++ PPPIOCSMAXCID = 0x80047451 ++ PPPIOCSMRRU = 0x8004743b ++ PPPIOCSMRU = 0x80047452 ++ PPPIOCSNPMODE = 0x8008744b ++ PPPIOCSPASS = 0x80107447 ++ PPPIOCSRASYNCMAP = 0x80047454 ++ PPPIOCSXASYNCMAP = 0x8020744f ++ PPPIOCUNBRIDGECHAN = 0x20007434 ++ PPPIOCXFERUNIT = 0x2000744e ++ PRIO_PGRP = 0x1 ++ PRIO_PROCESS = 0x0 ++ PRIO_USER = 0x2 ++ PROC_SUPER_MAGIC = 0x9fa0 ++ PROT_EXEC = 0x4 ++ PROT_GROWSDOWN = 0x1000000 ++ PROT_GROWSUP = 0x2000000 ++ PROT_NONE = 0x0 ++ PROT_READ = 0x1 ++ PROT_WRITE = 0x2 ++ PR_CAPBSET_DROP = 0x18 ++ PR_CAPBSET_READ = 0x17 ++ PR_CAP_AMBIENT = 0x2f ++ PR_CAP_AMBIENT_CLEAR_ALL = 0x4 ++ PR_CAP_AMBIENT_IS_SET = 0x1 ++ PR_CAP_AMBIENT_LOWER = 0x3 ++ PR_CAP_AMBIENT_RAISE = 0x2 ++ PR_ENDIAN_BIG = 0x0 ++ PR_ENDIAN_LITTLE = 0x1 ++ PR_ENDIAN_PPC_LITTLE = 0x2 ++ PR_FPEMU_NOPRINT = 0x1 ++ PR_FPEMU_SIGFPE = 0x2 ++ PR_FP_EXC_ASYNC = 0x2 ++ PR_FP_EXC_DISABLED = 0x0 ++ PR_FP_EXC_DIV = 0x10000 ++ PR_FP_EXC_INV = 0x100000 ++ PR_FP_EXC_NONRECOV = 0x1 ++ PR_FP_EXC_OVF = 0x20000 ++ PR_FP_EXC_PRECISE = 0x3 ++ PR_FP_EXC_RES = 0x80000 ++ PR_FP_EXC_SW_ENABLE = 0x80 ++ PR_FP_EXC_UND = 0x40000 ++ PR_FP_MODE_FR = 0x1 ++ PR_FP_MODE_FRE = 0x2 ++ PR_GET_AUXV = 0x41555856 ++ PR_GET_CHILD_SUBREAPER = 0x25 ++ PR_GET_DUMPABLE = 0x3 ++ PR_GET_ENDIAN = 0x13 ++ PR_GET_FPEMU = 0x9 ++ PR_GET_FPEXC = 0xb ++ PR_GET_FP_MODE = 0x2e ++ PR_GET_IO_FLUSHER = 0x3a ++ PR_GET_KEEPCAPS = 0x7 ++ PR_GET_MDWE = 0x42 ++ PR_GET_MEMORY_MERGE = 0x44 ++ PR_GET_NAME = 0x10 ++ PR_GET_NO_NEW_PRIVS = 0x27 ++ PR_GET_PDEATHSIG = 0x2 ++ PR_GET_SECCOMP = 0x15 ++ PR_GET_SECUREBITS = 0x1b ++ PR_GET_SPECULATION_CTRL = 0x34 ++ PR_GET_TAGGED_ADDR_CTRL = 0x38 ++ PR_GET_THP_DISABLE = 0x2a ++ PR_GET_TID_ADDRESS = 0x28 ++ PR_GET_TIMERSLACK = 0x1e ++ PR_GET_TIMING = 0xd ++ PR_GET_TSC = 0x19 ++ PR_GET_UNALIGN = 0x5 ++ PR_MCE_KILL = 0x21 ++ PR_MCE_KILL_CLEAR = 0x0 ++ PR_MCE_KILL_DEFAULT = 0x2 ++ PR_MCE_KILL_EARLY = 0x1 ++ PR_MCE_KILL_GET = 0x22 ++ PR_MCE_KILL_LATE = 0x0 ++ PR_MCE_KILL_SET = 0x1 ++ PR_MDWE_REFUSE_EXEC_GAIN = 0x1 ++ PR_MPX_DISABLE_MANAGEMENT = 0x2c ++ PR_MPX_ENABLE_MANAGEMENT = 0x2b ++ PR_MTE_TAG_MASK = 0x7fff8 ++ PR_MTE_TAG_SHIFT = 0x3 ++ PR_MTE_TCF_ASYNC = 0x4 ++ PR_MTE_TCF_MASK = 0x6 ++ PR_MTE_TCF_NONE = 0x0 ++ PR_MTE_TCF_SHIFT = 0x1 ++ PR_MTE_TCF_SYNC = 0x2 ++ PR_PAC_APDAKEY = 0x4 ++ PR_PAC_APDBKEY = 0x8 ++ PR_PAC_APGAKEY = 0x10 ++ PR_PAC_APIAKEY = 0x1 ++ PR_PAC_APIBKEY = 0x2 ++ PR_PAC_GET_ENABLED_KEYS = 0x3d ++ PR_PAC_RESET_KEYS = 0x36 ++ PR_PAC_SET_ENABLED_KEYS = 0x3c ++ PR_RISCV_V_GET_CONTROL = 0x46 ++ PR_RISCV_V_SET_CONTROL = 0x45 ++ PR_RISCV_V_VSTATE_CTRL_CUR_MASK = 0x3 ++ PR_RISCV_V_VSTATE_CTRL_DEFAULT = 0x0 ++ PR_RISCV_V_VSTATE_CTRL_INHERIT = 0x10 ++ PR_RISCV_V_VSTATE_CTRL_MASK = 0x1f ++ PR_RISCV_V_VSTATE_CTRL_NEXT_MASK = 0xc ++ PR_RISCV_V_VSTATE_CTRL_OFF = 0x1 ++ PR_RISCV_V_VSTATE_CTRL_ON = 0x2 ++ PR_SCHED_CORE = 0x3e ++ PR_SCHED_CORE_CREATE = 0x1 ++ PR_SCHED_CORE_GET = 0x0 ++ PR_SCHED_CORE_MAX = 0x4 ++ PR_SCHED_CORE_SCOPE_PROCESS_GROUP = 0x2 ++ PR_SCHED_CORE_SCOPE_THREAD = 0x0 ++ PR_SCHED_CORE_SCOPE_THREAD_GROUP = 0x1 ++ PR_SCHED_CORE_SHARE_FROM = 0x3 ++ PR_SCHED_CORE_SHARE_TO = 0x2 ++ PR_SET_CHILD_SUBREAPER = 0x24 ++ PR_SET_DUMPABLE = 0x4 ++ PR_SET_ENDIAN = 0x14 ++ PR_SET_FPEMU = 0xa ++ PR_SET_FPEXC = 0xc ++ PR_SET_FP_MODE = 0x2d ++ PR_SET_IO_FLUSHER = 0x39 ++ PR_SET_KEEPCAPS = 0x8 ++ PR_SET_MDWE = 0x41 ++ PR_SET_MEMORY_MERGE = 0x43 ++ PR_SET_MM = 0x23 ++ PR_SET_MM_ARG_END = 0x9 ++ PR_SET_MM_ARG_START = 0x8 ++ PR_SET_MM_AUXV = 0xc ++ PR_SET_MM_BRK = 0x7 ++ PR_SET_MM_END_CODE = 0x2 ++ PR_SET_MM_END_DATA = 0x4 ++ PR_SET_MM_ENV_END = 0xb ++ PR_SET_MM_ENV_START = 0xa ++ PR_SET_MM_EXE_FILE = 0xd ++ PR_SET_MM_MAP = 0xe ++ PR_SET_MM_MAP_SIZE = 0xf ++ PR_SET_MM_START_BRK = 0x6 ++ PR_SET_MM_START_CODE = 0x1 ++ PR_SET_MM_START_DATA = 0x3 ++ PR_SET_MM_START_STACK = 0x5 ++ PR_SET_NAME = 0xf ++ PR_SET_NO_NEW_PRIVS = 0x26 ++ PR_SET_PDEATHSIG = 0x1 ++ PR_SET_PTRACER = 0x59616d61 ++ PR_SET_PTRACER_ANY = 0xffffffffffffffff ++ PR_SET_SECCOMP = 0x16 ++ PR_SET_SECUREBITS = 0x1c ++ PR_SET_SPECULATION_CTRL = 0x35 ++ PR_SET_SYSCALL_USER_DISPATCH = 0x3b ++ PR_SET_TAGGED_ADDR_CTRL = 0x37 ++ PR_SET_THP_DISABLE = 0x29 ++ PR_SET_TIMERSLACK = 0x1d ++ PR_SET_TIMING = 0xe ++ PR_SET_TSC = 0x1a ++ PR_SET_UNALIGN = 0x6 ++ PR_SET_VMA = 0x53564d41 ++ PR_SET_VMA_ANON_NAME = 0x0 ++ PR_SME_GET_VL = 0x40 ++ PR_SME_SET_VL = 0x3f ++ PR_SME_SET_VL_ONEXEC = 0x40000 ++ PR_SME_VL_INHERIT = 0x20000 ++ PR_SME_VL_LEN_MASK = 0xffff ++ PR_SPEC_DISABLE = 0x4 ++ PR_SPEC_DISABLE_NOEXEC = 0x10 ++ PR_SPEC_ENABLE = 0x2 ++ PR_SPEC_FORCE_DISABLE = 0x8 ++ PR_SPEC_INDIRECT_BRANCH = 0x1 ++ PR_SPEC_L1D_FLUSH = 0x2 ++ PR_SPEC_NOT_AFFECTED = 0x0 ++ PR_SPEC_PRCTL = 0x1 ++ PR_SPEC_STORE_BYPASS = 0x0 ++ PR_SVE_GET_VL = 0x33 ++ PR_SVE_SET_VL = 0x32 ++ PR_SVE_SET_VL_ONEXEC = 0x40000 ++ PR_SVE_VL_INHERIT = 0x20000 ++ PR_SVE_VL_LEN_MASK = 0xffff ++ PR_SYS_DISPATCH_OFF = 0x0 ++ PR_SYS_DISPATCH_ON = 0x1 ++ PR_TAGGED_ADDR_ENABLE = 0x1 ++ PR_TASK_PERF_EVENTS_DISABLE = 0x1f ++ PR_TASK_PERF_EVENTS_ENABLE = 0x20 ++ PR_TIMING_STATISTICAL = 0x0 ++ PR_TIMING_TIMESTAMP = 0x1 ++ PR_TSC_ENABLE = 0x1 ++ PR_TSC_SIGSEGV = 0x2 ++ PR_UNALIGN_NOPRINT = 0x1 ++ PR_UNALIGN_SIGBUS = 0x2 ++ PSTOREFS_MAGIC = 0x6165676c ++ PTP_CLK_MAGIC = '=' ++ PTP_CLOCK_GETCAPS = 0x40503d01 ++ PTP_CLOCK_GETCAPS2 = 0x40503d0a ++ PTP_ENABLE_FEATURE = 0x1 ++ PTP_ENABLE_PPS = 0x80043d04 ++ PTP_ENABLE_PPS2 = 0x80043d0d ++ PTP_EXTTS_EDGES = 0x6 ++ PTP_EXTTS_REQUEST = 0x80103d02 ++ PTP_EXTTS_REQUEST2 = 0x80103d0b ++ PTP_EXTTS_V1_VALID_FLAGS = 0x7 ++ PTP_EXTTS_VALID_FLAGS = 0xf ++ PTP_FALLING_EDGE = 0x4 ++ PTP_MAX_SAMPLES = 0x19 ++ PTP_PEROUT_DUTY_CYCLE = 0x2 ++ PTP_PEROUT_ONE_SHOT = 0x1 ++ PTP_PEROUT_PHASE = 0x4 ++ PTP_PEROUT_REQUEST = 0x80383d03 ++ PTP_PEROUT_REQUEST2 = 0x80383d0c ++ PTP_PEROUT_V1_VALID_FLAGS = 0x0 ++ PTP_PEROUT_VALID_FLAGS = 0x7 ++ PTP_PIN_GETFUNC = 0xc0603d06 ++ PTP_PIN_GETFUNC2 = 0xc0603d0f ++ PTP_PIN_SETFUNC = 0x80603d07 ++ PTP_PIN_SETFUNC2 = 0x80603d10 ++ PTP_RISING_EDGE = 0x2 ++ PTP_STRICT_FLAGS = 0x8 ++ PTP_SYS_OFFSET = 0x83403d05 ++ PTP_SYS_OFFSET2 = 0x83403d0e ++ PTP_SYS_OFFSET_EXTENDED = 0xc4c03d09 ++ PTP_SYS_OFFSET_EXTENDED2 = 0xc4c03d12 ++ PTP_SYS_OFFSET_PRECISE = 0xc0403d08 ++ PTP_SYS_OFFSET_PRECISE2 = 0xc0403d11 ++ PTRACE_ATTACH = 0x10 ++ PTRACE_CONT = 0x7 ++ PTRACE_DETACH = 0x11 ++ PTRACE_EVENTMSG_SYSCALL_ENTRY = 0x1 ++ PTRACE_EVENTMSG_SYSCALL_EXIT = 0x2 ++ PTRACE_EVENT_CLONE = 0x3 ++ PTRACE_EVENT_EXEC = 0x4 ++ PTRACE_EVENT_EXIT = 0x6 ++ PTRACE_EVENT_FORK = 0x1 ++ PTRACE_EVENT_SECCOMP = 0x7 ++ PTRACE_EVENT_STOP = 0x80 ++ PTRACE_EVENT_VFORK = 0x2 ++ PTRACE_EVENT_VFORK_DONE = 0x5 ++ PTRACE_GETEVENTMSG = 0x4201 ++ PTRACE_GETREGS = 0xc ++ PTRACE_GETREGSET = 0x4204 ++ PTRACE_GETSIGINFO = 0x4202 ++ PTRACE_GETSIGMASK = 0x420a ++ PTRACE_GET_RSEQ_CONFIGURATION = 0x420f ++ PTRACE_GET_SYSCALL_INFO = 0x420e ++ PTRACE_GET_SYSCALL_USER_DISPATCH_CONFIG = 0x4211 ++ PTRACE_INTERRUPT = 0x4207 ++ PTRACE_KILL = 0x8 ++ PTRACE_LISTEN = 0x4208 ++ PTRACE_O_EXITKILL = 0x100000 ++ PTRACE_O_MASK = 0x3000ff ++ PTRACE_O_SUSPEND_SECCOMP = 0x200000 ++ PTRACE_O_TRACECLONE = 0x8 ++ PTRACE_O_TRACEEXEC = 0x10 ++ PTRACE_O_TRACEEXIT = 0x40 ++ PTRACE_O_TRACEFORK = 0x2 ++ PTRACE_O_TRACESECCOMP = 0x80 ++ PTRACE_O_TRACESYSGOOD = 0x1 ++ PTRACE_O_TRACEVFORK = 0x4 ++ PTRACE_O_TRACEVFORKDONE = 0x20 ++ PTRACE_PEEKDATA = 0x2 ++ PTRACE_PEEKSIGINFO = 0x4209 ++ PTRACE_PEEKSIGINFO_SHARED = 0x1 ++ PTRACE_PEEKTEXT = 0x1 ++ PTRACE_PEEKUSR = 0x3 ++ PTRACE_POKEDATA = 0x5 ++ PTRACE_POKETEXT = 0x4 ++ PTRACE_POKEUSR = 0x6 ++ PTRACE_SECCOMP_GET_FILTER = 0x420c ++ PTRACE_SECCOMP_GET_METADATA = 0x420d ++ PTRACE_SEIZE = 0x4206 ++ PTRACE_SETOPTIONS = 0x4200 ++ PTRACE_SETREGS = 0xd ++ PTRACE_SETREGSET = 0x4205 ++ PTRACE_SETSIGINFO = 0x4203 ++ PTRACE_SETSIGMASK = 0x420b ++ PTRACE_SET_SYSCALL_USER_DISPATCH_CONFIG = 0x4210 ++ PTRACE_SINGLESTEP = 0x9 ++ PTRACE_SYSCALL = 0x18 ++ PTRACE_SYSCALL_INFO_ENTRY = 0x1 ++ PTRACE_SYSCALL_INFO_EXIT = 0x2 ++ PTRACE_SYSCALL_INFO_NONE = 0x0 ++ PTRACE_SYSCALL_INFO_SECCOMP = 0x3 ++ PTRACE_TRACEME = 0x0 ++ PT_DA_MASK = 0xa4 ++ PT_DA_MATCH = 0xa3 ++ PT_DC_CTL = 0xa7 ++ PT_DV_MASK = 0xa6 ++ PT_DV_MATCH = 0xa5 ++ PT_F31_V1 = 0x62 ++ PT_F31_V2 = 0x82 ++ PT_FPCR = 0x3f ++ PT_FPREG_BASE = 0x20 ++ PT_FPREG_END = 0x3e ++ PT_IA_MASK = 0xa9 ++ PT_IA_MATCH = 0xa8 ++ PT_IDA_MASK = 0xac ++ PT_IDA_MATCH = 0xab ++ PT_IV_MATCH = 0xaa ++ PT_MATCH_CTL = 0xa7 ++ PT_PC = 0x40 ++ PT_REG_BASE = 0x0 ++ PT_REG_END = 0x1e ++ PT_TP = 0x41 ++ PT_UNIQUE = 0x41 ++ PT_VECREG_BASE = 0x43 ++ PT_VECREG_END = 0xa1 ++ P_ALL = 0x0 ++ P_PGID = 0x2 ++ P_PID = 0x1 ++ P_PIDFD = 0x3 ++ QNX4_SUPER_MAGIC = 0x2f ++ QNX6_SUPER_MAGIC = 0x68191122 ++ RAMFS_MAGIC = 0x858458f6 ++ RAW_PAYLOAD_DIGITAL = 0x3 ++ RAW_PAYLOAD_HCI = 0x2 ++ RAW_PAYLOAD_LLCP = 0x0 ++ RAW_PAYLOAD_NCI = 0x1 ++ RAW_PAYLOAD_PROPRIETARY = 0x4 ++ RDTGROUP_SUPER_MAGIC = 0x7655821 ++ REISERFS_SUPER_MAGIC = 0x52654973 ++ RENAME_EXCHANGE = 0x2 ++ RENAME_NOREPLACE = 0x1 ++ RENAME_WHITEOUT = 0x4 ++ RLIMIT_AS = 0x7 ++ RLIMIT_CORE = 0x4 ++ RLIMIT_CPU = 0x0 ++ RLIMIT_DATA = 0x2 ++ RLIMIT_FSIZE = 0x1 ++ RLIMIT_LOCKS = 0xa ++ RLIMIT_MEMLOCK = 0x9 ++ RLIMIT_MSGQUEUE = 0xc ++ RLIMIT_NICE = 0xd ++ RLIMIT_NOFILE = 0x6 ++ RLIMIT_NPROC = 0x8 ++ RLIMIT_RSS = 0x5 ++ RLIMIT_RTPRIO = 0xe ++ RLIMIT_RTTIME = 0xf ++ RLIMIT_SIGPENDING = 0xb ++ RLIMIT_STACK = 0x3 ++ RLIM_INFINITY = 0xffffffffffffffff ++ RNDADDENTROPY = 0x80085203 ++ RNDADDTOENTCNT = 0x80045201 ++ RNDCLEARPOOL = 0x20005206 ++ RNDGETENTCNT = 0x40045200 ++ RNDGETPOOL = 0x40085202 ++ RNDRESEEDCRNG = 0x20005207 ++ RNDZAPENTCNT = 0x20005204 ++ RTAX_ADVMSS = 0x8 ++ RTAX_CC_ALGO = 0x10 ++ RTAX_CWND = 0x7 ++ RTAX_FASTOPEN_NO_COOKIE = 0x11 ++ RTAX_FEATURES = 0xc ++ RTAX_FEATURE_ALLFRAG = 0x8 ++ RTAX_FEATURE_ECN = 0x1 ++ RTAX_FEATURE_MASK = 0xf ++ RTAX_FEATURE_SACK = 0x2 ++ RTAX_FEATURE_TIMESTAMP = 0x4 ++ RTAX_HOPLIMIT = 0xa ++ RTAX_INITCWND = 0xb ++ RTAX_INITRWND = 0xe ++ RTAX_LOCK = 0x1 ++ RTAX_MAX = 0x11 ++ RTAX_MTU = 0x2 ++ RTAX_QUICKACK = 0xf ++ RTAX_REORDERING = 0x9 ++ RTAX_RTO_MIN = 0xd ++ RTAX_RTT = 0x4 ++ RTAX_RTTVAR = 0x5 ++ RTAX_SSTHRESH = 0x6 ++ RTAX_UNSPEC = 0x0 ++ RTAX_WINDOW = 0x3 ++ RTA_ALIGNTO = 0x4 ++ RTA_MAX = 0x1e ++ RTCF_DIRECTSRC = 0x4000000 ++ RTCF_DOREDIRECT = 0x1000000 ++ RTCF_LOG = 0x2000000 ++ RTCF_MASQ = 0x400000 ++ RTCF_NAT = 0x800000 ++ RTCF_VALVE = 0x200000 ++ RTC_AF = 0x20 ++ RTC_AIE_OFF = 0x20007002 ++ RTC_AIE_ON = 0x20007001 ++ RTC_ALM_READ = 0x40247008 ++ RTC_ALM_SET = 0x80247007 ++ RTC_BSM_DIRECT = 0x1 ++ RTC_BSM_DISABLED = 0x0 ++ RTC_BSM_LEVEL = 0x2 ++ RTC_BSM_STANDBY = 0x3 ++ RTC_EPOCH_READ = 0x4008700d ++ RTC_EPOCH_SET = 0x8008700e ++ RTC_FEATURE_ALARM = 0x0 ++ RTC_FEATURE_ALARM_RES_2S = 0x3 ++ RTC_FEATURE_ALARM_RES_MINUTE = 0x1 ++ RTC_FEATURE_ALARM_WAKEUP_ONLY = 0x7 ++ RTC_FEATURE_BACKUP_SWITCH_MODE = 0x6 ++ RTC_FEATURE_CNT = 0x8 ++ RTC_FEATURE_CORRECTION = 0x5 ++ RTC_FEATURE_NEED_WEEK_DAY = 0x2 ++ RTC_FEATURE_UPDATE_INTERRUPT = 0x4 ++ RTC_IRQF = 0x80 ++ RTC_IRQP_READ = 0x4008700b ++ RTC_IRQP_SET = 0x8008700c ++ RTC_MAX_FREQ = 0x2000 ++ RTC_PARAM_BACKUP_SWITCH_MODE = 0x2 ++ RTC_PARAM_CORRECTION = 0x1 ++ RTC_PARAM_FEATURES = 0x0 ++ RTC_PARAM_GET = 0x80187013 ++ RTC_PARAM_SET = 0x80187014 ++ RTC_PF = 0x40 ++ RTC_PIE_OFF = 0x20007006 ++ RTC_PIE_ON = 0x20007005 ++ RTC_PLL_GET = 0x40207011 ++ RTC_PLL_SET = 0x80207012 ++ RTC_RD_TIME = 0x40247009 ++ RTC_SET_TIME = 0x8024700a ++ RTC_UF = 0x10 ++ RTC_UIE_OFF = 0x20007004 ++ RTC_UIE_ON = 0x20007003 ++ RTC_VL_CLR = 0x20007014 ++ RTC_VL_READ = 0x40047013 ++ RTC_WIE_OFF = 0x20007010 ++ RTC_WIE_ON = 0x2000700f ++ RTC_WKALM_RD = 0x40287010 ++ RTC_WKALM_SET = 0x8028700f ++ RTF_ADDRCLASSMASK = 0xf8000000 ++ RTF_ADDRCONF = 0x40000 ++ RTF_ALLONLINK = 0x20000 ++ RTF_BROADCAST = 0x10000000 ++ RTF_CACHE = 0x1000000 ++ RTF_DEFAULT = 0x10000 ++ RTF_DYNAMIC = 0x10 ++ RTF_FLOW = 0x2000000 ++ RTF_GATEWAY = 0x2 ++ RTF_HOST = 0x4 ++ RTF_INTERFACE = 0x40000000 ++ RTF_IRTT = 0x100 ++ RTF_LINKRT = 0x100000 ++ RTF_LOCAL = 0x80000000 ++ RTF_MODIFIED = 0x20 ++ RTF_MSS = 0x40 ++ RTF_MTU = 0x40 ++ RTF_MULTICAST = 0x20000000 ++ RTF_NAT = 0x8000000 ++ RTF_NOFORWARD = 0x1000 ++ RTF_NONEXTHOP = 0x200000 ++ RTF_NOPMTUDISC = 0x4000 ++ RTF_POLICY = 0x4000000 ++ RTF_REINSTATE = 0x8 ++ RTF_REJECT = 0x200 ++ RTF_STATIC = 0x400 ++ RTF_THROW = 0x2000 ++ RTF_UP = 0x1 ++ RTF_WINDOW = 0x80 ++ RTF_XRESOLVE = 0x800 ++ RTMGRP_DECnet_IFADDR = 0x1000 ++ RTMGRP_DECnet_ROUTE = 0x4000 ++ RTMGRP_IPV4_IFADDR = 0x10 ++ RTMGRP_IPV4_MROUTE = 0x20 ++ RTMGRP_IPV4_ROUTE = 0x40 ++ RTMGRP_IPV4_RULE = 0x80 ++ RTMGRP_IPV6_IFADDR = 0x100 ++ RTMGRP_IPV6_IFINFO = 0x800 ++ RTMGRP_IPV6_MROUTE = 0x200 ++ RTMGRP_IPV6_PREFIX = 0x20000 ++ RTMGRP_IPV6_ROUTE = 0x400 ++ RTMGRP_LINK = 0x1 ++ RTMGRP_NEIGH = 0x4 ++ RTMGRP_NOTIFY = 0x2 ++ RTMGRP_TC = 0x8 ++ RTM_BASE = 0x10 ++ RTM_DELACTION = 0x31 ++ RTM_DELADDR = 0x15 ++ RTM_DELADDRLABEL = 0x49 ++ RTM_DELCHAIN = 0x65 ++ RTM_DELLINK = 0x11 ++ RTM_DELLINKPROP = 0x6d ++ RTM_DELMDB = 0x55 ++ RTM_DELNEIGH = 0x1d ++ RTM_DELNETCONF = 0x51 ++ RTM_DELNEXTHOP = 0x69 ++ RTM_DELNEXTHOPBUCKET = 0x75 ++ RTM_DELNSID = 0x59 ++ RTM_DELQDISC = 0x25 ++ RTM_DELROUTE = 0x19 ++ RTM_DELRULE = 0x21 ++ RTM_DELTCLASS = 0x29 ++ RTM_DELTFILTER = 0x2d ++ RTM_DELTUNNEL = 0x79 ++ RTM_DELVLAN = 0x71 ++ RTM_F_CLONED = 0x200 ++ RTM_F_EQUALIZE = 0x400 ++ RTM_F_FIB_MATCH = 0x2000 ++ RTM_F_LOOKUP_TABLE = 0x1000 ++ RTM_F_NOTIFY = 0x100 ++ RTM_F_OFFLOAD = 0x4000 ++ RTM_F_OFFLOAD_FAILED = 0x20000000 ++ RTM_F_PREFIX = 0x800 ++ RTM_F_TRAP = 0x8000 ++ RTM_GETACTION = 0x32 ++ RTM_GETADDR = 0x16 ++ RTM_GETADDRLABEL = 0x4a ++ RTM_GETANYCAST = 0x3e ++ RTM_GETCHAIN = 0x66 ++ RTM_GETDCB = 0x4e ++ RTM_GETLINK = 0x12 ++ RTM_GETLINKPROP = 0x6e ++ RTM_GETMDB = 0x56 ++ RTM_GETMULTICAST = 0x3a ++ RTM_GETNEIGH = 0x1e ++ RTM_GETNEIGHTBL = 0x42 ++ RTM_GETNETCONF = 0x52 ++ RTM_GETNEXTHOP = 0x6a ++ RTM_GETNEXTHOPBUCKET = 0x76 ++ RTM_GETNSID = 0x5a ++ RTM_GETQDISC = 0x26 ++ RTM_GETROUTE = 0x1a ++ RTM_GETRULE = 0x22 ++ RTM_GETSTATS = 0x5e ++ RTM_GETTCLASS = 0x2a ++ RTM_GETTFILTER = 0x2e ++ RTM_GETTUNNEL = 0x7a ++ RTM_GETVLAN = 0x72 ++ RTM_MAX = 0x7b ++ RTM_NEWACTION = 0x30 ++ RTM_NEWADDR = 0x14 ++ RTM_NEWADDRLABEL = 0x48 ++ RTM_NEWCACHEREPORT = 0x60 ++ RTM_NEWCHAIN = 0x64 ++ RTM_NEWLINK = 0x10 ++ RTM_NEWLINKPROP = 0x6c ++ RTM_NEWMDB = 0x54 ++ RTM_NEWNDUSEROPT = 0x44 ++ RTM_NEWNEIGH = 0x1c ++ RTM_NEWNEIGHTBL = 0x40 ++ RTM_NEWNETCONF = 0x50 ++ RTM_NEWNEXTHOP = 0x68 ++ RTM_NEWNEXTHOPBUCKET = 0x74 ++ RTM_NEWNSID = 0x58 ++ RTM_NEWNVLAN = 0x70 ++ RTM_NEWPREFIX = 0x34 ++ RTM_NEWQDISC = 0x24 ++ RTM_NEWROUTE = 0x18 ++ RTM_NEWRULE = 0x20 ++ RTM_NEWSTATS = 0x5c ++ RTM_NEWTCLASS = 0x28 ++ RTM_NEWTFILTER = 0x2c ++ RTM_NEWTUNNEL = 0x78 ++ RTM_NR_FAMILIES = 0x1b ++ RTM_NR_MSGTYPES = 0x6c ++ RTM_SETDCB = 0x4f ++ RTM_SETLINK = 0x13 ++ RTM_SETNEIGHTBL = 0x43 ++ RTM_SETSTATS = 0x5f ++ RTNH_ALIGNTO = 0x4 ++ RTNH_COMPARE_MASK = 0x59 ++ RTNH_F_DEAD = 0x1 ++ RTNH_F_LINKDOWN = 0x10 ++ RTNH_F_OFFLOAD = 0x8 ++ RTNH_F_ONLINK = 0x4 ++ RTNH_F_PERVASIVE = 0x2 ++ RTNH_F_TRAP = 0x40 ++ RTNH_F_UNRESOLVED = 0x20 ++ RTN_MAX = 0xb ++ RTPROT_BABEL = 0x2a ++ RTPROT_BGP = 0xba ++ RTPROT_BIRD = 0xc ++ RTPROT_BOOT = 0x3 ++ RTPROT_DHCP = 0x10 ++ RTPROT_DNROUTED = 0xd ++ RTPROT_EIGRP = 0xc0 ++ RTPROT_GATED = 0x8 ++ RTPROT_ISIS = 0xbb ++ RTPROT_KEEPALIVED = 0x12 ++ RTPROT_KERNEL = 0x2 ++ RTPROT_MROUTED = 0x11 ++ RTPROT_MRT = 0xa ++ RTPROT_NTK = 0xf ++ RTPROT_OPENR = 0x63 ++ RTPROT_OSPF = 0xbc ++ RTPROT_RA = 0x9 ++ RTPROT_REDIRECT = 0x1 ++ RTPROT_RIP = 0xbd ++ RTPROT_STATIC = 0x4 ++ RTPROT_UNSPEC = 0x0 ++ RTPROT_XORP = 0xe ++ RTPROT_ZEBRA = 0xb ++ RT_CLASS_DEFAULT = 0xfd ++ RT_CLASS_LOCAL = 0xff ++ RT_CLASS_MAIN = 0xfe ++ RT_CLASS_MAX = 0xff ++ RT_CLASS_UNSPEC = 0x0 ++ RUSAGE_CHILDREN = -0x1 ++ RUSAGE_SELF = 0x0 ++ RUSAGE_THREAD = 0x1 ++ RWF_APPEND = 0x10 ++ RWF_DSYNC = 0x2 ++ RWF_HIPRI = 0x1 ++ RWF_NOWAIT = 0x8 ++ RWF_SUPPORTED = 0x1f ++ RWF_SYNC = 0x4 ++ RWF_WRITE_LIFE_NOT_SET = 0x0 ++ SCHED_BATCH = 0x3 ++ SCHED_DEADLINE = 0x6 ++ SCHED_FIFO = 0x1 ++ SCHED_FLAG_ALL = 0x7f ++ SCHED_FLAG_DL_OVERRUN = 0x4 ++ SCHED_FLAG_KEEP_ALL = 0x18 ++ SCHED_FLAG_KEEP_PARAMS = 0x10 ++ SCHED_FLAG_KEEP_POLICY = 0x8 ++ SCHED_FLAG_RECLAIM = 0x2 ++ SCHED_FLAG_RESET_ON_FORK = 0x1 ++ SCHED_FLAG_UTIL_CLAMP = 0x60 ++ SCHED_FLAG_UTIL_CLAMP_MAX = 0x40 ++ SCHED_FLAG_UTIL_CLAMP_MIN = 0x20 ++ SCHED_IDLE = 0x5 ++ SCHED_NORMAL = 0x0 ++ SCHED_RESET_ON_FORK = 0x40000000 ++ SCHED_RR = 0x2 ++ SCM_CREDENTIALS = 0x2 ++ SCM_RIGHTS = 0x1 ++ SCM_TIMESTAMP = 0x1d ++ SCM_TIMESTAMPING = 0x25 ++ SCM_TIMESTAMPING_OPT_STATS = 0x36 ++ SCM_TIMESTAMPING_PKTINFO = 0x3a ++ SCM_TIMESTAMPNS = 0x23 ++ SCM_TXTIME = 0x3d ++ SCM_WIFI_STATUS = 0x29 ++ SC_LOG_FLUSH = 0x100000 ++ SECCOMP_ADDFD_FLAG_SEND = 0x2 ++ SECCOMP_ADDFD_FLAG_SETFD = 0x1 ++ SECCOMP_FILTER_FLAG_LOG = 0x2 ++ SECCOMP_FILTER_FLAG_NEW_LISTENER = 0x8 ++ SECCOMP_FILTER_FLAG_SPEC_ALLOW = 0x4 ++ SECCOMP_FILTER_FLAG_TSYNC = 0x1 ++ SECCOMP_FILTER_FLAG_TSYNC_ESRCH = 0x10 ++ SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV = 0x20 ++ SECCOMP_GET_ACTION_AVAIL = 0x2 ++ SECCOMP_GET_NOTIF_SIZES = 0x3 ++ SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 ++ SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102 ++ SECCOMP_IOCTL_NOTIF_RECV = 0xc0502100 ++ SECCOMP_IOCTL_NOTIF_SEND = 0xc0182101 ++ SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104 ++ SECCOMP_IOC_MAGIC = '!' ++ SECCOMP_MODE_DISABLED = 0x0 ++ SECCOMP_MODE_FILTER = 0x2 ++ SECCOMP_MODE_STRICT = 0x1 ++ SECCOMP_RET_ACTION = 0x7fff0000 ++ SECCOMP_RET_ACTION_FULL = 0xffff0000 ++ SECCOMP_RET_ALLOW = 0x7fff0000 ++ SECCOMP_RET_DATA = 0xffff ++ SECCOMP_RET_ERRNO = 0x50000 ++ SECCOMP_RET_KILL = 0x0 ++ SECCOMP_RET_KILL_PROCESS = 0x80000000 ++ SECCOMP_RET_KILL_THREAD = 0x0 ++ SECCOMP_RET_LOG = 0x7ffc0000 ++ SECCOMP_RET_TRACE = 0x7ff00000 ++ SECCOMP_RET_TRAP = 0x30000 ++ SECCOMP_RET_USER_NOTIF = 0x7fc00000 ++ SECCOMP_SET_MODE_FILTER = 0x1 ++ SECCOMP_SET_MODE_STRICT = 0x0 ++ SECCOMP_USER_NOTIF_FD_SYNC_WAKE_UP = 0x1 ++ SECCOMP_USER_NOTIF_FLAG_CONTINUE = 0x1 ++ SECRETMEM_MAGIC = 0x5345434d ++ SECURITYFS_MAGIC = 0x73636673 ++ SEEK_CUR = 0x1 ++ SEEK_DATA = 0x3 ++ SEEK_END = 0x2 ++ SEEK_HOLE = 0x4 ++ SEEK_MAX = 0x4 ++ SEEK_SET = 0x0 ++ SELINUX_MAGIC = 0xf97cff8c ++ SFD_CLOEXEC = 0x200000 ++ SFD_NONBLOCK = 0x4 ++ SHUT_RD = 0x0 ++ SHUT_RDWR = 0x2 ++ SHUT_WR = 0x1 ++ SIOCADDDLCI = 0x8980 ++ SIOCADDMULTI = 0x8931 ++ SIOCADDRT = 0x890b ++ SIOCATMARK = 0x40047307 ++ SIOCBONDCHANGEACTIVE = 0x8995 ++ SIOCBONDENSLAVE = 0x8990 ++ SIOCBONDINFOQUERY = 0x8994 ++ SIOCBONDRELEASE = 0x8991 ++ SIOCBONDSETHWADDR = 0x8992 ++ SIOCBONDSLAVEINFOQUERY = 0x8993 ++ SIOCBRADDBR = 0x89a0 ++ SIOCBRADDIF = 0x89a2 ++ SIOCBRDELBR = 0x89a1 ++ SIOCBRDELIF = 0x89a3 ++ SIOCDARP = 0x8953 ++ SIOCDELDLCI = 0x8981 ++ SIOCDELMULTI = 0x8932 ++ SIOCDELRT = 0x890c ++ SIOCDEVPRIVATE = 0x89f0 ++ SIOCDIFADDR = 0x8936 ++ SIOCDRARP = 0x8960 ++ SIOCETHTOOL = 0x8946 ++ SIOCGARP = 0x8954 ++ SIOCGETLINKNAME = 0x89e0 ++ SIOCGETNODEID = 0x89e1 ++ SIOCGHWTSTAMP = 0x89b1 ++ SIOCGIFADDR = 0x8915 ++ SIOCGIFBR = 0x8940 ++ SIOCGIFBRDADDR = 0x8919 ++ SIOCGIFCONF = 0x8912 ++ SIOCGIFCOUNT = 0x8938 ++ SIOCGIFDSTADDR = 0x8917 ++ SIOCGIFENCAP = 0x8925 ++ SIOCGIFFLAGS = 0x8913 ++ SIOCGIFHWADDR = 0x8927 ++ SIOCGIFINDEX = 0x8933 ++ SIOCGIFMAP = 0x8970 ++ SIOCGIFMEM = 0x891f ++ SIOCGIFMETRIC = 0x891d ++ SIOCGIFMTU = 0x8921 ++ SIOCGIFNAME = 0x8910 ++ SIOCGIFNETMASK = 0x891b ++ SIOCGIFPFLAGS = 0x8935 ++ SIOCGIFSLAVE = 0x8929 ++ SIOCGIFTXQLEN = 0x8942 ++ SIOCGIFVLAN = 0x8982 ++ SIOCGMIIPHY = 0x8947 ++ SIOCGMIIREG = 0x8948 ++ SIOCGPGRP = 0x40047309 ++ SIOCGPPPCSTATS = 0x89f2 ++ SIOCGPPPSTATS = 0x89f0 ++ SIOCGPPPVER = 0x89f1 ++ SIOCGRARP = 0x8961 ++ SIOCGSKNS = 0x894c ++ SIOCGSTAMP = 0x8906 ++ SIOCGSTAMPNS = 0x8907 ++ SIOCGSTAMPNS_NEW = 0x40108907 ++ SIOCGSTAMPNS_OLD = 0x8907 ++ SIOCGSTAMP_NEW = 0x40108906 ++ SIOCGSTAMP_OLD = 0x8906 ++ SIOCINQ = 0x4004667f ++ SIOCKCMATTACH = 0x89e0 ++ SIOCKCMCLONE = 0x89e2 ++ SIOCKCMUNATTACH = 0x89e1 ++ SIOCOUTQ = 0x40047473 ++ SIOCOUTQNSD = 0x894b ++ SIOCPROTOPRIVATE = 0x89e0 ++ SIOCRTMSG = 0x890d ++ SIOCSARP = 0x8955 ++ SIOCSHWTSTAMP = 0x89b0 ++ SIOCSIFADDR = 0x8916 ++ SIOCSIFBR = 0x8941 ++ SIOCSIFBRDADDR = 0x891a ++ SIOCSIFDSTADDR = 0x8918 ++ SIOCSIFENCAP = 0x8926 ++ SIOCSIFFLAGS = 0x8914 ++ SIOCSIFHWADDR = 0x8924 ++ SIOCSIFHWBROADCAST = 0x8937 ++ SIOCSIFLINK = 0x8911 ++ SIOCSIFMAP = 0x8971 ++ SIOCSIFMEM = 0x8920 ++ SIOCSIFMETRIC = 0x891e ++ SIOCSIFMTU = 0x8922 ++ SIOCSIFNAME = 0x8923 ++ SIOCSIFNETMASK = 0x891c ++ SIOCSIFPFLAGS = 0x8934 ++ SIOCSIFSLAVE = 0x8930 ++ SIOCSIFTXQLEN = 0x8943 ++ SIOCSIFVLAN = 0x8983 ++ SIOCSMIIREG = 0x8949 ++ SIOCSPGRP = 0x80047308 ++ SIOCSRARP = 0x8962 ++ SIOCWANDEV = 0x894a ++ SK_DIAG_BPF_STORAGE_MAX = 0x3 ++ SK_DIAG_BPF_STORAGE_REQ_MAX = 0x1 ++ SMACK_MAGIC = 0x43415d53 ++ SMART_AUTOSAVE = 0xd2 ++ SMART_AUTO_OFFLINE = 0xdb ++ SMART_DISABLE = 0xd9 ++ SMART_ENABLE = 0xd8 ++ SMART_HCYL_PASS = 0xc2 ++ SMART_IMMEDIATE_OFFLINE = 0xd4 ++ SMART_LCYL_PASS = 0x4f ++ SMART_READ_LOG_SECTOR = 0xd5 ++ SMART_READ_THRESHOLDS = 0xd1 ++ SMART_READ_VALUES = 0xd0 ++ SMART_SAVE = 0xd3 ++ SMART_STATUS = 0xda ++ SMART_WRITE_LOG_SECTOR = 0xd6 ++ SMART_WRITE_THRESHOLDS = 0xd7 ++ SMB2_SUPER_MAGIC = 0xfe534d42 ++ SMB_SUPER_MAGIC = 0x517b ++ SOCKFS_MAGIC = 0x534f434b ++ SOCK_BUF_LOCK_MASK = 0x3 ++ SOCK_CLOEXEC = 0x200000 ++ SOCK_DCCP = 0x6 ++ SOCK_DESTROY = 0x15 ++ SOCK_DGRAM = 0x2 ++ SOCK_DIAG_BY_FAMILY = 0x14 ++ SOCK_IOC_TYPE = 0x89 ++ SOCK_NONBLOCK = 0x40000000 ++ SOCK_PACKET = 0xa ++ SOCK_RAW = 0x3 ++ SOCK_RCVBUF_LOCK = 0x2 ++ SOCK_RDM = 0x4 ++ SOCK_SEQPACKET = 0x5 ++ SOCK_SNDBUF_LOCK = 0x1 ++ SOCK_STREAM = 0x1 ++ SOCK_TXREHASH_DEFAULT = 0xff ++ SOCK_TXREHASH_DISABLED = 0x0 ++ SOCK_TXREHASH_ENABLED = 0x1 ++ SOL_AAL = 0x109 ++ SOL_ALG = 0x117 ++ SOL_ATM = 0x108 ++ SOL_CAIF = 0x116 ++ SOL_CAN_BASE = 0x64 ++ SOL_CAN_RAW = 0x65 ++ SOL_DCCP = 0x10d ++ SOL_DECNET = 0x105 ++ SOL_ICMPV6 = 0x3a ++ SOL_IP = 0x0 ++ SOL_IPV6 = 0x29 ++ SOL_IRDA = 0x10a ++ SOL_IUCV = 0x115 ++ SOL_KCM = 0x119 ++ SOL_LLC = 0x10c ++ SOL_MCTP = 0x11d ++ SOL_MPTCP = 0x11c ++ SOL_NETBEUI = 0x10b ++ SOL_NETLINK = 0x10e ++ SOL_NFC = 0x118 ++ SOL_PACKET = 0x107 ++ SOL_PNPIPE = 0x113 ++ SOL_PPPOL2TP = 0x111 ++ SOL_RAW = 0xff ++ SOL_RDS = 0x114 ++ SOL_RXRPC = 0x110 ++ SOL_SMC = 0x11e ++ SOL_SOCKET = 0xffff ++ SOL_TCP = 0x6 ++ SOL_TIPC = 0x10f ++ SOL_TLS = 0x11a ++ SOL_UDP = 0x11 ++ SOL_X25 = 0x106 ++ SOL_XDP = 0x11b ++ SOMAXCONN = 0x1000 ++ SO_ACCEPTCONN = 0x1014 ++ SO_ATTACH_BPF = 0x32 ++ SO_ATTACH_FILTER = 0x1a ++ SO_ATTACH_REUSEPORT_CBPF = 0x33 ++ SO_ATTACH_REUSEPORT_EBPF = 0x34 ++ SO_BINDTODEVICE = 0x19 ++ SO_BINDTOIFINDEX = 0x3e ++ SO_BPF_EXTENSIONS = 0x30 ++ SO_BROADCAST = 0x20 ++ SO_BSDCOMPAT = 0xe ++ SO_BUF_LOCK = 0x48 ++ SO_BUSY_POLL = 0x2e ++ SO_BUSY_POLL_BUDGET = 0x46 ++ SO_CNX_ADVICE = 0x35 ++ SO_COOKIE = 0x39 ++ SO_DEBUG = 0x1 ++ SO_DETACH_BPF = 0x1b ++ SO_DETACH_FILTER = 0x1b ++ SO_DETACH_REUSEPORT_BPF = 0x44 ++ SO_DOMAIN = 0x1029 ++ SO_DONTROUTE = 0x10 ++ SO_EE_CODE_TXTIME_INVALID_PARAM = 0x1 ++ SO_EE_CODE_TXTIME_MISSED = 0x2 ++ SO_EE_CODE_ZEROCOPY_COPIED = 0x1 ++ SO_EE_ORIGIN_ICMP = 0x2 ++ SO_EE_ORIGIN_ICMP6 = 0x3 ++ SO_EE_ORIGIN_LOCAL = 0x1 ++ SO_EE_ORIGIN_NONE = 0x0 ++ SO_EE_ORIGIN_TIMESTAMPING = 0x4 ++ SO_EE_ORIGIN_TXSTATUS = 0x4 ++ SO_EE_ORIGIN_TXTIME = 0x6 ++ SO_EE_ORIGIN_ZEROCOPY = 0x5 ++ SO_EE_RFC4884_FLAG_INVALID = 0x1 ++ SO_ERROR = 0x1007 ++ SO_GET_FILTER = 0x1a ++ SO_INCOMING_CPU = 0x31 ++ SO_INCOMING_NAPI_ID = 0x38 ++ SO_KEEPALIVE = 0x8 ++ SO_LINGER = 0x80 ++ SO_LOCK_FILTER = 0x2c ++ SO_MARK = 0x24 ++ SO_MAX_PACING_RATE = 0x2f ++ SO_MEMINFO = 0x37 ++ SO_NETNS_COOKIE = 0x47 ++ SO_NOFCS = 0x2b ++ SO_NO_CHECK = 0xb ++ SO_OOBINLINE = 0x100 ++ SO_PASSCRED = 0x11 ++ SO_PASSPIDFD = 0x4c ++ SO_PASSSEC = 0x22 ++ SO_PEEK_OFF = 0x2a ++ SO_PEERCRED = 0x12 ++ SO_PEERGROUPS = 0x3b ++ SO_PEERNAME = 0x1c ++ SO_PEERPIDFD = 0x4d ++ SO_PEERSEC = 0x1e ++ SO_PREFER_BUSY_POLL = 0x45 ++ SO_PRIORITY = 0xc ++ SO_PROTOCOL = 0x1028 ++ SO_RCVBUF = 0x1002 ++ SO_RCVBUFFORCE = 0x100b ++ SO_RCVLOWAT = 0x1010 ++ SO_RCVMARK = 0x4b ++ SO_RCVTIMEO = 0x1012 ++ SO_RCVTIMEO_NEW = 0x42 ++ SO_RCVTIMEO_OLD = 0x1012 ++ SO_RESERVE_MEM = 0x49 ++ SO_REUSEADDR = 0x4 ++ SO_REUSEPORT = 0x200 ++ SO_RXQ_OVFL = 0x28 ++ SO_SECURITY_AUTHENTICATION = 0x13 ++ SO_SECURITY_ENCRYPTION_NETWORK = 0x15 ++ SO_SECURITY_ENCRYPTION_TRANSPORT = 0x14 ++ SO_SELECT_ERR_QUEUE = 0x2d ++ SO_SNDBUF = 0x1001 ++ SO_SNDBUFFORCE = 0x100a ++ SO_SNDLOWAT = 0x1011 ++ SO_SNDTIMEO = 0x1013 ++ SO_SNDTIMEO_NEW = 0x43 ++ SO_SNDTIMEO_OLD = 0x1013 ++ SO_TIMESTAMP = 0x1d ++ SO_TIMESTAMPING = 0x25 ++ SO_TIMESTAMPING_NEW = 0x41 ++ SO_TIMESTAMPING_OLD = 0x25 ++ SO_TIMESTAMPNS = 0x23 ++ SO_TIMESTAMPNS_NEW = 0x40 ++ SO_TIMESTAMPNS_OLD = 0x23 ++ SO_TIMESTAMP_NEW = 0x3f ++ SO_TIMESTAMP_OLD = 0x1d ++ SO_TXREHASH = 0x4a ++ SO_TXTIME = 0x3d ++ SO_TYPE = 0x1008 ++ SO_VM_SOCKETS_BUFFER_MAX_SIZE = 0x2 ++ SO_VM_SOCKETS_BUFFER_MIN_SIZE = 0x1 ++ SO_VM_SOCKETS_BUFFER_SIZE = 0x0 ++ SO_VM_SOCKETS_CONNECT_TIMEOUT = 0x6 ++ SO_VM_SOCKETS_CONNECT_TIMEOUT_NEW = 0x8 ++ SO_VM_SOCKETS_CONNECT_TIMEOUT_OLD = 0x6 ++ SO_VM_SOCKETS_NONBLOCK_TXRX = 0x7 ++ SO_VM_SOCKETS_PEER_HOST_VM_ID = 0x3 ++ SO_VM_SOCKETS_TRUSTED = 0x5 ++ SO_WIFI_STATUS = 0x29 ++ SO_ZEROCOPY = 0x3c ++ SPLICE_F_GIFT = 0x8 ++ SPLICE_F_MORE = 0x4 ++ SPLICE_F_MOVE = 0x1 ++ SPLICE_F_NONBLOCK = 0x2 ++ SQUASHFS_MAGIC = 0x73717368 ++ STACK_END_MAGIC = 0x57ac6e9d ++ STATX_ALL = 0xfff ++ STATX_ATIME = 0x20 ++ STATX_ATTR_APPEND = 0x20 ++ STATX_ATTR_AUTOMOUNT = 0x1000 ++ STATX_ATTR_COMPRESSED = 0x4 ++ STATX_ATTR_DAX = 0x200000 ++ STATX_ATTR_ENCRYPTED = 0x800 ++ STATX_ATTR_IMMUTABLE = 0x10 ++ STATX_ATTR_MOUNT_ROOT = 0x2000 ++ STATX_ATTR_NODUMP = 0x40 ++ STATX_ATTR_VERITY = 0x100000 ++ STATX_BASIC_STATS = 0x7ff ++ STATX_BLOCKS = 0x400 ++ STATX_BTIME = 0x800 ++ STATX_CTIME = 0x80 ++ STATX_DIOALIGN = 0x2000 ++ STATX_GID = 0x10 ++ STATX_INO = 0x100 ++ STATX_MNT_ID = 0x1000 ++ STATX_MODE = 0x2 ++ STATX_MTIME = 0x40 ++ STATX_NLINK = 0x4 ++ STATX_SIZE = 0x200 ++ STATX_TYPE = 0x1 ++ STATX_UID = 0x8 ++ STATX__RESERVED = 0x80000000 ++ SYNC_FILE_RANGE_WAIT_AFTER = 0x4 ++ SYNC_FILE_RANGE_WAIT_BEFORE = 0x1 ++ SYNC_FILE_RANGE_WRITE = 0x2 ++ SYNC_FILE_RANGE_WRITE_AND_WAIT = 0x7 ++ SYSFS_MAGIC = 0x62656572 ++ S_BLKSIZE = 0x200 ++ S_IEXEC = 0x40 ++ S_IFBLK = 0x6000 ++ S_IFCHR = 0x2000 ++ S_IFDIR = 0x4000 ++ S_IFIFO = 0x1000 ++ S_IFLNK = 0xa000 ++ S_IFMT = 0xf000 ++ S_IFREG = 0x8000 ++ S_IFSOCK = 0xc000 ++ S_IREAD = 0x100 ++ S_IRGRP = 0x20 ++ S_IROTH = 0x4 ++ S_IRUSR = 0x100 ++ S_IRWXG = 0x38 ++ S_IRWXO = 0x7 ++ S_IRWXU = 0x1c0 ++ S_ISGID = 0x400 ++ S_ISUID = 0x800 ++ S_ISVTX = 0x200 ++ S_IWGRP = 0x10 ++ S_IWOTH = 0x2 ++ S_IWRITE = 0x80 ++ S_IWUSR = 0x80 ++ S_IXGRP = 0x8 ++ S_IXOTH = 0x1 ++ S_IXUSR = 0x40 ++ TAB0 = 0x0 ++ TAB1 = 0x400 ++ TAB2 = 0x800 ++ TAB3 = 0xc00 ++ TABDLY = 0xc00 ++ TASKSTATS_CMD_ATTR_MAX = 0x4 ++ TASKSTATS_CMD_MAX = 0x2 ++ TASKSTATS_GENL_NAME = "TASKSTATS" ++ TASKSTATS_GENL_VERSION = 0x1 ++ TASKSTATS_TYPE_MAX = 0x6 ++ TASKSTATS_VERSION = 0xe ++ TCFLSH = 0x2000741f ++ TCGETA = 0x40127417 ++ TCGETS = 0x402c7413 ++ TCGETS2 = 0x402c542a ++ TCIFLUSH = 0x0 ++ TCIOFF = 0x2 ++ TCIOFLUSH = 0x2 ++ TCION = 0x3 ++ TCOFLUSH = 0x1 ++ TCOOFF = 0x0 ++ TCOON = 0x1 ++ TCPOPT_EOL = 0x0 ++ TCPOPT_MAXSEG = 0x2 ++ TCPOPT_NOP = 0x1 ++ TCPOPT_SACK = 0x5 ++ TCPOPT_SACK_PERMITTED = 0x4 ++ TCPOPT_TIMESTAMP = 0x8 ++ TCPOPT_TSTAMP_HDR = 0x101080a ++ TCPOPT_WINDOW = 0x3 ++ TCP_CC_INFO = 0x1a ++ TCP_CM_INQ = 0x24 ++ TCP_CONGESTION = 0xd ++ TCP_COOKIE_IN_ALWAYS = 0x1 ++ TCP_COOKIE_MAX = 0x10 ++ TCP_COOKIE_MIN = 0x8 ++ TCP_COOKIE_OUT_NEVER = 0x2 ++ TCP_COOKIE_PAIR_SIZE = 0x20 ++ TCP_COOKIE_TRANSACTIONS = 0xf ++ TCP_CORK = 0x3 ++ TCP_DEFER_ACCEPT = 0x9 ++ TCP_FASTOPEN = 0x17 ++ TCP_FASTOPEN_CONNECT = 0x1e ++ TCP_FASTOPEN_KEY = 0x21 ++ TCP_FASTOPEN_NO_COOKIE = 0x22 ++ TCP_INFO = 0xb ++ TCP_INQ = 0x24 ++ TCP_KEEPCNT = 0x6 ++ TCP_KEEPIDLE = 0x4 ++ TCP_KEEPINTVL = 0x5 ++ TCP_LINGER2 = 0x8 ++ TCP_MAXSEG = 0x2 ++ TCP_MAXWIN = 0xffff ++ TCP_MAX_WINSHIFT = 0xe ++ TCP_MD5SIG = 0xe ++ TCP_MD5SIG_EXT = 0x20 ++ TCP_MD5SIG_FLAG_PREFIX = 0x1 ++ TCP_MD5SIG_MAXKEYLEN = 0x50 ++ TCP_MSS = 0x200 ++ TCP_MSS_DEFAULT = 0x218 ++ TCP_MSS_DESIRED = 0x4c4 ++ TCP_NODELAY = 0x1 ++ TCP_NOTSENT_LOWAT = 0x19 ++ TCP_QUEUE_SEQ = 0x15 ++ TCP_QUICKACK = 0xc ++ TCP_REPAIR = 0x13 ++ TCP_REPAIR_OFF = 0x0 ++ TCP_REPAIR_OFF_NO_WP = -0x1 ++ TCP_REPAIR_ON = 0x1 ++ TCP_REPAIR_OPTIONS = 0x16 ++ TCP_REPAIR_QUEUE = 0x14 ++ TCP_REPAIR_WINDOW = 0x1d ++ TCP_SAVED_SYN = 0x1c ++ TCP_SAVE_SYN = 0x1b ++ TCP_SYNCNT = 0x7 ++ TCP_S_DATA_IN = 0x4 ++ TCP_S_DATA_OUT = 0x8 ++ TCP_THIN_DUPACK = 0x11 ++ TCP_THIN_LINEAR_TIMEOUTS = 0x10 ++ TCP_TIMESTAMP = 0x18 ++ TCP_TX_DELAY = 0x25 ++ TCP_ULP = 0x1f ++ TCP_USER_TIMEOUT = 0x12 ++ TCP_V4_FLOW = 0x1 ++ TCP_V6_FLOW = 0x5 ++ TCP_WINDOW_CLAMP = 0xa ++ TCP_ZEROCOPY_RECEIVE = 0x23 ++ TCSAFLUSH = 0x2 ++ TCSBRK = 0x2000741d ++ TCSBRKP = 0x5425 ++ TCSETA = 0x80127418 ++ TCSETAF = 0x8012741c ++ TCSETAW = 0x80127419 ++ TCSETS = 0x802c7414 ++ TCSETS2 = 0x802c542b ++ TCSETSF = 0x802c7416 ++ TCSETSF2 = 0x802c542d ++ TCSETSW = 0x802c7415 ++ TCSETSW2 = 0x802c542c ++ TCXONC = 0x2000741e ++ TFD_CLOEXEC = 0x200000 ++ TFD_NONBLOCK = 0x4 ++ TFD_TIMER_ABSTIME = 0x1 ++ TFD_TIMER_CANCEL_ON_SET = 0x2 ++ TIMER_ABSTIME = 0x1 ++ TIOCCBRK = 0x5428 ++ TIOCCONS = 0x541d ++ TIOCEXCL = 0x540c ++ TIOCGDEV = 0x40045432 ++ TIOCGETD = 0x5424 ++ TIOCGEXCL = 0x40045440 ++ TIOCGICOUNT = 0x545d ++ TIOCGLCKTRMIOS = 0x5456 ++ TIOCGPGRP = 0x40047477 ++ TIOCGPKT = 0x40045438 ++ TIOCGPTLCK = 0x40045439 ++ TIOCGPTN = 0x40045430 ++ TIOCGPTPEER = 0x20005441 ++ TIOCGSERIAL = 0x541e ++ TIOCGSID = 0x5429 ++ TIOCGSOFTCAR = 0x5419 ++ TIOCLINUX = 0x541c ++ TIOCMBIC = 0x5417 ++ TIOCMBIS = 0x5416 ++ TIOCMGET = 0x5415 ++ TIOCMIWAIT = 0x545c ++ TIOCMSET = 0x5418 ++ TIOCM_CAR = 0x40 ++ TIOCM_CD = 0x40 ++ TIOCM_CTS = 0x20 ++ TIOCM_DSR = 0x100 ++ TIOCM_DTR = 0x2 ++ TIOCM_LE = 0x1 ++ TIOCM_LOOP = 0x8000 ++ TIOCM_OUT1 = 0x2000 ++ TIOCM_OUT2 = 0x4000 ++ TIOCM_RI = 0x80 ++ TIOCM_RNG = 0x80 ++ TIOCM_RTS = 0x4 ++ TIOCM_SR = 0x10 ++ TIOCM_ST = 0x8 ++ TIOCNOTTY = 0x5422 ++ TIOCNXCL = 0x540d ++ TIOCOUTQ = 0x40047473 ++ TIOCPKT = 0x5420 ++ TIOCPKT_DATA = 0x0 ++ TIOCPKT_DOSTOP = 0x20 ++ TIOCPKT_FLUSHREAD = 0x1 ++ TIOCPKT_FLUSHWRITE = 0x2 ++ TIOCPKT_IOCTL = 0x40 ++ TIOCPKT_NOSTOP = 0x10 ++ TIOCPKT_START = 0x8 ++ TIOCPKT_STOP = 0x4 ++ TIOCSBRK = 0x5427 ++ TIOCSCTTY = 0x540e ++ TIOCSERCONFIG = 0x5453 ++ TIOCSERGETLSR = 0x5459 ++ TIOCSERGETMULTI = 0x545a ++ TIOCSERGSTRUCT = 0x5458 ++ TIOCSERGWILD = 0x5454 ++ TIOCSERSETMULTI = 0x545b ++ TIOCSERSWILD = 0x5455 ++ TIOCSER_TEMT = 0x1 ++ TIOCSETD = 0x5423 ++ TIOCSIG = 0x80045436 ++ TIOCSLCKTRMIOS = 0x5457 ++ TIOCSPGRP = 0x80047476 ++ TIOCSPTLCK = 0x80045431 ++ TIOCSSERIAL = 0x541f ++ TIOCSSOFTCAR = 0x541a ++ TIOCSTART = 0x2000746e ++ TIOCSTI = 0x5412 ++ TIOCSTOP = 0x2000746f ++ TIOCVHANGUP = 0x5437 ++ TIPC_ADDR_ID = 0x3 ++ TIPC_ADDR_MCAST = 0x1 ++ TIPC_ADDR_NAME = 0x2 ++ TIPC_ADDR_NAMESEQ = 0x1 ++ TIPC_AEAD_ALG_NAME = 0x20 ++ TIPC_AEAD_KEYLEN_MAX = 0x24 ++ TIPC_AEAD_KEYLEN_MIN = 0x14 ++ TIPC_AEAD_KEY_SIZE_MAX = 0x48 ++ TIPC_CFG_SRV = 0x0 ++ TIPC_CLUSTER_BITS = 0xc ++ TIPC_CLUSTER_MASK = 0xfff000 ++ TIPC_CLUSTER_OFFSET = 0xc ++ TIPC_CLUSTER_SIZE = 0xfff ++ TIPC_CONN_SHUTDOWN = 0x5 ++ TIPC_CONN_TIMEOUT = 0x82 ++ TIPC_CRITICAL_IMPORTANCE = 0x3 ++ TIPC_DESTNAME = 0x3 ++ TIPC_DEST_DROPPABLE = 0x81 ++ TIPC_ERRINFO = 0x1 ++ TIPC_ERR_NO_NAME = 0x1 ++ TIPC_ERR_NO_NODE = 0x3 ++ TIPC_ERR_NO_PORT = 0x2 ++ TIPC_ERR_OVERLOAD = 0x4 ++ TIPC_GROUP_JOIN = 0x87 ++ TIPC_GROUP_LEAVE = 0x88 ++ TIPC_GROUP_LOOPBACK = 0x1 ++ TIPC_GROUP_MEMBER_EVTS = 0x2 ++ TIPC_HIGH_IMPORTANCE = 0x2 ++ TIPC_IMPORTANCE = 0x7f ++ TIPC_LINK_STATE = 0x2 ++ TIPC_LOW_IMPORTANCE = 0x0 ++ TIPC_MAX_BEARER_NAME = 0x20 ++ TIPC_MAX_IF_NAME = 0x10 ++ TIPC_MAX_LINK_NAME = 0x44 ++ TIPC_MAX_MEDIA_NAME = 0x10 ++ TIPC_MAX_USER_MSG_SIZE = 0x101d0 ++ TIPC_MCAST_BROADCAST = 0x85 ++ TIPC_MCAST_REPLICAST = 0x86 ++ TIPC_MEDIUM_IMPORTANCE = 0x1 ++ TIPC_NODEID_LEN = 0x10 ++ TIPC_NODELAY = 0x8a ++ TIPC_NODE_BITS = 0xc ++ TIPC_NODE_MASK = 0xfff ++ TIPC_NODE_OFFSET = 0x0 ++ TIPC_NODE_RECVQ_DEPTH = 0x83 ++ TIPC_NODE_SIZE = 0xfff ++ TIPC_NODE_STATE = 0x0 ++ TIPC_OK = 0x0 ++ TIPC_PUBLISHED = 0x1 ++ TIPC_REKEYING_NOW = 0xffffffff ++ TIPC_RESERVED_TYPES = 0x40 ++ TIPC_RETDATA = 0x2 ++ TIPC_SERVICE_ADDR = 0x2 ++ TIPC_SERVICE_RANGE = 0x1 ++ TIPC_SOCKET_ADDR = 0x3 ++ TIPC_SOCK_RECVQ_DEPTH = 0x84 ++ TIPC_SOCK_RECVQ_USED = 0x89 ++ TIPC_SRC_DROPPABLE = 0x80 ++ TIPC_SUBSCR_TIMEOUT = 0x3 ++ TIPC_SUB_CANCEL = 0x4 ++ TIPC_SUB_PORTS = 0x1 ++ TIPC_SUB_SERVICE = 0x2 ++ TIPC_TOP_SRV = 0x1 ++ TIPC_WAIT_FOREVER = 0xffffffff ++ TIPC_WITHDRAWN = 0x2 ++ TIPC_ZONE_BITS = 0x8 ++ TIPC_ZONE_CLUSTER_MASK = 0xfffff000 ++ TIPC_ZONE_MASK = 0xff000000 ++ TIPC_ZONE_OFFSET = 0x18 ++ TIPC_ZONE_SCOPE = 0x1 ++ TIPC_ZONE_SIZE = 0xff ++ TMPFS_MAGIC = 0x1021994 ++ TOSTOP = 0x400000 ++ TPACKET_ALIGNMENT = 0x10 ++ TPACKET_HDRLEN = 0x34 ++ TP_STATUS_AVAILABLE = 0x0 ++ TP_STATUS_BLK_TMO = 0x20 ++ TP_STATUS_COPY = 0x2 ++ TP_STATUS_CSUMNOTREADY = 0x8 ++ TP_STATUS_CSUM_VALID = 0x80 ++ TP_STATUS_GSO_TCP = 0x100 ++ TP_STATUS_KERNEL = 0x0 ++ TP_STATUS_LOSING = 0x4 ++ TP_STATUS_SENDING = 0x2 ++ TP_STATUS_SEND_REQUEST = 0x1 ++ TP_STATUS_TS_RAW_HARDWARE = 0x80000000 ++ TP_STATUS_TS_SOFTWARE = 0x20000000 ++ TP_STATUS_TS_SYS_HARDWARE = 0x40000000 ++ TP_STATUS_USER = 0x1 ++ TP_STATUS_VLAN_TPID_VALID = 0x40 ++ TP_STATUS_VLAN_VALID = 0x10 ++ TP_STATUS_WRONG_FORMAT = 0x4 ++ TRACEFS_MAGIC = 0x74726163 ++ TS_COMM_LEN = 0x20 ++ TUNATTACHFILTER = 0x801054d5 ++ TUNDETACHFILTER = 0x801054d6 ++ TUNGETDEVNETNS = 0x200054e3 ++ TUNGETFEATURES = 0x400454cf ++ TUNGETFILTER = 0x401054db ++ TUNGETIFF = 0x400454d2 ++ TUNGETSNDBUF = 0x400454d3 ++ TUNGETVNETBE = 0x400454df ++ TUNGETVNETHDRSZ = 0x400454d7 ++ TUNGETVNETLE = 0x400454dd ++ TUNSETCARRIER = 0x800454e2 ++ TUNSETDEBUG = 0x800454c9 ++ TUNSETFILTEREBPF = 0x400454e1 ++ TUNSETGROUP = 0x800454ce ++ TUNSETIFF = 0x800454ca ++ TUNSETIFINDEX = 0x800454da ++ TUNSETLINK = 0x800454cd ++ TUNSETNOCSUM = 0x800454c8 ++ TUNSETOFFLOAD = 0x800454d0 ++ TUNSETOWNER = 0x800454cc ++ TUNSETPERSIST = 0x800454cb ++ TUNSETQUEUE = 0x800454d9 ++ TUNSETSNDBUF = 0x800454d4 ++ TUNSETSTEERINGEBPF = 0x400454e0 ++ TUNSETTXFILTER = 0x800454d1 ++ TUNSETVNETBE = 0x800454de ++ TUNSETVNETHDRSZ = 0x800454d8 ++ TUNSETVNETLE = 0x800454dc ++ UBI_IOCATT = 0x80186f40 ++ UBI_IOCDET = 0x80046f41 ++ UBI_IOCEBCH = 0x80044f02 ++ UBI_IOCEBER = 0x80044f01 ++ UBI_IOCEBISMAP = 0x40044f05 ++ UBI_IOCEBMAP = 0x80084f03 ++ UBI_IOCEBUNMAP = 0x80044f04 ++ UBI_IOCMKVOL = 0x80986f00 ++ UBI_IOCRMVOL = 0x80046f01 ++ UBI_IOCRNVOL = 0x91106f03 ++ UBI_IOCRPEB = 0x80046f04 ++ UBI_IOCRSVOL = 0x800c6f02 ++ UBI_IOCSETVOLPROP = 0x80104f06 ++ UBI_IOCSPEB = 0x80046f05 ++ UBI_IOCVOLCRBLK = 0x80804f07 ++ UBI_IOCVOLRMBLK = 0x20004f08 ++ UBI_IOCVOLUP = 0x80084f00 ++ UDF_SUPER_MAGIC = 0x15013346 ++ UDP_CORK = 0x1 ++ UDP_ENCAP = 0x64 ++ UDP_ENCAP_ESPINUDP = 0x2 ++ UDP_ENCAP_ESPINUDP_NON_IKE = 0x1 ++ UDP_ENCAP_GTP0 = 0x4 ++ UDP_ENCAP_GTP1U = 0x5 ++ UDP_ENCAP_L2TPINUDP = 0x3 ++ UDP_GRO = 0x68 ++ UDP_NO_CHECK6_RX = 0x66 ++ UDP_NO_CHECK6_TX = 0x65 ++ UDP_SEGMENT = 0x67 ++ UDP_V4_FLOW = 0x2 ++ UDP_V6_FLOW = 0x6 ++ UMOUNT_NOFOLLOW = 0x8 ++ USBDEVICE_SUPER_MAGIC = 0x9fa2 ++ UTIME_NOW = 0x3fffffff ++ UTIME_OMIT = 0x3ffffffe ++ V9FS_MAGIC = 0x1021997 ++ VDISCARD = 0xf ++ VEOF = 0x0 ++ VEOL = 0x1 ++ VEOL2 = 0x2 ++ VERASE = 0x3 ++ VINTR = 0x8 ++ VKILL = 0x5 ++ VLNEXT = 0xe ++ VMADDR_CID_ANY = 0xffffffff ++ VMADDR_CID_HOST = 0x2 ++ VMADDR_CID_HYPERVISOR = 0x0 ++ VMADDR_CID_LOCAL = 0x1 ++ VMADDR_FLAG_TO_HOST = 0x1 ++ VMADDR_PORT_ANY = 0xffffffff ++ VMIN = 0x10 ++ VM_SOCKETS_INVALID_VERSION = 0xffffffff ++ VQUIT = 0x9 ++ VREPRINT = 0x6 ++ VSTART = 0xc ++ VSTOP = 0xd ++ VSUSP = 0xa ++ VSWTC = 0x7 ++ VT0 = 0x0 ++ VT1 = 0x10000 ++ VTDLY = 0x10000 ++ VTIME = 0x11 ++ VWERASE = 0x4 ++ WAKE_MAGIC = 0x20 ++ WALL = 0x40000000 ++ WCLONE = 0x80000000 ++ WCONTINUED = 0x8 ++ WDIOC_GETBOOTSTATUS = 0x40045702 ++ WDIOC_GETPRETIMEOUT = 0x40045709 ++ WDIOC_GETSTATUS = 0x40045701 ++ WDIOC_GETSUPPORT = 0x40285700 ++ WDIOC_GETTEMP = 0x40045703 ++ WDIOC_GETTIMELEFT = 0x4004570a ++ WDIOC_GETTIMEOUT = 0x40045707 ++ WDIOC_KEEPALIVE = 0x40045705 ++ WDIOC_SETOPTIONS = 0x40045704 ++ WDIOC_SETPRETIMEOUT = 0xc0045708 ++ WDIOC_SETTIMEOUT = 0xc0045706 ++ WDIOF_ALARMONLY = 0x400 ++ WDIOF_CARDRESET = 0x20 ++ WDIOF_EXTERN1 = 0x4 ++ WDIOF_EXTERN2 = 0x8 ++ WDIOF_FANFAULT = 0x2 ++ WDIOF_KEEPALIVEPING = 0x8000 ++ WDIOF_MAGICCLOSE = 0x100 ++ WDIOF_OVERHEAT = 0x1 ++ WDIOF_POWEROVER = 0x40 ++ WDIOF_POWERUNDER = 0x10 ++ WDIOF_PRETIMEOUT = 0x200 ++ WDIOF_SETTIMEOUT = 0x80 ++ WDIOF_UNKNOWN = -0x1 ++ WDIOS_DISABLECARD = 0x1 ++ WDIOS_ENABLECARD = 0x2 ++ WDIOS_TEMPPANIC = 0x4 ++ WDIOS_UNKNOWN = -0x1 ++ WEXITED = 0x4 ++ WGALLOWEDIP_A_MAX = 0x3 ++ WGDEVICE_A_MAX = 0x8 ++ WGPEER_A_MAX = 0xa ++ WG_CMD_MAX = 0x1 ++ WG_GENL_NAME = "wireguard" ++ WG_GENL_VERSION = 0x1 ++ WG_KEY_LEN = 0x20 ++ WIN_ACKMEDIACHANGE = 0xdb ++ WIN_CHECKPOWERMODE1 = 0xe5 ++ WIN_CHECKPOWERMODE2 = 0x98 ++ WIN_DEVICE_RESET = 0x8 ++ WIN_DIAGNOSE = 0x90 ++ WIN_DOORLOCK = 0xde ++ WIN_DOORUNLOCK = 0xdf ++ WIN_DOWNLOAD_MICROCODE = 0x92 ++ WIN_FLUSH_CACHE = 0xe7 ++ WIN_FLUSH_CACHE_EXT = 0xea ++ WIN_FORMAT = 0x50 ++ WIN_GETMEDIASTATUS = 0xda ++ WIN_IDENTIFY = 0xec ++ WIN_IDENTIFY_DMA = 0xee ++ WIN_IDLEIMMEDIATE = 0xe1 ++ WIN_INIT = 0x60 ++ WIN_MEDIAEJECT = 0xed ++ WIN_MULTREAD = 0xc4 ++ WIN_MULTREAD_EXT = 0x29 ++ WIN_MULTWRITE = 0xc5 ++ WIN_MULTWRITE_EXT = 0x39 ++ WIN_NOP = 0x0 ++ WIN_PACKETCMD = 0xa0 ++ WIN_PIDENTIFY = 0xa1 ++ WIN_POSTBOOT = 0xdc ++ WIN_PREBOOT = 0xdd ++ WIN_QUEUED_SERVICE = 0xa2 ++ WIN_READ = 0x20 ++ WIN_READDMA = 0xc8 ++ WIN_READDMA_EXT = 0x25 ++ WIN_READDMA_ONCE = 0xc9 ++ WIN_READDMA_QUEUED = 0xc7 ++ WIN_READDMA_QUEUED_EXT = 0x26 ++ WIN_READ_BUFFER = 0xe4 ++ WIN_READ_EXT = 0x24 ++ WIN_READ_LONG = 0x22 ++ WIN_READ_LONG_ONCE = 0x23 ++ WIN_READ_NATIVE_MAX = 0xf8 ++ WIN_READ_NATIVE_MAX_EXT = 0x27 ++ WIN_READ_ONCE = 0x21 ++ WIN_RECAL = 0x10 ++ WIN_RESTORE = 0x10 ++ WIN_SECURITY_DISABLE = 0xf6 ++ WIN_SECURITY_ERASE_PREPARE = 0xf3 ++ WIN_SECURITY_ERASE_UNIT = 0xf4 ++ WIN_SECURITY_FREEZE_LOCK = 0xf5 ++ WIN_SECURITY_SET_PASS = 0xf1 ++ WIN_SECURITY_UNLOCK = 0xf2 ++ WIN_SEEK = 0x70 ++ WIN_SETFEATURES = 0xef ++ WIN_SETIDLE1 = 0xe3 ++ WIN_SETIDLE2 = 0x97 ++ WIN_SETMULT = 0xc6 ++ WIN_SET_MAX = 0xf9 ++ WIN_SET_MAX_EXT = 0x37 ++ WIN_SLEEPNOW1 = 0xe6 ++ WIN_SLEEPNOW2 = 0x99 ++ WIN_SMART = 0xb0 ++ WIN_SPECIFY = 0x91 ++ WIN_SRST = 0x8 ++ WIN_STANDBY = 0xe2 ++ WIN_STANDBY2 = 0x96 ++ WIN_STANDBYNOW1 = 0xe0 ++ WIN_STANDBYNOW2 = 0x94 ++ WIN_VERIFY = 0x40 ++ WIN_VERIFY_EXT = 0x42 ++ WIN_VERIFY_ONCE = 0x41 ++ WIN_WRITE = 0x30 ++ WIN_WRITEDMA = 0xca ++ WIN_WRITEDMA_EXT = 0x35 ++ WIN_WRITEDMA_ONCE = 0xcb ++ WIN_WRITEDMA_QUEUED = 0xcc ++ WIN_WRITEDMA_QUEUED_EXT = 0x36 ++ WIN_WRITE_BUFFER = 0xe8 ++ WIN_WRITE_EXT = 0x34 ++ WIN_WRITE_LONG = 0x32 ++ WIN_WRITE_LONG_ONCE = 0x33 ++ WIN_WRITE_ONCE = 0x31 ++ WIN_WRITE_SAME = 0xe9 ++ WIN_WRITE_VERIFY = 0x3c ++ WNOHANG = 0x1 ++ WNOTHREAD = 0x20000000 ++ WNOWAIT = 0x1000000 ++ WORDSIZE = 0x40 ++ WSTOPPED = 0x2 ++ WUNTRACED = 0x2 ++ XATTR_CREATE = 0x1 ++ XATTR_REPLACE = 0x2 ++ XCASE = 0x4000 ++ XDP_COPY = 0x2 ++ XDP_FLAGS_DRV_MODE = 0x4 ++ XDP_FLAGS_HW_MODE = 0x8 ++ XDP_FLAGS_MASK = 0x1f ++ XDP_FLAGS_MODES = 0xe ++ XDP_FLAGS_REPLACE = 0x10 ++ XDP_FLAGS_SKB_MODE = 0x2 ++ XDP_FLAGS_UPDATE_IF_NOEXIST = 0x1 ++ XDP_MMAP_OFFSETS = 0x1 ++ XDP_OPTIONS = 0x8 ++ XDP_OPTIONS_ZEROCOPY = 0x1 ++ XDP_PACKET_HEADROOM = 0x100 ++ XDP_PGOFF_RX_RING = 0x0 ++ XDP_PGOFF_TX_RING = 0x80000000 ++ XDP_PKT_CONTD = 0x1 ++ XDP_RING_NEED_WAKEUP = 0x1 ++ XDP_RX_RING = 0x2 ++ XDP_SHARED_UMEM = 0x1 ++ XDP_STATISTICS = 0x7 ++ XDP_TX_RING = 0x3 ++ XDP_UMEM_COMPLETION_RING = 0x6 ++ XDP_UMEM_FILL_RING = 0x5 ++ XDP_UMEM_PGOFF_COMPLETION_RING = 0x180000000 ++ XDP_UMEM_PGOFF_FILL_RING = 0x100000000 ++ XDP_UMEM_REG = 0x4 ++ XDP_UMEM_UNALIGNED_CHUNK_FLAG = 0x1 ++ XDP_USE_NEED_WAKEUP = 0x8 ++ XDP_USE_SG = 0x10 ++ XDP_ZEROCOPY = 0x4 ++ XENFS_SUPER_MAGIC = 0xabba1974 ++ XFS_SUPER_MAGIC = 0x58465342 ++ XTABS = 0xc00 ++ ZONEFS_MAGIC = 0x5a4f4653 ++ _HIDIOCGRAWNAME = 0x40804804 ++ _HIDIOCGRAWNAME_LEN = 0x80 ++ _HIDIOCGRAWPHYS = 0x40404805 ++ _HIDIOCGRAWPHYS_LEN = 0x40 ++ _HIDIOCGRAWUNIQ = 0x40404808 ++ _HIDIOCGRAWUNIQ_LEN = 0x40 ++) ++ ++// Errors ++const ( ++ E2BIG = syscall.Errno( 0x7) ++ EACCES = syscall.Errno( 0xd) ++ EADDRINUSE = syscall.Errno( 0x30) ++ EADDRNOTAVAIL = syscall.Errno( 0x31) ++ EADV = syscall.Errno( 0x6b) ++ EAFNOSUPPORT = syscall.Errno( 0x2f) ++ EAGAIN = syscall.Errno( 0x23) ++ EALREADY = syscall.Errno( 0x25) ++ EBADE = syscall.Errno( 0x61) ++ EBADF = syscall.Errno( 0x9) ++ EBADFD = syscall.Errno( 0x72) ++ EBADMSG = syscall.Errno( 0x54) ++ EBADR = syscall.Errno( 0x62) ++ EBADRQC = syscall.Errno( 0x65) ++ EBADSLT = syscall.Errno( 0x66) ++ EBFONT = syscall.Errno( 0x68) ++ EBUSY = syscall.Errno( 0x10) ++ ECANCELED = syscall.Errno( 0x83) ++ ECHILD = syscall.Errno( 0xa) ++ ECHRNG = syscall.Errno( 0x58) ++ ECOMM = syscall.Errno( 0x6d) ++ ECONNABORTED = syscall.Errno( 0x35) ++ ECONNREFUSED = syscall.Errno( 0x3d) ++ ECONNRESET = syscall.Errno( 0x36) ++ EDEADLK = syscall.Errno( 0xb) ++ EDEADLOCK = syscall.Errno( 0xb) ++ EDESTADDRREQ = syscall.Errno( 0x27) ++ EDOM = syscall.Errno( 0x21) ++ EDOTDOT = syscall.Errno( 0x6f) ++ EDQUOT = syscall.Errno( 0x45) ++ EEXIST = syscall.Errno( 0x11) ++ EFAULT = syscall.Errno( 0xe) ++ EFBIG = syscall.Errno( 0x1b) ++ EHOSTDOWN = syscall.Errno( 0x40) ++ EHOSTUNREACH = syscall.Errno( 0x41) ++ EHWPOISON = syscall.Errno( 0x8b) ++ EIDRM = syscall.Errno( 0x51) ++ EILSEQ = syscall.Errno( 0x74) ++ EINPROGRESS = syscall.Errno( 0x24) ++ EINTR = syscall.Errno( 0x4) ++ EINVAL = syscall.Errno( 0x16) ++ EIO = syscall.Errno( 0x5) ++ EISCONN = syscall.Errno( 0x38) ++ EISDIR = syscall.Errno( 0x15) ++ EISNAM = syscall.Errno( 0x78) ++ EKEYEXPIRED = syscall.Errno( 0x85) ++ EKEYREJECTED = syscall.Errno( 0x87) ++ EKEYREVOKED = syscall.Errno( 0x86) ++ EL2HLT = syscall.Errno( 0x60) ++ EL2NSYNC = syscall.Errno( 0x59) ++ EL3HLT = syscall.Errno( 0x5a) ++ EL3RST = syscall.Errno( 0x5b) ++ ELIBACC = syscall.Errno( 0x7a) ++ ELIBBAD = syscall.Errno( 0x7b) ++ ELIBEXEC = syscall.Errno( 0x7e) ++ ELIBMAX = syscall.Errno( 0x7d) ++ ELIBSCN = syscall.Errno( 0x7c) ++ ELNRNG = syscall.Errno( 0x5d) ++ ELOOP = syscall.Errno( 0x3e) ++ EMEDIUMTYPE = syscall.Errno( 0x82) ++ EMFILE = syscall.Errno( 0x18) ++ EMLINK = syscall.Errno( 0x1f) ++ EMSGSIZE = syscall.Errno( 0x28) ++ EMULTIHOP = syscall.Errno( 0x6e) ++ ENAMETOOLONG = syscall.Errno( 0x3f) ++ ENAVAIL = syscall.Errno( 0x77) ++ ENETDOWN = syscall.Errno( 0x32) ++ ENETRESET = syscall.Errno( 0x34) ++ ENETUNREACH = syscall.Errno( 0x33) ++ ENFILE = syscall.Errno( 0x17) ++ ENOANO = syscall.Errno( 0x64) ++ ENOBUFS = syscall.Errno( 0x37) ++ ENOCSI = syscall.Errno( 0x5f) ++ ENODATA = syscall.Errno( 0x56) ++ ENODEV = syscall.Errno( 0x13) ++ ENOENT = syscall.Errno( 0x2) ++ ENOEXEC = syscall.Errno( 0x8) ++ ENOKEY = syscall.Errno( 0x84) ++ ENOLCK = syscall.Errno( 0x4d) ++ ENOLINK = syscall.Errno( 0x6a) ++ ENOMEDIUM = syscall.Errno( 0x81) ++ ENOMEM = syscall.Errno( 0xc) ++ ENOMSG = syscall.Errno( 0x50) ++ ENONET = syscall.Errno( 0x69) ++ ENOPKG = syscall.Errno( 0x5c) ++ ENOPROTOOPT = syscall.Errno( 0x2a) ++ ENOSPC = syscall.Errno( 0x1c) ++ ENOSR = syscall.Errno( 0x52) ++ ENOSTR = syscall.Errno( 0x57) ++ ENOSYS = syscall.Errno( 0x4e) ++ ENOTBLK = syscall.Errno( 0xf) ++ ENOTCONN = syscall.Errno( 0x39) ++ ENOTDIR = syscall.Errno( 0x14) ++ ENOTEMPTY = syscall.Errno( 0x42) ++ ENOTNAM = syscall.Errno( 0x76) ++ ENOTRECOVERABLE = syscall.Errno( 0x89) ++ ENOTSOCK = syscall.Errno( 0x26) ++ ENOTSUP = syscall.Errno( 0x2d) ++ ENOTTY = syscall.Errno( 0x19) ++ ENOTUNIQ = syscall.Errno( 0x71) ++ ENXIO = syscall.Errno( 0x6) ++ EOPNOTSUPP = syscall.Errno( 0x2d) ++ EOVERFLOW = syscall.Errno( 0x70) ++ EOWNERDEAD = syscall.Errno( 0x88) ++ EPERM = syscall.Errno( 0x1) ++ EPFNOSUPPORT = syscall.Errno( 0x2e) ++ EPIPE = syscall.Errno( 0x20) ++ EPROTO = syscall.Errno( 0x55) ++ EPROTONOSUPPORT = syscall.Errno( 0x2b) ++ EPROTOTYPE = syscall.Errno( 0x29) ++ ERANGE = syscall.Errno( 0x22) ++ EREMCHG = syscall.Errno( 0x73) ++ EREMOTE = syscall.Errno( 0x47) ++ EREMOTEIO = syscall.Errno( 0x79) ++ ERESTART = syscall.Errno( 0x7f) ++ ERFKILL = syscall.Errno( 0x8a) ++ EROFS = syscall.Errno( 0x1e) ++ ESHUTDOWN = syscall.Errno( 0x3a) ++ ESOCKTNOSUPPORT = syscall.Errno( 0x2c) ++ ESPIPE = syscall.Errno( 0x1d) ++ ESRCH = syscall.Errno( 0x3) ++ ESRMNT = syscall.Errno( 0x6c) ++ ESTALE = syscall.Errno( 0x46) ++ ESTRPIPE = syscall.Errno( 0x80) ++ ETIME = syscall.Errno( 0x53) ++ ETIMEDOUT = syscall.Errno( 0x3c) ++ ETOOMANYREFS = syscall.Errno( 0x3b) ++ ETXTBSY = syscall.Errno( 0x1a) ++ EUCLEAN = syscall.Errno( 0x75) ++ EUNATCH = syscall.Errno( 0x5e) ++ EUSERS = syscall.Errno( 0x44) ++ EWOULDBLOCK = syscall.Errno( 0x23) ++ EXDEV = syscall.Errno( 0x12) ++ EXFULL = syscall.Errno( 0x63) ++) ++ ++// Signals ++const ( ++ SIGABRT = syscall.Signal( 0x6) ++ SIGALRM = syscall.Signal( 0xe) ++ SIGBUS = syscall.Signal( 0xa) ++ SIGCHLD = syscall.Signal( 0x14) ++ SIGCLD = syscall.Signal( 0x14) ++ SIGCONT = syscall.Signal( 0x13) ++ SIGEMT = syscall.Signal( 0x7) ++ SIGFPE = syscall.Signal( 0x8) ++ SIGHUP = syscall.Signal( 0x1) ++ SIGILL = syscall.Signal( 0x4) ++ SIGINFO = syscall.Signal( 0x1d) ++ SIGINT = syscall.Signal( 0x2) ++ SIGIO = syscall.Signal( 0x17) ++ SIGIOT = syscall.Signal( 0x6) ++ SIGKILL = syscall.Signal( 0x9) ++ SIGPIPE = syscall.Signal( 0xd) ++ SIGPOLL = syscall.Signal( 0x17) ++ SIGPROF = syscall.Signal( 0x1b) ++ SIGPWR = syscall.Signal( 0x1d) ++ SIGQUIT = syscall.Signal( 0x3) ++ SIGSEGV = syscall.Signal( 0xb) ++ SIGSTOP = syscall.Signal( 0x11) ++ SIGSYS = syscall.Signal( 0xc) ++ SIGTERM = syscall.Signal( 0xf) ++ SIGTRAP = syscall.Signal( 0x5) ++ SIGTSTP = syscall.Signal( 0x12) ++ SIGTTIN = syscall.Signal( 0x15) ++ SIGTTOU = syscall.Signal( 0x16) ++ SIGURG = syscall.Signal( 0x10) ++ SIGUSR1 = syscall.Signal( 0x1e) ++ SIGUSR2 = syscall.Signal( 0x1f) ++ SIGVTALRM = syscall.Signal( 0x1a) ++ SIGWINCH = syscall.Signal( 0x1c) ++ SIGXCPU = syscall.Signal( 0x18) ++ SIGXFSZ = syscall.Signal( 0x19) ++) ++ ++ ++// Error table ++var errorList = [...]struct { ++ num syscall.Errno ++ name string ++ desc string ++} { ++ { 1, "EPERM", "operation not permitted" }, ++ { 2, "ENOENT", "no such file or directory" }, ++ { 3, "ESRCH", "no such process" }, ++ { 4, "EINTR", "interrupted system call" }, ++ { 5, "EIO", "input/output error" }, ++ { 6, "ENXIO", "no such device or address" }, ++ { 7, "E2BIG", "argument list too long" }, ++ { 8, "ENOEXEC", "exec format error" }, ++ { 9, "EBADF", "bad file descriptor" }, ++ { 10, "ECHILD", "no child processes" }, ++ { 11, "EDEADLK", "resource deadlock avoided" }, ++ { 12, "ENOMEM", "cannot allocate memory" }, ++ { 13, "EACCES", "permission denied" }, ++ { 14, "EFAULT", "bad address" }, ++ { 15, "ENOTBLK", "block device required" }, ++ { 16, "EBUSY", "device or resource busy" }, ++ { 17, "EEXIST", "file exists" }, ++ { 18, "EXDEV", "invalid cross-device link" }, ++ { 19, "ENODEV", "no such device" }, ++ { 20, "ENOTDIR", "not a directory" }, ++ { 21, "EISDIR", "is a directory" }, ++ { 22, "EINVAL", "invalid argument" }, ++ { 23, "ENFILE", "too many open files in system" }, ++ { 24, "EMFILE", "too many open files" }, ++ { 25, "ENOTTY", "inappropriate ioctl for device" }, ++ { 26, "ETXTBSY", "text file busy" }, ++ { 27, "EFBIG", "file too large" }, ++ { 28, "ENOSPC", "no space left on device" }, ++ { 29, "ESPIPE", "illegal seek" }, ++ { 30, "EROFS", "read-only file system" }, ++ { 31, "EMLINK", "too many links" }, ++ { 32, "EPIPE", "broken pipe" }, ++ { 33, "EDOM", "numerical argument out of domain" }, ++ { 34, "ERANGE", "numerical result out of range" }, ++ { 35, "EAGAIN", "resource temporarily unavailable" }, ++ { 36, "EINPROGRESS", "operation now in progress" }, ++ { 37, "EALREADY", "operation already in progress" }, ++ { 38, "ENOTSOCK", "socket operation on non-socket" }, ++ { 39, "EDESTADDRREQ", "destination address required" }, ++ { 40, "EMSGSIZE", "message too long" }, ++ { 41, "EPROTOTYPE", "protocol wrong type for socket" }, ++ { 42, "ENOPROTOOPT", "protocol not available" }, ++ { 43, "EPROTONOSUPPORT", "protocol not supported" }, ++ { 44, "ESOCKTNOSUPPORT", "socket type not supported" }, ++ { 45, "ENOTSUP", "operation not supported" }, ++ { 46, "EPFNOSUPPORT", "protocol family not supported" }, ++ { 47, "EAFNOSUPPORT", "address family not supported by protocol" }, ++ { 48, "EADDRINUSE", "address already in use" }, ++ { 49, "EADDRNOTAVAIL", "cannot assign requested address" }, ++ { 50, "ENETDOWN", "network is down" }, ++ { 51, "ENETUNREACH", "network is unreachable" }, ++ { 52, "ENETRESET", "network dropped connection on reset" }, ++ { 53, "ECONNABORTED", "software caused connection abort" }, ++ { 54, "ECONNRESET", "connection reset by peer" }, ++ { 55, "ENOBUFS", "no buffer space available" }, ++ { 56, "EISCONN", "transport endpoint is already connected" }, ++ { 57, "ENOTCONN", "transport endpoint is not connected" }, ++ { 58, "ESHUTDOWN", "cannot send after transport endpoint shutdown" }, ++ { 59, "ETOOMANYREFS", "too many references: cannot splice" }, ++ { 60, "ETIMEDOUT", "connection timed out" }, ++ { 61, "ECONNREFUSED", "connection refused" }, ++ { 62, "ELOOP", "too many levels of symbolic links" }, ++ { 63, "ENAMETOOLONG", "file name too long" }, ++ { 64, "EHOSTDOWN", "host is down" }, ++ { 65, "EHOSTUNREACH", "no route to host" }, ++ { 66, "ENOTEMPTY", "directory not empty" }, ++ { 68, "EUSERS", "too many users" }, ++ { 69, "EDQUOT", "disk quota exceeded" }, ++ { 70, "ESTALE", "stale file handle" }, ++ { 71, "EREMOTE", "object is remote" }, ++ { 77, "ENOLCK", "no locks available" }, ++ { 78, "ENOSYS", "function not implemented" }, ++ { 80, "ENOMSG", "no message of desired type" }, ++ { 81, "EIDRM", "identifier removed" }, ++ { 82, "ENOSR", "out of streams resources" }, ++ { 83, "ETIME", "timer expired" }, ++ { 84, "EBADMSG", "bad message" }, ++ { 85, "EPROTO", "protocol error" }, ++ { 86, "ENODATA", "no data available" }, ++ { 87, "ENOSTR", "device not a stream" }, ++ { 88, "ECHRNG", "channel number out of range" }, ++ { 89, "EL2NSYNC", "level 2 not synchronized" }, ++ { 90, "EL3HLT", "level 3 halted" }, ++ { 91, "EL3RST", "level 3 reset" }, ++ { 92, "ENOPKG", "package not installed" }, ++ { 93, "ELNRNG", "link number out of range" }, ++ { 94, "EUNATCH", "protocol driver not attached" }, ++ { 95, "ENOCSI", "no CSI structure available" }, ++ { 96, "EL2HLT", "level 2 halted" }, ++ { 97, "EBADE", "invalid exchange" }, ++ { 98, "EBADR", "invalid request descriptor" }, ++ { 99, "EXFULL", "exchange full" }, ++ { 100, "ENOANO", "no anode" }, ++ { 101, "EBADRQC", "invalid request code" }, ++ { 102, "EBADSLT", "invalid slot" }, ++ { 104, "EBFONT", "bad font file format" }, ++ { 105, "ENONET", "machine is not on the network" }, ++ { 106, "ENOLINK", "link has been severed" }, ++ { 107, "EADV", "advertise error" }, ++ { 108, "ESRMNT", "srmount error" }, ++ { 109, "ECOMM", "communication error on send" }, ++ { 110, "EMULTIHOP", "multihop attempted" }, ++ { 111, "EDOTDOT", "RFS specific error" }, ++ { 112, "EOVERFLOW", "value too large for defined data type" }, ++ { 113, "ENOTUNIQ", "name not unique on network" }, ++ { 114, "EBADFD", "file descriptor in bad state" }, ++ { 115, "EREMCHG", "remote address changed" }, ++ { 116, "EILSEQ", "invalid or incomplete multibyte or wide character" }, ++ { 117, "EUCLEAN", "structure needs cleaning" }, ++ { 118, "ENOTNAM", "not a XENIX named type file" }, ++ { 119, "ENAVAIL", "no XENIX semaphores available" }, ++ { 120, "EISNAM", "is a named type file" }, ++ { 121, "EREMOTEIO", "remote I/O error" }, ++ { 122, "ELIBACC", "can not access a needed shared library" }, ++ { 123, "ELIBBAD", "accessing a corrupted shared library" }, ++ { 124, "ELIBSCN", ".lib section in a.out corrupted" }, ++ { 125, "ELIBMAX", "attempting to link in too many shared libraries" }, ++ { 126, "ELIBEXEC", "cannot exec a shared library directly" }, ++ { 127, "ERESTART", "interrupted system call should be restarted" }, ++ { 128, "ESTRPIPE", "streams pipe error" }, ++ { 129, "ENOMEDIUM", "no medium found" }, ++ { 130, "EMEDIUMTYPE", "wrong medium type" }, ++ { 131, "ECANCELED", "operation canceled" }, ++ { 132, "ENOKEY", "required key not available" }, ++ { 133, "EKEYEXPIRED", "key has expired" }, ++ { 134, "EKEYREVOKED", "key has been revoked" }, ++ { 135, "EKEYREJECTED", "key was rejected by service" }, ++ { 136, "EOWNERDEAD", "owner died" }, ++ { 137, "ENOTRECOVERABLE", "state not recoverable" }, ++ { 138, "ERFKILL", "operation not possible due to RF-kill" }, ++ { 139, "EHWPOISON", "memory page has hardware error" }, ++} ++ ++ ++ ++// Signal table ++var signalList = [...]struct { ++ num syscall.Signal ++ name string ++ desc string ++} { ++ { 1, "SIGHUP", "hangup" }, ++ { 2, "SIGINT", "interrupt" }, ++ { 3, "SIGQUIT", "quit" }, ++ { 4, "SIGILL", "illegal instruction" }, ++ { 5, "SIGTRAP", "trace/breakpoint trap" }, ++ { 6, "SIGABRT", "aborted" }, ++ { 7, "SIGEMT", "EMT trap" }, ++ { 8, "SIGFPE", "floating point exception" }, ++ { 9, "SIGKILL", "killed" }, ++ { 10, "SIGBUS", "bus error" }, ++ { 11, "SIGSEGV", "segmentation fault" }, ++ { 12, "SIGSYS", "bad system call" }, ++ { 13, "SIGPIPE", "broken pipe" }, ++ { 14, "SIGALRM", "alarm clock" }, ++ { 15, "SIGTERM", "terminated" }, ++ { 16, "SIGURG", "urgent I/O condition" }, ++ { 17, "SIGSTOP", "stopped (signal)" }, ++ { 18, "SIGTSTP", "stopped" }, ++ { 19, "SIGCONT", "continued" }, ++ { 20, "SIGCHLD", "child exited" }, ++ { 21, "SIGTTIN", "stopped (tty input)" }, ++ { 22, "SIGTTOU", "stopped (tty output)" }, ++ { 23, "SIGIO", "I/O possible" }, ++ { 24, "SIGXCPU", "CPU time limit exceeded" }, ++ { 25, "SIGXFSZ", "file size limit exceeded" }, ++ { 26, "SIGVTALRM", "virtual timer expired" }, ++ { 27, "SIGPROF", "profiling timer expired" }, ++ { 28, "SIGWINCH", "window changed" }, ++ { 29, "SIGINFO", "power failure" }, ++ { 30, "SIGUSR1", "user defined signal 1" }, ++ { 31, "SIGUSR2", "user defined signal 2" }, ++} +diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux.go +index 5cc1e8eb2f..1d62524add 100644 +--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux.go ++++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux.go +@@ -1,6 +1,6 @@ + // Code generated by mkmerge; DO NOT EDIT. + +-//go:build linux ++//go:build linux && !sw64 + + package unix + +diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_sw64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_sw64.go +new file mode 100644 +index 0000000000..063f98774c +--- /dev/null ++++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_sw64.go +@@ -0,0 +1,2831 @@ ++// go run mksyscall.go -tags linux,sw64 syscall_linux.go syscall_linux_sw64.go ++// Code generated by the command above; see README.md. DO NOT EDIT. ++ ++//go:build linux && sw64 ++ ++package unix ++ ++import ( ++ "syscall" ++ "unsafe" ++) ++ ++var _ syscall.Errno ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func FanotifyInit(flags uint, event_f_flags uint) (fd int, err error) { ++ r0, _, e1 := Syscall(SYS_FANOTIFY_INIT, uintptr(flags), uintptr(event_f_flags), 0) ++ fd = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func fanotifyMark(fd int, flags uint, mask uint64, dirFd int, pathname *byte) (err error) { ++ _, _, e1 := Syscall6(SYS_FANOTIFY_MARK, uintptr(fd), uintptr(flags), uintptr(mask), uintptr(dirFd), uintptr(unsafe.Pointer(pathname)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func fchmodat(dirfd int, path string, mode uint32) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode)) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func fchmodat2(dirfd int, path string, mode uint32, flags int) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall6(SYS_FCHMODAT2, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func ioctl(fd int, req uint, arg uintptr) (err error) { ++ _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { ++ _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(oldpath) ++ if err != nil { ++ return ++ } ++ var _p1 *byte ++ _p1, err = BytePtrFromString(newpath) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall6(SYS_LINKAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ r0, _, e1 := Syscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mode), 0, 0) ++ fd = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func openat2(dirfd int, path string, open_how *OpenHow, size int) (fd int, err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ r0, _, e1 := Syscall6(SYS_OPENAT2, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(open_how)), uintptr(size), 0, 0) ++ fd = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func pipe2(p *[2]_C_int, flags int) (err error) { ++ _, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) { ++ r0, _, e1 := Syscall6(SYS_PPOLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0) ++ n = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Readlinkat(dirfd int, path string, buf []byte) (n int, err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ var _p1 unsafe.Pointer ++ if len(buf) > 0 { ++ _p1 = unsafe.Pointer(&buf[0]) ++ } else { ++ _p1 = unsafe.Pointer(&_zero) ++ } ++ r0, _, e1 := Syscall6(SYS_READLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0) ++ n = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Symlinkat(oldpath string, newdirfd int, newpath string) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(oldpath) ++ if err != nil { ++ return ++ } ++ var _p1 *byte ++ _p1, err = BytePtrFromString(newpath) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall(SYS_SYMLINKAT, uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1))) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Unlinkat(dirfd int, path string, flags int) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall(SYS_UNLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags)) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Getcwd(buf []byte) (n int, err error) { ++ var _p0 unsafe.Pointer ++ if len(buf) > 0 { ++ _p0 = unsafe.Pointer(&buf[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ r0, _, e1 := Syscall(SYS_GETCWD, uintptr(_p0), uintptr(len(buf)), 0) ++ n = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) { ++ r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0) ++ wpid = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Waitid(idType int, id int, info *Siginfo, options int, rusage *Rusage) (err error) { ++ _, _, e1 := Syscall6(SYS_WAITID, uintptr(idType), uintptr(id), uintptr(unsafe.Pointer(info)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func KeyctlInt(cmd int, arg2 int, arg3 int, arg4 int, arg5 int) (ret int, err error) { ++ r0, _, e1 := Syscall6(SYS_KEYCTL, uintptr(cmd), uintptr(arg2), uintptr(arg3), uintptr(arg4), uintptr(arg5), 0) ++ ret = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func KeyctlBuffer(cmd int, arg2 int, buf []byte, arg5 int) (ret int, err error) { ++ var _p0 unsafe.Pointer ++ if len(buf) > 0 { ++ _p0 = unsafe.Pointer(&buf[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ r0, _, e1 := Syscall6(SYS_KEYCTL, uintptr(cmd), uintptr(arg2), uintptr(_p0), uintptr(len(buf)), uintptr(arg5), 0) ++ ret = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func keyctlJoin(cmd int, arg2 string) (ret int, err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(arg2) ++ if err != nil { ++ return ++ } ++ r0, _, e1 := Syscall(SYS_KEYCTL, uintptr(cmd), uintptr(unsafe.Pointer(_p0)), 0) ++ ret = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func keyctlSearch(cmd int, arg2 int, arg3 string, arg4 string, arg5 int) (ret int, err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(arg3) ++ if err != nil { ++ return ++ } ++ var _p1 *byte ++ _p1, err = BytePtrFromString(arg4) ++ if err != nil { ++ return ++ } ++ r0, _, e1 := Syscall6(SYS_KEYCTL, uintptr(cmd), uintptr(arg2), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(arg5), 0) ++ ret = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func keyctlIOV(cmd int, arg2 int, payload []Iovec, arg5 int) (err error) { ++ var _p0 unsafe.Pointer ++ if len(payload) > 0 { ++ _p0 = unsafe.Pointer(&payload[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ _, _, e1 := Syscall6(SYS_KEYCTL, uintptr(cmd), uintptr(arg2), uintptr(_p0), uintptr(len(payload)), uintptr(arg5), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func keyctlDH(cmd int, arg2 *KeyctlDHParams, buf []byte) (ret int, err error) { ++ var _p0 unsafe.Pointer ++ if len(buf) > 0 { ++ _p0 = unsafe.Pointer(&buf[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ r0, _, e1 := Syscall6(SYS_KEYCTL, uintptr(cmd), uintptr(unsafe.Pointer(arg2)), uintptr(_p0), uintptr(len(buf)), 0, 0) ++ ret = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func keyctlRestrictKeyringByType(cmd int, arg2 int, keyType string, restriction string) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(keyType) ++ if err != nil { ++ return ++ } ++ var _p1 *byte ++ _p1, err = BytePtrFromString(restriction) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall6(SYS_KEYCTL, uintptr(cmd), uintptr(arg2), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func keyctlRestrictKeyring(cmd int, arg2 int) (err error) { ++ _, _, e1 := Syscall(SYS_KEYCTL, uintptr(cmd), uintptr(arg2), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) { ++ _, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func ptracePtr(request int, pid int, addr uintptr, data unsafe.Pointer) (err error) { ++ _, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(arg) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall6(SYS_REBOOT, uintptr(magic1), uintptr(magic2), uintptr(cmd), uintptr(unsafe.Pointer(_p0)), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func mount(source string, target string, fstype string, flags uintptr, data *byte) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(source) ++ if err != nil { ++ return ++ } ++ var _p1 *byte ++ _p1, err = BytePtrFromString(target) ++ if err != nil { ++ return ++ } ++ var _p2 *byte ++ _p2, err = BytePtrFromString(fstype) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall6(SYS_MOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(_p2)), uintptr(flags), uintptr(unsafe.Pointer(data)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func mountSetattr(dirfd int, pathname string, flags uint, attr *MountAttr, size uintptr) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(pathname) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall6(SYS_MOUNT_SETATTR, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(unsafe.Pointer(attr)), uintptr(size), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Acct(path string) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall(SYS_ACCT, uintptr(unsafe.Pointer(_p0)), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func AddKey(keyType string, description string, payload []byte, ringid int) (id int, err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(keyType) ++ if err != nil { ++ return ++ } ++ var _p1 *byte ++ _p1, err = BytePtrFromString(description) ++ if err != nil { ++ return ++ } ++ var _p2 unsafe.Pointer ++ if len(payload) > 0 { ++ _p2 = unsafe.Pointer(&payload[0]) ++ } else { ++ _p2 = unsafe.Pointer(&_zero) ++ } ++ r0, _, e1 := Syscall6(SYS_ADD_KEY, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(payload)), uintptr(ringid), 0) ++ id = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Adjtimex(buf *Timex) (state int, err error) { ++ r0, _, e1 := Syscall(SYS_ADJTIMEX, uintptr(unsafe.Pointer(buf)), 0, 0) ++ state = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Capget(hdr *CapUserHeader, data *CapUserData) (err error) { ++ _, _, e1 := RawSyscall(SYS_CAPGET, uintptr(unsafe.Pointer(hdr)), uintptr(unsafe.Pointer(data)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Capset(hdr *CapUserHeader, data *CapUserData) (err error) { ++ _, _, e1 := RawSyscall(SYS_CAPSET, uintptr(unsafe.Pointer(hdr)), uintptr(unsafe.Pointer(data)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Chdir(path string) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Chroot(path string) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func ClockAdjtime(clockid int32, buf *Timex) (state int, err error) { ++ r0, _, e1 := Syscall(SYS_CLOCK_ADJTIME, uintptr(clockid), uintptr(unsafe.Pointer(buf)), 0) ++ state = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func ClockGetres(clockid int32, res *Timespec) (err error) { ++ _, _, e1 := Syscall(SYS_CLOCK_GETRES, uintptr(clockid), uintptr(unsafe.Pointer(res)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func ClockGettime(clockid int32, time *Timespec) (err error) { ++ _, _, e1 := Syscall(SYS_CLOCK_GETTIME, uintptr(clockid), uintptr(unsafe.Pointer(time)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func ClockSettime(clockid int32, time *Timespec) (err error) { ++ _, _, e1 := Syscall(SYS_CLOCK_SETTIME, uintptr(clockid), uintptr(unsafe.Pointer(time)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func ClockNanosleep(clockid int32, flags int, request *Timespec, remain *Timespec) (err error) { ++ _, _, e1 := Syscall6(SYS_CLOCK_NANOSLEEP, uintptr(clockid), uintptr(flags), uintptr(unsafe.Pointer(request)), uintptr(unsafe.Pointer(remain)), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Close(fd int) (err error) { ++ _, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func CloseRange(first uint, last uint, flags uint) (err error) { ++ _, _, e1 := Syscall(SYS_CLOSE_RANGE, uintptr(first), uintptr(last), uintptr(flags)) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error) { ++ r0, _, e1 := Syscall6(SYS_COPY_FILE_RANGE, uintptr(rfd), uintptr(unsafe.Pointer(roff)), uintptr(wfd), uintptr(unsafe.Pointer(woff)), uintptr(len), uintptr(flags)) ++ n = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func DeleteModule(name string, flags int) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(name) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall(SYS_DELETE_MODULE, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Dup(oldfd int) (fd int, err error) { ++ r0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), 0, 0) ++ fd = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Dup3(oldfd int, newfd int, flags int) (err error) { ++ _, _, e1 := Syscall(SYS_DUP3, uintptr(oldfd), uintptr(newfd), uintptr(flags)) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func EpollCreate1(flag int) (fd int, err error) { ++ r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE1, uintptr(flag), 0, 0) ++ fd = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) { ++ _, _, e1 := RawSyscall6(SYS_EPOLL_CTL, uintptr(epfd), uintptr(op), uintptr(fd), uintptr(unsafe.Pointer(event)), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Eventfd(initval uint, flags int) (fd int, err error) { ++ r0, _, e1 := Syscall(SYS_EVENTFD2, uintptr(initval), uintptr(flags), 0) ++ fd = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Exit(code int) { ++ SyscallNoError(SYS_EXIT_GROUP, uintptr(code), 0, 0) ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Fallocate(fd int, mode uint32, off int64, len int64) (err error) { ++ _, _, e1 := Syscall6(SYS_FALLOCATE, uintptr(fd), uintptr(mode), uintptr(off), uintptr(len), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Fchdir(fd int) (err error) { ++ _, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Fchmod(fd int, mode uint32) (err error) { ++ _, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall6(SYS_FCHOWNAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Fdatasync(fd int) (err error) { ++ _, _, e1 := Syscall(SYS_FDATASYNC, uintptr(fd), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Fgetxattr(fd int, attr string, dest []byte) (sz int, err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(attr) ++ if err != nil { ++ return ++ } ++ var _p1 unsafe.Pointer ++ if len(dest) > 0 { ++ _p1 = unsafe.Pointer(&dest[0]) ++ } else { ++ _p1 = unsafe.Pointer(&_zero) ++ } ++ r0, _, e1 := Syscall6(SYS_FGETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)), 0, 0) ++ sz = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func FinitModule(fd int, params string, flags int) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(params) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall(SYS_FINIT_MODULE, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(flags)) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Flistxattr(fd int, dest []byte) (sz int, err error) { ++ var _p0 unsafe.Pointer ++ if len(dest) > 0 { ++ _p0 = unsafe.Pointer(&dest[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ r0, _, e1 := Syscall(SYS_FLISTXATTR, uintptr(fd), uintptr(_p0), uintptr(len(dest))) ++ sz = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Flock(fd int, how int) (err error) { ++ _, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Fremovexattr(fd int, attr string) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(attr) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall(SYS_FREMOVEXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Fsetxattr(fd int, attr string, dest []byte, flags int) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(attr) ++ if err != nil { ++ return ++ } ++ var _p1 unsafe.Pointer ++ if len(dest) > 0 { ++ _p1 = unsafe.Pointer(&dest[0]) ++ } else { ++ _p1 = unsafe.Pointer(&_zero) ++ } ++ _, _, e1 := Syscall6(SYS_FSETXATTR, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)), uintptr(flags), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Fsync(fd int) (err error) { ++ _, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Fsmount(fd int, flags int, mountAttrs int) (fsfd int, err error) { ++ r0, _, e1 := Syscall(SYS_FSMOUNT, uintptr(fd), uintptr(flags), uintptr(mountAttrs)) ++ fsfd = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Fsopen(fsName string, flags int) (fd int, err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(fsName) ++ if err != nil { ++ return ++ } ++ r0, _, e1 := Syscall(SYS_FSOPEN, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0) ++ fd = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Fspick(dirfd int, pathName string, flags int) (fd int, err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(pathName) ++ if err != nil { ++ return ++ } ++ r0, _, e1 := Syscall(SYS_FSPICK, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags)) ++ fd = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func fsconfig(fd int, cmd uint, key *byte, value *byte, aux int) (err error) { ++ _, _, e1 := Syscall6(SYS_FSCONFIG, uintptr(fd), uintptr(cmd), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(value)), uintptr(aux), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Getdents(fd int, buf []byte) (n int, err error) { ++ var _p0 unsafe.Pointer ++ if len(buf) > 0 { ++ _p0 = unsafe.Pointer(&buf[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ r0, _, e1 := Syscall(SYS_GETDENTS64, uintptr(fd), uintptr(_p0), uintptr(len(buf))) ++ n = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Getpgid(pid int) (pgid int, err error) { ++ r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0) ++ pgid = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Getpriority(which int, who int) (prio int, err error) { ++ r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0) ++ prio = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Getrusage(who int, rusage *Rusage) (err error) { ++ _, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Getsid(pid int) (sid int, err error) { ++ r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0) ++ sid = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Gettid() (tid int) { ++ r0, _ := RawSyscallNoError(SYS_GETTID, 0, 0, 0) ++ tid = int(r0) ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Getxattr(path string, attr string, dest []byte) (sz int, err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ var _p1 *byte ++ _p1, err = BytePtrFromString(attr) ++ if err != nil { ++ return ++ } ++ var _p2 unsafe.Pointer ++ if len(dest) > 0 { ++ _p2 = unsafe.Pointer(&dest[0]) ++ } else { ++ _p2 = unsafe.Pointer(&_zero) ++ } ++ r0, _, e1 := Syscall6(SYS_GETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(dest)), 0, 0) ++ sz = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func InitModule(moduleImage []byte, params string) (err error) { ++ var _p0 unsafe.Pointer ++ if len(moduleImage) > 0 { ++ _p0 = unsafe.Pointer(&moduleImage[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ var _p1 *byte ++ _p1, err = BytePtrFromString(params) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall(SYS_INIT_MODULE, uintptr(_p0), uintptr(len(moduleImage)), uintptr(unsafe.Pointer(_p1))) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(pathname) ++ if err != nil { ++ return ++ } ++ r0, _, e1 := Syscall(SYS_INOTIFY_ADD_WATCH, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(mask)) ++ watchdesc = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func InotifyInit1(flags int) (fd int, err error) { ++ r0, _, e1 := RawSyscall(SYS_INOTIFY_INIT1, uintptr(flags), 0, 0) ++ fd = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func InotifyRmWatch(fd int, watchdesc uint32) (success int, err error) { ++ r0, _, e1 := RawSyscall(SYS_INOTIFY_RM_WATCH, uintptr(fd), uintptr(watchdesc), 0) ++ success = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Kill(pid int, sig syscall.Signal) (err error) { ++ _, _, e1 := RawSyscall(SYS_KILL, uintptr(pid), uintptr(sig), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Klogctl(typ int, buf []byte) (n int, err error) { ++ var _p0 unsafe.Pointer ++ if len(buf) > 0 { ++ _p0 = unsafe.Pointer(&buf[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ r0, _, e1 := Syscall(SYS_SYSLOG, uintptr(typ), uintptr(_p0), uintptr(len(buf))) ++ n = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Lgetxattr(path string, attr string, dest []byte) (sz int, err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ var _p1 *byte ++ _p1, err = BytePtrFromString(attr) ++ if err != nil { ++ return ++ } ++ var _p2 unsafe.Pointer ++ if len(dest) > 0 { ++ _p2 = unsafe.Pointer(&dest[0]) ++ } else { ++ _p2 = unsafe.Pointer(&_zero) ++ } ++ r0, _, e1 := Syscall6(SYS_LGETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(dest)), 0, 0) ++ sz = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Listxattr(path string, dest []byte) (sz int, err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ var _p1 unsafe.Pointer ++ if len(dest) > 0 { ++ _p1 = unsafe.Pointer(&dest[0]) ++ } else { ++ _p1 = unsafe.Pointer(&_zero) ++ } ++ r0, _, e1 := Syscall(SYS_LISTXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest))) ++ sz = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Llistxattr(path string, dest []byte) (sz int, err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ var _p1 unsafe.Pointer ++ if len(dest) > 0 { ++ _p1 = unsafe.Pointer(&dest[0]) ++ } else { ++ _p1 = unsafe.Pointer(&_zero) ++ } ++ r0, _, e1 := Syscall(SYS_LLISTXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest))) ++ sz = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Lremovexattr(path string, attr string) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ var _p1 *byte ++ _p1, err = BytePtrFromString(attr) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall(SYS_LREMOVEXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Lsetxattr(path string, attr string, data []byte, flags int) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ var _p1 *byte ++ _p1, err = BytePtrFromString(attr) ++ if err != nil { ++ return ++ } ++ var _p2 unsafe.Pointer ++ if len(data) > 0 { ++ _p2 = unsafe.Pointer(&data[0]) ++ } else { ++ _p2 = unsafe.Pointer(&_zero) ++ } ++ _, _, e1 := Syscall6(SYS_LSETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(data)), uintptr(flags), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func MemfdCreate(name string, flags int) (fd int, err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(name) ++ if err != nil { ++ return ++ } ++ r0, _, e1 := Syscall(SYS_MEMFD_CREATE, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0) ++ fd = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Mkdirat(dirfd int, path string, mode uint32) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall(SYS_MKDIRAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode)) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Mknodat(dirfd int, path string, mode uint32, dev int) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall6(SYS_MKNODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func MoveMount(fromDirfd int, fromPathName string, toDirfd int, toPathName string, flags int) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(fromPathName) ++ if err != nil { ++ return ++ } ++ var _p1 *byte ++ _p1, err = BytePtrFromString(toPathName) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall6(SYS_MOVE_MOUNT, uintptr(fromDirfd), uintptr(unsafe.Pointer(_p0)), uintptr(toDirfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Nanosleep(time *Timespec, leftover *Timespec) (err error) { ++ _, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func OpenTree(dfd int, fileName string, flags uint) (r int, err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(fileName) ++ if err != nil { ++ return ++ } ++ r0, _, e1 := Syscall(SYS_OPEN_TREE, uintptr(dfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags)) ++ r = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error) { ++ r0, _, e1 := Syscall6(SYS_PERF_EVENT_OPEN, uintptr(unsafe.Pointer(attr)), uintptr(pid), uintptr(cpu), uintptr(groupFd), uintptr(flags), 0) ++ fd = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func PivotRoot(newroot string, putold string) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(newroot) ++ if err != nil { ++ return ++ } ++ var _p1 *byte ++ _p1, err = BytePtrFromString(putold) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall(SYS_PIVOT_ROOT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error) { ++ _, _, e1 := Syscall6(SYS_PRCTL, uintptr(option), uintptr(arg2), uintptr(arg3), uintptr(arg4), uintptr(arg5), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func pselect6(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *sigset_argpack) (n int, err error) { ++ r0, _, e1 := Syscall6(SYS_PSELECT6, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask))) ++ n = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func read(fd int, p []byte) (n int, err error) { ++ var _p0 unsafe.Pointer ++ if len(p) > 0 { ++ _p0 = unsafe.Pointer(&p[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p))) ++ n = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Removexattr(path string, attr string) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ var _p1 *byte ++ _p1, err = BytePtrFromString(attr) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall(SYS_REMOVEXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(oldpath) ++ if err != nil { ++ return ++ } ++ var _p1 *byte ++ _p1, err = BytePtrFromString(newpath) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall6(SYS_RENAMEAT2, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func RequestKey(keyType string, description string, callback string, destRingid int) (id int, err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(keyType) ++ if err != nil { ++ return ++ } ++ var _p1 *byte ++ _p1, err = BytePtrFromString(description) ++ if err != nil { ++ return ++ } ++ var _p2 *byte ++ _p2, err = BytePtrFromString(callback) ++ if err != nil { ++ return ++ } ++ r0, _, e1 := Syscall6(SYS_REQUEST_KEY, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(_p2)), uintptr(destRingid), 0, 0) ++ id = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Setdomainname(p []byte) (err error) { ++ var _p0 unsafe.Pointer ++ if len(p) > 0 { ++ _p0 = unsafe.Pointer(&p[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ _, _, e1 := Syscall(SYS_SETDOMAINNAME, uintptr(_p0), uintptr(len(p)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Sethostname(p []byte) (err error) { ++ var _p0 unsafe.Pointer ++ if len(p) > 0 { ++ _p0 = unsafe.Pointer(&p[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ _, _, e1 := Syscall(SYS_SETHOSTNAME, uintptr(_p0), uintptr(len(p)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Setpgid(pid int, pgid int) (err error) { ++ _, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Setsid() (pid int, err error) { ++ r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0) ++ pid = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Settimeofday(tv *Timeval) (err error) { ++ _, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Setns(fd int, nstype int) (err error) { ++ _, _, e1 := Syscall(SYS_SETNS, uintptr(fd), uintptr(nstype), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Setpriority(which int, who int, prio int) (err error) { ++ _, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio)) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Setxattr(path string, attr string, data []byte, flags int) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ var _p1 *byte ++ _p1, err = BytePtrFromString(attr) ++ if err != nil { ++ return ++ } ++ var _p2 unsafe.Pointer ++ if len(data) > 0 { ++ _p2 = unsafe.Pointer(&data[0]) ++ } else { ++ _p2 = unsafe.Pointer(&_zero) ++ } ++ _, _, e1 := Syscall6(SYS_SETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(data)), uintptr(flags), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func signalfd(fd int, sigmask *Sigset_t, maskSize uintptr, flags int) (newfd int, err error) { ++ r0, _, e1 := Syscall6(SYS_SIGNALFD4, uintptr(fd), uintptr(unsafe.Pointer(sigmask)), uintptr(maskSize), uintptr(flags), 0, 0) ++ newfd = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall6(SYS_STATX, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mask), uintptr(unsafe.Pointer(stat)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Sync() { ++ SyscallNoError(SYS_SYNC, 0, 0, 0) ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Syncfs(fd int) (err error) { ++ _, _, e1 := Syscall(SYS_SYNCFS, uintptr(fd), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Sysinfo(info *Sysinfo_t) (err error) { ++ _, _, e1 := RawSyscall(SYS_SYSINFO, uintptr(unsafe.Pointer(info)), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) { ++ r0, _, e1 := Syscall6(SYS_TEE, uintptr(rfd), uintptr(wfd), uintptr(len), uintptr(flags), 0, 0) ++ n = int64(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func TimerfdCreate(clockid int, flags int) (fd int, err error) { ++ r0, _, e1 := RawSyscall(SYS_TIMERFD_CREATE, uintptr(clockid), uintptr(flags), 0) ++ fd = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func TimerfdGettime(fd int, currValue *ItimerSpec) (err error) { ++ _, _, e1 := RawSyscall(SYS_TIMERFD_GETTIME, uintptr(fd), uintptr(unsafe.Pointer(currValue)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func TimerfdSettime(fd int, flags int, newValue *ItimerSpec, oldValue *ItimerSpec) (err error) { ++ _, _, e1 := RawSyscall6(SYS_TIMERFD_SETTIME, uintptr(fd), uintptr(flags), uintptr(unsafe.Pointer(newValue)), uintptr(unsafe.Pointer(oldValue)), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Tgkill(tgid int, tid int, sig syscall.Signal) (err error) { ++ _, _, e1 := RawSyscall(SYS_TGKILL, uintptr(tgid), uintptr(tid), uintptr(sig)) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Times(tms *Tms) (ticks uintptr, err error) { ++ r0, _, e1 := RawSyscall(SYS_TIMES, uintptr(unsafe.Pointer(tms)), 0, 0) ++ ticks = uintptr(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Umask(mask int) (oldmask int) { ++ r0, _ := RawSyscallNoError(SYS_UMASK, uintptr(mask), 0, 0) ++ oldmask = int(r0) ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Uname(buf *Utsname) (err error) { ++ _, _, e1 := RawSyscall(SYS_UNAME, uintptr(unsafe.Pointer(buf)), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Unmount(target string, flags int) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(target) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall(SYS_UMOUNT2, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Unshare(flags int) (err error) { ++ _, _, e1 := Syscall(SYS_UNSHARE, uintptr(flags), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func write(fd int, p []byte) (n int, err error) { ++ var _p0 unsafe.Pointer ++ if len(p) > 0 { ++ _p0 = unsafe.Pointer(&p[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p))) ++ n = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func exitThread(code int) (err error) { ++ _, _, e1 := Syscall(SYS_EXIT, uintptr(code), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func readv(fd int, iovs []Iovec) (n int, err error) { ++ var _p0 unsafe.Pointer ++ if len(iovs) > 0 { ++ _p0 = unsafe.Pointer(&iovs[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ r0, _, e1 := Syscall(SYS_READV, uintptr(fd), uintptr(_p0), uintptr(len(iovs))) ++ n = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func writev(fd int, iovs []Iovec) (n int, err error) { ++ var _p0 unsafe.Pointer ++ if len(iovs) > 0 { ++ _p0 = unsafe.Pointer(&iovs[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ r0, _, e1 := Syscall(SYS_WRITEV, uintptr(fd), uintptr(_p0), uintptr(len(iovs))) ++ n = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func preadv(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr) (n int, err error) { ++ var _p0 unsafe.Pointer ++ if len(iovs) > 0 { ++ _p0 = unsafe.Pointer(&iovs[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ r0, _, e1 := Syscall6(SYS_PREADV, uintptr(fd), uintptr(_p0), uintptr(len(iovs)), uintptr(offs_l), uintptr(offs_h), 0) ++ n = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func pwritev(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr) (n int, err error) { ++ var _p0 unsafe.Pointer ++ if len(iovs) > 0 { ++ _p0 = unsafe.Pointer(&iovs[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ r0, _, e1 := Syscall6(SYS_PWRITEV, uintptr(fd), uintptr(_p0), uintptr(len(iovs)), uintptr(offs_l), uintptr(offs_h), 0) ++ n = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func preadv2(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr, flags int) (n int, err error) { ++ var _p0 unsafe.Pointer ++ if len(iovs) > 0 { ++ _p0 = unsafe.Pointer(&iovs[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ r0, _, e1 := Syscall6(SYS_PREADV2, uintptr(fd), uintptr(_p0), uintptr(len(iovs)), uintptr(offs_l), uintptr(offs_h), uintptr(flags)) ++ n = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func pwritev2(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr, flags int) (n int, err error) { ++ var _p0 unsafe.Pointer ++ if len(iovs) > 0 { ++ _p0 = unsafe.Pointer(&iovs[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ r0, _, e1 := Syscall6(SYS_PWRITEV2, uintptr(fd), uintptr(_p0), uintptr(len(iovs)), uintptr(offs_l), uintptr(offs_h), uintptr(flags)) ++ n = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func munmap(addr uintptr, length uintptr) (err error) { ++ _, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func mremap(oldaddr uintptr, oldlength uintptr, newlength uintptr, flags int, newaddr uintptr) (xaddr uintptr, err error) { ++ r0, _, e1 := Syscall6(SYS_MREMAP, uintptr(oldaddr), uintptr(oldlength), uintptr(newlength), uintptr(flags), uintptr(newaddr), 0) ++ xaddr = uintptr(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Madvise(b []byte, advice int) (err error) { ++ var _p0 unsafe.Pointer ++ if len(b) > 0 { ++ _p0 = unsafe.Pointer(&b[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ _, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(advice)) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Mprotect(b []byte, prot int) (err error) { ++ var _p0 unsafe.Pointer ++ if len(b) > 0 { ++ _p0 = unsafe.Pointer(&b[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot)) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Mlock(b []byte) (err error) { ++ var _p0 unsafe.Pointer ++ if len(b) > 0 { ++ _p0 = unsafe.Pointer(&b[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Mlockall(flags int) (err error) { ++ _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Msync(b []byte, flags int) (err error) { ++ var _p0 unsafe.Pointer ++ if len(b) > 0 { ++ _p0 = unsafe.Pointer(&b[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ _, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags)) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Munlock(b []byte) (err error) { ++ var _p0 unsafe.Pointer ++ if len(b) > 0 { ++ _p0 = unsafe.Pointer(&b[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Munlockall() (err error) { ++ _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func faccessat(dirfd int, path string, mode uint32) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode)) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Faccessat2(dirfd int, path string, mode uint32, flags int) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall6(SYS_FACCESSAT2, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func nameToHandleAt(dirFD int, pathname string, fh *fileHandle, mountID *_C_int, flags int) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(pathname) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall6(SYS_NAME_TO_HANDLE_AT, uintptr(dirFD), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(fh)), uintptr(unsafe.Pointer(mountID)), uintptr(flags), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func openByHandleAt(mountFD int, fh *fileHandle, flags int) (fd int, err error) { ++ r0, _, e1 := Syscall(SYS_OPEN_BY_HANDLE_AT, uintptr(mountFD), uintptr(unsafe.Pointer(fh)), uintptr(flags)) ++ fd = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func ProcessVMReadv(pid int, localIov []Iovec, remoteIov []RemoteIovec, flags uint) (n int, err error) { ++ var _p0 unsafe.Pointer ++ if len(localIov) > 0 { ++ _p0 = unsafe.Pointer(&localIov[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ var _p1 unsafe.Pointer ++ if len(remoteIov) > 0 { ++ _p1 = unsafe.Pointer(&remoteIov[0]) ++ } else { ++ _p1 = unsafe.Pointer(&_zero) ++ } ++ r0, _, e1 := Syscall6(SYS_PROCESS_VM_READV, uintptr(pid), uintptr(_p0), uintptr(len(localIov)), uintptr(_p1), uintptr(len(remoteIov)), uintptr(flags)) ++ n = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func ProcessVMWritev(pid int, localIov []Iovec, remoteIov []RemoteIovec, flags uint) (n int, err error) { ++ var _p0 unsafe.Pointer ++ if len(localIov) > 0 { ++ _p0 = unsafe.Pointer(&localIov[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ var _p1 unsafe.Pointer ++ if len(remoteIov) > 0 { ++ _p1 = unsafe.Pointer(&remoteIov[0]) ++ } else { ++ _p1 = unsafe.Pointer(&_zero) ++ } ++ r0, _, e1 := Syscall6(SYS_PROCESS_VM_WRITEV, uintptr(pid), uintptr(_p0), uintptr(len(localIov)), uintptr(_p1), uintptr(len(remoteIov)), uintptr(flags)) ++ n = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func PidfdOpen(pid int, flags int) (fd int, err error) { ++ r0, _, e1 := Syscall(SYS_PIDFD_OPEN, uintptr(pid), uintptr(flags), 0) ++ fd = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func PidfdGetfd(pidfd int, targetfd int, flags int) (fd int, err error) { ++ r0, _, e1 := Syscall(SYS_PIDFD_GETFD, uintptr(pidfd), uintptr(targetfd), uintptr(flags)) ++ fd = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func PidfdSendSignal(pidfd int, sig Signal, info *Siginfo, flags int) (err error) { ++ _, _, e1 := Syscall6(SYS_PIDFD_SEND_SIGNAL, uintptr(pidfd), uintptr(sig), uintptr(unsafe.Pointer(info)), uintptr(flags), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func shmat(id int, addr uintptr, flag int) (ret uintptr, err error) { ++ r0, _, e1 := Syscall(SYS_SHMAT, uintptr(id), uintptr(addr), uintptr(flag)) ++ ret = uintptr(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func shmctl(id int, cmd int, buf *SysvShmDesc) (result int, err error) { ++ r0, _, e1 := Syscall(SYS_SHMCTL, uintptr(id), uintptr(cmd), uintptr(unsafe.Pointer(buf))) ++ result = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func shmdt(addr uintptr) (err error) { ++ _, _, e1 := Syscall(SYS_SHMDT, uintptr(addr), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func shmget(key int, size int, flag int) (id int, err error) { ++ r0, _, e1 := Syscall(SYS_SHMGET, uintptr(key), uintptr(size), uintptr(flag)) ++ id = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func getitimer(which int, currValue *Itimerval) (err error) { ++ _, _, e1 := Syscall(SYS_GETITIMER, uintptr(which), uintptr(unsafe.Pointer(currValue)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func setitimer(which int, newValue *Itimerval, oldValue *Itimerval) (err error) { ++ _, _, e1 := Syscall(SYS_SETITIMER, uintptr(which), uintptr(unsafe.Pointer(newValue)), uintptr(unsafe.Pointer(oldValue))) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func rtSigprocmask(how int, set *Sigset_t, oldset *Sigset_t, sigsetsize uintptr) (err error) { ++ _, _, e1 := RawSyscall6(SYS_RT_SIGPROCMASK, uintptr(how), uintptr(unsafe.Pointer(set)), uintptr(unsafe.Pointer(oldset)), uintptr(sigsetsize), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func getresuid(ruid *_C_int, euid *_C_int, suid *_C_int) { ++ RawSyscallNoError(SYS_GETRESUID, uintptr(unsafe.Pointer(ruid)), uintptr(unsafe.Pointer(euid)), uintptr(unsafe.Pointer(suid))) ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func getresgid(rgid *_C_int, egid *_C_int, sgid *_C_int) { ++ RawSyscallNoError(SYS_GETRESGID, uintptr(unsafe.Pointer(rgid)), uintptr(unsafe.Pointer(egid)), uintptr(unsafe.Pointer(sgid))) ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func schedSetattr(pid int, attr *SchedAttr, flags uint) (err error) { ++ _, _, e1 := Syscall(SYS_SCHED_SETATTR, uintptr(pid), uintptr(unsafe.Pointer(attr)), uintptr(flags)) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func schedGetattr(pid int, attr *SchedAttr, size uint, flags uint) (err error) { ++ _, _, e1 := Syscall6(SYS_SCHED_GETATTR, uintptr(pid), uintptr(unsafe.Pointer(attr)), uintptr(size), uintptr(flags), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Cachestat(fd uint, crange *CachestatRange, cstat *Cachestat_t, flags uint) (err error) { ++ _, _, e1 := Syscall6(SYS_CACHESTAT, uintptr(fd), uintptr(unsafe.Pointer(crange)), uintptr(unsafe.Pointer(cstat)), uintptr(flags), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Mseal(b []byte, flags uint) (err error) { ++ var _p0 unsafe.Pointer ++ if len(b) > 0 { ++ _p0 = unsafe.Pointer(&b[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ _, _, e1 := Syscall(SYS_MSEAL, uintptr(_p0), uintptr(len(b)), uintptr(flags)) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func getxpid() (pid int, ppid int) { ++ r0, r1 := RawSyscallNoError(SYS_GETXPID, 0, 0, 0) ++ pid = int(r0) ++ ppid = int(r1) ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Fstat64(fd int, st *Stat_t) (err error) { ++ _, _, e1 := Syscall(SYS_FSTAT64, uintptr(fd), uintptr(unsafe.Pointer(st)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Lstat64(path string, st *Stat_t) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall(SYS_LSTAT64, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(st)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Stat64(path string, st *Stat_t) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall(SYS_STAT64, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(st)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func getxuid() (uid int, euid int) { ++ r0, r1 := SyscallNoError(SYS_GETXUID, 0, 0, 0) ++ uid = int(r0) ++ euid = int(r1) ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func getxgid() (gid int, egid int) { ++ r0, r1 := SyscallNoError(SYS_GETXGID, 0, 0, 0) ++ gid = int(r0) ++ egid = int(r1) ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Statfs(path string, buf *Statfs_t) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(buf)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Fstatfs(fd int, buf *Statfs_t) (err error) { ++ _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(buf)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Fchown(fd int, uid int, gid int) (err error) { ++ _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid)) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Ftruncate(fd int, length int64) (err error) { ++ _, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), uintptr(length), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Getrlimit(resource int, rlim *Rlimit) (err error) { ++ _, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Lchown(path string, uid int, gid int) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid)) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Listen(s int, n int) (err error) { ++ _, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(n), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func pread(fd int, p []byte, offset int64) (n int, err error) { ++ var _p0 unsafe.Pointer ++ if len(p) > 0 { ++ _p0 = unsafe.Pointer(&p[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ r0, _, e1 := Syscall6(SYS_PREAD64, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0) ++ n = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func pwrite(fd int, p []byte, offset int64) (n int, err error) { ++ var _p0 unsafe.Pointer ++ if len(p) > 0 { ++ _p0 = unsafe.Pointer(&p[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ r0, _, e1 := Syscall6(SYS_PWRITE64, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0) ++ n = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Seek(fd int, offset int64, whence int) (off int64, err error) { ++ r0, _, e1 := Syscall(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(whence)) ++ off = int64(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { ++ r0, _, e1 := Syscall6(SYS_SENDFILE, uintptr(outfd), uintptr(infd), uintptr(unsafe.Pointer(offset)), uintptr(count), 0, 0) ++ written = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func setfsgid(gid int) (prev int, err error) { ++ r0, _, e1 := Syscall(SYS_SETFSGID, uintptr(gid), 0, 0) ++ prev = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func setfsuid(uid int) (prev int, err error) { ++ r0, _, e1 := Syscall(SYS_SETFSUID, uintptr(uid), 0, 0) ++ prev = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Shutdown(fd int, how int) (err error) { ++ _, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) { ++ r0, _, e1 := Syscall6(SYS_SPLICE, uintptr(rfd), uintptr(unsafe.Pointer(roff)), uintptr(wfd), uintptr(unsafe.Pointer(woff)), uintptr(len), uintptr(flags)) ++ n = int64(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func SyncFileRange(fd int, off int64, n int64, flags int) (err error) { ++ _, _, e1 := Syscall6(SYS_SYNC_FILE_RANGE, uintptr(fd), uintptr(off), uintptr(n), uintptr(flags), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Truncate(path string, length int64) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), uintptr(length), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) { ++ r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) ++ fd = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) { ++ r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0) ++ fd = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { ++ _, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen)) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { ++ _, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen)) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func getgroups(n int, list *_Gid_t) (nn int, err error) { ++ r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(n), uintptr(unsafe.Pointer(list)), 0) ++ nn = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func setgroups(n int, list *_Gid_t) (err error) { ++ _, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(n), uintptr(unsafe.Pointer(list)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) { ++ _, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) { ++ _, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func socket(domain int, typ int, proto int) (fd int, err error) { ++ r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto)) ++ fd = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) { ++ _, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { ++ _, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { ++ _, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) { ++ var _p0 unsafe.Pointer ++ if len(p) > 0 { ++ _p0 = unsafe.Pointer(&p[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen))) ++ n = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) { ++ var _p0 unsafe.Pointer ++ if len(buf) > 0 { ++ _p0 = unsafe.Pointer(&buf[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ _, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen)) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) { ++ r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags)) ++ n = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) { ++ r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags)) ++ n = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) { ++ r0, _, e1 := Syscall6(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flags), uintptr(fd), uintptr(offset)) ++ xaddr = uintptr(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Gettimeofday(tv *Timeval) (err error) { ++ _, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) { ++ var _p0 unsafe.Pointer ++ if len(events) > 0 { ++ _p0 = unsafe.Pointer(&events[0]) ++ } else { ++ _p0 = unsafe.Pointer(&_zero) ++ } ++ r0, _, e1 := Syscall6(SYS_EPOLL_WAIT, uintptr(epfd), uintptr(_p0), uintptr(len(events)), uintptr(msec), 0, 0) ++ n = int(r0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Fadvise(fd int, offset int64, length int64, advice int) (err error) { ++ _, _, e1 := Syscall6(SYS_FADVISE64, uintptr(fd), uintptr(offset), uintptr(length), uintptr(advice), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall6(SYS_NEWFSTATAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Ustat(dev int, ubuf *Ustat_t) (err error) { ++ _, _, e1 := Syscall(SYS_USTAT, uintptr(dev), uintptr(unsafe.Pointer(ubuf)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func futimesat(dirfd int, path string, times *[2]Timeval) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall(SYS_FUTIMESAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times))) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func utimes(path string, times *[2]Timeval) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} ++ ++// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT ++ ++func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(oldpath) ++ if err != nil { ++ return ++ } ++ var _p1 *byte ++ _p1, err = BytePtrFromString(newpath) ++ if err != nil { ++ return ++ } ++ _, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), 0, 0) ++ if e1 != 0 { ++ err = errnoErr(e1) ++ } ++ return ++} +diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_sw64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_sw64.go +new file mode 100644 +index 0000000000..e4e3102a64 +--- /dev/null ++++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_sw64.go +@@ -0,0 +1,390 @@ ++// go run linux/mksysnum.go -Wall -Werror -static -I/tmp/sw64/include /tmp/sw64/include/asm/unistd.h ++// Code generated by the command above; see README.md. DO NOT EDIT. ++ ++//go:build sw64 && linux ++ ++package unix ++ ++const ( ++ SYS_EXIT = 1 ++ SYS_FORK = 2 ++ SYS_READ = 3 ++ SYS_WRITE = 4 ++ SYS_CLOSE = 6 ++ SYS_LINK = 9 ++ SYS_UNLINK = 10 ++ SYS_CHDIR = 12 ++ SYS_FCHDIR = 13 ++ SYS_MKNOD = 14 ++ SYS_CHMOD = 15 ++ SYS_CHOWN = 16 ++ SYS_BRK = 17 ++ SYS_LSEEK = 19 ++ SYS_GETXPID = 20 ++ SYS_UMOUNT2 = 22 ++ SYS_SETUID = 23 ++ SYS_GETXUID = 24 ++ SYS_PTRACE = 26 ++ SYS_ACCESS = 33 ++ SYS_SYNC = 36 ++ SYS_KILL = 37 ++ SYS_SETPGID = 39 ++ SYS_DUP = 41 ++ SYS_PIPE = 42 ++ SYS_OPEN = 45 ++ SYS_GETXGID = 47 ++ SYS_ODD_SIGPROCMASK = 48 ++ SYS_ACCT = 51 ++ SYS_SIGPENDING = 52 ++ SYS_IOCTL = 54 ++ SYS_SYMLINK = 57 ++ SYS_READLINK = 58 ++ SYS_EXECVE = 59 ++ SYS_UMASK = 60 ++ SYS_CHROOT = 61 ++ SYS_GETPGRP = 63 ++ SYS_VFORK = 66 ++ SYS_STAT = 67 ++ SYS_LSTAT = 68 ++ SYS_MMAP = 71 ++ SYS_MUNMAP = 73 ++ SYS_MPROTECT = 74 ++ SYS_MADVISE = 75 ++ SYS_VHANGUP = 76 ++ SYS_GETGROUPS = 79 ++ SYS_SETGROUPS = 80 ++ SYS_SETPGRP = 82 ++ SYS_GETHOSTNAME = 87 ++ SYS_SETHOSTNAME = 88 ++ SYS_DUP2 = 90 ++ SYS_FSTAT = 91 ++ SYS_FCNTL = 92 ++ SYS_POLL = 94 ++ SYS_FSYNC = 95 ++ SYS_SETPRIORITY = 96 ++ SYS_SOCKET = 97 ++ SYS_CONNECT = 98 ++ SYS_ACCEPT = 99 ++ SYS_ODD_GETPRIORITY = 100 ++ SYS_SEND = 101 ++ SYS_RECV = 102 ++ SYS_SIGRETURN = 103 ++ SYS_BIND = 104 ++ SYS_SETSOCKOPT = 105 ++ SYS_LISTEN = 106 ++ SYS_SIGSUSPEND = 111 ++ SYS_RECVMSG = 113 ++ SYS_SENDMSG = 114 ++ SYS_GETSOCKOPT = 118 ++ SYS_SOCKETCALL = 119 ++ SYS_READV = 120 ++ SYS_WRITEV = 121 ++ SYS_FCHOWN = 123 ++ SYS_FCHMOD = 124 ++ SYS_RECVFROM = 125 ++ SYS_SETREUID = 126 ++ SYS_SETREGID = 127 ++ SYS_RENAME = 128 ++ SYS_TRUNCATE = 129 ++ SYS_FTRUNCATE = 130 ++ SYS_FLOCK = 131 ++ SYS_SETGID = 132 ++ SYS_SENDTO = 133 ++ SYS_SHUTDOWN = 134 ++ SYS_SOCKETPAIR = 135 ++ SYS_MKDIR = 136 ++ SYS_RMDIR = 137 ++ SYS_GETPEERNAME = 141 ++ SYS_GETRLIMIT = 144 ++ SYS_SETRLIMIT = 145 ++ SYS_SETSID = 147 ++ SYS_QUOTACTL = 148 ++ SYS_GETSOCKNAME = 150 ++ SYS_SIGACTION = 156 ++ SYS_SETDOMAINNAME = 166 ++ SYS_BPF = 170 ++ SYS_USERFAULTFD = 171 ++ SYS_MEMBARRIER = 172 ++ SYS_MLOCK2 = 173 ++ SYS_GETPID = 174 ++ SYS_GETPPID = 175 ++ SYS_GETUID = 176 ++ SYS_GETEUID = 177 ++ SYS_GETGID = 178 ++ SYS_GETEGID = 179 ++ SYS_EPOLL_PWAIT2 = 180 ++ SYS_MOUNT_SETATTR = 181 ++ SYS_QUOTACTL_FD = 182 ++ SYS_LANDLOCK_CREATE_RULESET = 183 ++ SYS_LANDLOCK_ADD_RULE = 184 ++ SYS_LANDLOCK_RESTRICT_SELF = 185 ++ SYS_PROCESS_MRELEASE = 187 ++ SYS_FUTEX_WAITV = 188 ++ SYS_SET_MEMPOLICY_HOME_NODE = 189 ++ SYS_CACHESTAT = 190 ++ SYS_FCHMODAT2 = 191 ++ SYS_MSGCTL = 200 ++ SYS_MSGGET = 201 ++ SYS_MSGRCV = 202 ++ SYS_MSGSND = 203 ++ SYS_SEMCTL = 204 ++ SYS_SEMGET = 205 ++ SYS_SEMOP = 206 ++ SYS_LCHOWN = 208 ++ SYS_SHMAT = 209 ++ SYS_SHMCTL = 210 ++ SYS_SHMDT = 211 ++ SYS_SHMGET = 212 ++ SYS_MSYNC = 217 ++ SYS_STATFS64 = 229 ++ SYS_FSTATFS64 = 230 ++ SYS_GETPGID = 233 ++ SYS_GETSID = 234 ++ SYS_SIGALTSTACK = 235 ++ SYS_SYSFS = 254 ++ SYS_GETSYSINFO = 256 ++ SYS_SETSYSINFO = 257 ++ SYS_PIDFD_SEND_SIGNAL = 271 ++ SYS_IO_URING_SETUP = 272 ++ SYS_IO_URING_ENTER = 273 ++ SYS_IO_URING_REGISTER = 274 ++ SYS_OPEN_TREE = 275 ++ SYS_MOVE_MOUNT = 276 ++ SYS_FSOPEN = 277 ++ SYS_FSCONFIG = 278 ++ SYS_FSMOUNT = 279 ++ SYS_FSPICK = 280 ++ SYS_PIDFD_OPEN = 281 ++ SYS_CLONE3 = 282 ++ SYS_CLOSE_RANGE = 283 ++ SYS_OPENAT2 = 284 ++ SYS_PIDFD_GETFD = 285 ++ SYS_FACCESSAT2 = 286 ++ SYS_PROCESS_MADVISE = 287 ++ SYS_PKEY_MPROTECT = 288 ++ SYS_PKEY_ALLOC = 289 ++ SYS_PKEY_FREE = 290 ++ SYS_GETPRIORITY = 298 ++ SYS_SIGPROCMASK = 299 ++ SYS_BDFLUSH = 300 ++ SYS_MOUNT = 302 ++ SYS_SWAPOFF = 304 ++ SYS_GETDENTS = 305 ++ SYS_CREATE_MODULE = 306 ++ SYS_INIT_MODULE = 307 ++ SYS_DELETE_MODULE = 308 ++ SYS_GET_KERNEL_SYMS = 309 ++ SYS_SYSLOG = 310 ++ SYS_REBOOT = 311 ++ SYS_CLONE = 312 ++ SYS_USELIB = 313 ++ SYS_MLOCK = 314 ++ SYS_MUNLOCK = 315 ++ SYS_MLOCKALL = 316 ++ SYS_MUNLOCKALL = 317 ++ SYS_SYSINFO = 318 ++ SYS_OLDUMOUNT = 321 ++ SYS_SWAPON = 322 ++ SYS_TIMES = 323 ++ SYS_PERSONALITY = 324 ++ SYS_SETFSUID = 325 ++ SYS_SETFSGID = 326 ++ SYS_USTAT = 327 ++ SYS_STATFS = 328 ++ SYS_FSTATFS = 329 ++ SYS_SCHED_SETPARAM = 330 ++ SYS_SCHED_GETPARAM = 331 ++ SYS_SCHED_SETSCHEDULER = 332 ++ SYS_SCHED_GETSCHEDULER = 333 ++ SYS_SCHED_YIELD = 334 ++ SYS_SCHED_GET_PRIORITY_MAX = 335 ++ SYS_SCHED_GET_PRIORITY_MIN = 336 ++ SYS_SCHED_RR_GET_INTERVAL = 337 ++ SYS_AFS_SYSCALL = 338 ++ SYS_UNAME = 339 ++ SYS_NANOSLEEP = 340 ++ SYS_MREMAP = 341 ++ SYS_NFSSERVCTL = 342 ++ SYS_SETRESUID = 343 ++ SYS_GETRESUID = 344 ++ SYS_PCICONFIG_READ = 345 ++ SYS_PCICONFIG_WRITE = 346 ++ SYS_QUERY_MODULE = 347 ++ SYS_PRCTL = 348 ++ SYS_PREAD64 = 349 ++ SYS_PWRITE64 = 350 ++ SYS_RT_SIGRETURN = 351 ++ SYS_RT_SIGACTION = 352 ++ SYS_RT_SIGPROCMASK = 353 ++ SYS_RT_SIGPENDING = 354 ++ SYS_RT_SIGTIMEDWAIT = 355 ++ SYS_RT_SIGQUEUEINFO = 356 ++ SYS_RT_SIGSUSPEND = 357 ++ SYS_SELECT = 358 ++ SYS_GETTIMEOFDAY = 359 ++ SYS_SETTIMEOFDAY = 360 ++ SYS_GETITIMER = 361 ++ SYS_SETITIMER = 362 ++ SYS_UTIMES = 363 ++ SYS_GETRUSAGE = 364 ++ SYS_WAIT4 = 365 ++ SYS_ADJTIMEX = 366 ++ SYS_GETCWD = 367 ++ SYS_CAPGET = 368 ++ SYS_CAPSET = 369 ++ SYS_SENDFILE = 370 ++ SYS_SETRESGID = 371 ++ SYS_GETRESGID = 372 ++ SYS_DIPC = 373 ++ SYS_PIVOT_ROOT = 374 ++ SYS_MINCORE = 375 ++ SYS_PCICONFIG_IOBASE = 376 ++ SYS_GETDENTS64 = 377 ++ SYS_GETTID = 378 ++ SYS_READAHEAD = 379 ++ SYS_TKILL = 381 ++ SYS_SETXATTR = 382 ++ SYS_LSETXATTR = 383 ++ SYS_FSETXATTR = 384 ++ SYS_GETXATTR = 385 ++ SYS_LGETXATTR = 386 ++ SYS_FGETXATTR = 387 ++ SYS_LISTXATTR = 388 ++ SYS_LLISTXATTR = 389 ++ SYS_FLISTXATTR = 390 ++ SYS_REMOVEXATTR = 391 ++ SYS_LREMOVEXATTR = 392 ++ SYS_FREMOVEXATTR = 393 ++ SYS_FUTEX = 394 ++ SYS_SCHED_SETAFFINITY = 395 ++ SYS_SCHED_GETAFFINITY = 396 ++ SYS_TUXCALL = 397 ++ SYS_IO_SETUP = 398 ++ SYS_IO_DESTROY = 399 ++ SYS_IO_GETEVENTS = 400 ++ SYS_IO_SUBMIT = 401 ++ SYS_IO_CANCEL = 402 ++ SYS_IO_PGETEVENTS = 403 ++ SYS_RSEQ = 404 ++ SYS_EXIT_GROUP = 405 ++ SYS_LOOKUP_DCOOKIE = 406 ++ SYS_EPOLL_CREATE = 407 ++ SYS_EPOLL_CTL = 408 ++ SYS_EPOLL_WAIT = 409 ++ SYS_REMAP_FILE_PAGES = 410 ++ SYS_SET_TID_ADDRESS = 411 ++ SYS_RESTART_SYSCALL = 412 ++ SYS_FADVISE64 = 413 ++ SYS_TIMER_CREATE = 414 ++ SYS_TIMER_SETTIME = 415 ++ SYS_TIMER_GETTIME = 416 ++ SYS_TIMER_GETOVERRUN = 417 ++ SYS_TIMER_DELETE = 418 ++ SYS_CLOCK_SETTIME = 419 ++ SYS_CLOCK_GETTIME = 420 ++ SYS_CLOCK_GETRES = 421 ++ SYS_CLOCK_NANOSLEEP = 422 ++ SYS_SEMTIMEDOP = 423 ++ SYS_TGKILL = 424 ++ SYS_STAT64 = 425 ++ SYS_LSTAT64 = 426 ++ SYS_FSTAT64 = 427 ++ SYS_VSERVER = 428 ++ SYS_MBIND = 429 ++ SYS_GET_MEMPOLICY = 430 ++ SYS_SET_MEMPOLICY = 431 ++ SYS_MQ_OPEN = 432 ++ SYS_MQ_UNLINK = 433 ++ SYS_MQ_TIMEDSEND = 434 ++ SYS_MQ_TIMEDRECEIVE = 435 ++ SYS_MQ_NOTIFY = 436 ++ SYS_MQ_GETSETATTR = 437 ++ SYS_WAITID = 438 ++ SYS_ADD_KEY = 439 ++ SYS_REQUEST_KEY = 440 ++ SYS_KEYCTL = 441 ++ SYS_IOPRIO_SET = 442 ++ SYS_IOPRIO_GET = 443 ++ SYS_INOTIFY_INIT = 444 ++ SYS_INOTIFY_ADD_WATCH = 445 ++ SYS_INOTIFY_RM_WATCH = 446 ++ SYS_FDATASYNC = 447 ++ SYS_KEXEC_LOAD = 448 ++ SYS_MIGRATE_PAGES = 449 ++ SYS_OPENAT = 450 ++ SYS_MKDIRAT = 451 ++ SYS_MKNODAT = 452 ++ SYS_FCHOWNAT = 453 ++ SYS_FUTIMESAT = 454 ++ SYS_FSTATAT64 = 455 ++ SYS_UNLINKAT = 456 ++ SYS_RENAMEAT = 457 ++ SYS_LINKAT = 458 ++ SYS_SYMLINKAT = 459 ++ SYS_READLINKAT = 460 ++ SYS_FCHMODAT = 461 ++ SYS_FACCESSAT = 462 ++ SYS_PSELECT6 = 463 ++ SYS_PPOLL = 464 ++ SYS_UNSHARE = 465 ++ SYS_SET_ROBUST_LIST = 466 ++ SYS_GET_ROBUST_LIST = 467 ++ SYS_SPLICE = 468 ++ SYS_SYNC_FILE_RANGE = 469 ++ SYS_TEE = 470 ++ SYS_VMSPLICE = 471 ++ SYS_MOVE_PAGES = 472 ++ SYS_GETCPU = 473 ++ SYS_EPOLL_PWAIT = 474 ++ SYS_UTIMENSAT = 475 ++ SYS_SIGNALFD = 476 ++ SYS_TIMERFD = 477 ++ SYS_EVENTFD = 478 ++ SYS_RECVMMSG = 479 ++ SYS_FALLOCATE = 480 ++ SYS_TIMERFD_CREATE = 481 ++ SYS_TIMERFD_SETTIME = 482 ++ SYS_TIMERFD_GETTIME = 483 ++ SYS_SIGNALFD4 = 484 ++ SYS_EVENTFD2 = 485 ++ SYS_EPOLL_CREATE1 = 486 ++ SYS_DUP3 = 487 ++ SYS_PIPE2 = 488 ++ SYS_INOTIFY_INIT1 = 489 ++ SYS_PREADV = 490 ++ SYS_PWRITEV = 491 ++ SYS_RT_TGSIGQUEUEINFO = 492 ++ SYS_PERF_EVENT_OPEN = 493 ++ SYS_FANOTIFY_INIT = 494 ++ SYS_FANOTIFY_MARK = 495 ++ SYS_PRLIMIT64 = 496 ++ SYS_NAME_TO_HANDLE_AT = 497 ++ SYS_OPEN_BY_HANDLE_AT = 498 ++ SYS_CLOCK_ADJTIME = 499 ++ SYS_SYNCFS = 500 ++ SYS_SETNS = 501 ++ SYS_ACCEPT4 = 502 ++ SYS_SENDMMSG = 503 ++ SYS_PROCESS_VM_READV = 504 ++ SYS_PROCESS_VM_WRITEV = 505 ++ SYS_KCMP = 506 ++ SYS_FINIT_MODULE = 507 ++ SYS_SCHED_SETATTR = 508 ++ SYS_SCHED_GETATTR = 509 ++ SYS_RENAMEAT2 = 510 ++ SYS_GETRANDOM = 511 ++ SYS_MEMFD_CREATE = 512 ++ SYS_EXECVEAT = 513 ++ SYS_SECCOMP = 514 ++ SYS_COPY_FILE_RANGE = 515 ++ SYS_PREADV2 = 516 ++ SYS_PWRITEV2 = 517 ++ SYS_STATX = 518 ++ /* ++ WARNING ++ SYS_MSEAL is introduced in linux6.10 while the latest linux of SW64 ++ is 6.6. So the number blow is only for pass the compile and should be ++ changed to correct one in the future. ++ */ ++ SYS_MSEAL = 9462 ++) +diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux.go +index 5537148dcb..99b7274d3e 100644 +--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux.go ++++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux.go +@@ -1,6 +1,6 @@ + // Code generated by mkmerge; DO NOT EDIT. + +-//go:build linux ++//go:build linux && !sw64 + + package unix + +diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_sw64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_sw64.go +new file mode 100644 +index 0000000000..9cc2a5b091 +--- /dev/null ++++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_sw64.go +@@ -0,0 +1,6786 @@ ++// cgo -godefs -objdir=/tmp/sw64/cgo -- -Wall -Werror -static -I/tmp/sw64/include /home/zhangjh/git-source/go/sys-1.24/unix/linux/types.go | go run mkpost.go ++// Code generated by the command above; see README.md. DO NOT EDIT. ++ ++//go:build sw64 && linux ++ ++package unix ++ ++const ( ++ SizeofPtr = 0x8 ++ SizeofShort = 0x2 ++ SizeofInt = 0x4 ++ SizeofLong = 0x8 ++ SizeofLongLong = 0x8 ++ PathMax = 0x1000 ++) ++ ++type ( ++ _C_short int16 ++ _C_int int32 ++ _C_long int64 ++ _C_long_long int64 ++) ++ ++type Timespec struct { ++ Sec int64 ++ Nsec int64 ++} ++ ++type Timeval struct { ++ Sec int64 ++ Usec int64 ++} ++ ++type Timex struct { ++ Modes uint32 ++ Offset int64 ++ Freq int64 ++ Maxerror int64 ++ Esterror int64 ++ Status int32 ++ Constant int64 ++ Precision int64 ++ Tolerance int64 ++ Time Timeval ++ Tick int64 ++ Ppsfreq int64 ++ Jitter int64 ++ Shift int32 ++ Stabil int64 ++ Jitcnt int64 ++ Calcnt int64 ++ Errcnt int64 ++ Stbcnt int64 ++ Tai int32 ++ _ [44]byte ++} ++ ++type ItimerSpec struct { ++ Interval Timespec ++ Value Timespec ++} ++ ++type Itimerval struct { ++ Interval Timeval ++ Value Timeval ++} ++ ++const ( ++ ADJ_OFFSET = 0x1 ++ ADJ_FREQUENCY = 0x2 ++ ADJ_MAXERROR = 0x4 ++ ADJ_ESTERROR = 0x8 ++ ADJ_STATUS = 0x10 ++ ADJ_TIMECONST = 0x20 ++ ADJ_TAI = 0x80 ++ ADJ_SETOFFSET = 0x100 ++ ADJ_MICRO = 0x1000 ++ ADJ_NANO = 0x2000 ++ ADJ_TICK = 0x4000 ++ ADJ_OFFSET_SINGLESHOT = 0x8001 ++ ADJ_OFFSET_SS_READ = 0xa001 ++) ++ ++const ( ++ STA_PLL = 0x1 ++ STA_PPSFREQ = 0x2 ++ STA_PPSTIME = 0x4 ++ STA_FLL = 0x8 ++ STA_INS = 0x10 ++ STA_DEL = 0x20 ++ STA_UNSYNC = 0x40 ++ STA_FREQHOLD = 0x80 ++ STA_PPSSIGNAL = 0x100 ++ STA_PPSJITTER = 0x200 ++ STA_PPSWANDER = 0x400 ++ STA_PPSERROR = 0x800 ++ STA_CLOCKERR = 0x1000 ++ STA_NANO = 0x2000 ++ STA_MODE = 0x4000 ++ STA_CLK = 0x8000 ++) ++ ++const ( ++ TIME_OK = 0x0 ++ TIME_INS = 0x1 ++ TIME_DEL = 0x2 ++ TIME_OOP = 0x3 ++ TIME_WAIT = 0x4 ++ TIME_ERROR = 0x5 ++ TIME_BAD = 0x5 ++) ++ ++type Time_t int64 ++ ++type Tms struct { ++ Utime int64 ++ Stime int64 ++ Cutime int64 ++ Cstime int64 ++} ++ ++type Utimbuf struct { ++ Actime int64 ++ Modtime int64 ++} ++ ++type Rusage struct { ++ Utime Timeval ++ Stime Timeval ++ Maxrss int64 ++ Ixrss int64 ++ Idrss int64 ++ Isrss int64 ++ Minflt int64 ++ Majflt int64 ++ Nswap int64 ++ Inblock int64 ++ Oublock int64 ++ Msgsnd int64 ++ Msgrcv int64 ++ Nsignals int64 ++ Nvcsw int64 ++ Nivcsw int64 ++} ++ ++type Rlimit struct { ++ Cur uint64 ++ Max uint64 ++} ++ ++type _Gid_t uint32 ++ ++type Stat_t struct { ++ Dev uint64 ++ Ino uint64 ++ Rdev uint64 ++ Size int64 ++ Blocks uint64 ++ Mode uint32 ++ Uid uint32 ++ Gid uint32 ++ Blksize uint32 ++ Nlink uint32 ++ _ int32 ++ Atim Timespec ++ Mtim Timespec ++ Ctim Timespec ++ _ [3]int64 ++} ++ ++type StatxTimestamp struct { ++ Sec int64 ++ Nsec uint32 ++ _ int32 ++} ++ ++type Statx_t struct { ++ Mask uint32 ++ Blksize uint32 ++ Attributes uint64 ++ Nlink uint32 ++ Uid uint32 ++ Gid uint32 ++ Mode uint16 ++ _ [1]uint16 ++ Ino uint64 ++ Size uint64 ++ Blocks uint64 ++ Attributes_mask uint64 ++ Atime StatxTimestamp ++ Btime StatxTimestamp ++ Ctime StatxTimestamp ++ Mtime StatxTimestamp ++ Rdev_major uint32 ++ Rdev_minor uint32 ++ Dev_major uint32 ++ Dev_minor uint32 ++ Mnt_id uint64 ++ Dio_mem_align uint32 ++ Dio_offset_align uint32 ++ _ [12]uint64 ++} ++ ++type Dirent struct { ++ Ino uint64 ++ Off int64 ++ Reclen uint16 ++ Type uint8 ++ Name [256]int8 ++ _ [5]byte ++} ++ ++type Fsid struct { ++ Val [2]int32 ++} ++ ++type Flock_t struct { ++ Type int16 ++ Whence int16 ++ Start int64 ++ Len int64 ++ Pid int32 ++ _ [4]byte ++} ++ ++type FileCloneRange struct { ++ Src_fd int64 ++ Src_offset uint64 ++ Src_length uint64 ++ Dest_offset uint64 ++} ++ ++type RawFileDedupeRange struct { ++ Src_offset uint64 ++ Src_length uint64 ++ Dest_count uint16 ++ Reserved1 uint16 ++ Reserved2 uint32 ++} ++ ++type RawFileDedupeRangeInfo struct { ++ Dest_fd int64 ++ Dest_offset uint64 ++ Bytes_deduped uint64 ++ Status int32 ++ Reserved uint32 ++} ++ ++const ( ++ SizeofRawFileDedupeRange = 0x18 ++ SizeofRawFileDedupeRangeInfo = 0x20 ++ FILE_DEDUPE_RANGE_SAME = 0x0 ++ FILE_DEDUPE_RANGE_DIFFERS = 0x1 ++) ++ ++type FscryptPolicy struct { ++ Version uint8 ++ Contents_encryption_mode uint8 ++ Filenames_encryption_mode uint8 ++ Flags uint8 ++ Master_key_descriptor [8]uint8 ++} ++ ++type FscryptKey struct { ++ Mode uint32 ++ Raw [64]uint8 ++ Size uint32 ++} ++ ++type FscryptPolicyV1 struct { ++ Version uint8 ++ Contents_encryption_mode uint8 ++ Filenames_encryption_mode uint8 ++ Flags uint8 ++ Master_key_descriptor [8]uint8 ++} ++ ++type FscryptPolicyV2 struct { ++ Version uint8 ++ Contents_encryption_mode uint8 ++ Filenames_encryption_mode uint8 ++ Flags uint8 ++ _ [4]uint8 ++ Master_key_identifier [16]uint8 ++} ++ ++type FscryptGetPolicyExArg struct { ++ Size uint64 ++ Policy [24]byte ++} ++ ++type FscryptKeySpecifier struct { ++ Type uint32 ++ _ uint32 ++ U [32]byte ++} ++ ++type FscryptAddKeyArg struct { ++ Key_spec FscryptKeySpecifier ++ Raw_size uint32 ++ Key_id uint32 ++ _ [8]uint32 ++} ++ ++type FscryptRemoveKeyArg struct { ++ Key_spec FscryptKeySpecifier ++ Removal_status_flags uint32 ++ _ [5]uint32 ++} ++ ++type FscryptGetKeyStatusArg struct { ++ Key_spec FscryptKeySpecifier ++ _ [6]uint32 ++ Status uint32 ++ Status_flags uint32 ++ User_count uint32 ++ _ [13]uint32 ++} ++ ++type DmIoctl struct { ++ Version [3]uint32 ++ Data_size uint32 ++ Data_start uint32 ++ Target_count uint32 ++ Open_count int32 ++ Flags uint32 ++ Event_nr uint32 ++ _ uint32 ++ Dev uint64 ++ Name [128]byte ++ Uuid [129]byte ++ Data [7]byte ++} ++ ++type DmTargetSpec struct { ++ Sector_start uint64 ++ Length uint64 ++ Status int32 ++ Next uint32 ++ Target_type [16]byte ++} ++ ++type DmTargetDeps struct { ++ Count uint32 ++ _ uint32 ++} ++ ++type DmNameList struct { ++ Dev uint64 ++ Next uint32 ++ Name [0]byte ++ _ [4]byte ++} ++ ++type DmTargetVersions struct { ++ Next uint32 ++ Version [3]uint32 ++} ++ ++type DmTargetMsg struct { ++ Sector uint64 ++} ++ ++const ( ++ SizeofDmIoctl = 0x138 ++ SizeofDmTargetSpec = 0x28 ++) ++ ++type KeyctlDHParams struct { ++ Private int32 ++ Prime int32 ++ Base int32 ++} ++ ++const ( ++ FADV_NORMAL = 0x0 ++ FADV_RANDOM = 0x1 ++ FADV_SEQUENTIAL = 0x2 ++ FADV_WILLNEED = 0x3 ++ FADV_DONTNEED = 0x4 ++ FADV_NOREUSE = 0x5 ++) ++ ++type RawSockaddrInet4 struct { ++ Family uint16 ++ Port uint16 ++ Addr [4]byte /* in_addr */ ++ Zero [8]uint8 ++} ++ ++type RawSockaddrInet6 struct { ++ Family uint16 ++ Port uint16 ++ Flowinfo uint32 ++ Addr [16]byte /* in6_addr */ ++ Scope_id uint32 ++} ++ ++type RawSockaddrUnix struct { ++ Family uint16 ++ Path [108]int8 ++} ++ ++type RawSockaddrLinklayer struct { ++ Family uint16 ++ Protocol uint16 ++ Ifindex int32 ++ Hatype uint16 ++ Pkttype uint8 ++ Halen uint8 ++ Addr [8]uint8 ++} ++ ++type RawSockaddrNetlink struct { ++ Family uint16 ++ Pad uint16 ++ Pid uint32 ++ Groups uint32 ++} ++ ++type RawSockaddrHCI struct { ++ Family uint16 ++ Dev uint16 ++ Channel uint16 ++} ++ ++type RawSockaddrL2 struct { ++ Family uint16 ++ Psm uint16 ++ Bdaddr [6]uint8 ++ Cid uint16 ++ Bdaddr_type uint8 ++ _ [1]byte ++} ++ ++type RawSockaddrRFCOMM struct { ++ Family uint16 ++ Bdaddr [6]uint8 ++ Channel uint8 ++ _ [1]byte ++} ++ ++type RawSockaddrCAN struct { ++ Family uint16 ++ Ifindex int32 ++ Addr [16]byte ++} ++ ++type RawSockaddrALG struct { ++ Family uint16 ++ Type [14]uint8 ++ Feat uint32 ++ Mask uint32 ++ Name [64]uint8 ++} ++ ++type RawSockaddrVM struct { ++ Family uint16 ++ Reserved1 uint16 ++ Port uint32 ++ Cid uint32 ++ Flags uint8 ++ Zero [3]uint8 ++} ++ ++type RawSockaddrXDP struct { ++ Family uint16 ++ Flags uint16 ++ Ifindex uint32 ++ Queue_id uint32 ++ Shared_umem_fd uint32 ++} ++ ++type RawSockaddrPPPoX [0x1e]byte ++ ++type RawSockaddrTIPC struct { ++ Family uint16 ++ Addrtype uint8 ++ Scope int8 ++ Addr [12]byte ++} ++ ++type RawSockaddrL2TPIP struct { ++ Family uint16 ++ Unused uint16 ++ Addr [4]byte /* in_addr */ ++ Conn_id uint32 ++ _ [4]uint8 ++} ++ ++type RawSockaddrL2TPIP6 struct { ++ Family uint16 ++ Unused uint16 ++ Flowinfo uint32 ++ Addr [16]byte /* in6_addr */ ++ Scope_id uint32 ++ Conn_id uint32 ++} ++ ++type RawSockaddrIUCV struct { ++ Family uint16 ++ Port uint16 ++ Addr uint32 ++ Nodeid [8]int8 ++ User_id [8]int8 ++ Name [8]int8 ++} ++ ++type RawSockaddrNFC struct { ++ Sa_family uint16 ++ Dev_idx uint32 ++ Target_idx uint32 ++ Nfc_protocol uint32 ++} ++ ++type RawSockaddrNFCLLCP struct { ++ Sa_family uint16 ++ Dev_idx uint32 ++ Target_idx uint32 ++ Nfc_protocol uint32 ++ Dsap uint8 ++ Ssap uint8 ++ Service_name [63]uint8 ++ Service_name_len uint64 ++} ++ ++type RawSockaddr struct { ++ Family uint16 ++ Data [14]int8 ++} ++ ++type RawSockaddrAny struct { ++ Addr RawSockaddr ++ Pad [96]int8 ++} ++ ++type _Socklen uint32 ++ ++type Linger struct { ++ Onoff int32 ++ Linger int32 ++} ++ ++type Iovec struct { ++ Base *byte ++ Len uint64 ++} ++ ++type IPMreq struct { ++ Multiaddr [4]byte /* in_addr */ ++ Interface [4]byte /* in_addr */ ++} ++ ++type IPMreqn struct { ++ Multiaddr [4]byte /* in_addr */ ++ Address [4]byte /* in_addr */ ++ Ifindex int32 ++} ++ ++type IPv6Mreq struct { ++ Multiaddr [16]byte /* in6_addr */ ++ Interface uint32 ++} ++ ++type PacketMreq struct { ++ Ifindex int32 ++ Type uint16 ++ Alen uint16 ++ Address [8]uint8 ++} ++ ++type Msghdr struct { ++ Name *byte ++ Namelen uint32 ++ Iov *Iovec ++ Iovlen uint64 ++ Control *byte ++ Controllen uint64 ++ Flags int32 ++ _ [4]byte ++} ++ ++type Cmsghdr struct { ++ Len uint64 ++ Level int32 ++ Type int32 ++} ++ ++type Inet4Pktinfo struct { ++ Ifindex int32 ++ Spec_dst [4]byte /* in_addr */ ++ Addr [4]byte /* in_addr */ ++} ++ ++type Inet6Pktinfo struct { ++ Addr [16]byte /* in6_addr */ ++ Ifindex uint32 ++} ++ ++type IPv6MTUInfo struct { ++ Addr RawSockaddrInet6 ++ Mtu uint32 ++} ++ ++type ICMPv6Filter struct { ++ Data [8]uint32 ++} ++ ++type Ucred struct { ++ Pid int32 ++ Uid uint32 ++ Gid uint32 ++} ++ ++type TCPInfo struct { ++ State uint8 ++ Ca_state uint8 ++ Retransmits uint8 ++ Probes uint8 ++ Backoff uint8 ++ Options uint8 ++ Rto uint32 ++ Ato uint32 ++ Snd_mss uint32 ++ Rcv_mss uint32 ++ Unacked uint32 ++ Sacked uint32 ++ Lost uint32 ++ Retrans uint32 ++ Fackets uint32 ++ Last_data_sent uint32 ++ Last_ack_sent uint32 ++ Last_data_recv uint32 ++ Last_ack_recv uint32 ++ Pmtu uint32 ++ Rcv_ssthresh uint32 ++ Rtt uint32 ++ Rttvar uint32 ++ Snd_ssthresh uint32 ++ Snd_cwnd uint32 ++ Advmss uint32 ++ Reordering uint32 ++ Rcv_rtt uint32 ++ Rcv_space uint32 ++ Total_retrans uint32 ++ Pacing_rate uint64 ++ Max_pacing_rate uint64 ++ Bytes_acked uint64 ++ Bytes_received uint64 ++ Segs_out uint32 ++ Segs_in uint32 ++ Notsent_bytes uint32 ++ Min_rtt uint32 ++ Data_segs_in uint32 ++ Data_segs_out uint32 ++ Delivery_rate uint64 ++ Busy_time uint64 ++ Rwnd_limited uint64 ++ Sndbuf_limited uint64 ++ Delivered uint32 ++ Delivered_ce uint32 ++ Bytes_sent uint64 ++ Bytes_retrans uint64 ++ Dsack_dups uint32 ++ Reord_seen uint32 ++ Rcv_ooopack uint32 ++ Snd_wnd uint32 ++ Rcv_wnd uint32 ++ Rehash uint32 ++} ++ ++type TCPVegasInfo struct { ++ Enabled uint32 ++ Rttcnt uint32 ++ Rtt uint32 ++ Minrtt uint32 ++} ++ ++type TCPDCTCPInfo struct { ++ Enabled uint16 ++ Ce_state uint16 ++ Alpha uint32 ++ Ab_ecn uint32 ++ Ab_tot uint32 ++} ++ ++type TCPBBRInfo struct { ++ Bw_lo uint32 ++ Bw_hi uint32 ++ Min_rtt uint32 ++ Pacing_gain uint32 ++ Cwnd_gain uint32 ++} ++ ++type CanFilter struct { ++ Id uint32 ++ Mask uint32 ++} ++ ++type ifreq struct { ++ Ifrn [16]byte ++ Ifru [24]byte ++} ++ ++type TCPRepairOpt struct { ++ Code uint32 ++ Val uint32 ++} ++ ++const ( ++ SizeofSockaddrInet4 = 0x10 ++ SizeofSockaddrInet6 = 0x1c ++ SizeofSockaddrAny = 0x70 ++ SizeofSockaddrUnix = 0x6e ++ SizeofSockaddrLinklayer = 0x14 ++ SizeofSockaddrNetlink = 0xc ++ SizeofSockaddrHCI = 0x6 ++ SizeofSockaddrL2 = 0xe ++ SizeofSockaddrRFCOMM = 0xa ++ SizeofSockaddrCAN = 0x18 ++ SizeofSockaddrALG = 0x58 ++ SizeofSockaddrVM = 0x10 ++ SizeofSockaddrXDP = 0x10 ++ SizeofSockaddrPPPoX = 0x1e ++ SizeofSockaddrTIPC = 0x10 ++ SizeofSockaddrL2TPIP = 0x10 ++ SizeofSockaddrL2TPIP6 = 0x20 ++ SizeofSockaddrIUCV = 0x20 ++ SizeofSockaddrNFC = 0x10 ++ SizeofSockaddrNFCLLCP = 0x60 ++ SizeofLinger = 0x8 ++ SizeofIovec = 0x10 ++ SizeofIPMreq = 0x8 ++ SizeofIPMreqn = 0xc ++ SizeofIPv6Mreq = 0x14 ++ SizeofPacketMreq = 0x10 ++ SizeofMsghdr = 0x38 ++ SizeofCmsghdr = 0x10 ++ SizeofInet4Pktinfo = 0xc ++ SizeofInet6Pktinfo = 0x14 ++ SizeofIPv6MTUInfo = 0x20 ++ SizeofICMPv6Filter = 0x20 ++ SizeofUcred = 0xc ++ SizeofTCPInfo = 0xf0 ++ SizeofTCPCCInfo = 0x14 ++ SizeofCanFilter = 0x8 ++ SizeofTCPRepairOpt = 0x8 ++) ++ ++const ( ++ NDA_UNSPEC = 0x0 ++ NDA_DST = 0x1 ++ NDA_LLADDR = 0x2 ++ NDA_CACHEINFO = 0x3 ++ NDA_PROBES = 0x4 ++ NDA_VLAN = 0x5 ++ NDA_PORT = 0x6 ++ NDA_VNI = 0x7 ++ NDA_IFINDEX = 0x8 ++ NDA_MASTER = 0x9 ++ NDA_LINK_NETNSID = 0xa ++ NDA_SRC_VNI = 0xb ++ NTF_USE = 0x1 ++ NTF_SELF = 0x2 ++ NTF_MASTER = 0x4 ++ NTF_PROXY = 0x8 ++ NTF_EXT_LEARNED = 0x10 ++ NTF_OFFLOADED = 0x20 ++ NTF_ROUTER = 0x80 ++ NUD_INCOMPLETE = 0x1 ++ NUD_REACHABLE = 0x2 ++ NUD_STALE = 0x4 ++ NUD_DELAY = 0x8 ++ NUD_PROBE = 0x10 ++ NUD_FAILED = 0x20 ++ NUD_NOARP = 0x40 ++ NUD_PERMANENT = 0x80 ++ NUD_NONE = 0x0 ++ IFA_UNSPEC = 0x0 ++ IFA_ADDRESS = 0x1 ++ IFA_LOCAL = 0x2 ++ IFA_LABEL = 0x3 ++ IFA_BROADCAST = 0x4 ++ IFA_ANYCAST = 0x5 ++ IFA_CACHEINFO = 0x6 ++ IFA_MULTICAST = 0x7 ++ IFA_FLAGS = 0x8 ++ IFA_RT_PRIORITY = 0x9 ++ IFA_TARGET_NETNSID = 0xa ++ RT_SCOPE_UNIVERSE = 0x0 ++ RT_SCOPE_SITE = 0xc8 ++ RT_SCOPE_LINK = 0xfd ++ RT_SCOPE_HOST = 0xfe ++ RT_SCOPE_NOWHERE = 0xff ++ RT_TABLE_UNSPEC = 0x0 ++ RT_TABLE_COMPAT = 0xfc ++ RT_TABLE_DEFAULT = 0xfd ++ RT_TABLE_MAIN = 0xfe ++ RT_TABLE_LOCAL = 0xff ++ RT_TABLE_MAX = 0xffffffff ++ RTA_UNSPEC = 0x0 ++ RTA_DST = 0x1 ++ RTA_SRC = 0x2 ++ RTA_IIF = 0x3 ++ RTA_OIF = 0x4 ++ RTA_GATEWAY = 0x5 ++ RTA_PRIORITY = 0x6 ++ RTA_PREFSRC = 0x7 ++ RTA_METRICS = 0x8 ++ RTA_MULTIPATH = 0x9 ++ RTA_FLOW = 0xb ++ RTA_CACHEINFO = 0xc ++ RTA_TABLE = 0xf ++ RTA_MARK = 0x10 ++ RTA_MFC_STATS = 0x11 ++ RTA_VIA = 0x12 ++ RTA_NEWDST = 0x13 ++ RTA_PREF = 0x14 ++ RTA_ENCAP_TYPE = 0x15 ++ RTA_ENCAP = 0x16 ++ RTA_EXPIRES = 0x17 ++ RTA_PAD = 0x18 ++ RTA_UID = 0x19 ++ RTA_TTL_PROPAGATE = 0x1a ++ RTA_IP_PROTO = 0x1b ++ RTA_SPORT = 0x1c ++ RTA_DPORT = 0x1d ++ RTN_UNSPEC = 0x0 ++ RTN_UNICAST = 0x1 ++ RTN_LOCAL = 0x2 ++ RTN_BROADCAST = 0x3 ++ RTN_ANYCAST = 0x4 ++ RTN_MULTICAST = 0x5 ++ RTN_BLACKHOLE = 0x6 ++ RTN_UNREACHABLE = 0x7 ++ RTN_PROHIBIT = 0x8 ++ RTN_THROW = 0x9 ++ RTN_NAT = 0xa ++ RTN_XRESOLVE = 0xb ++ SizeofNlMsghdr = 0x10 ++ SizeofNlMsgerr = 0x14 ++ SizeofRtGenmsg = 0x1 ++ SizeofNlAttr = 0x4 ++ SizeofRtAttr = 0x4 ++ SizeofIfInfomsg = 0x10 ++ SizeofIfAddrmsg = 0x8 ++ SizeofIfaCacheinfo = 0x10 ++ SizeofRtMsg = 0xc ++ SizeofRtNexthop = 0x8 ++ SizeofNdUseroptmsg = 0x10 ++ SizeofNdMsg = 0xc ++) ++ ++type NlMsghdr struct { ++ Len uint32 ++ Type uint16 ++ Flags uint16 ++ Seq uint32 ++ Pid uint32 ++} ++ ++type NlMsgerr struct { ++ Error int32 ++ Msg NlMsghdr ++} ++ ++type RtGenmsg struct { ++ Family uint8 ++} ++ ++type NlAttr struct { ++ Len uint16 ++ Type uint16 ++} ++ ++type RtAttr struct { ++ Len uint16 ++ Type uint16 ++} ++ ++type IfInfomsg struct { ++ Family uint8 ++ _ uint8 ++ Type uint16 ++ Index int32 ++ Flags uint32 ++ Change uint32 ++} ++ ++type IfAddrmsg struct { ++ Family uint8 ++ Prefixlen uint8 ++ Flags uint8 ++ Scope uint8 ++ Index uint32 ++} ++ ++type IfaCacheinfo struct { ++ Prefered uint32 ++ Valid uint32 ++ Cstamp uint32 ++ Tstamp uint32 ++} ++ ++type RtMsg struct { ++ Family uint8 ++ Dst_len uint8 ++ Src_len uint8 ++ Tos uint8 ++ Table uint8 ++ Protocol uint8 ++ Scope uint8 ++ Type uint8 ++ Flags uint32 ++} ++ ++type RtNexthop struct { ++ Len uint16 ++ Flags uint8 ++ Hops uint8 ++ Ifindex int32 ++} ++ ++type NdUseroptmsg struct { ++ Family uint8 ++ Pad1 uint8 ++ Opts_len uint16 ++ Ifindex int32 ++ Icmp_type uint8 ++ Icmp_code uint8 ++ Pad2 uint16 ++ Pad3 uint32 ++} ++ ++type NdMsg struct { ++ Family uint8 ++ Pad1 uint8 ++ Pad2 uint16 ++ Ifindex int32 ++ State uint16 ++ Flags uint8 ++ Type uint8 ++} ++ ++const ( ++ ICMP_FILTER = 0x1 ++ ++ ICMPV6_FILTER = 0x1 ++ ICMPV6_FILTER_BLOCK = 0x1 ++ ICMPV6_FILTER_BLOCKOTHERS = 0x3 ++ ICMPV6_FILTER_PASS = 0x2 ++ ICMPV6_FILTER_PASSONLY = 0x4 ++) ++ ++const ( ++ SizeofSockFilter = 0x8 ++ SizeofSockFprog = 0x10 ++) ++ ++type SockFilter struct { ++ Code uint16 ++ Jt uint8 ++ Jf uint8 ++ K uint32 ++} ++ ++type SockFprog struct { ++ Len uint16 ++ Filter *SockFilter ++} ++ ++type InotifyEvent struct { ++ Wd int32 ++ Mask uint32 ++ Cookie uint32 ++ Len uint32 ++} ++ ++const SizeofInotifyEvent = 0x10 ++ ++type PtraceRegs struct{} ++ ++type FdSet struct { ++ Bits [16]int64 ++} ++ ++type Sysinfo_t struct { ++ Uptime int64 ++ Loads [3]uint64 ++ Totalram uint64 ++ Freeram uint64 ++ Sharedram uint64 ++ Bufferram uint64 ++ Totalswap uint64 ++ Freeswap uint64 ++ Procs uint16 ++ Pad uint16 ++ Totalhigh uint64 ++ Freehigh uint64 ++ Unit uint32 ++ _ [0]int8 ++ _ [4]byte ++} ++ ++const SI_LOAD_SHIFT = 0x10 ++ ++type Utsname struct { ++ Sysname [65]byte ++ Nodename [65]byte ++ Release [65]byte ++ Version [65]byte ++ Machine [65]byte ++ Domainname [65]byte ++} ++ ++type Ustat_t struct { ++ Tfree int32 ++ Tinode uint64 ++ Fname [6]int8 ++ Fpack [6]int8 ++ _ [4]byte ++} ++ ++type EpollEvent struct { ++ Events uint32 ++ Fd int32 ++ Pad int32 ++} ++ ++const ( ++ AT_EMPTY_PATH = 0x1000 ++ AT_FDCWD = -0x64 ++ AT_NO_AUTOMOUNT = 0x800 ++ AT_REMOVEDIR = 0x200 ++ ++ AT_STATX_SYNC_AS_STAT = 0x0 ++ AT_STATX_FORCE_SYNC = 0x2000 ++ AT_STATX_DONT_SYNC = 0x4000 ++ ++ AT_RECURSIVE = 0x8000 ++ ++ AT_SYMLINK_FOLLOW = 0x400 ++ AT_SYMLINK_NOFOLLOW = 0x100 ++ ++ AT_EACCESS = 0x200 ++ ++ OPEN_TREE_CLONE = 0x1 ++ OPEN_TREE_CLOEXEC = 0x200000 ++ ++ MOVE_MOUNT_F_SYMLINKS = 0x1 ++ MOVE_MOUNT_F_AUTOMOUNTS = 0x2 ++ MOVE_MOUNT_F_EMPTY_PATH = 0x4 ++ MOVE_MOUNT_T_SYMLINKS = 0x10 ++ MOVE_MOUNT_T_AUTOMOUNTS = 0x20 ++ MOVE_MOUNT_T_EMPTY_PATH = 0x40 ++ ++ FSOPEN_CLOEXEC = 0x1 ++ ++ FSPICK_CLOEXEC = 0x1 ++ FSPICK_SYMLINK_NOFOLLOW = 0x2 ++ FSPICK_NO_AUTOMOUNT = 0x4 ++ FSPICK_EMPTY_PATH = 0x8 ++ ++ FSMOUNT_CLOEXEC = 0x1 ++ ++ FSCONFIG_SET_FLAG = 0x0 ++ FSCONFIG_SET_STRING = 0x1 ++ FSCONFIG_SET_BINARY = 0x2 ++ FSCONFIG_SET_PATH = 0x3 ++ FSCONFIG_SET_PATH_EMPTY = 0x4 ++ FSCONFIG_SET_FD = 0x5 ++ FSCONFIG_CMD_CREATE = 0x6 ++ FSCONFIG_CMD_RECONFIGURE = 0x7 ++) ++ ++type OpenHow struct { ++ Flags uint64 ++ Mode uint64 ++ Resolve uint64 ++} ++ ++const SizeofOpenHow = 0x18 ++ ++const ( ++ RESOLVE_BENEATH = 0x8 ++ RESOLVE_IN_ROOT = 0x10 ++ RESOLVE_NO_MAGICLINKS = 0x2 ++ RESOLVE_NO_SYMLINKS = 0x4 ++ RESOLVE_NO_XDEV = 0x1 ++) ++ ++type PollFd struct { ++ Fd int32 ++ Events int16 ++ Revents int16 ++} ++ ++const ( ++ POLLIN = 0x1 ++ POLLPRI = 0x2 ++ POLLOUT = 0x4 ++ POLLRDHUP = 0x2000 ++ POLLERR = 0x8 ++ POLLHUP = 0x10 ++ POLLNVAL = 0x20 ++) ++ ++type Sigset_t struct { ++ Val [16]uint64 ++} ++type sigset_argpack struct { ++ ss *Sigset_t ++ ssLen uintptr ++} ++ ++const _C__NSIG = 0x41 ++ ++const ( ++ SIG_BLOCK = 0x1 ++ SIG_UNBLOCK = 0x2 ++ SIG_SETMASK = 0x3 ++) ++ ++type SignalfdSiginfo struct { ++ Signo uint32 ++ Errno int32 ++ Code int32 ++ Pid uint32 ++ Uid uint32 ++ Fd int32 ++ Tid uint32 ++ Band uint32 ++ Overrun uint32 ++ Trapno uint32 ++ Status int32 ++ Int int32 ++ Ptr uint64 ++ Utime uint64 ++ Stime uint64 ++ Addr uint64 ++ Addr_lsb uint16 ++ _ uint16 ++ Syscall int32 ++ Call_addr uint64 ++ Arch uint32 ++ _ [28]uint8 ++} ++ ++type Siginfo struct { ++ Signo int32 ++ Errno int32 ++ Code int32 ++ _ int32 ++ _ [112]byte ++} ++ ++type Termios struct { ++ Iflag uint32 ++ Oflag uint32 ++ Cflag uint32 ++ Lflag uint32 ++ Cc [19]uint8 ++ Line uint8 ++ Ispeed uint32 ++ Ospeed uint32 ++} ++ ++type Winsize struct { ++ Row uint16 ++ Col uint16 ++ Xpixel uint16 ++ Ypixel uint16 ++} ++ ++type Taskstats struct { ++ Version uint16 ++ Ac_exitcode uint32 ++ Ac_flag uint8 ++ Ac_nice uint8 ++ Cpu_count uint64 ++ Cpu_delay_total uint64 ++ Blkio_count uint64 ++ Blkio_delay_total uint64 ++ Swapin_count uint64 ++ Swapin_delay_total uint64 ++ Cpu_run_real_total uint64 ++ Cpu_run_virtual_total uint64 ++ Ac_comm [32]int8 ++ Ac_sched uint8 ++ Ac_pad [3]uint8 ++ _ [4]byte ++ Ac_uid uint32 ++ Ac_gid uint32 ++ Ac_pid uint32 ++ Ac_ppid uint32 ++ Ac_btime uint32 ++ Ac_etime uint64 ++ Ac_utime uint64 ++ Ac_stime uint64 ++ Ac_minflt uint64 ++ Ac_majflt uint64 ++ Coremem uint64 ++ Virtmem uint64 ++ Hiwater_rss uint64 ++ Hiwater_vm uint64 ++ Read_char uint64 ++ Write_char uint64 ++ Read_syscalls uint64 ++ Write_syscalls uint64 ++ Read_bytes uint64 ++ Write_bytes uint64 ++ Cancelled_write_bytes uint64 ++ Nvcsw uint64 ++ Nivcsw uint64 ++ Ac_utimescaled uint64 ++ Ac_stimescaled uint64 ++ Cpu_scaled_run_real_total uint64 ++ Freepages_count uint64 ++ Freepages_delay_total uint64 ++ Thrashing_count uint64 ++ Thrashing_delay_total uint64 ++ Ac_btime64 uint64 ++ Compact_count uint64 ++ Compact_delay_total uint64 ++ Ac_tgid uint32 ++ Ac_tgetime uint64 ++ Ac_exe_dev uint64 ++ Ac_exe_inode uint64 ++ Wpcopy_count uint64 ++ Wpcopy_delay_total uint64 ++ Irq_count uint64 ++ Irq_delay_total uint64 ++} ++ ++const ( ++ TASKSTATS_CMD_UNSPEC = 0x0 ++ TASKSTATS_CMD_GET = 0x1 ++ TASKSTATS_CMD_NEW = 0x2 ++ TASKSTATS_TYPE_UNSPEC = 0x0 ++ TASKSTATS_TYPE_PID = 0x1 ++ TASKSTATS_TYPE_TGID = 0x2 ++ TASKSTATS_TYPE_STATS = 0x3 ++ TASKSTATS_TYPE_AGGR_PID = 0x4 ++ TASKSTATS_TYPE_AGGR_TGID = 0x5 ++ TASKSTATS_TYPE_NULL = 0x6 ++ TASKSTATS_CMD_ATTR_UNSPEC = 0x0 ++ TASKSTATS_CMD_ATTR_PID = 0x1 ++ TASKSTATS_CMD_ATTR_TGID = 0x2 ++ TASKSTATS_CMD_ATTR_REGISTER_CPUMASK = 0x3 ++ TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK = 0x4 ++) ++ ++type CGroupStats struct { ++ Sleeping uint64 ++ Running uint64 ++ Stopped uint64 ++ Uninterruptible uint64 ++ Io_wait uint64 ++} ++ ++const ( ++ CGROUPSTATS_CMD_UNSPEC = 0x3 ++ CGROUPSTATS_CMD_GET = 0x4 ++ CGROUPSTATS_CMD_NEW = 0x5 ++ CGROUPSTATS_TYPE_UNSPEC = 0x0 ++ CGROUPSTATS_TYPE_CGROUP_STATS = 0x1 ++ CGROUPSTATS_CMD_ATTR_UNSPEC = 0x0 ++ CGROUPSTATS_CMD_ATTR_FD = 0x1 ++) ++ ++type Genlmsghdr struct { ++ Cmd uint8 ++ Version uint8 ++ Reserved uint16 ++} ++ ++const ( ++ CTRL_CMD_UNSPEC = 0x0 ++ CTRL_CMD_NEWFAMILY = 0x1 ++ CTRL_CMD_DELFAMILY = 0x2 ++ CTRL_CMD_GETFAMILY = 0x3 ++ CTRL_CMD_NEWOPS = 0x4 ++ CTRL_CMD_DELOPS = 0x5 ++ CTRL_CMD_GETOPS = 0x6 ++ CTRL_CMD_NEWMCAST_GRP = 0x7 ++ CTRL_CMD_DELMCAST_GRP = 0x8 ++ CTRL_CMD_GETMCAST_GRP = 0x9 ++ CTRL_CMD_GETPOLICY = 0xa ++ CTRL_ATTR_UNSPEC = 0x0 ++ CTRL_ATTR_FAMILY_ID = 0x1 ++ CTRL_ATTR_FAMILY_NAME = 0x2 ++ CTRL_ATTR_VERSION = 0x3 ++ CTRL_ATTR_HDRSIZE = 0x4 ++ CTRL_ATTR_MAXATTR = 0x5 ++ CTRL_ATTR_OPS = 0x6 ++ CTRL_ATTR_MCAST_GROUPS = 0x7 ++ CTRL_ATTR_POLICY = 0x8 ++ CTRL_ATTR_OP_POLICY = 0x9 ++ CTRL_ATTR_OP = 0xa ++ CTRL_ATTR_OP_UNSPEC = 0x0 ++ CTRL_ATTR_OP_ID = 0x1 ++ CTRL_ATTR_OP_FLAGS = 0x2 ++ CTRL_ATTR_MCAST_GRP_UNSPEC = 0x0 ++ CTRL_ATTR_MCAST_GRP_NAME = 0x1 ++ CTRL_ATTR_MCAST_GRP_ID = 0x2 ++ CTRL_ATTR_POLICY_UNSPEC = 0x0 ++ CTRL_ATTR_POLICY_DO = 0x1 ++ CTRL_ATTR_POLICY_DUMP = 0x2 ++ CTRL_ATTR_POLICY_DUMP_MAX = 0x2 ++) ++ ++type cpuMask uint64 ++ ++const ( ++ _CPU_SETSIZE = 0x400 ++ _NCPUBITS = 0x40 ++) ++ ++const ( ++ BDADDR_BREDR = 0x0 ++ BDADDR_LE_PUBLIC = 0x1 ++ BDADDR_LE_RANDOM = 0x2 ++) ++ ++type PerfEventAttr struct { ++ Type uint32 ++ Size uint32 ++ Config uint64 ++ Sample uint64 ++ Sample_type uint64 ++ Read_format uint64 ++ Bits uint64 ++ Wakeup uint32 ++ Bp_type uint32 ++ Ext1 uint64 ++ Ext2 uint64 ++ Branch_sample_type uint64 ++ Sample_regs_user uint64 ++ Sample_stack_user uint32 ++ Clockid int32 ++ Sample_regs_intr uint64 ++ Aux_watermark uint32 ++ Sample_max_stack uint16 ++ _ uint16 ++ Aux_sample_size uint32 ++ _ uint32 ++ Sig_data uint64 ++} ++ ++type PerfEventMmapPage struct { ++ Version uint32 ++ Compat_version uint32 ++ Lock uint32 ++ Index uint32 ++ Offset int64 ++ Time_enabled uint64 ++ Time_running uint64 ++ Capabilities uint64 ++ Pmc_width uint16 ++ Time_shift uint16 ++ Time_mult uint32 ++ Time_offset uint64 ++ Time_zero uint64 ++ Size uint32 ++ _ uint32 ++ Time_cycles uint64 ++ Time_mask uint64 ++ _ [928]uint8 ++ Data_head uint64 ++ Data_tail uint64 ++ Data_offset uint64 ++ Data_size uint64 ++ Aux_head uint64 ++ Aux_tail uint64 ++ Aux_offset uint64 ++ Aux_size uint64 ++} ++ ++const ( ++ PerfBitDisabled uint64 = CBitFieldMaskBit0 ++ PerfBitInherit = CBitFieldMaskBit1 ++ PerfBitPinned = CBitFieldMaskBit2 ++ PerfBitExclusive = CBitFieldMaskBit3 ++ PerfBitExcludeUser = CBitFieldMaskBit4 ++ PerfBitExcludeKernel = CBitFieldMaskBit5 ++ PerfBitExcludeHv = CBitFieldMaskBit6 ++ PerfBitExcludeIdle = CBitFieldMaskBit7 ++ PerfBitMmap = CBitFieldMaskBit8 ++ PerfBitComm = CBitFieldMaskBit9 ++ PerfBitFreq = CBitFieldMaskBit10 ++ PerfBitInheritStat = CBitFieldMaskBit11 ++ PerfBitEnableOnExec = CBitFieldMaskBit12 ++ PerfBitTask = CBitFieldMaskBit13 ++ PerfBitWatermark = CBitFieldMaskBit14 ++ PerfBitPreciseIPBit1 = CBitFieldMaskBit15 ++ PerfBitPreciseIPBit2 = CBitFieldMaskBit16 ++ PerfBitMmapData = CBitFieldMaskBit17 ++ PerfBitSampleIDAll = CBitFieldMaskBit18 ++ PerfBitExcludeHost = CBitFieldMaskBit19 ++ PerfBitExcludeGuest = CBitFieldMaskBit20 ++ PerfBitExcludeCallchainKernel = CBitFieldMaskBit21 ++ PerfBitExcludeCallchainUser = CBitFieldMaskBit22 ++ PerfBitMmap2 = CBitFieldMaskBit23 ++ PerfBitCommExec = CBitFieldMaskBit24 ++ PerfBitUseClockID = CBitFieldMaskBit25 ++ PerfBitContextSwitch = CBitFieldMaskBit26 ++ PerfBitWriteBackward = CBitFieldMaskBit27 ++) ++ ++const ( ++ PERF_TYPE_HARDWARE = 0x0 ++ PERF_TYPE_SOFTWARE = 0x1 ++ PERF_TYPE_TRACEPOINT = 0x2 ++ PERF_TYPE_HW_CACHE = 0x3 ++ PERF_TYPE_RAW = 0x4 ++ PERF_TYPE_BREAKPOINT = 0x5 ++ PERF_TYPE_MAX = 0x6 ++ PERF_COUNT_HW_CPU_CYCLES = 0x0 ++ PERF_COUNT_HW_INSTRUCTIONS = 0x1 ++ PERF_COUNT_HW_CACHE_REFERENCES = 0x2 ++ PERF_COUNT_HW_CACHE_MISSES = 0x3 ++ PERF_COUNT_HW_BRANCH_INSTRUCTIONS = 0x4 ++ PERF_COUNT_HW_BRANCH_MISSES = 0x5 ++ PERF_COUNT_HW_BUS_CYCLES = 0x6 ++ PERF_COUNT_HW_STALLED_CYCLES_FRONTEND = 0x7 ++ PERF_COUNT_HW_STALLED_CYCLES_BACKEND = 0x8 ++ PERF_COUNT_HW_REF_CPU_CYCLES = 0x9 ++ PERF_COUNT_HW_MAX = 0xa ++ PERF_COUNT_HW_CACHE_L1D = 0x0 ++ PERF_COUNT_HW_CACHE_L1I = 0x1 ++ PERF_COUNT_HW_CACHE_LL = 0x2 ++ PERF_COUNT_HW_CACHE_DTLB = 0x3 ++ PERF_COUNT_HW_CACHE_ITLB = 0x4 ++ PERF_COUNT_HW_CACHE_BPU = 0x5 ++ PERF_COUNT_HW_CACHE_NODE = 0x6 ++ PERF_COUNT_HW_CACHE_MAX = 0x7 ++ PERF_COUNT_HW_CACHE_OP_READ = 0x0 ++ PERF_COUNT_HW_CACHE_OP_WRITE = 0x1 ++ PERF_COUNT_HW_CACHE_OP_PREFETCH = 0x2 ++ PERF_COUNT_HW_CACHE_OP_MAX = 0x3 ++ PERF_COUNT_HW_CACHE_RESULT_ACCESS = 0x0 ++ PERF_COUNT_HW_CACHE_RESULT_MISS = 0x1 ++ PERF_COUNT_HW_CACHE_RESULT_MAX = 0x2 ++ PERF_COUNT_SW_CPU_CLOCK = 0x0 ++ PERF_COUNT_SW_TASK_CLOCK = 0x1 ++ PERF_COUNT_SW_PAGE_FAULTS = 0x2 ++ PERF_COUNT_SW_CONTEXT_SWITCHES = 0x3 ++ PERF_COUNT_SW_CPU_MIGRATIONS = 0x4 ++ PERF_COUNT_SW_PAGE_FAULTS_MIN = 0x5 ++ PERF_COUNT_SW_PAGE_FAULTS_MAJ = 0x6 ++ PERF_COUNT_SW_ALIGNMENT_FAULTS = 0x7 ++ PERF_COUNT_SW_EMULATION_FAULTS = 0x8 ++ PERF_COUNT_SW_DUMMY = 0x9 ++ PERF_COUNT_SW_BPF_OUTPUT = 0xa ++ PERF_COUNT_SW_MAX = 0xc ++ PERF_SAMPLE_IP = 0x1 ++ PERF_SAMPLE_TID = 0x2 ++ PERF_SAMPLE_TIME = 0x4 ++ PERF_SAMPLE_ADDR = 0x8 ++ PERF_SAMPLE_READ = 0x10 ++ PERF_SAMPLE_CALLCHAIN = 0x20 ++ PERF_SAMPLE_ID = 0x40 ++ PERF_SAMPLE_CPU = 0x80 ++ PERF_SAMPLE_PERIOD = 0x100 ++ PERF_SAMPLE_STREAM_ID = 0x200 ++ PERF_SAMPLE_RAW = 0x400 ++ PERF_SAMPLE_BRANCH_STACK = 0x800 ++ PERF_SAMPLE_REGS_USER = 0x1000 ++ PERF_SAMPLE_STACK_USER = 0x2000 ++ PERF_SAMPLE_WEIGHT = 0x4000 ++ PERF_SAMPLE_DATA_SRC = 0x8000 ++ PERF_SAMPLE_IDENTIFIER = 0x10000 ++ PERF_SAMPLE_TRANSACTION = 0x20000 ++ PERF_SAMPLE_REGS_INTR = 0x40000 ++ PERF_SAMPLE_PHYS_ADDR = 0x80000 ++ PERF_SAMPLE_AUX = 0x100000 ++ PERF_SAMPLE_CGROUP = 0x200000 ++ ++ PERF_SAMPLE_MAX = 0x2000000 ++ PERF_SAMPLE_BRANCH_USER_SHIFT = 0x0 ++ PERF_SAMPLE_BRANCH_KERNEL_SHIFT = 0x1 ++ PERF_SAMPLE_BRANCH_HV_SHIFT = 0x2 ++ PERF_SAMPLE_BRANCH_ANY_SHIFT = 0x3 ++ PERF_SAMPLE_BRANCH_ANY_CALL_SHIFT = 0x4 ++ PERF_SAMPLE_BRANCH_ANY_RETURN_SHIFT = 0x5 ++ PERF_SAMPLE_BRANCH_IND_CALL_SHIFT = 0x6 ++ PERF_SAMPLE_BRANCH_ABORT_TX_SHIFT = 0x7 ++ PERF_SAMPLE_BRANCH_IN_TX_SHIFT = 0x8 ++ PERF_SAMPLE_BRANCH_NO_TX_SHIFT = 0x9 ++ PERF_SAMPLE_BRANCH_COND_SHIFT = 0xa ++ PERF_SAMPLE_BRANCH_CALL_STACK_SHIFT = 0xb ++ PERF_SAMPLE_BRANCH_IND_JUMP_SHIFT = 0xc ++ PERF_SAMPLE_BRANCH_CALL_SHIFT = 0xd ++ PERF_SAMPLE_BRANCH_NO_FLAGS_SHIFT = 0xe ++ PERF_SAMPLE_BRANCH_NO_CYCLES_SHIFT = 0xf ++ PERF_SAMPLE_BRANCH_TYPE_SAVE_SHIFT = 0x10 ++ PERF_SAMPLE_BRANCH_HW_INDEX_SHIFT = 0x11 ++ PERF_SAMPLE_BRANCH_PRIV_SAVE_SHIFT = 0x12 ++ ++ PERF_SAMPLE_BRANCH_MAX_SHIFT = 0x13 ++ PERF_SAMPLE_BRANCH_USER = 0x1 ++ PERF_SAMPLE_BRANCH_KERNEL = 0x2 ++ PERF_SAMPLE_BRANCH_HV = 0x4 ++ PERF_SAMPLE_BRANCH_ANY = 0x8 ++ PERF_SAMPLE_BRANCH_ANY_CALL = 0x10 ++ PERF_SAMPLE_BRANCH_ANY_RETURN = 0x20 ++ PERF_SAMPLE_BRANCH_IND_CALL = 0x40 ++ PERF_SAMPLE_BRANCH_ABORT_TX = 0x80 ++ PERF_SAMPLE_BRANCH_IN_TX = 0x100 ++ PERF_SAMPLE_BRANCH_NO_TX = 0x200 ++ PERF_SAMPLE_BRANCH_COND = 0x400 ++ PERF_SAMPLE_BRANCH_CALL_STACK = 0x800 ++ PERF_SAMPLE_BRANCH_IND_JUMP = 0x1000 ++ PERF_SAMPLE_BRANCH_CALL = 0x2000 ++ PERF_SAMPLE_BRANCH_NO_FLAGS = 0x4000 ++ PERF_SAMPLE_BRANCH_NO_CYCLES = 0x8000 ++ PERF_SAMPLE_BRANCH_TYPE_SAVE = 0x10000 ++ PERF_SAMPLE_BRANCH_HW_INDEX = 0x20000 ++ PERF_SAMPLE_BRANCH_PRIV_SAVE = 0x40000 ++ PERF_SAMPLE_BRANCH_MAX = 0x80000 ++ PERF_BR_UNKNOWN = 0x0 ++ PERF_BR_COND = 0x1 ++ PERF_BR_UNCOND = 0x2 ++ PERF_BR_IND = 0x3 ++ PERF_BR_CALL = 0x4 ++ PERF_BR_IND_CALL = 0x5 ++ PERF_BR_RET = 0x6 ++ PERF_BR_SYSCALL = 0x7 ++ PERF_BR_SYSRET = 0x8 ++ PERF_BR_COND_CALL = 0x9 ++ PERF_BR_COND_RET = 0xa ++ ++ PERF_BR_SERROR = 0xd ++ PERF_BR_NO_TX = 0xe ++ PERF_BR_EXTEND_ABI = 0xf ++ PERF_BR_MAX = 0x10 ++ PERF_SAMPLE_REGS_ABI_NONE = 0x0 ++ PERF_SAMPLE_REGS_ABI_32 = 0x1 ++ PERF_SAMPLE_REGS_ABI_64 = 0x2 ++ PERF_TXN_ELISION = 0x1 ++ PERF_TXN_TRANSACTION = 0x2 ++ PERF_TXN_SYNC = 0x4 ++ PERF_TXN_ASYNC = 0x8 ++ PERF_TXN_RETRY = 0x10 ++ PERF_TXN_CONFLICT = 0x20 ++ PERF_TXN_CAPACITY_WRITE = 0x40 ++ PERF_TXN_CAPACITY_READ = 0x80 ++ PERF_TXN_MAX = 0x100 ++ PERF_TXN_ABORT_MASK = -0x100000000 ++ PERF_TXN_ABORT_SHIFT = 0x20 ++ PERF_FORMAT_TOTAL_TIME_ENABLED = 0x1 ++ PERF_FORMAT_TOTAL_TIME_RUNNING = 0x2 ++ PERF_FORMAT_ID = 0x4 ++ PERF_FORMAT_GROUP = 0x8 ++ PERF_FORMAT_LOST = 0x10 ++ PERF_FORMAT_MAX = 0x20 ++ PERF_IOC_FLAG_GROUP = 0x1 ++ PERF_RECORD_MMAP = 0x1 ++ PERF_RECORD_LOST = 0x2 ++ PERF_RECORD_COMM = 0x3 ++ PERF_RECORD_EXIT = 0x4 ++ PERF_RECORD_THROTTLE = 0x5 ++ PERF_RECORD_UNTHROTTLE = 0x6 ++ PERF_RECORD_FORK = 0x7 ++ PERF_RECORD_READ = 0x8 ++ PERF_RECORD_SAMPLE = 0x9 ++ PERF_RECORD_MMAP2 = 0xa ++ PERF_RECORD_AUX = 0xb ++ PERF_RECORD_ITRACE_START = 0xc ++ PERF_RECORD_LOST_SAMPLES = 0xd ++ PERF_RECORD_SWITCH = 0xe ++ PERF_RECORD_SWITCH_CPU_WIDE = 0xf ++ PERF_RECORD_NAMESPACES = 0x10 ++ PERF_RECORD_KSYMBOL = 0x11 ++ PERF_RECORD_BPF_EVENT = 0x12 ++ PERF_RECORD_CGROUP = 0x13 ++ PERF_RECORD_TEXT_POKE = 0x14 ++ ++ PERF_RECORD_MAX = 0x16 ++ PERF_RECORD_KSYMBOL_TYPE_UNKNOWN = 0x0 ++ PERF_RECORD_KSYMBOL_TYPE_BPF = 0x1 ++ PERF_RECORD_KSYMBOL_TYPE_OOL = 0x2 ++ PERF_RECORD_KSYMBOL_TYPE_MAX = 0x3 ++ PERF_BPF_EVENT_UNKNOWN = 0x0 ++ PERF_BPF_EVENT_PROG_LOAD = 0x1 ++ PERF_BPF_EVENT_PROG_UNLOAD = 0x2 ++ PERF_BPF_EVENT_MAX = 0x3 ++ PERF_CONTEXT_HV = -0x20 ++ PERF_CONTEXT_KERNEL = -0x80 ++ PERF_CONTEXT_USER = -0x200 ++ PERF_CONTEXT_GUEST = -0x800 ++ PERF_CONTEXT_GUEST_KERNEL = -0x880 ++ PERF_CONTEXT_GUEST_USER = -0xa00 ++ PERF_CONTEXT_MAX = -0xfff ++) ++ ++const ( ++ CBitFieldMaskBit0 = 0x1 ++ CBitFieldMaskBit1 = 0x2 ++ CBitFieldMaskBit2 = 0x4 ++ CBitFieldMaskBit3 = 0x8 ++ CBitFieldMaskBit4 = 0x10 ++ CBitFieldMaskBit5 = 0x20 ++ CBitFieldMaskBit6 = 0x40 ++ CBitFieldMaskBit7 = 0x80 ++ CBitFieldMaskBit8 = 0x100 ++ CBitFieldMaskBit9 = 0x200 ++ CBitFieldMaskBit10 = 0x400 ++ CBitFieldMaskBit11 = 0x800 ++ CBitFieldMaskBit12 = 0x1000 ++ CBitFieldMaskBit13 = 0x2000 ++ CBitFieldMaskBit14 = 0x4000 ++ CBitFieldMaskBit15 = 0x8000 ++ CBitFieldMaskBit16 = 0x10000 ++ CBitFieldMaskBit17 = 0x20000 ++ CBitFieldMaskBit18 = 0x40000 ++ CBitFieldMaskBit19 = 0x80000 ++ CBitFieldMaskBit20 = 0x100000 ++ CBitFieldMaskBit21 = 0x200000 ++ CBitFieldMaskBit22 = 0x400000 ++ CBitFieldMaskBit23 = 0x800000 ++ CBitFieldMaskBit24 = 0x1000000 ++ CBitFieldMaskBit25 = 0x2000000 ++ CBitFieldMaskBit26 = 0x4000000 ++ CBitFieldMaskBit27 = 0x8000000 ++ CBitFieldMaskBit28 = 0x10000000 ++ CBitFieldMaskBit29 = 0x20000000 ++ CBitFieldMaskBit30 = 0x40000000 ++ CBitFieldMaskBit31 = 0x80000000 ++ CBitFieldMaskBit32 = 0x100000000 ++ CBitFieldMaskBit33 = 0x200000000 ++ CBitFieldMaskBit34 = 0x400000000 ++ CBitFieldMaskBit35 = 0x800000000 ++ CBitFieldMaskBit36 = 0x1000000000 ++ CBitFieldMaskBit37 = 0x2000000000 ++ CBitFieldMaskBit38 = 0x4000000000 ++ CBitFieldMaskBit39 = 0x8000000000 ++ CBitFieldMaskBit40 = 0x10000000000 ++ CBitFieldMaskBit41 = 0x20000000000 ++ CBitFieldMaskBit42 = 0x40000000000 ++ CBitFieldMaskBit43 = 0x80000000000 ++ CBitFieldMaskBit44 = 0x100000000000 ++ CBitFieldMaskBit45 = 0x200000000000 ++ CBitFieldMaskBit46 = 0x400000000000 ++ CBitFieldMaskBit47 = 0x800000000000 ++ CBitFieldMaskBit48 = 0x1000000000000 ++ CBitFieldMaskBit49 = 0x2000000000000 ++ CBitFieldMaskBit50 = 0x4000000000000 ++ CBitFieldMaskBit51 = 0x8000000000000 ++ CBitFieldMaskBit52 = 0x10000000000000 ++ CBitFieldMaskBit53 = 0x20000000000000 ++ CBitFieldMaskBit54 = 0x40000000000000 ++ CBitFieldMaskBit55 = 0x80000000000000 ++ CBitFieldMaskBit56 = 0x100000000000000 ++ CBitFieldMaskBit57 = 0x200000000000000 ++ CBitFieldMaskBit58 = 0x400000000000000 ++ CBitFieldMaskBit59 = 0x800000000000000 ++ CBitFieldMaskBit60 = 0x1000000000000000 ++ CBitFieldMaskBit61 = 0x2000000000000000 ++ CBitFieldMaskBit62 = 0x4000000000000000 ++ CBitFieldMaskBit63 = 0x8000000000000000 ++) ++ ++type SockaddrStorage struct { ++ Family uint16 ++ Data [118]byte ++ _ uint64 ++} ++ ++type TCPMD5Sig struct { ++ Addr SockaddrStorage ++ Flags uint8 ++ Prefixlen uint8 ++ Keylen uint16 ++ Ifindex int32 ++ Key [80]uint8 ++} ++ ++type HDDriveCmdHdr struct { ++ Command uint8 ++ Number uint8 ++ Feature uint8 ++ Count uint8 ++} ++ ++type HDGeometry struct { ++ Heads uint8 ++ Sectors uint8 ++ Cylinders uint16 ++ Start uint64 ++} ++ ++type HDDriveID struct { ++ Config uint16 ++ Cyls uint16 ++ Reserved2 uint16 ++ Heads uint16 ++ Track_bytes uint16 ++ Sector_bytes uint16 ++ Sectors uint16 ++ Vendor0 uint16 ++ Vendor1 uint16 ++ Vendor2 uint16 ++ Serial_no [20]uint8 ++ Buf_type uint16 ++ Buf_size uint16 ++ Ecc_bytes uint16 ++ Fw_rev [8]uint8 ++ Model [40]uint8 ++ Max_multsect uint8 ++ Vendor3 uint8 ++ Dword_io uint16 ++ Vendor4 uint8 ++ Capability uint8 ++ Reserved50 uint16 ++ Vendor5 uint8 ++ TPIO uint8 ++ Vendor6 uint8 ++ TDMA uint8 ++ Field_valid uint16 ++ Cur_cyls uint16 ++ Cur_heads uint16 ++ Cur_sectors uint16 ++ Cur_capacity0 uint16 ++ Cur_capacity1 uint16 ++ Multsect uint8 ++ Multsect_valid uint8 ++ Lba_capacity uint32 ++ Dma_1word uint16 ++ Dma_mword uint16 ++ Eide_pio_modes uint16 ++ Eide_dma_min uint16 ++ Eide_dma_time uint16 ++ Eide_pio uint16 ++ Eide_pio_iordy uint16 ++ Words69_70 [2]uint16 ++ Words71_74 [4]uint16 ++ Queue_depth uint16 ++ Words76_79 [4]uint16 ++ Major_rev_num uint16 ++ Minor_rev_num uint16 ++ Command_set_1 uint16 ++ Command_set_2 uint16 ++ Cfsse uint16 ++ Cfs_enable_1 uint16 ++ Cfs_enable_2 uint16 ++ Csf_default uint16 ++ Dma_ultra uint16 ++ Trseuc uint16 ++ TrsEuc uint16 ++ CurAPMvalues uint16 ++ Mprc uint16 ++ Hw_config uint16 ++ Acoustic uint16 ++ Msrqs uint16 ++ Sxfert uint16 ++ Sal uint16 ++ Spg uint32 ++ Lba_capacity_2 uint64 ++ Words104_125 [22]uint16 ++ Last_lun uint16 ++ Word127 uint16 ++ Dlf uint16 ++ Csfo uint16 ++ Words130_155 [26]uint16 ++ Word156 uint16 ++ Words157_159 [3]uint16 ++ Cfa_power uint16 ++ Words161_175 [15]uint16 ++ Words176_205 [30]uint16 ++ Words206_254 [49]uint16 ++ Integrity_word uint16 ++} ++ ++type Statfs_t struct { ++ Type int64 ++ Bsize int64 ++ Blocks uint64 ++ Bfree uint64 ++ Bavail uint64 ++ Files uint64 ++ Ffree uint64 ++ Fsid Fsid ++ Namelen int64 ++ Frsize int64 ++ Flags int64 ++ Spare [4]int64 ++} ++ ++const ( ++ ST_MANDLOCK = 0x40 ++ ST_NOATIME = 0x400 ++ ST_NODEV = 0x4 ++ ST_NODIRATIME = 0x800 ++ ST_NOEXEC = 0x8 ++ ST_NOSUID = 0x2 ++ ST_RDONLY = 0x1 ++ ST_RELATIME = 0x1000 ++ ST_SYNCHRONOUS = 0x10 ++) ++ ++type TpacketHdr struct { ++ Status uint64 ++ Len uint32 ++ Snaplen uint32 ++ Mac uint16 ++ Net uint16 ++ Sec uint32 ++ Usec uint32 ++ _ [4]byte ++} ++ ++type Tpacket2Hdr struct { ++ Status uint32 ++ Len uint32 ++ Snaplen uint32 ++ Mac uint16 ++ Net uint16 ++ Sec uint32 ++ Nsec uint32 ++ Vlan_tci uint16 ++ Vlan_tpid uint16 ++ _ [4]uint8 ++} ++ ++type Tpacket3Hdr struct { ++ Next_offset uint32 ++ Sec uint32 ++ Nsec uint32 ++ Snaplen uint32 ++ Len uint32 ++ Status uint32 ++ Mac uint16 ++ Net uint16 ++ Hv1 TpacketHdrVariant1 ++ _ [8]uint8 ++} ++ ++type TpacketHdrVariant1 struct { ++ Rxhash uint32 ++ Vlan_tci uint32 ++ Vlan_tpid uint16 ++ _ uint16 ++} ++ ++type TpacketBlockDesc struct { ++ Version uint32 ++ To_priv uint32 ++ Hdr [40]byte ++} ++ ++type TpacketBDTS struct { ++ Sec uint32 ++ Usec uint32 ++} ++ ++type TpacketHdrV1 struct { ++ Block_status uint32 ++ Num_pkts uint32 ++ Offset_to_first_pkt uint32 ++ Blk_len uint32 ++ Seq_num uint64 ++ Ts_first_pkt TpacketBDTS ++ Ts_last_pkt TpacketBDTS ++} ++ ++type TpacketReq struct { ++ Block_size uint32 ++ Block_nr uint32 ++ Frame_size uint32 ++ Frame_nr uint32 ++} ++ ++type TpacketReq3 struct { ++ Block_size uint32 ++ Block_nr uint32 ++ Frame_size uint32 ++ Frame_nr uint32 ++ Retire_blk_tov uint32 ++ Sizeof_priv uint32 ++ Feature_req_word uint32 ++} ++ ++type TpacketStats struct { ++ Packets uint32 ++ Drops uint32 ++} ++ ++type TpacketStatsV3 struct { ++ Packets uint32 ++ Drops uint32 ++ Freeze_q_cnt uint32 ++} ++ ++type TpacketAuxdata struct { ++ Status uint32 ++ Len uint32 ++ Snaplen uint32 ++ Mac uint16 ++ Net uint16 ++ Vlan_tci uint16 ++ Vlan_tpid uint16 ++} ++ ++const ( ++ TPACKET_V1 = 0x0 ++ TPACKET_V2 = 0x1 ++ TPACKET_V3 = 0x2 ++) ++ ++const ( ++ SizeofTpacketHdr = 0x20 ++ SizeofTpacket2Hdr = 0x20 ++ SizeofTpacket3Hdr = 0x30 ++ ++ SizeofTpacketStats = 0x8 ++ SizeofTpacketStatsV3 = 0xc ++) ++ ++const ( ++ IFLA_UNSPEC = 0x0 ++ IFLA_ADDRESS = 0x1 ++ IFLA_BROADCAST = 0x2 ++ IFLA_IFNAME = 0x3 ++ IFLA_MTU = 0x4 ++ IFLA_LINK = 0x5 ++ IFLA_QDISC = 0x6 ++ IFLA_STATS = 0x7 ++ IFLA_COST = 0x8 ++ IFLA_PRIORITY = 0x9 ++ IFLA_MASTER = 0xa ++ IFLA_WIRELESS = 0xb ++ IFLA_PROTINFO = 0xc ++ IFLA_TXQLEN = 0xd ++ IFLA_MAP = 0xe ++ IFLA_WEIGHT = 0xf ++ IFLA_OPERSTATE = 0x10 ++ IFLA_LINKMODE = 0x11 ++ IFLA_LINKINFO = 0x12 ++ IFLA_NET_NS_PID = 0x13 ++ IFLA_IFALIAS = 0x14 ++ IFLA_NUM_VF = 0x15 ++ IFLA_VFINFO_LIST = 0x16 ++ IFLA_STATS64 = 0x17 ++ IFLA_VF_PORTS = 0x18 ++ IFLA_PORT_SELF = 0x19 ++ IFLA_AF_SPEC = 0x1a ++ IFLA_GROUP = 0x1b ++ IFLA_NET_NS_FD = 0x1c ++ IFLA_EXT_MASK = 0x1d ++ IFLA_PROMISCUITY = 0x1e ++ IFLA_NUM_TX_QUEUES = 0x1f ++ IFLA_NUM_RX_QUEUES = 0x20 ++ IFLA_CARRIER = 0x21 ++ IFLA_PHYS_PORT_ID = 0x22 ++ IFLA_CARRIER_CHANGES = 0x23 ++ IFLA_PHYS_SWITCH_ID = 0x24 ++ IFLA_LINK_NETNSID = 0x25 ++ IFLA_PHYS_PORT_NAME = 0x26 ++ IFLA_PROTO_DOWN = 0x27 ++ IFLA_GSO_MAX_SEGS = 0x28 ++ IFLA_GSO_MAX_SIZE = 0x29 ++ IFLA_PAD = 0x2a ++ IFLA_XDP = 0x2b ++ IFLA_EVENT = 0x2c ++ IFLA_NEW_NETNSID = 0x2d ++ IFLA_IF_NETNSID = 0x2e ++ IFLA_TARGET_NETNSID = 0x2e ++ IFLA_CARRIER_UP_COUNT = 0x2f ++ IFLA_CARRIER_DOWN_COUNT = 0x30 ++ IFLA_NEW_IFINDEX = 0x31 ++ IFLA_MIN_MTU = 0x32 ++ IFLA_MAX_MTU = 0x33 ++ IFLA_PROP_LIST = 0x34 ++ IFLA_ALT_IFNAME = 0x35 ++ IFLA_PERM_ADDRESS = 0x36 ++ IFLA_PROTO_DOWN_REASON = 0x37 ++ ++ IFLA_ALLMULTI = 0x3d ++ IFLA_DEVLINK_PORT = 0x3e ++ IFLA_GSO_IPV4_MAX_SIZE = 0x3f ++ IFLA_GRO_IPV4_MAX_SIZE = 0x40 ++ ++ IFLA_PROTO_DOWN_REASON_UNSPEC = 0x0 ++ IFLA_PROTO_DOWN_REASON_MASK = 0x1 ++ IFLA_PROTO_DOWN_REASON_VALUE = 0x2 ++ IFLA_PROTO_DOWN_REASON_MAX = 0x2 ++ IFLA_INET_UNSPEC = 0x0 ++ IFLA_INET_CONF = 0x1 ++ IFLA_INET6_UNSPEC = 0x0 ++ IFLA_INET6_FLAGS = 0x1 ++ IFLA_INET6_CONF = 0x2 ++ IFLA_INET6_STATS = 0x3 ++ IFLA_INET6_MCAST = 0x4 ++ IFLA_INET6_CACHEINFO = 0x5 ++ IFLA_INET6_ICMP6STATS = 0x6 ++ IFLA_INET6_TOKEN = 0x7 ++ IFLA_INET6_ADDR_GEN_MODE = 0x8 ++ IFLA_INET6_RA_MTU = 0x9 ++ IFLA_BR_UNSPEC = 0x0 ++ IFLA_BR_FORWARD_DELAY = 0x1 ++ IFLA_BR_HELLO_TIME = 0x2 ++ IFLA_BR_MAX_AGE = 0x3 ++ IFLA_BR_AGEING_TIME = 0x4 ++ IFLA_BR_STP_STATE = 0x5 ++ IFLA_BR_PRIORITY = 0x6 ++ IFLA_BR_VLAN_FILTERING = 0x7 ++ IFLA_BR_VLAN_PROTOCOL = 0x8 ++ IFLA_BR_GROUP_FWD_MASK = 0x9 ++ IFLA_BR_ROOT_ID = 0xa ++ IFLA_BR_BRIDGE_ID = 0xb ++ IFLA_BR_ROOT_PORT = 0xc ++ IFLA_BR_ROOT_PATH_COST = 0xd ++ IFLA_BR_TOPOLOGY_CHANGE = 0xe ++ IFLA_BR_TOPOLOGY_CHANGE_DETECTED = 0xf ++ IFLA_BR_HELLO_TIMER = 0x10 ++ IFLA_BR_TCN_TIMER = 0x11 ++ IFLA_BR_TOPOLOGY_CHANGE_TIMER = 0x12 ++ IFLA_BR_GC_TIMER = 0x13 ++ IFLA_BR_GROUP_ADDR = 0x14 ++ IFLA_BR_FDB_FLUSH = 0x15 ++ IFLA_BR_MCAST_ROUTER = 0x16 ++ IFLA_BR_MCAST_SNOOPING = 0x17 ++ IFLA_BR_MCAST_QUERY_USE_IFADDR = 0x18 ++ IFLA_BR_MCAST_QUERIER = 0x19 ++ IFLA_BR_MCAST_HASH_ELASTICITY = 0x1a ++ IFLA_BR_MCAST_HASH_MAX = 0x1b ++ IFLA_BR_MCAST_LAST_MEMBER_CNT = 0x1c ++ IFLA_BR_MCAST_STARTUP_QUERY_CNT = 0x1d ++ IFLA_BR_MCAST_LAST_MEMBER_INTVL = 0x1e ++ IFLA_BR_MCAST_MEMBERSHIP_INTVL = 0x1f ++ IFLA_BR_MCAST_QUERIER_INTVL = 0x20 ++ IFLA_BR_MCAST_QUERY_INTVL = 0x21 ++ IFLA_BR_MCAST_QUERY_RESPONSE_INTVL = 0x22 ++ IFLA_BR_MCAST_STARTUP_QUERY_INTVL = 0x23 ++ IFLA_BR_NF_CALL_IPTABLES = 0x24 ++ IFLA_BR_NF_CALL_IP6TABLES = 0x25 ++ IFLA_BR_NF_CALL_ARPTABLES = 0x26 ++ IFLA_BR_VLAN_DEFAULT_PVID = 0x27 ++ IFLA_BR_PAD = 0x28 ++ IFLA_BR_VLAN_STATS_ENABLED = 0x29 ++ IFLA_BR_MCAST_STATS_ENABLED = 0x2a ++ IFLA_BR_MCAST_IGMP_VERSION = 0x2b ++ IFLA_BR_MCAST_MLD_VERSION = 0x2c ++ IFLA_BR_VLAN_STATS_PER_PORT = 0x2d ++ IFLA_BR_MULTI_BOOLOPT = 0x2e ++ IFLA_BR_MCAST_QUERIER_STATE = 0x2f ++ ++ IFLA_BRPORT_UNSPEC = 0x0 ++ IFLA_BRPORT_STATE = 0x1 ++ IFLA_BRPORT_PRIORITY = 0x2 ++ IFLA_BRPORT_COST = 0x3 ++ IFLA_BRPORT_MODE = 0x4 ++ IFLA_BRPORT_GUARD = 0x5 ++ IFLA_BRPORT_PROTECT = 0x6 ++ IFLA_BRPORT_FAST_LEAVE = 0x7 ++ IFLA_BRPORT_LEARNING = 0x8 ++ IFLA_BRPORT_UNICAST_FLOOD = 0x9 ++ IFLA_BRPORT_PROXYARP = 0xa ++ IFLA_BRPORT_LEARNING_SYNC = 0xb ++ IFLA_BRPORT_PROXYARP_WIFI = 0xc ++ IFLA_BRPORT_ROOT_ID = 0xd ++ IFLA_BRPORT_BRIDGE_ID = 0xe ++ IFLA_BRPORT_DESIGNATED_PORT = 0xf ++ IFLA_BRPORT_DESIGNATED_COST = 0x10 ++ IFLA_BRPORT_ID = 0x11 ++ IFLA_BRPORT_NO = 0x12 ++ IFLA_BRPORT_TOPOLOGY_CHANGE_ACK = 0x13 ++ IFLA_BRPORT_CONFIG_PENDING = 0x14 ++ IFLA_BRPORT_MESSAGE_AGE_TIMER = 0x15 ++ IFLA_BRPORT_FORWARD_DELAY_TIMER = 0x16 ++ IFLA_BRPORT_HOLD_TIMER = 0x17 ++ IFLA_BRPORT_FLUSH = 0x18 ++ IFLA_BRPORT_MULTICAST_ROUTER = 0x19 ++ IFLA_BRPORT_PAD = 0x1a ++ IFLA_BRPORT_MCAST_FLOOD = 0x1b ++ IFLA_BRPORT_MCAST_TO_UCAST = 0x1c ++ IFLA_BRPORT_VLAN_TUNNEL = 0x1d ++ IFLA_BRPORT_BCAST_FLOOD = 0x1e ++ IFLA_BRPORT_GROUP_FWD_MASK = 0x1f ++ IFLA_BRPORT_NEIGH_SUPPRESS = 0x20 ++ IFLA_BRPORT_ISOLATED = 0x21 ++ IFLA_BRPORT_BACKUP_PORT = 0x22 ++ IFLA_BRPORT_MRP_RING_OPEN = 0x23 ++ IFLA_BRPORT_MRP_IN_OPEN = 0x24 ++ IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT = 0x25 ++ IFLA_BRPORT_MCAST_EHT_HOSTS_CNT = 0x26 ++ IFLA_BRPORT_LOCKED = 0x27 ++ IFLA_BRPORT_MAB = 0x28 ++ IFLA_BRPORT_MCAST_N_GROUPS = 0x29 ++ IFLA_BRPORT_MCAST_MAX_GROUPS = 0x2a ++ IFLA_BRPORT_NEIGH_VLAN_SUPPRESS = 0x2b ++ IFLA_BRPORT_BACKUP_NHID = 0x2c ++ IFLA_INFO_UNSPEC = 0x0 ++ IFLA_INFO_KIND = 0x1 ++ IFLA_INFO_DATA = 0x2 ++ IFLA_INFO_XSTATS = 0x3 ++ IFLA_INFO_SLAVE_KIND = 0x4 ++ IFLA_INFO_SLAVE_DATA = 0x5 ++ IFLA_VLAN_UNSPEC = 0x0 ++ IFLA_VLAN_ID = 0x1 ++ IFLA_VLAN_FLAGS = 0x2 ++ IFLA_VLAN_EGRESS_QOS = 0x3 ++ IFLA_VLAN_INGRESS_QOS = 0x4 ++ IFLA_VLAN_PROTOCOL = 0x5 ++ IFLA_VLAN_QOS_UNSPEC = 0x0 ++ IFLA_VLAN_QOS_MAPPING = 0x1 ++ IFLA_MACVLAN_UNSPEC = 0x0 ++ IFLA_MACVLAN_MODE = 0x1 ++ IFLA_MACVLAN_FLAGS = 0x2 ++ IFLA_MACVLAN_MACADDR_MODE = 0x3 ++ IFLA_MACVLAN_MACADDR = 0x4 ++ IFLA_MACVLAN_MACADDR_DATA = 0x5 ++ IFLA_MACVLAN_MACADDR_COUNT = 0x6 ++ IFLA_MACVLAN_BC_QUEUE_LEN = 0x7 ++ IFLA_MACVLAN_BC_QUEUE_LEN_USED = 0x8 ++ IFLA_MACVLAN_BC_CUTOFF = 0x9 ++ IFLA_VRF_UNSPEC = 0x0 ++ IFLA_VRF_TABLE = 0x1 ++ IFLA_VRF_PORT_UNSPEC = 0x0 ++ IFLA_VRF_PORT_TABLE = 0x1 ++ IFLA_MACSEC_UNSPEC = 0x0 ++ IFLA_MACSEC_SCI = 0x1 ++ IFLA_MACSEC_PORT = 0x2 ++ IFLA_MACSEC_ICV_LEN = 0x3 ++ IFLA_MACSEC_CIPHER_SUITE = 0x4 ++ IFLA_MACSEC_WINDOW = 0x5 ++ IFLA_MACSEC_ENCODING_SA = 0x6 ++ IFLA_MACSEC_ENCRYPT = 0x7 ++ IFLA_MACSEC_PROTECT = 0x8 ++ IFLA_MACSEC_INC_SCI = 0x9 ++ IFLA_MACSEC_ES = 0xa ++ IFLA_MACSEC_SCB = 0xb ++ IFLA_MACSEC_REPLAY_PROTECT = 0xc ++ IFLA_MACSEC_VALIDATION = 0xd ++ IFLA_MACSEC_PAD = 0xe ++ IFLA_MACSEC_OFFLOAD = 0xf ++ IFLA_XFRM_UNSPEC = 0x0 ++ IFLA_XFRM_LINK = 0x1 ++ IFLA_XFRM_IF_ID = 0x2 ++ IFLA_XFRM_COLLECT_METADATA = 0x3 ++ IFLA_IPVLAN_UNSPEC = 0x0 ++ IFLA_IPVLAN_MODE = 0x1 ++ IFLA_IPVLAN_FLAGS = 0x2 ++ ++ IFLA_VXLAN_UNSPEC = 0x0 ++ IFLA_VXLAN_ID = 0x1 ++ IFLA_VXLAN_GROUP = 0x2 ++ IFLA_VXLAN_LINK = 0x3 ++ IFLA_VXLAN_LOCAL = 0x4 ++ IFLA_VXLAN_TTL = 0x5 ++ IFLA_VXLAN_TOS = 0x6 ++ IFLA_VXLAN_LEARNING = 0x7 ++ IFLA_VXLAN_AGEING = 0x8 ++ IFLA_VXLAN_LIMIT = 0x9 ++ IFLA_VXLAN_PORT_RANGE = 0xa ++ IFLA_VXLAN_PROXY = 0xb ++ IFLA_VXLAN_RSC = 0xc ++ IFLA_VXLAN_L2MISS = 0xd ++ IFLA_VXLAN_L3MISS = 0xe ++ IFLA_VXLAN_PORT = 0xf ++ IFLA_VXLAN_GROUP6 = 0x10 ++ IFLA_VXLAN_LOCAL6 = 0x11 ++ IFLA_VXLAN_UDP_CSUM = 0x12 ++ IFLA_VXLAN_UDP_ZERO_CSUM6_TX = 0x13 ++ IFLA_VXLAN_UDP_ZERO_CSUM6_RX = 0x14 ++ IFLA_VXLAN_REMCSUM_TX = 0x15 ++ IFLA_VXLAN_REMCSUM_RX = 0x16 ++ IFLA_VXLAN_GBP = 0x17 ++ IFLA_VXLAN_REMCSUM_NOPARTIAL = 0x18 ++ IFLA_VXLAN_COLLECT_METADATA = 0x19 ++ IFLA_VXLAN_LABEL = 0x1a ++ IFLA_VXLAN_GPE = 0x1b ++ IFLA_VXLAN_TTL_INHERIT = 0x1c ++ IFLA_VXLAN_DF = 0x1d ++ IFLA_VXLAN_VNIFILTER = 0x1e ++ IFLA_VXLAN_LOCALBYPASS = 0x1f ++ ++ IFLA_GENEVE_UNSPEC = 0x0 ++ IFLA_GENEVE_ID = 0x1 ++ IFLA_GENEVE_REMOTE = 0x2 ++ IFLA_GENEVE_TTL = 0x3 ++ IFLA_GENEVE_TOS = 0x4 ++ IFLA_GENEVE_PORT = 0x5 ++ IFLA_GENEVE_COLLECT_METADATA = 0x6 ++ IFLA_GENEVE_REMOTE6 = 0x7 ++ IFLA_GENEVE_UDP_CSUM = 0x8 ++ IFLA_GENEVE_UDP_ZERO_CSUM6_TX = 0x9 ++ IFLA_GENEVE_UDP_ZERO_CSUM6_RX = 0xa ++ IFLA_GENEVE_LABEL = 0xb ++ IFLA_GENEVE_TTL_INHERIT = 0xc ++ IFLA_GENEVE_DF = 0xd ++ IFLA_GENEVE_INNER_PROTO_INHERIT = 0xe ++ IFLA_BAREUDP_UNSPEC = 0x0 ++ IFLA_BAREUDP_PORT = 0x1 ++ IFLA_BAREUDP_ETHERTYPE = 0x2 ++ IFLA_BAREUDP_SRCPORT_MIN = 0x3 ++ IFLA_BAREUDP_MULTIPROTO_MODE = 0x4 ++ IFLA_PPP_UNSPEC = 0x0 ++ IFLA_PPP_DEV_FD = 0x1 ++ IFLA_GTP_UNSPEC = 0x0 ++ IFLA_GTP_FD0 = 0x1 ++ IFLA_GTP_FD1 = 0x2 ++ IFLA_GTP_PDP_HASHSIZE = 0x3 ++ IFLA_GTP_ROLE = 0x4 ++ IFLA_GTP_CREATE_SOCKETS = 0x5 ++ IFLA_GTP_RESTART_COUNT = 0x6 ++ ++ IFLA_BOND_UNSPEC = 0x0 ++ IFLA_BOND_MODE = 0x1 ++ IFLA_BOND_ACTIVE_SLAVE = 0x2 ++ IFLA_BOND_MIIMON = 0x3 ++ IFLA_BOND_UPDELAY = 0x4 ++ IFLA_BOND_DOWNDELAY = 0x5 ++ IFLA_BOND_USE_CARRIER = 0x6 ++ IFLA_BOND_ARP_INTERVAL = 0x7 ++ IFLA_BOND_ARP_IP_TARGET = 0x8 ++ IFLA_BOND_ARP_VALIDATE = 0x9 ++ IFLA_BOND_ARP_ALL_TARGETS = 0xa ++ IFLA_BOND_PRIMARY = 0xb ++ IFLA_BOND_PRIMARY_RESELECT = 0xc ++ IFLA_BOND_FAIL_OVER_MAC = 0xd ++ IFLA_BOND_XMIT_HASH_POLICY = 0xe ++ IFLA_BOND_RESEND_IGMP = 0xf ++ IFLA_BOND_NUM_PEER_NOTIF = 0x10 ++ IFLA_BOND_ALL_SLAVES_ACTIVE = 0x11 ++ IFLA_BOND_MIN_LINKS = 0x12 ++ IFLA_BOND_LP_INTERVAL = 0x13 ++ IFLA_BOND_PACKETS_PER_SLAVE = 0x14 ++ IFLA_BOND_AD_LACP_RATE = 0x15 ++ IFLA_BOND_AD_SELECT = 0x16 ++ IFLA_BOND_AD_INFO = 0x17 ++ IFLA_BOND_AD_ACTOR_SYS_PRIO = 0x18 ++ IFLA_BOND_AD_USER_PORT_KEY = 0x19 ++ IFLA_BOND_AD_ACTOR_SYSTEM = 0x1a ++ IFLA_BOND_TLB_DYNAMIC_LB = 0x1b ++ IFLA_BOND_PEER_NOTIF_DELAY = 0x1c ++ IFLA_BOND_AD_LACP_ACTIVE = 0x1d ++ IFLA_BOND_MISSED_MAX = 0x1e ++ IFLA_BOND_NS_IP6_TARGET = 0x1f ++ ++ IFLA_BOND_AD_INFO_UNSPEC = 0x0 ++ IFLA_BOND_AD_INFO_AGGREGATOR = 0x1 ++ IFLA_BOND_AD_INFO_NUM_PORTS = 0x2 ++ IFLA_BOND_AD_INFO_ACTOR_KEY = 0x3 ++ IFLA_BOND_AD_INFO_PARTNER_KEY = 0x4 ++ IFLA_BOND_AD_INFO_PARTNER_MAC = 0x5 ++ IFLA_BOND_SLAVE_UNSPEC = 0x0 ++ IFLA_BOND_SLAVE_STATE = 0x1 ++ IFLA_BOND_SLAVE_MII_STATUS = 0x2 ++ IFLA_BOND_SLAVE_LINK_FAILURE_COUNT = 0x3 ++ IFLA_BOND_SLAVE_PERM_HWADDR = 0x4 ++ IFLA_BOND_SLAVE_QUEUE_ID = 0x5 ++ IFLA_BOND_SLAVE_AD_AGGREGATOR_ID = 0x6 ++ IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE = 0x7 ++ IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE = 0x8 ++ IFLA_BOND_SLAVE_PRIO = 0x9 ++ IFLA_VF_INFO_UNSPEC = 0x0 ++ IFLA_VF_INFO = 0x1 ++ IFLA_VF_UNSPEC = 0x0 ++ IFLA_VF_MAC = 0x1 ++ IFLA_VF_VLAN = 0x2 ++ IFLA_VF_TX_RATE = 0x3 ++ IFLA_VF_SPOOFCHK = 0x4 ++ IFLA_VF_LINK_STATE = 0x5 ++ IFLA_VF_RATE = 0x6 ++ IFLA_VF_RSS_QUERY_EN = 0x7 ++ IFLA_VF_STATS = 0x8 ++ IFLA_VF_TRUST = 0x9 ++ IFLA_VF_IB_NODE_GUID = 0xa ++ IFLA_VF_IB_PORT_GUID = 0xb ++ IFLA_VF_VLAN_LIST = 0xc ++ IFLA_VF_BROADCAST = 0xd ++ IFLA_VF_VLAN_INFO_UNSPEC = 0x0 ++ IFLA_VF_VLAN_INFO = 0x1 ++ IFLA_VF_LINK_STATE_AUTO = 0x0 ++ IFLA_VF_LINK_STATE_ENABLE = 0x1 ++ IFLA_VF_LINK_STATE_DISABLE = 0x2 ++ IFLA_VF_STATS_RX_PACKETS = 0x0 ++ IFLA_VF_STATS_TX_PACKETS = 0x1 ++ IFLA_VF_STATS_RX_BYTES = 0x2 ++ IFLA_VF_STATS_TX_BYTES = 0x3 ++ IFLA_VF_STATS_BROADCAST = 0x4 ++ IFLA_VF_STATS_MULTICAST = 0x5 ++ IFLA_VF_STATS_PAD = 0x6 ++ IFLA_VF_STATS_RX_DROPPED = 0x7 ++ IFLA_VF_STATS_TX_DROPPED = 0x8 ++ IFLA_VF_PORT_UNSPEC = 0x0 ++ IFLA_VF_PORT = 0x1 ++ IFLA_PORT_UNSPEC = 0x0 ++ IFLA_PORT_VF = 0x1 ++ IFLA_PORT_PROFILE = 0x2 ++ IFLA_PORT_VSI_TYPE = 0x3 ++ IFLA_PORT_INSTANCE_UUID = 0x4 ++ IFLA_PORT_HOST_UUID = 0x5 ++ IFLA_PORT_REQUEST = 0x6 ++ IFLA_PORT_RESPONSE = 0x7 ++ IFLA_IPOIB_UNSPEC = 0x0 ++ IFLA_IPOIB_PKEY = 0x1 ++ IFLA_IPOIB_MODE = 0x2 ++ IFLA_IPOIB_UMCAST = 0x3 ++ IFLA_HSR_UNSPEC = 0x0 ++ IFLA_HSR_SLAVE1 = 0x1 ++ IFLA_HSR_SLAVE2 = 0x2 ++ IFLA_HSR_MULTICAST_SPEC = 0x3 ++ IFLA_HSR_SUPERVISION_ADDR = 0x4 ++ IFLA_HSR_SEQ_NR = 0x5 ++ IFLA_HSR_VERSION = 0x6 ++ IFLA_HSR_PROTOCOL = 0x7 ++ ++ IFLA_STATS_UNSPEC = 0x0 ++ IFLA_STATS_LINK_64 = 0x1 ++ IFLA_STATS_LINK_XSTATS = 0x2 ++ IFLA_STATS_LINK_XSTATS_SLAVE = 0x3 ++ IFLA_STATS_LINK_OFFLOAD_XSTATS = 0x4 ++ IFLA_STATS_AF_SPEC = 0x5 ++ IFLA_STATS_GETSET_UNSPEC = 0x0 ++ IFLA_STATS_GET_FILTERS = 0x1 ++ IFLA_STATS_SET_OFFLOAD_XSTATS_L3_STATS = 0x2 ++ IFLA_OFFLOAD_XSTATS_UNSPEC = 0x0 ++ IFLA_OFFLOAD_XSTATS_CPU_HIT = 0x1 ++ IFLA_OFFLOAD_XSTATS_HW_S_INFO = 0x2 ++ IFLA_OFFLOAD_XSTATS_L3_STATS = 0x3 ++ IFLA_OFFLOAD_XSTATS_HW_S_INFO_UNSPEC = 0x0 ++ IFLA_OFFLOAD_XSTATS_HW_S_INFO_REQUEST = 0x1 ++ IFLA_OFFLOAD_XSTATS_HW_S_INFO_USED = 0x2 ++ IFLA_XDP_UNSPEC = 0x0 ++ IFLA_XDP_FD = 0x1 ++ IFLA_XDP_ATTACHED = 0x2 ++ IFLA_XDP_FLAGS = 0x3 ++ IFLA_XDP_PROG_ID = 0x4 ++ IFLA_XDP_DRV_PROG_ID = 0x5 ++ IFLA_XDP_SKB_PROG_ID = 0x6 ++ IFLA_XDP_HW_PROG_ID = 0x7 ++ IFLA_XDP_EXPECTED_FD = 0x8 ++ IFLA_EVENT_NONE = 0x0 ++ IFLA_EVENT_REBOOT = 0x1 ++ IFLA_EVENT_FEATURES = 0x2 ++ IFLA_EVENT_BONDING_FAILOVER = 0x3 ++ IFLA_EVENT_NOTIFY_PEERS = 0x4 ++ IFLA_EVENT_IGMP_RESEND = 0x5 ++ IFLA_EVENT_BONDING_OPTIONS = 0x6 ++ IFLA_TUN_UNSPEC = 0x0 ++ IFLA_TUN_OWNER = 0x1 ++ IFLA_TUN_GROUP = 0x2 ++ IFLA_TUN_TYPE = 0x3 ++ IFLA_TUN_PI = 0x4 ++ IFLA_TUN_VNET_HDR = 0x5 ++ IFLA_TUN_PERSIST = 0x6 ++ IFLA_TUN_MULTI_QUEUE = 0x7 ++ IFLA_TUN_NUM_QUEUES = 0x8 ++ IFLA_TUN_NUM_DISABLED_QUEUES = 0x9 ++ IFLA_RMNET_UNSPEC = 0x0 ++ IFLA_RMNET_MUX_ID = 0x1 ++ IFLA_RMNET_FLAGS = 0x2 ++ IFLA_MCTP_UNSPEC = 0x0 ++ IFLA_MCTP_NET = 0x1 ++ IFLA_DSA_UNSPEC = 0x0 ++ ++ IFLA_DSA_MASTER = 0x1 ++) ++ ++const ( ++ NF_INET_PRE_ROUTING = 0x0 ++ NF_INET_LOCAL_IN = 0x1 ++ NF_INET_FORWARD = 0x2 ++ NF_INET_LOCAL_OUT = 0x3 ++ NF_INET_POST_ROUTING = 0x4 ++ NF_INET_NUMHOOKS = 0x5 ++) ++ ++const ( ++ NF_NETDEV_INGRESS = 0x0 ++ ++ NF_NETDEV_NUMHOOKS = 0x2 ++) ++ ++const ( ++ NFPROTO_UNSPEC = 0x0 ++ NFPROTO_INET = 0x1 ++ NFPROTO_IPV4 = 0x2 ++ NFPROTO_ARP = 0x3 ++ NFPROTO_NETDEV = 0x5 ++ NFPROTO_BRIDGE = 0x7 ++ NFPROTO_IPV6 = 0xa ++ NFPROTO_DECNET = 0xc ++ NFPROTO_NUMPROTO = 0xd ++) ++ ++const SO_ORIGINAL_DST = 0x50 ++ ++type Nfgenmsg struct { ++ Nfgen_family uint8 ++ Version uint8 ++ Res_id uint16 ++} ++ ++const ( ++ NFNL_BATCH_UNSPEC = 0x0 ++ NFNL_BATCH_GENID = 0x1 ++) ++ ++const ( ++ NFT_REG_VERDICT = 0x0 ++ NFT_REG_1 = 0x1 ++ NFT_REG_2 = 0x2 ++ NFT_REG_3 = 0x3 ++ NFT_REG_4 = 0x4 ++ NFT_REG32_00 = 0x8 ++ NFT_REG32_01 = 0x9 ++ NFT_REG32_02 = 0xa ++ NFT_REG32_03 = 0xb ++ NFT_REG32_04 = 0xc ++ NFT_REG32_05 = 0xd ++ NFT_REG32_06 = 0xe ++ NFT_REG32_07 = 0xf ++ NFT_REG32_08 = 0x10 ++ NFT_REG32_09 = 0x11 ++ NFT_REG32_10 = 0x12 ++ NFT_REG32_11 = 0x13 ++ NFT_REG32_12 = 0x14 ++ NFT_REG32_13 = 0x15 ++ NFT_REG32_14 = 0x16 ++ NFT_REG32_15 = 0x17 ++ NFT_CONTINUE = -0x1 ++ NFT_BREAK = -0x2 ++ NFT_JUMP = -0x3 ++ NFT_GOTO = -0x4 ++ NFT_RETURN = -0x5 ++ NFT_MSG_NEWTABLE = 0x0 ++ NFT_MSG_GETTABLE = 0x1 ++ NFT_MSG_DELTABLE = 0x2 ++ NFT_MSG_NEWCHAIN = 0x3 ++ NFT_MSG_GETCHAIN = 0x4 ++ NFT_MSG_DELCHAIN = 0x5 ++ NFT_MSG_NEWRULE = 0x6 ++ NFT_MSG_GETRULE = 0x7 ++ NFT_MSG_DELRULE = 0x8 ++ NFT_MSG_NEWSET = 0x9 ++ NFT_MSG_GETSET = 0xa ++ NFT_MSG_DELSET = 0xb ++ NFT_MSG_NEWSETELEM = 0xc ++ NFT_MSG_GETSETELEM = 0xd ++ NFT_MSG_DELSETELEM = 0xe ++ NFT_MSG_NEWGEN = 0xf ++ NFT_MSG_GETGEN = 0x10 ++ NFT_MSG_TRACE = 0x11 ++ NFT_MSG_NEWOBJ = 0x12 ++ NFT_MSG_GETOBJ = 0x13 ++ NFT_MSG_DELOBJ = 0x14 ++ NFT_MSG_GETOBJ_RESET = 0x15 ++ NFT_MSG_NEWFLOWTABLE = 0x16 ++ NFT_MSG_GETFLOWTABLE = 0x17 ++ NFT_MSG_DELFLOWTABLE = 0x18 ++ NFT_MSG_GETRULE_RESET = 0x19 ++ NFT_MSG_MAX = 0x22 ++ NFTA_LIST_UNSPEC = 0x0 ++ NFTA_LIST_ELEM = 0x1 ++ NFTA_HOOK_UNSPEC = 0x0 ++ NFTA_HOOK_HOOKNUM = 0x1 ++ NFTA_HOOK_PRIORITY = 0x2 ++ NFTA_HOOK_DEV = 0x3 ++ NFT_TABLE_F_DORMANT = 0x1 ++ NFTA_TABLE_UNSPEC = 0x0 ++ NFTA_TABLE_NAME = 0x1 ++ NFTA_TABLE_FLAGS = 0x2 ++ NFTA_TABLE_USE = 0x3 ++ NFTA_CHAIN_UNSPEC = 0x0 ++ NFTA_CHAIN_TABLE = 0x1 ++ NFTA_CHAIN_HANDLE = 0x2 ++ NFTA_CHAIN_NAME = 0x3 ++ NFTA_CHAIN_HOOK = 0x4 ++ NFTA_CHAIN_POLICY = 0x5 ++ NFTA_CHAIN_USE = 0x6 ++ NFTA_CHAIN_TYPE = 0x7 ++ NFTA_CHAIN_COUNTERS = 0x8 ++ NFTA_CHAIN_PAD = 0x9 ++ NFTA_RULE_UNSPEC = 0x0 ++ NFTA_RULE_TABLE = 0x1 ++ NFTA_RULE_CHAIN = 0x2 ++ NFTA_RULE_HANDLE = 0x3 ++ NFTA_RULE_EXPRESSIONS = 0x4 ++ NFTA_RULE_COMPAT = 0x5 ++ NFTA_RULE_POSITION = 0x6 ++ NFTA_RULE_USERDATA = 0x7 ++ NFTA_RULE_PAD = 0x8 ++ NFTA_RULE_ID = 0x9 ++ NFT_RULE_COMPAT_F_INV = 0x2 ++ NFT_RULE_COMPAT_F_MASK = 0x2 ++ NFTA_RULE_COMPAT_UNSPEC = 0x0 ++ NFTA_RULE_COMPAT_PROTO = 0x1 ++ NFTA_RULE_COMPAT_FLAGS = 0x2 ++ NFT_SET_ANONYMOUS = 0x1 ++ NFT_SET_CONSTANT = 0x2 ++ NFT_SET_INTERVAL = 0x4 ++ NFT_SET_MAP = 0x8 ++ NFT_SET_TIMEOUT = 0x10 ++ NFT_SET_EVAL = 0x20 ++ NFT_SET_OBJECT = 0x40 ++ NFT_SET_POL_PERFORMANCE = 0x0 ++ NFT_SET_POL_MEMORY = 0x1 ++ NFTA_SET_DESC_UNSPEC = 0x0 ++ NFTA_SET_DESC_SIZE = 0x1 ++ NFTA_SET_UNSPEC = 0x0 ++ NFTA_SET_TABLE = 0x1 ++ NFTA_SET_NAME = 0x2 ++ NFTA_SET_FLAGS = 0x3 ++ NFTA_SET_KEY_TYPE = 0x4 ++ NFTA_SET_KEY_LEN = 0x5 ++ NFTA_SET_DATA_TYPE = 0x6 ++ NFTA_SET_DATA_LEN = 0x7 ++ NFTA_SET_POLICY = 0x8 ++ NFTA_SET_DESC = 0x9 ++ NFTA_SET_ID = 0xa ++ NFTA_SET_TIMEOUT = 0xb ++ NFTA_SET_GC_INTERVAL = 0xc ++ NFTA_SET_USERDATA = 0xd ++ NFTA_SET_PAD = 0xe ++ NFTA_SET_OBJ_TYPE = 0xf ++ NFT_SET_ELEM_INTERVAL_END = 0x1 ++ NFTA_SET_ELEM_UNSPEC = 0x0 ++ NFTA_SET_ELEM_KEY = 0x1 ++ NFTA_SET_ELEM_DATA = 0x2 ++ NFTA_SET_ELEM_FLAGS = 0x3 ++ NFTA_SET_ELEM_TIMEOUT = 0x4 ++ NFTA_SET_ELEM_EXPIRATION = 0x5 ++ NFTA_SET_ELEM_USERDATA = 0x6 ++ NFTA_SET_ELEM_EXPR = 0x7 ++ NFTA_SET_ELEM_PAD = 0x8 ++ NFTA_SET_ELEM_OBJREF = 0x9 ++ NFTA_SET_ELEM_LIST_UNSPEC = 0x0 ++ NFTA_SET_ELEM_LIST_TABLE = 0x1 ++ NFTA_SET_ELEM_LIST_SET = 0x2 ++ NFTA_SET_ELEM_LIST_ELEMENTS = 0x3 ++ NFTA_SET_ELEM_LIST_SET_ID = 0x4 ++ NFT_DATA_VALUE = 0x0 ++ NFT_DATA_VERDICT = 0xffffff00 ++ NFTA_DATA_UNSPEC = 0x0 ++ NFTA_DATA_VALUE = 0x1 ++ NFTA_DATA_VERDICT = 0x2 ++ NFTA_VERDICT_UNSPEC = 0x0 ++ NFTA_VERDICT_CODE = 0x1 ++ NFTA_VERDICT_CHAIN = 0x2 ++ NFTA_EXPR_UNSPEC = 0x0 ++ NFTA_EXPR_NAME = 0x1 ++ NFTA_EXPR_DATA = 0x2 ++ NFTA_IMMEDIATE_UNSPEC = 0x0 ++ NFTA_IMMEDIATE_DREG = 0x1 ++ NFTA_IMMEDIATE_DATA = 0x2 ++ NFTA_BITWISE_UNSPEC = 0x0 ++ NFTA_BITWISE_SREG = 0x1 ++ NFTA_BITWISE_DREG = 0x2 ++ NFTA_BITWISE_LEN = 0x3 ++ NFTA_BITWISE_MASK = 0x4 ++ NFTA_BITWISE_XOR = 0x5 ++ NFT_BYTEORDER_NTOH = 0x0 ++ NFT_BYTEORDER_HTON = 0x1 ++ NFTA_BYTEORDER_UNSPEC = 0x0 ++ NFTA_BYTEORDER_SREG = 0x1 ++ NFTA_BYTEORDER_DREG = 0x2 ++ NFTA_BYTEORDER_OP = 0x3 ++ NFTA_BYTEORDER_LEN = 0x4 ++ NFTA_BYTEORDER_SIZE = 0x5 ++ NFT_CMP_EQ = 0x0 ++ NFT_CMP_NEQ = 0x1 ++ NFT_CMP_LT = 0x2 ++ NFT_CMP_LTE = 0x3 ++ NFT_CMP_GT = 0x4 ++ NFT_CMP_GTE = 0x5 ++ NFTA_CMP_UNSPEC = 0x0 ++ NFTA_CMP_SREG = 0x1 ++ NFTA_CMP_OP = 0x2 ++ NFTA_CMP_DATA = 0x3 ++ NFT_RANGE_EQ = 0x0 ++ NFT_RANGE_NEQ = 0x1 ++ NFTA_RANGE_UNSPEC = 0x0 ++ NFTA_RANGE_SREG = 0x1 ++ NFTA_RANGE_OP = 0x2 ++ NFTA_RANGE_FROM_DATA = 0x3 ++ NFTA_RANGE_TO_DATA = 0x4 ++ NFT_LOOKUP_F_INV = 0x1 ++ NFTA_LOOKUP_UNSPEC = 0x0 ++ NFTA_LOOKUP_SET = 0x1 ++ NFTA_LOOKUP_SREG = 0x2 ++ NFTA_LOOKUP_DREG = 0x3 ++ NFTA_LOOKUP_SET_ID = 0x4 ++ NFTA_LOOKUP_FLAGS = 0x5 ++ NFT_DYNSET_OP_ADD = 0x0 ++ NFT_DYNSET_OP_UPDATE = 0x1 ++ NFT_DYNSET_F_INV = 0x1 ++ NFTA_DYNSET_UNSPEC = 0x0 ++ NFTA_DYNSET_SET_NAME = 0x1 ++ NFTA_DYNSET_SET_ID = 0x2 ++ NFTA_DYNSET_OP = 0x3 ++ NFTA_DYNSET_SREG_KEY = 0x4 ++ NFTA_DYNSET_SREG_DATA = 0x5 ++ NFTA_DYNSET_TIMEOUT = 0x6 ++ NFTA_DYNSET_EXPR = 0x7 ++ NFTA_DYNSET_PAD = 0x8 ++ NFTA_DYNSET_FLAGS = 0x9 ++ NFT_PAYLOAD_LL_HEADER = 0x0 ++ NFT_PAYLOAD_NETWORK_HEADER = 0x1 ++ NFT_PAYLOAD_TRANSPORT_HEADER = 0x2 ++ NFT_PAYLOAD_CSUM_NONE = 0x0 ++ NFT_PAYLOAD_CSUM_INET = 0x1 ++ NFT_PAYLOAD_L4CSUM_PSEUDOHDR = 0x1 ++ NFTA_PAYLOAD_UNSPEC = 0x0 ++ NFTA_PAYLOAD_DREG = 0x1 ++ NFTA_PAYLOAD_BASE = 0x2 ++ NFTA_PAYLOAD_OFFSET = 0x3 ++ NFTA_PAYLOAD_LEN = 0x4 ++ NFTA_PAYLOAD_SREG = 0x5 ++ NFTA_PAYLOAD_CSUM_TYPE = 0x6 ++ NFTA_PAYLOAD_CSUM_OFFSET = 0x7 ++ NFTA_PAYLOAD_CSUM_FLAGS = 0x8 ++ NFT_EXTHDR_F_PRESENT = 0x1 ++ NFT_EXTHDR_OP_IPV6 = 0x0 ++ NFT_EXTHDR_OP_TCPOPT = 0x1 ++ NFTA_EXTHDR_UNSPEC = 0x0 ++ NFTA_EXTHDR_DREG = 0x1 ++ NFTA_EXTHDR_TYPE = 0x2 ++ NFTA_EXTHDR_OFFSET = 0x3 ++ NFTA_EXTHDR_LEN = 0x4 ++ NFTA_EXTHDR_FLAGS = 0x5 ++ NFTA_EXTHDR_OP = 0x6 ++ NFTA_EXTHDR_SREG = 0x7 ++ NFT_META_LEN = 0x0 ++ NFT_META_PROTOCOL = 0x1 ++ NFT_META_PRIORITY = 0x2 ++ NFT_META_MARK = 0x3 ++ NFT_META_IIF = 0x4 ++ NFT_META_OIF = 0x5 ++ NFT_META_IIFNAME = 0x6 ++ NFT_META_OIFNAME = 0x7 ++ NFT_META_IIFTYPE = 0x8 ++ NFT_META_OIFTYPE = 0x9 ++ NFT_META_SKUID = 0xa ++ NFT_META_SKGID = 0xb ++ NFT_META_NFTRACE = 0xc ++ NFT_META_RTCLASSID = 0xd ++ NFT_META_SECMARK = 0xe ++ NFT_META_NFPROTO = 0xf ++ NFT_META_L4PROTO = 0x10 ++ NFT_META_BRI_IIFNAME = 0x11 ++ NFT_META_BRI_OIFNAME = 0x12 ++ NFT_META_PKTTYPE = 0x13 ++ NFT_META_CPU = 0x14 ++ NFT_META_IIFGROUP = 0x15 ++ NFT_META_OIFGROUP = 0x16 ++ NFT_META_CGROUP = 0x17 ++ NFT_META_PRANDOM = 0x18 ++ NFT_RT_CLASSID = 0x0 ++ NFT_RT_NEXTHOP4 = 0x1 ++ NFT_RT_NEXTHOP6 = 0x2 ++ NFT_RT_TCPMSS = 0x3 ++ NFT_HASH_JENKINS = 0x0 ++ NFT_HASH_SYM = 0x1 ++ NFTA_HASH_UNSPEC = 0x0 ++ NFTA_HASH_SREG = 0x1 ++ NFTA_HASH_DREG = 0x2 ++ NFTA_HASH_LEN = 0x3 ++ NFTA_HASH_MODULUS = 0x4 ++ NFTA_HASH_SEED = 0x5 ++ NFTA_HASH_OFFSET = 0x6 ++ NFTA_HASH_TYPE = 0x7 ++ NFTA_META_UNSPEC = 0x0 ++ NFTA_META_DREG = 0x1 ++ NFTA_META_KEY = 0x2 ++ NFTA_META_SREG = 0x3 ++ NFTA_RT_UNSPEC = 0x0 ++ NFTA_RT_DREG = 0x1 ++ NFTA_RT_KEY = 0x2 ++ NFT_CT_STATE = 0x0 ++ NFT_CT_DIRECTION = 0x1 ++ NFT_CT_STATUS = 0x2 ++ NFT_CT_MARK = 0x3 ++ NFT_CT_SECMARK = 0x4 ++ NFT_CT_EXPIRATION = 0x5 ++ NFT_CT_HELPER = 0x6 ++ NFT_CT_L3PROTOCOL = 0x7 ++ NFT_CT_SRC = 0x8 ++ NFT_CT_DST = 0x9 ++ NFT_CT_PROTOCOL = 0xa ++ NFT_CT_PROTO_SRC = 0xb ++ NFT_CT_PROTO_DST = 0xc ++ NFT_CT_LABELS = 0xd ++ NFT_CT_PKTS = 0xe ++ NFT_CT_BYTES = 0xf ++ NFT_CT_AVGPKT = 0x10 ++ NFT_CT_ZONE = 0x11 ++ NFT_CT_EVENTMASK = 0x12 ++ NFTA_CT_UNSPEC = 0x0 ++ NFTA_CT_DREG = 0x1 ++ NFTA_CT_KEY = 0x2 ++ NFTA_CT_DIRECTION = 0x3 ++ NFTA_CT_SREG = 0x4 ++ NFT_LIMIT_PKTS = 0x0 ++ NFT_LIMIT_PKT_BYTES = 0x1 ++ NFT_LIMIT_F_INV = 0x1 ++ NFTA_LIMIT_UNSPEC = 0x0 ++ NFTA_LIMIT_RATE = 0x1 ++ NFTA_LIMIT_UNIT = 0x2 ++ NFTA_LIMIT_BURST = 0x3 ++ NFTA_LIMIT_TYPE = 0x4 ++ NFTA_LIMIT_FLAGS = 0x5 ++ NFTA_LIMIT_PAD = 0x6 ++ NFTA_COUNTER_UNSPEC = 0x0 ++ NFTA_COUNTER_BYTES = 0x1 ++ NFTA_COUNTER_PACKETS = 0x2 ++ NFTA_COUNTER_PAD = 0x3 ++ NFTA_LOG_UNSPEC = 0x0 ++ NFTA_LOG_GROUP = 0x1 ++ NFTA_LOG_PREFIX = 0x2 ++ NFTA_LOG_SNAPLEN = 0x3 ++ NFTA_LOG_QTHRESHOLD = 0x4 ++ NFTA_LOG_LEVEL = 0x5 ++ NFTA_LOG_FLAGS = 0x6 ++ NFTA_QUEUE_UNSPEC = 0x0 ++ NFTA_QUEUE_NUM = 0x1 ++ NFTA_QUEUE_TOTAL = 0x2 ++ NFTA_QUEUE_FLAGS = 0x3 ++ NFTA_QUEUE_SREG_QNUM = 0x4 ++ NFT_QUOTA_F_INV = 0x1 ++ NFT_QUOTA_F_DEPLETED = 0x2 ++ NFTA_QUOTA_UNSPEC = 0x0 ++ NFTA_QUOTA_BYTES = 0x1 ++ NFTA_QUOTA_FLAGS = 0x2 ++ NFTA_QUOTA_PAD = 0x3 ++ NFTA_QUOTA_CONSUMED = 0x4 ++ NFT_REJECT_ICMP_UNREACH = 0x0 ++ NFT_REJECT_TCP_RST = 0x1 ++ NFT_REJECT_ICMPX_UNREACH = 0x2 ++ NFT_REJECT_ICMPX_NO_ROUTE = 0x0 ++ NFT_REJECT_ICMPX_PORT_UNREACH = 0x1 ++ NFT_REJECT_ICMPX_HOST_UNREACH = 0x2 ++ NFT_REJECT_ICMPX_ADMIN_PROHIBITED = 0x3 ++ NFTA_REJECT_UNSPEC = 0x0 ++ NFTA_REJECT_TYPE = 0x1 ++ NFTA_REJECT_ICMP_CODE = 0x2 ++ NFT_NAT_SNAT = 0x0 ++ NFT_NAT_DNAT = 0x1 ++ NFTA_NAT_UNSPEC = 0x0 ++ NFTA_NAT_TYPE = 0x1 ++ NFTA_NAT_FAMILY = 0x2 ++ NFTA_NAT_REG_ADDR_MIN = 0x3 ++ NFTA_NAT_REG_ADDR_MAX = 0x4 ++ NFTA_NAT_REG_PROTO_MIN = 0x5 ++ NFTA_NAT_REG_PROTO_MAX = 0x6 ++ NFTA_NAT_FLAGS = 0x7 ++ NFTA_MASQ_UNSPEC = 0x0 ++ NFTA_MASQ_FLAGS = 0x1 ++ NFTA_MASQ_REG_PROTO_MIN = 0x2 ++ NFTA_MASQ_REG_PROTO_MAX = 0x3 ++ NFTA_REDIR_UNSPEC = 0x0 ++ NFTA_REDIR_REG_PROTO_MIN = 0x1 ++ NFTA_REDIR_REG_PROTO_MAX = 0x2 ++ NFTA_REDIR_FLAGS = 0x3 ++ NFTA_DUP_UNSPEC = 0x0 ++ NFTA_DUP_SREG_ADDR = 0x1 ++ NFTA_DUP_SREG_DEV = 0x2 ++ NFTA_FWD_UNSPEC = 0x0 ++ NFTA_FWD_SREG_DEV = 0x1 ++ NFTA_OBJREF_UNSPEC = 0x0 ++ NFTA_OBJREF_IMM_TYPE = 0x1 ++ NFTA_OBJREF_IMM_NAME = 0x2 ++ NFTA_OBJREF_SET_SREG = 0x3 ++ NFTA_OBJREF_SET_NAME = 0x4 ++ NFTA_OBJREF_SET_ID = 0x5 ++ NFTA_GEN_UNSPEC = 0x0 ++ NFTA_GEN_ID = 0x1 ++ NFTA_GEN_PROC_PID = 0x2 ++ NFTA_GEN_PROC_NAME = 0x3 ++ NFTA_FIB_UNSPEC = 0x0 ++ NFTA_FIB_DREG = 0x1 ++ NFTA_FIB_RESULT = 0x2 ++ NFTA_FIB_FLAGS = 0x3 ++ NFT_FIB_RESULT_UNSPEC = 0x0 ++ NFT_FIB_RESULT_OIF = 0x1 ++ NFT_FIB_RESULT_OIFNAME = 0x2 ++ NFT_FIB_RESULT_ADDRTYPE = 0x3 ++ NFTA_FIB_F_SADDR = 0x1 ++ NFTA_FIB_F_DADDR = 0x2 ++ NFTA_FIB_F_MARK = 0x4 ++ NFTA_FIB_F_IIF = 0x8 ++ NFTA_FIB_F_OIF = 0x10 ++ NFTA_FIB_F_PRESENT = 0x20 ++ NFTA_CT_HELPER_UNSPEC = 0x0 ++ NFTA_CT_HELPER_NAME = 0x1 ++ NFTA_CT_HELPER_L3PROTO = 0x2 ++ NFTA_CT_HELPER_L4PROTO = 0x3 ++ NFTA_OBJ_UNSPEC = 0x0 ++ NFTA_OBJ_TABLE = 0x1 ++ NFTA_OBJ_NAME = 0x2 ++ NFTA_OBJ_TYPE = 0x3 ++ NFTA_OBJ_DATA = 0x4 ++ NFTA_OBJ_USE = 0x5 ++ NFTA_TRACE_UNSPEC = 0x0 ++ NFTA_TRACE_TABLE = 0x1 ++ NFTA_TRACE_CHAIN = 0x2 ++ NFTA_TRACE_RULE_HANDLE = 0x3 ++ NFTA_TRACE_TYPE = 0x4 ++ NFTA_TRACE_VERDICT = 0x5 ++ NFTA_TRACE_ID = 0x6 ++ NFTA_TRACE_LL_HEADER = 0x7 ++ NFTA_TRACE_NETWORK_HEADER = 0x8 ++ NFTA_TRACE_TRANSPORT_HEADER = 0x9 ++ NFTA_TRACE_IIF = 0xa ++ NFTA_TRACE_IIFTYPE = 0xb ++ NFTA_TRACE_OIF = 0xc ++ NFTA_TRACE_OIFTYPE = 0xd ++ NFTA_TRACE_MARK = 0xe ++ NFTA_TRACE_NFPROTO = 0xf ++ NFTA_TRACE_POLICY = 0x10 ++ NFTA_TRACE_PAD = 0x11 ++ NFT_TRACETYPE_UNSPEC = 0x0 ++ NFT_TRACETYPE_POLICY = 0x1 ++ NFT_TRACETYPE_RETURN = 0x2 ++ NFT_TRACETYPE_RULE = 0x3 ++ NFTA_NG_UNSPEC = 0x0 ++ NFTA_NG_DREG = 0x1 ++ NFTA_NG_MODULUS = 0x2 ++ NFTA_NG_TYPE = 0x3 ++ NFTA_NG_OFFSET = 0x4 ++ NFT_NG_INCREMENTAL = 0x0 ++ NFT_NG_RANDOM = 0x1 ++) ++ ++const ( ++ NFTA_TARGET_UNSPEC = 0x0 ++ NFTA_TARGET_NAME = 0x1 ++ NFTA_TARGET_REV = 0x2 ++ NFTA_TARGET_INFO = 0x3 ++ NFTA_MATCH_UNSPEC = 0x0 ++ NFTA_MATCH_NAME = 0x1 ++ NFTA_MATCH_REV = 0x2 ++ NFTA_MATCH_INFO = 0x3 ++ NFTA_COMPAT_UNSPEC = 0x0 ++ NFTA_COMPAT_NAME = 0x1 ++ NFTA_COMPAT_REV = 0x2 ++ NFTA_COMPAT_TYPE = 0x3 ++) ++ ++type RTCTime struct { ++ Sec int32 ++ Min int32 ++ Hour int32 ++ Mday int32 ++ Mon int32 ++ Year int32 ++ Wday int32 ++ Yday int32 ++ Isdst int32 ++} ++ ++type RTCWkAlrm struct { ++ Enabled uint8 ++ Pending uint8 ++ Time RTCTime ++} ++ ++type RTCPLLInfo struct { ++ Ctrl int32 ++ Value int32 ++ Max int32 ++ Min int32 ++ Posmult int32 ++ Negmult int32 ++ Clock int64 ++} ++ ++type BlkpgIoctlArg struct { ++ Op int32 ++ Flags int32 ++ Datalen int32 ++ Data *byte ++} ++ ++type BlkpgPartition struct { ++ Start int64 ++ Length int64 ++ Pno int32 ++ Devname [64]uint8 ++ Volname [64]uint8 ++ _ [4]byte ++} ++ ++const ( ++ BLKPG = 0x20001269 ++ BLKPG_ADD_PARTITION = 0x1 ++ BLKPG_DEL_PARTITION = 0x2 ++ BLKPG_RESIZE_PARTITION = 0x3 ++) ++ ++const ( ++ NETNSA_NONE = 0x0 ++ NETNSA_NSID = 0x1 ++ NETNSA_PID = 0x2 ++ NETNSA_FD = 0x3 ++ NETNSA_TARGET_NSID = 0x4 ++ NETNSA_CURRENT_NSID = 0x5 ++) ++ ++type XDPRingOffset struct { ++ Producer uint64 ++ Consumer uint64 ++ Desc uint64 ++ Flags uint64 ++} ++ ++type XDPMmapOffsets struct { ++ Rx XDPRingOffset ++ Tx XDPRingOffset ++ Fr XDPRingOffset ++ Cr XDPRingOffset ++} ++ ++type XDPUmemReg struct { ++ Addr uint64 ++ Len uint64 ++ Size uint32 ++ Headroom uint32 ++ Flags uint32 ++ _ [4]byte ++} ++ ++type XDPStatistics struct { ++ Rx_dropped uint64 ++ Rx_invalid_descs uint64 ++ Tx_invalid_descs uint64 ++ Rx_ring_full uint64 ++ Rx_fill_ring_empty_descs uint64 ++ Tx_ring_empty_descs uint64 ++} ++ ++type XDPDesc struct { ++ Addr uint64 ++ Len uint32 ++ Options uint32 ++} ++ ++const ( ++ NCSI_CMD_UNSPEC = 0x0 ++ NCSI_CMD_PKG_INFO = 0x1 ++ NCSI_CMD_SET_INTERFACE = 0x2 ++ NCSI_CMD_CLEAR_INTERFACE = 0x3 ++ NCSI_ATTR_UNSPEC = 0x0 ++ NCSI_ATTR_IFINDEX = 0x1 ++ NCSI_ATTR_PACKAGE_LIST = 0x2 ++ NCSI_ATTR_PACKAGE_ID = 0x3 ++ NCSI_ATTR_CHANNEL_ID = 0x4 ++ NCSI_PKG_ATTR_UNSPEC = 0x0 ++ NCSI_PKG_ATTR = 0x1 ++ NCSI_PKG_ATTR_ID = 0x2 ++ NCSI_PKG_ATTR_FORCED = 0x3 ++ NCSI_PKG_ATTR_CHANNEL_LIST = 0x4 ++ NCSI_CHANNEL_ATTR_UNSPEC = 0x0 ++ NCSI_CHANNEL_ATTR = 0x1 ++ NCSI_CHANNEL_ATTR_ID = 0x2 ++ NCSI_CHANNEL_ATTR_VERSION_MAJOR = 0x3 ++ NCSI_CHANNEL_ATTR_VERSION_MINOR = 0x4 ++ NCSI_CHANNEL_ATTR_VERSION_STR = 0x5 ++ NCSI_CHANNEL_ATTR_LINK_STATE = 0x6 ++ NCSI_CHANNEL_ATTR_ACTIVE = 0x7 ++ NCSI_CHANNEL_ATTR_FORCED = 0x8 ++ NCSI_CHANNEL_ATTR_VLAN_LIST = 0x9 ++ NCSI_CHANNEL_ATTR_VLAN_ID = 0xa ++) ++ ++type ScmTimestamping struct { ++ Ts [3]Timespec ++} ++ ++const ( ++ SOF_TIMESTAMPING_TX_HARDWARE = 0x1 ++ SOF_TIMESTAMPING_TX_SOFTWARE = 0x2 ++ SOF_TIMESTAMPING_RX_HARDWARE = 0x4 ++ SOF_TIMESTAMPING_RX_SOFTWARE = 0x8 ++ SOF_TIMESTAMPING_SOFTWARE = 0x10 ++ SOF_TIMESTAMPING_SYS_HARDWARE = 0x20 ++ SOF_TIMESTAMPING_RAW_HARDWARE = 0x40 ++ SOF_TIMESTAMPING_OPT_ID = 0x80 ++ SOF_TIMESTAMPING_TX_SCHED = 0x100 ++ SOF_TIMESTAMPING_TX_ACK = 0x200 ++ SOF_TIMESTAMPING_OPT_CMSG = 0x400 ++ SOF_TIMESTAMPING_OPT_TSONLY = 0x800 ++ SOF_TIMESTAMPING_OPT_STATS = 0x1000 ++ SOF_TIMESTAMPING_OPT_PKTINFO = 0x2000 ++ SOF_TIMESTAMPING_OPT_TX_SWHW = 0x4000 ++ SOF_TIMESTAMPING_BIND_PHC = 0x8000 ++ SOF_TIMESTAMPING_OPT_ID_TCP = 0x10000 ++ ++ SOF_TIMESTAMPING_LAST = 0x10000 ++ SOF_TIMESTAMPING_MASK = 0x1ffff ++ ++ SCM_TSTAMP_SND = 0x0 ++ SCM_TSTAMP_SCHED = 0x1 ++ SCM_TSTAMP_ACK = 0x2 ++) ++ ++type SockExtendedErr struct { ++ Errno uint32 ++ Origin uint8 ++ Type uint8 ++ Code uint8 ++ Pad uint8 ++ Info uint32 ++ Data uint32 ++} ++ ++type FanotifyEventMetadata struct { ++ Event_len uint32 ++ Vers uint8 ++ Reserved uint8 ++ Metadata_len uint16 ++ Mask uint64 ++ Fd int32 ++ Pid int32 ++} ++ ++type FanotifyResponse struct { ++ Fd int32 ++ Response uint32 ++} ++ ++const ( ++ CRYPTO_MSG_BASE = 0x10 ++ CRYPTO_MSG_NEWALG = 0x10 ++ CRYPTO_MSG_DELALG = 0x11 ++ CRYPTO_MSG_UPDATEALG = 0x12 ++ CRYPTO_MSG_GETALG = 0x13 ++ CRYPTO_MSG_DELRNG = 0x14 ++ CRYPTO_MSG_GETSTAT = 0x15 ++) ++ ++const ( ++ CRYPTOCFGA_UNSPEC = 0x0 ++ CRYPTOCFGA_PRIORITY_VAL = 0x1 ++ CRYPTOCFGA_REPORT_LARVAL = 0x2 ++ CRYPTOCFGA_REPORT_HASH = 0x3 ++ CRYPTOCFGA_REPORT_BLKCIPHER = 0x4 ++ CRYPTOCFGA_REPORT_AEAD = 0x5 ++ CRYPTOCFGA_REPORT_COMPRESS = 0x6 ++ CRYPTOCFGA_REPORT_RNG = 0x7 ++ CRYPTOCFGA_REPORT_CIPHER = 0x8 ++ CRYPTOCFGA_REPORT_AKCIPHER = 0x9 ++ CRYPTOCFGA_REPORT_KPP = 0xa ++ CRYPTOCFGA_REPORT_ACOMP = 0xb ++ CRYPTOCFGA_STAT_LARVAL = 0xc ++ CRYPTOCFGA_STAT_HASH = 0xd ++ CRYPTOCFGA_STAT_BLKCIPHER = 0xe ++ CRYPTOCFGA_STAT_AEAD = 0xf ++ CRYPTOCFGA_STAT_COMPRESS = 0x10 ++ CRYPTOCFGA_STAT_RNG = 0x11 ++ CRYPTOCFGA_STAT_CIPHER = 0x12 ++ CRYPTOCFGA_STAT_AKCIPHER = 0x13 ++ CRYPTOCFGA_STAT_KPP = 0x14 ++ CRYPTOCFGA_STAT_ACOMP = 0x15 ++) ++ ++type CryptoUserAlg struct { ++ Name [64]int8 ++ Driver_name [64]int8 ++ Module_name [64]int8 ++ Type uint32 ++ Mask uint32 ++ Refcnt uint32 ++ Flags uint32 ++} ++ ++type CryptoStatAEAD struct { ++ Type [64]int8 ++ Encrypt_cnt uint64 ++ Encrypt_tlen uint64 ++ Decrypt_cnt uint64 ++ Decrypt_tlen uint64 ++ Err_cnt uint64 ++} ++ ++type CryptoStatAKCipher struct { ++ Type [64]int8 ++ Encrypt_cnt uint64 ++ Encrypt_tlen uint64 ++ Decrypt_cnt uint64 ++ Decrypt_tlen uint64 ++ Verify_cnt uint64 ++ Sign_cnt uint64 ++ Err_cnt uint64 ++} ++ ++type CryptoStatCipher struct { ++ Type [64]int8 ++ Encrypt_cnt uint64 ++ Encrypt_tlen uint64 ++ Decrypt_cnt uint64 ++ Decrypt_tlen uint64 ++ Err_cnt uint64 ++} ++ ++type CryptoStatCompress struct { ++ Type [64]int8 ++ Compress_cnt uint64 ++ Compress_tlen uint64 ++ Decompress_cnt uint64 ++ Decompress_tlen uint64 ++ Err_cnt uint64 ++} ++ ++type CryptoStatHash struct { ++ Type [64]int8 ++ Hash_cnt uint64 ++ Hash_tlen uint64 ++ Err_cnt uint64 ++} ++ ++type CryptoStatKPP struct { ++ Type [64]int8 ++ Setsecret_cnt uint64 ++ Generate_public_key_cnt uint64 ++ Compute_shared_secret_cnt uint64 ++ Err_cnt uint64 ++} ++ ++type CryptoStatRNG struct { ++ Type [64]int8 ++ Generate_cnt uint64 ++ Generate_tlen uint64 ++ Seed_cnt uint64 ++ Err_cnt uint64 ++} ++ ++type CryptoStatLarval struct { ++ Type [64]int8 ++} ++ ++type CryptoReportLarval struct { ++ Type [64]int8 ++} ++ ++type CryptoReportHash struct { ++ Type [64]int8 ++ Blocksize uint32 ++ Digestsize uint32 ++} ++ ++type CryptoReportCipher struct { ++ Type [64]int8 ++ Blocksize uint32 ++ Min_keysize uint32 ++ Max_keysize uint32 ++} ++ ++type CryptoReportBlkCipher struct { ++ Type [64]int8 ++ Geniv [64]int8 ++ Blocksize uint32 ++ Min_keysize uint32 ++ Max_keysize uint32 ++ Ivsize uint32 ++} ++ ++type CryptoReportAEAD struct { ++ Type [64]int8 ++ Geniv [64]int8 ++ Blocksize uint32 ++ Maxauthsize uint32 ++ Ivsize uint32 ++} ++ ++type CryptoReportComp struct { ++ Type [64]int8 ++} ++ ++type CryptoReportRNG struct { ++ Type [64]int8 ++ Seedsize uint32 ++} ++ ++type CryptoReportAKCipher struct { ++ Type [64]int8 ++} ++ ++type CryptoReportKPP struct { ++ Type [64]int8 ++} ++ ++type CryptoReportAcomp struct { ++ Type [64]int8 ++} ++ ++const ( ++ BPF_REG_0 = 0x0 ++ BPF_REG_1 = 0x1 ++ BPF_REG_2 = 0x2 ++ BPF_REG_3 = 0x3 ++ BPF_REG_4 = 0x4 ++ BPF_REG_5 = 0x5 ++ BPF_REG_6 = 0x6 ++ BPF_REG_7 = 0x7 ++ BPF_REG_8 = 0x8 ++ BPF_REG_9 = 0x9 ++ BPF_REG_10 = 0xa ++ BPF_CGROUP_ITER_ORDER_UNSPEC = 0x0 ++ BPF_CGROUP_ITER_SELF_ONLY = 0x1 ++ BPF_CGROUP_ITER_DESCENDANTS_PRE = 0x2 ++ BPF_CGROUP_ITER_DESCENDANTS_POST = 0x3 ++ BPF_CGROUP_ITER_ANCESTORS_UP = 0x4 ++ BPF_MAP_CREATE = 0x0 ++ BPF_MAP_LOOKUP_ELEM = 0x1 ++ BPF_MAP_UPDATE_ELEM = 0x2 ++ BPF_MAP_DELETE_ELEM = 0x3 ++ BPF_MAP_GET_NEXT_KEY = 0x4 ++ BPF_PROG_LOAD = 0x5 ++ BPF_OBJ_PIN = 0x6 ++ BPF_OBJ_GET = 0x7 ++ BPF_PROG_ATTACH = 0x8 ++ BPF_PROG_DETACH = 0x9 ++ BPF_PROG_TEST_RUN = 0xa ++ BPF_PROG_RUN = 0xa ++ BPF_PROG_GET_NEXT_ID = 0xb ++ BPF_MAP_GET_NEXT_ID = 0xc ++ BPF_PROG_GET_FD_BY_ID = 0xd ++ BPF_MAP_GET_FD_BY_ID = 0xe ++ BPF_OBJ_GET_INFO_BY_FD = 0xf ++ BPF_PROG_QUERY = 0x10 ++ BPF_RAW_TRACEPOINT_OPEN = 0x11 ++ BPF_BTF_LOAD = 0x12 ++ BPF_BTF_GET_FD_BY_ID = 0x13 ++ BPF_TASK_FD_QUERY = 0x14 ++ BPF_MAP_LOOKUP_AND_DELETE_ELEM = 0x15 ++ BPF_MAP_FREEZE = 0x16 ++ BPF_BTF_GET_NEXT_ID = 0x17 ++ BPF_MAP_LOOKUP_BATCH = 0x18 ++ BPF_MAP_LOOKUP_AND_DELETE_BATCH = 0x19 ++ BPF_MAP_UPDATE_BATCH = 0x1a ++ BPF_MAP_DELETE_BATCH = 0x1b ++ BPF_LINK_CREATE = 0x1c ++ BPF_LINK_UPDATE = 0x1d ++ BPF_LINK_GET_FD_BY_ID = 0x1e ++ BPF_LINK_GET_NEXT_ID = 0x1f ++ BPF_ENABLE_STATS = 0x20 ++ BPF_ITER_CREATE = 0x21 ++ BPF_LINK_DETACH = 0x22 ++ BPF_PROG_BIND_MAP = 0x23 ++ BPF_MAP_TYPE_UNSPEC = 0x0 ++ BPF_MAP_TYPE_HASH = 0x1 ++ BPF_MAP_TYPE_ARRAY = 0x2 ++ BPF_MAP_TYPE_PROG_ARRAY = 0x3 ++ BPF_MAP_TYPE_PERF_EVENT_ARRAY = 0x4 ++ BPF_MAP_TYPE_PERCPU_HASH = 0x5 ++ BPF_MAP_TYPE_PERCPU_ARRAY = 0x6 ++ BPF_MAP_TYPE_STACK_TRACE = 0x7 ++ BPF_MAP_TYPE_CGROUP_ARRAY = 0x8 ++ BPF_MAP_TYPE_LRU_HASH = 0x9 ++ BPF_MAP_TYPE_LRU_PERCPU_HASH = 0xa ++ BPF_MAP_TYPE_LPM_TRIE = 0xb ++ BPF_MAP_TYPE_ARRAY_OF_MAPS = 0xc ++ BPF_MAP_TYPE_HASH_OF_MAPS = 0xd ++ BPF_MAP_TYPE_DEVMAP = 0xe ++ BPF_MAP_TYPE_SOCKMAP = 0xf ++ BPF_MAP_TYPE_CPUMAP = 0x10 ++ BPF_MAP_TYPE_XSKMAP = 0x11 ++ BPF_MAP_TYPE_SOCKHASH = 0x12 ++ BPF_MAP_TYPE_CGROUP_STORAGE_DEPRECATED = 0x13 ++ BPF_MAP_TYPE_CGROUP_STORAGE = 0x13 ++ BPF_MAP_TYPE_REUSEPORT_SOCKARRAY = 0x14 ++ BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE = 0x15 ++ BPF_MAP_TYPE_QUEUE = 0x16 ++ BPF_MAP_TYPE_STACK = 0x17 ++ BPF_MAP_TYPE_SK_STORAGE = 0x18 ++ BPF_MAP_TYPE_DEVMAP_HASH = 0x19 ++ BPF_MAP_TYPE_STRUCT_OPS = 0x1a ++ BPF_MAP_TYPE_RINGBUF = 0x1b ++ BPF_MAP_TYPE_INODE_STORAGE = 0x1c ++ BPF_MAP_TYPE_TASK_STORAGE = 0x1d ++ BPF_MAP_TYPE_BLOOM_FILTER = 0x1e ++ BPF_MAP_TYPE_USER_RINGBUF = 0x1f ++ BPF_MAP_TYPE_CGRP_STORAGE = 0x20 ++ BPF_PROG_TYPE_UNSPEC = 0x0 ++ BPF_PROG_TYPE_SOCKET_FILTER = 0x1 ++ BPF_PROG_TYPE_KPROBE = 0x2 ++ BPF_PROG_TYPE_SCHED_CLS = 0x3 ++ BPF_PROG_TYPE_SCHED_ACT = 0x4 ++ BPF_PROG_TYPE_TRACEPOINT = 0x5 ++ BPF_PROG_TYPE_XDP = 0x6 ++ BPF_PROG_TYPE_PERF_EVENT = 0x7 ++ BPF_PROG_TYPE_CGROUP_SKB = 0x8 ++ BPF_PROG_TYPE_CGROUP_SOCK = 0x9 ++ BPF_PROG_TYPE_LWT_IN = 0xa ++ BPF_PROG_TYPE_LWT_OUT = 0xb ++ BPF_PROG_TYPE_LWT_XMIT = 0xc ++ BPF_PROG_TYPE_SOCK_OPS = 0xd ++ BPF_PROG_TYPE_SK_SKB = 0xe ++ BPF_PROG_TYPE_CGROUP_DEVICE = 0xf ++ BPF_PROG_TYPE_SK_MSG = 0x10 ++ BPF_PROG_TYPE_RAW_TRACEPOINT = 0x11 ++ BPF_PROG_TYPE_CGROUP_SOCK_ADDR = 0x12 ++ BPF_PROG_TYPE_LWT_SEG6LOCAL = 0x13 ++ BPF_PROG_TYPE_LIRC_MODE2 = 0x14 ++ BPF_PROG_TYPE_SK_REUSEPORT = 0x15 ++ BPF_PROG_TYPE_FLOW_DISSECTOR = 0x16 ++ BPF_PROG_TYPE_CGROUP_SYSCTL = 0x17 ++ BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE = 0x18 ++ BPF_PROG_TYPE_CGROUP_SOCKOPT = 0x19 ++ BPF_PROG_TYPE_TRACING = 0x1a ++ BPF_PROG_TYPE_STRUCT_OPS = 0x1b ++ BPF_PROG_TYPE_EXT = 0x1c ++ BPF_PROG_TYPE_LSM = 0x1d ++ BPF_PROG_TYPE_SK_LOOKUP = 0x1e ++ BPF_PROG_TYPE_SYSCALL = 0x1f ++ BPF_PROG_TYPE_NETFILTER = 0x20 ++ BPF_CGROUP_INET_INGRESS = 0x0 ++ BPF_CGROUP_INET_EGRESS = 0x1 ++ BPF_CGROUP_INET_SOCK_CREATE = 0x2 ++ BPF_CGROUP_SOCK_OPS = 0x3 ++ BPF_SK_SKB_STREAM_PARSER = 0x4 ++ BPF_SK_SKB_STREAM_VERDICT = 0x5 ++ BPF_CGROUP_DEVICE = 0x6 ++ BPF_SK_MSG_VERDICT = 0x7 ++ BPF_CGROUP_INET4_BIND = 0x8 ++ BPF_CGROUP_INET6_BIND = 0x9 ++ BPF_CGROUP_INET4_CONNECT = 0xa ++ BPF_CGROUP_INET6_CONNECT = 0xb ++ BPF_CGROUP_INET4_POST_BIND = 0xc ++ BPF_CGROUP_INET6_POST_BIND = 0xd ++ BPF_CGROUP_UDP4_SENDMSG = 0xe ++ BPF_CGROUP_UDP6_SENDMSG = 0xf ++ BPF_LIRC_MODE2 = 0x10 ++ BPF_FLOW_DISSECTOR = 0x11 ++ BPF_CGROUP_SYSCTL = 0x12 ++ BPF_CGROUP_UDP4_RECVMSG = 0x13 ++ BPF_CGROUP_UDP6_RECVMSG = 0x14 ++ BPF_CGROUP_GETSOCKOPT = 0x15 ++ BPF_CGROUP_SETSOCKOPT = 0x16 ++ BPF_TRACE_RAW_TP = 0x17 ++ BPF_TRACE_FENTRY = 0x18 ++ BPF_TRACE_FEXIT = 0x19 ++ BPF_MODIFY_RETURN = 0x1a ++ BPF_LSM_MAC = 0x1b ++ BPF_TRACE_ITER = 0x1c ++ BPF_CGROUP_INET4_GETPEERNAME = 0x1d ++ BPF_CGROUP_INET6_GETPEERNAME = 0x1e ++ BPF_CGROUP_INET4_GETSOCKNAME = 0x1f ++ BPF_CGROUP_INET6_GETSOCKNAME = 0x20 ++ BPF_XDP_DEVMAP = 0x21 ++ BPF_CGROUP_INET_SOCK_RELEASE = 0x22 ++ BPF_XDP_CPUMAP = 0x23 ++ BPF_SK_LOOKUP = 0x24 ++ BPF_XDP = 0x25 ++ BPF_SK_SKB_VERDICT = 0x26 ++ BPF_SK_REUSEPORT_SELECT = 0x27 ++ BPF_SK_REUSEPORT_SELECT_OR_MIGRATE = 0x28 ++ BPF_PERF_EVENT = 0x29 ++ BPF_TRACE_KPROBE_MULTI = 0x2a ++ BPF_LSM_CGROUP = 0x2b ++ BPF_STRUCT_OPS = 0x2c ++ BPF_NETFILTER = 0x2d ++ BPF_TCX_INGRESS = 0x2e ++ BPF_TCX_EGRESS = 0x2f ++ BPF_TRACE_UPROBE_MULTI = 0x30 ++ BPF_LINK_TYPE_UNSPEC = 0x0 ++ BPF_LINK_TYPE_RAW_TRACEPOINT = 0x1 ++ BPF_LINK_TYPE_TRACING = 0x2 ++ BPF_LINK_TYPE_CGROUP = 0x3 ++ BPF_LINK_TYPE_ITER = 0x4 ++ BPF_LINK_TYPE_NETNS = 0x5 ++ BPF_LINK_TYPE_XDP = 0x6 ++ BPF_LINK_TYPE_PERF_EVENT = 0x7 ++ BPF_LINK_TYPE_KPROBE_MULTI = 0x8 ++ BPF_LINK_TYPE_STRUCT_OPS = 0x9 ++ BPF_LINK_TYPE_NETFILTER = 0xa ++ BPF_LINK_TYPE_TCX = 0xb ++ BPF_LINK_TYPE_UPROBE_MULTI = 0xc ++ BPF_PERF_EVENT_UNSPEC = 0x0 ++ BPF_PERF_EVENT_UPROBE = 0x1 ++ BPF_PERF_EVENT_URETPROBE = 0x2 ++ BPF_PERF_EVENT_KPROBE = 0x3 ++ BPF_PERF_EVENT_KRETPROBE = 0x4 ++ BPF_PERF_EVENT_TRACEPOINT = 0x5 ++ BPF_PERF_EVENT_EVENT = 0x6 ++ BPF_F_KPROBE_MULTI_RETURN = 0x1 ++ BPF_F_UPROBE_MULTI_RETURN = 0x1 ++ BPF_ANY = 0x0 ++ BPF_NOEXIST = 0x1 ++ BPF_EXIST = 0x2 ++ BPF_F_LOCK = 0x4 ++ BPF_F_NO_PREALLOC = 0x1 ++ BPF_F_NO_COMMON_LRU = 0x2 ++ BPF_F_NUMA_NODE = 0x4 ++ BPF_F_RDONLY = 0x8 ++ BPF_F_WRONLY = 0x10 ++ BPF_F_STACK_BUILD_ID = 0x20 ++ BPF_F_ZERO_SEED = 0x40 ++ BPF_F_RDONLY_PROG = 0x80 ++ BPF_F_WRONLY_PROG = 0x100 ++ BPF_F_CLONE = 0x200 ++ BPF_F_MMAPABLE = 0x400 ++ BPF_F_PRESERVE_ELEMS = 0x800 ++ BPF_F_INNER_MAP = 0x1000 ++ BPF_F_LINK = 0x2000 ++ BPF_F_PATH_FD = 0x4000 ++ BPF_STATS_RUN_TIME = 0x0 ++ BPF_STACK_BUILD_ID_EMPTY = 0x0 ++ BPF_STACK_BUILD_ID_VALID = 0x1 ++ BPF_STACK_BUILD_ID_IP = 0x2 ++ BPF_F_RECOMPUTE_CSUM = 0x1 ++ BPF_F_INVALIDATE_HASH = 0x2 ++ BPF_F_HDR_FIELD_MASK = 0xf ++ BPF_F_PSEUDO_HDR = 0x10 ++ BPF_F_MARK_MANGLED_0 = 0x20 ++ BPF_F_MARK_ENFORCE = 0x40 ++ BPF_F_INGRESS = 0x1 ++ BPF_F_TUNINFO_IPV6 = 0x1 ++ BPF_F_SKIP_FIELD_MASK = 0xff ++ BPF_F_USER_STACK = 0x100 ++ BPF_F_FAST_STACK_CMP = 0x200 ++ BPF_F_REUSE_STACKID = 0x400 ++ BPF_F_USER_BUILD_ID = 0x800 ++ BPF_F_ZERO_CSUM_TX = 0x2 ++ BPF_F_DONT_FRAGMENT = 0x4 ++ BPF_F_SEQ_NUMBER = 0x8 ++ BPF_F_NO_TUNNEL_KEY = 0x10 ++ BPF_F_TUNINFO_FLAGS = 0x10 ++ BPF_F_INDEX_MASK = 0xffffffff ++ BPF_F_CURRENT_CPU = 0xffffffff ++ BPF_F_CTXLEN_MASK = 0xfffff00000000 ++ BPF_F_CURRENT_NETNS = -0x1 ++ BPF_CSUM_LEVEL_QUERY = 0x0 ++ BPF_CSUM_LEVEL_INC = 0x1 ++ BPF_CSUM_LEVEL_DEC = 0x2 ++ BPF_CSUM_LEVEL_RESET = 0x3 ++ BPF_F_ADJ_ROOM_FIXED_GSO = 0x1 ++ BPF_F_ADJ_ROOM_ENCAP_L3_IPV4 = 0x2 ++ BPF_F_ADJ_ROOM_ENCAP_L3_IPV6 = 0x4 ++ BPF_F_ADJ_ROOM_ENCAP_L4_GRE = 0x8 ++ BPF_F_ADJ_ROOM_ENCAP_L4_UDP = 0x10 ++ BPF_F_ADJ_ROOM_NO_CSUM_RESET = 0x20 ++ BPF_F_ADJ_ROOM_ENCAP_L2_ETH = 0x40 ++ BPF_F_ADJ_ROOM_DECAP_L3_IPV4 = 0x80 ++ BPF_F_ADJ_ROOM_DECAP_L3_IPV6 = 0x100 ++ BPF_ADJ_ROOM_ENCAP_L2_MASK = 0xff ++ BPF_ADJ_ROOM_ENCAP_L2_SHIFT = 0x38 ++ BPF_F_SYSCTL_BASE_NAME = 0x1 ++ BPF_LOCAL_STORAGE_GET_F_CREATE = 0x1 ++ BPF_SK_STORAGE_GET_F_CREATE = 0x1 ++ BPF_F_GET_BRANCH_RECORDS_SIZE = 0x1 ++ BPF_RB_NO_WAKEUP = 0x1 ++ BPF_RB_FORCE_WAKEUP = 0x2 ++ BPF_RB_AVAIL_DATA = 0x0 ++ BPF_RB_RING_SIZE = 0x1 ++ BPF_RB_CONS_POS = 0x2 ++ BPF_RB_PROD_POS = 0x3 ++ BPF_RINGBUF_BUSY_BIT = 0x80000000 ++ BPF_RINGBUF_DISCARD_BIT = 0x40000000 ++ BPF_RINGBUF_HDR_SZ = 0x8 ++ BPF_SK_LOOKUP_F_REPLACE = 0x1 ++ BPF_SK_LOOKUP_F_NO_REUSEPORT = 0x2 ++ BPF_ADJ_ROOM_NET = 0x0 ++ BPF_ADJ_ROOM_MAC = 0x1 ++ BPF_HDR_START_MAC = 0x0 ++ BPF_HDR_START_NET = 0x1 ++ BPF_LWT_ENCAP_SEG6 = 0x0 ++ BPF_LWT_ENCAP_SEG6_INLINE = 0x1 ++ BPF_LWT_ENCAP_IP = 0x2 ++ BPF_F_BPRM_SECUREEXEC = 0x1 ++ BPF_F_BROADCAST = 0x8 ++ BPF_F_EXCLUDE_INGRESS = 0x10 ++ BPF_SKB_TSTAMP_UNSPEC = 0x0 ++ BPF_SKB_TSTAMP_DELIVERY_MONO = 0x1 ++ BPF_OK = 0x0 ++ BPF_DROP = 0x2 ++ BPF_REDIRECT = 0x7 ++ BPF_LWT_REROUTE = 0x80 ++ BPF_FLOW_DISSECTOR_CONTINUE = 0x81 ++ BPF_SOCK_OPS_RTO_CB_FLAG = 0x1 ++ BPF_SOCK_OPS_RETRANS_CB_FLAG = 0x2 ++ BPF_SOCK_OPS_STATE_CB_FLAG = 0x4 ++ BPF_SOCK_OPS_RTT_CB_FLAG = 0x8 ++ BPF_SOCK_OPS_PARSE_ALL_HDR_OPT_CB_FLAG = 0x10 ++ BPF_SOCK_OPS_PARSE_UNKNOWN_HDR_OPT_CB_FLAG = 0x20 ++ BPF_SOCK_OPS_WRITE_HDR_OPT_CB_FLAG = 0x40 ++ BPF_SOCK_OPS_ALL_CB_FLAGS = 0x7f ++ BPF_SOCK_OPS_VOID = 0x0 ++ BPF_SOCK_OPS_TIMEOUT_INIT = 0x1 ++ BPF_SOCK_OPS_RWND_INIT = 0x2 ++ BPF_SOCK_OPS_TCP_CONNECT_CB = 0x3 ++ BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB = 0x4 ++ BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB = 0x5 ++ BPF_SOCK_OPS_NEEDS_ECN = 0x6 ++ BPF_SOCK_OPS_BASE_RTT = 0x7 ++ BPF_SOCK_OPS_RTO_CB = 0x8 ++ BPF_SOCK_OPS_RETRANS_CB = 0x9 ++ BPF_SOCK_OPS_STATE_CB = 0xa ++ BPF_SOCK_OPS_TCP_LISTEN_CB = 0xb ++ BPF_SOCK_OPS_RTT_CB = 0xc ++ BPF_SOCK_OPS_PARSE_HDR_OPT_CB = 0xd ++ BPF_SOCK_OPS_HDR_OPT_LEN_CB = 0xe ++ BPF_SOCK_OPS_WRITE_HDR_OPT_CB = 0xf ++ BPF_TCP_ESTABLISHED = 0x1 ++ BPF_TCP_SYN_SENT = 0x2 ++ BPF_TCP_SYN_RECV = 0x3 ++ BPF_TCP_FIN_WAIT1 = 0x4 ++ BPF_TCP_FIN_WAIT2 = 0x5 ++ BPF_TCP_TIME_WAIT = 0x6 ++ BPF_TCP_CLOSE = 0x7 ++ BPF_TCP_CLOSE_WAIT = 0x8 ++ BPF_TCP_LAST_ACK = 0x9 ++ BPF_TCP_LISTEN = 0xa ++ BPF_TCP_CLOSING = 0xb ++ BPF_TCP_NEW_SYN_RECV = 0xc ++ BPF_TCP_MAX_STATES = 0xd ++ TCP_BPF_IW = 0x3e9 ++ TCP_BPF_SNDCWND_CLAMP = 0x3ea ++ TCP_BPF_DELACK_MAX = 0x3eb ++ TCP_BPF_RTO_MIN = 0x3ec ++ TCP_BPF_SYN = 0x3ed ++ TCP_BPF_SYN_IP = 0x3ee ++ TCP_BPF_SYN_MAC = 0x3ef ++ BPF_LOAD_HDR_OPT_TCP_SYN = 0x1 ++ BPF_WRITE_HDR_TCP_CURRENT_MSS = 0x1 ++ BPF_WRITE_HDR_TCP_SYNACK_COOKIE = 0x2 ++ BPF_DEVCG_ACC_MKNOD = 0x1 ++ BPF_DEVCG_ACC_READ = 0x2 ++ BPF_DEVCG_ACC_WRITE = 0x4 ++ BPF_DEVCG_DEV_BLOCK = 0x1 ++ BPF_DEVCG_DEV_CHAR = 0x2 ++ BPF_FIB_LOOKUP_DIRECT = 0x1 ++ BPF_FIB_LOOKUP_OUTPUT = 0x2 ++ BPF_FIB_LOOKUP_SKIP_NEIGH = 0x4 ++ BPF_FIB_LOOKUP_TBID = 0x8 ++ BPF_FIB_LKUP_RET_SUCCESS = 0x0 ++ BPF_FIB_LKUP_RET_BLACKHOLE = 0x1 ++ BPF_FIB_LKUP_RET_UNREACHABLE = 0x2 ++ BPF_FIB_LKUP_RET_PROHIBIT = 0x3 ++ BPF_FIB_LKUP_RET_NOT_FWDED = 0x4 ++ BPF_FIB_LKUP_RET_FWD_DISABLED = 0x5 ++ BPF_FIB_LKUP_RET_UNSUPP_LWT = 0x6 ++ BPF_FIB_LKUP_RET_NO_NEIGH = 0x7 ++ BPF_FIB_LKUP_RET_FRAG_NEEDED = 0x8 ++ BPF_MTU_CHK_SEGS = 0x1 ++ BPF_MTU_CHK_RET_SUCCESS = 0x0 ++ BPF_MTU_CHK_RET_FRAG_NEEDED = 0x1 ++ BPF_MTU_CHK_RET_SEGS_TOOBIG = 0x2 ++ BPF_FD_TYPE_RAW_TRACEPOINT = 0x0 ++ BPF_FD_TYPE_TRACEPOINT = 0x1 ++ BPF_FD_TYPE_KPROBE = 0x2 ++ BPF_FD_TYPE_KRETPROBE = 0x3 ++ BPF_FD_TYPE_UPROBE = 0x4 ++ BPF_FD_TYPE_URETPROBE = 0x5 ++ BPF_FLOW_DISSECTOR_F_PARSE_1ST_FRAG = 0x1 ++ BPF_FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL = 0x2 ++ BPF_FLOW_DISSECTOR_F_STOP_AT_ENCAP = 0x4 ++ BPF_CORE_FIELD_BYTE_OFFSET = 0x0 ++ BPF_CORE_FIELD_BYTE_SIZE = 0x1 ++ BPF_CORE_FIELD_EXISTS = 0x2 ++ BPF_CORE_FIELD_SIGNED = 0x3 ++ BPF_CORE_FIELD_LSHIFT_U64 = 0x4 ++ BPF_CORE_FIELD_RSHIFT_U64 = 0x5 ++ BPF_CORE_TYPE_ID_LOCAL = 0x6 ++ BPF_CORE_TYPE_ID_TARGET = 0x7 ++ BPF_CORE_TYPE_EXISTS = 0x8 ++ BPF_CORE_TYPE_SIZE = 0x9 ++ BPF_CORE_ENUMVAL_EXISTS = 0xa ++ BPF_CORE_ENUMVAL_VALUE = 0xb ++ BPF_CORE_TYPE_MATCHES = 0xc ++ BPF_F_TIMER_ABS = 0x1 ++) ++ ++const ( ++ RTNLGRP_NONE = 0x0 ++ RTNLGRP_LINK = 0x1 ++ RTNLGRP_NOTIFY = 0x2 ++ RTNLGRP_NEIGH = 0x3 ++ RTNLGRP_TC = 0x4 ++ RTNLGRP_IPV4_IFADDR = 0x5 ++ RTNLGRP_IPV4_MROUTE = 0x6 ++ RTNLGRP_IPV4_ROUTE = 0x7 ++ RTNLGRP_IPV4_RULE = 0x8 ++ RTNLGRP_IPV6_IFADDR = 0x9 ++ RTNLGRP_IPV6_MROUTE = 0xa ++ RTNLGRP_IPV6_ROUTE = 0xb ++ RTNLGRP_IPV6_IFINFO = 0xc ++ RTNLGRP_DECnet_IFADDR = 0xd ++ RTNLGRP_NOP2 = 0xe ++ RTNLGRP_DECnet_ROUTE = 0xf ++ RTNLGRP_DECnet_RULE = 0x10 ++ RTNLGRP_NOP4 = 0x11 ++ RTNLGRP_IPV6_PREFIX = 0x12 ++ RTNLGRP_IPV6_RULE = 0x13 ++ RTNLGRP_ND_USEROPT = 0x14 ++ RTNLGRP_PHONET_IFADDR = 0x15 ++ RTNLGRP_PHONET_ROUTE = 0x16 ++ RTNLGRP_DCB = 0x17 ++ RTNLGRP_IPV4_NETCONF = 0x18 ++ RTNLGRP_IPV6_NETCONF = 0x19 ++ RTNLGRP_MDB = 0x1a ++ RTNLGRP_MPLS_ROUTE = 0x1b ++ RTNLGRP_NSID = 0x1c ++ RTNLGRP_MPLS_NETCONF = 0x1d ++ RTNLGRP_IPV4_MROUTE_R = 0x1e ++ RTNLGRP_IPV6_MROUTE_R = 0x1f ++ RTNLGRP_NEXTHOP = 0x20 ++ RTNLGRP_BRVLAN = 0x21 ++) ++ ++type CapUserHeader struct { ++ Version uint32 ++ Pid int32 ++} ++ ++type CapUserData struct { ++ Effective uint32 ++ Permitted uint32 ++ Inheritable uint32 ++} ++ ++const ( ++ LINUX_CAPABILITY_VERSION_1 = 0x19980330 ++ LINUX_CAPABILITY_VERSION_2 = 0x20071026 ++ LINUX_CAPABILITY_VERSION_3 = 0x20080522 ++) ++ ++const ( ++ LO_FLAGS_READ_ONLY = 0x1 ++ LO_FLAGS_AUTOCLEAR = 0x4 ++ LO_FLAGS_PARTSCAN = 0x8 ++ LO_FLAGS_DIRECT_IO = 0x10 ++) ++ ++type LoopInfo struct { ++ Number int32 ++ Device uint32 ++ Inode uint64 ++ Rdevice uint32 ++ Offset int32 ++ Encrypt_type int32 ++ Encrypt_key_size int32 ++ Flags int32 ++ Name [64]int8 ++ Encrypt_key [32]uint8 ++ Init [2]uint64 ++ Reserved [4]int8 ++ _ [4]byte ++} ++type LoopInfo64 struct { ++ Device uint64 ++ Inode uint64 ++ Rdevice uint64 ++ Offset uint64 ++ Sizelimit uint64 ++ Number uint32 ++ Encrypt_type uint32 ++ Encrypt_key_size uint32 ++ Flags uint32 ++ File_name [64]uint8 ++ Crypt_name [64]uint8 ++ Encrypt_key [32]uint8 ++ Init [2]uint64 ++} ++type LoopConfig struct { ++ Fd uint32 ++ Size uint32 ++ Info LoopInfo64 ++ _ [8]uint64 ++} ++ ++type TIPCSocketAddr struct { ++ Ref uint32 ++ Node uint32 ++} ++ ++type TIPCServiceRange struct { ++ Type uint32 ++ Lower uint32 ++ Upper uint32 ++} ++ ++type TIPCServiceName struct { ++ Type uint32 ++ Instance uint32 ++ Domain uint32 ++} ++ ++type TIPCSubscr struct { ++ Seq TIPCServiceRange ++ Timeout uint32 ++ Filter uint32 ++ Handle [8]int8 ++} ++ ++type TIPCEvent struct { ++ Event uint32 ++ Lower uint32 ++ Upper uint32 ++ Port TIPCSocketAddr ++ S TIPCSubscr ++} ++ ++type TIPCGroupReq struct { ++ Type uint32 ++ Instance uint32 ++ Scope uint32 ++ Flags uint32 ++} ++ ++type TIPCSIOCLNReq struct { ++ Peer uint32 ++ Id uint32 ++ Linkname [68]int8 ++} ++ ++type TIPCSIOCNodeIDReq struct { ++ Peer uint32 ++ Id [16]int8 ++} ++ ++const ( ++ TIPC_CLUSTER_SCOPE = 0x2 ++ TIPC_NODE_SCOPE = 0x3 ++) ++ ++const ( ++ SYSLOG_ACTION_CLOSE = 0 ++ SYSLOG_ACTION_OPEN = 1 ++ SYSLOG_ACTION_READ = 2 ++ SYSLOG_ACTION_READ_ALL = 3 ++ SYSLOG_ACTION_READ_CLEAR = 4 ++ SYSLOG_ACTION_CLEAR = 5 ++ SYSLOG_ACTION_CONSOLE_OFF = 6 ++ SYSLOG_ACTION_CONSOLE_ON = 7 ++ SYSLOG_ACTION_CONSOLE_LEVEL = 8 ++ SYSLOG_ACTION_SIZE_UNREAD = 9 ++ SYSLOG_ACTION_SIZE_BUFFER = 10 ++) ++ ++const ( ++ DEVLINK_CMD_UNSPEC = 0x0 ++ DEVLINK_CMD_GET = 0x1 ++ DEVLINK_CMD_SET = 0x2 ++ DEVLINK_CMD_NEW = 0x3 ++ DEVLINK_CMD_DEL = 0x4 ++ DEVLINK_CMD_PORT_GET = 0x5 ++ DEVLINK_CMD_PORT_SET = 0x6 ++ DEVLINK_CMD_PORT_NEW = 0x7 ++ DEVLINK_CMD_PORT_DEL = 0x8 ++ DEVLINK_CMD_PORT_SPLIT = 0x9 ++ DEVLINK_CMD_PORT_UNSPLIT = 0xa ++ DEVLINK_CMD_SB_GET = 0xb ++ DEVLINK_CMD_SB_SET = 0xc ++ DEVLINK_CMD_SB_NEW = 0xd ++ DEVLINK_CMD_SB_DEL = 0xe ++ DEVLINK_CMD_SB_POOL_GET = 0xf ++ DEVLINK_CMD_SB_POOL_SET = 0x10 ++ DEVLINK_CMD_SB_POOL_NEW = 0x11 ++ DEVLINK_CMD_SB_POOL_DEL = 0x12 ++ DEVLINK_CMD_SB_PORT_POOL_GET = 0x13 ++ DEVLINK_CMD_SB_PORT_POOL_SET = 0x14 ++ DEVLINK_CMD_SB_PORT_POOL_NEW = 0x15 ++ DEVLINK_CMD_SB_PORT_POOL_DEL = 0x16 ++ DEVLINK_CMD_SB_TC_POOL_BIND_GET = 0x17 ++ DEVLINK_CMD_SB_TC_POOL_BIND_SET = 0x18 ++ DEVLINK_CMD_SB_TC_POOL_BIND_NEW = 0x19 ++ DEVLINK_CMD_SB_TC_POOL_BIND_DEL = 0x1a ++ DEVLINK_CMD_SB_OCC_SNAPSHOT = 0x1b ++ DEVLINK_CMD_SB_OCC_MAX_CLEAR = 0x1c ++ DEVLINK_CMD_ESWITCH_GET = 0x1d ++ DEVLINK_CMD_ESWITCH_SET = 0x1e ++ DEVLINK_CMD_DPIPE_TABLE_GET = 0x1f ++ DEVLINK_CMD_DPIPE_ENTRIES_GET = 0x20 ++ DEVLINK_CMD_DPIPE_HEADERS_GET = 0x21 ++ DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET = 0x22 ++ DEVLINK_CMD_RESOURCE_SET = 0x23 ++ DEVLINK_CMD_RESOURCE_DUMP = 0x24 ++ DEVLINK_CMD_RELOAD = 0x25 ++ DEVLINK_CMD_PARAM_GET = 0x26 ++ DEVLINK_CMD_PARAM_SET = 0x27 ++ DEVLINK_CMD_PARAM_NEW = 0x28 ++ DEVLINK_CMD_PARAM_DEL = 0x29 ++ DEVLINK_CMD_REGION_GET = 0x2a ++ DEVLINK_CMD_REGION_SET = 0x2b ++ DEVLINK_CMD_REGION_NEW = 0x2c ++ DEVLINK_CMD_REGION_DEL = 0x2d ++ DEVLINK_CMD_REGION_READ = 0x2e ++ DEVLINK_CMD_PORT_PARAM_GET = 0x2f ++ DEVLINK_CMD_PORT_PARAM_SET = 0x30 ++ DEVLINK_CMD_PORT_PARAM_NEW = 0x31 ++ DEVLINK_CMD_PORT_PARAM_DEL = 0x32 ++ DEVLINK_CMD_INFO_GET = 0x33 ++ DEVLINK_CMD_HEALTH_REPORTER_GET = 0x34 ++ DEVLINK_CMD_HEALTH_REPORTER_SET = 0x35 ++ DEVLINK_CMD_HEALTH_REPORTER_RECOVER = 0x36 ++ DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE = 0x37 ++ DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET = 0x38 ++ DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR = 0x39 ++ DEVLINK_CMD_FLASH_UPDATE = 0x3a ++ DEVLINK_CMD_FLASH_UPDATE_END = 0x3b ++ DEVLINK_CMD_FLASH_UPDATE_STATUS = 0x3c ++ DEVLINK_CMD_TRAP_GET = 0x3d ++ DEVLINK_CMD_TRAP_SET = 0x3e ++ DEVLINK_CMD_TRAP_NEW = 0x3f ++ DEVLINK_CMD_TRAP_DEL = 0x40 ++ DEVLINK_CMD_TRAP_GROUP_GET = 0x41 ++ DEVLINK_CMD_TRAP_GROUP_SET = 0x42 ++ DEVLINK_CMD_TRAP_GROUP_NEW = 0x43 ++ DEVLINK_CMD_TRAP_GROUP_DEL = 0x44 ++ DEVLINK_CMD_TRAP_POLICER_GET = 0x45 ++ DEVLINK_CMD_TRAP_POLICER_SET = 0x46 ++ DEVLINK_CMD_TRAP_POLICER_NEW = 0x47 ++ DEVLINK_CMD_TRAP_POLICER_DEL = 0x48 ++ DEVLINK_CMD_HEALTH_REPORTER_TEST = 0x49 ++ DEVLINK_CMD_RATE_GET = 0x4a ++ DEVLINK_CMD_RATE_SET = 0x4b ++ DEVLINK_CMD_RATE_NEW = 0x4c ++ DEVLINK_CMD_RATE_DEL = 0x4d ++ DEVLINK_CMD_LINECARD_GET = 0x4e ++ DEVLINK_CMD_LINECARD_SET = 0x4f ++ DEVLINK_CMD_LINECARD_NEW = 0x50 ++ DEVLINK_CMD_LINECARD_DEL = 0x51 ++ DEVLINK_CMD_SELFTESTS_GET = 0x52 ++ DEVLINK_CMD_MAX = 0x53 ++ DEVLINK_PORT_TYPE_NOTSET = 0x0 ++ DEVLINK_PORT_TYPE_AUTO = 0x1 ++ DEVLINK_PORT_TYPE_ETH = 0x2 ++ DEVLINK_PORT_TYPE_IB = 0x3 ++ DEVLINK_SB_POOL_TYPE_INGRESS = 0x0 ++ DEVLINK_SB_POOL_TYPE_EGRESS = 0x1 ++ DEVLINK_SB_THRESHOLD_TYPE_STATIC = 0x0 ++ DEVLINK_SB_THRESHOLD_TYPE_DYNAMIC = 0x1 ++ DEVLINK_ESWITCH_MODE_LEGACY = 0x0 ++ DEVLINK_ESWITCH_MODE_SWITCHDEV = 0x1 ++ DEVLINK_ESWITCH_INLINE_MODE_NONE = 0x0 ++ DEVLINK_ESWITCH_INLINE_MODE_LINK = 0x1 ++ DEVLINK_ESWITCH_INLINE_MODE_NETWORK = 0x2 ++ DEVLINK_ESWITCH_INLINE_MODE_TRANSPORT = 0x3 ++ DEVLINK_ESWITCH_ENCAP_MODE_NONE = 0x0 ++ DEVLINK_ESWITCH_ENCAP_MODE_BASIC = 0x1 ++ DEVLINK_PORT_FLAVOUR_PHYSICAL = 0x0 ++ DEVLINK_PORT_FLAVOUR_CPU = 0x1 ++ DEVLINK_PORT_FLAVOUR_DSA = 0x2 ++ DEVLINK_PORT_FLAVOUR_PCI_PF = 0x3 ++ DEVLINK_PORT_FLAVOUR_PCI_VF = 0x4 ++ DEVLINK_PORT_FLAVOUR_VIRTUAL = 0x5 ++ DEVLINK_PORT_FLAVOUR_UNUSED = 0x6 ++ DEVLINK_PARAM_CMODE_RUNTIME = 0x0 ++ DEVLINK_PARAM_CMODE_DRIVERINIT = 0x1 ++ DEVLINK_PARAM_CMODE_PERMANENT = 0x2 ++ DEVLINK_PARAM_CMODE_MAX = 0x2 ++ DEVLINK_PARAM_FW_LOAD_POLICY_VALUE_DRIVER = 0x0 ++ DEVLINK_PARAM_FW_LOAD_POLICY_VALUE_FLASH = 0x1 ++ DEVLINK_PARAM_FW_LOAD_POLICY_VALUE_DISK = 0x2 ++ DEVLINK_PARAM_FW_LOAD_POLICY_VALUE_UNKNOWN = 0x3 ++ DEVLINK_PARAM_RESET_DEV_ON_DRV_PROBE_VALUE_UNKNOWN = 0x0 ++ DEVLINK_PARAM_RESET_DEV_ON_DRV_PROBE_VALUE_ALWAYS = 0x1 ++ DEVLINK_PARAM_RESET_DEV_ON_DRV_PROBE_VALUE_NEVER = 0x2 ++ DEVLINK_PARAM_RESET_DEV_ON_DRV_PROBE_VALUE_DISK = 0x3 ++ DEVLINK_ATTR_STATS_RX_PACKETS = 0x0 ++ DEVLINK_ATTR_STATS_RX_BYTES = 0x1 ++ DEVLINK_ATTR_STATS_RX_DROPPED = 0x2 ++ DEVLINK_ATTR_STATS_MAX = 0x2 ++ DEVLINK_FLASH_OVERWRITE_SETTINGS_BIT = 0x0 ++ DEVLINK_FLASH_OVERWRITE_IDENTIFIERS_BIT = 0x1 ++ DEVLINK_FLASH_OVERWRITE_MAX_BIT = 0x1 ++ DEVLINK_TRAP_ACTION_DROP = 0x0 ++ DEVLINK_TRAP_ACTION_TRAP = 0x1 ++ DEVLINK_TRAP_ACTION_MIRROR = 0x2 ++ DEVLINK_TRAP_TYPE_DROP = 0x0 ++ DEVLINK_TRAP_TYPE_EXCEPTION = 0x1 ++ DEVLINK_TRAP_TYPE_CONTROL = 0x2 ++ DEVLINK_ATTR_TRAP_METADATA_TYPE_IN_PORT = 0x0 ++ DEVLINK_ATTR_TRAP_METADATA_TYPE_FA_COOKIE = 0x1 ++ DEVLINK_RELOAD_ACTION_UNSPEC = 0x0 ++ DEVLINK_RELOAD_ACTION_DRIVER_REINIT = 0x1 ++ DEVLINK_RELOAD_ACTION_FW_ACTIVATE = 0x2 ++ DEVLINK_RELOAD_ACTION_MAX = 0x2 ++ DEVLINK_RELOAD_LIMIT_UNSPEC = 0x0 ++ DEVLINK_RELOAD_LIMIT_NO_RESET = 0x1 ++ DEVLINK_RELOAD_LIMIT_MAX = 0x1 ++ DEVLINK_ATTR_UNSPEC = 0x0 ++ DEVLINK_ATTR_BUS_NAME = 0x1 ++ DEVLINK_ATTR_DEV_NAME = 0x2 ++ DEVLINK_ATTR_PORT_INDEX = 0x3 ++ DEVLINK_ATTR_PORT_TYPE = 0x4 ++ DEVLINK_ATTR_PORT_DESIRED_TYPE = 0x5 ++ DEVLINK_ATTR_PORT_NETDEV_IFINDEX = 0x6 ++ DEVLINK_ATTR_PORT_NETDEV_NAME = 0x7 ++ DEVLINK_ATTR_PORT_IBDEV_NAME = 0x8 ++ DEVLINK_ATTR_PORT_SPLIT_COUNT = 0x9 ++ DEVLINK_ATTR_PORT_SPLIT_GROUP = 0xa ++ DEVLINK_ATTR_SB_INDEX = 0xb ++ DEVLINK_ATTR_SB_SIZE = 0xc ++ DEVLINK_ATTR_SB_INGRESS_POOL_COUNT = 0xd ++ DEVLINK_ATTR_SB_EGRESS_POOL_COUNT = 0xe ++ DEVLINK_ATTR_SB_INGRESS_TC_COUNT = 0xf ++ DEVLINK_ATTR_SB_EGRESS_TC_COUNT = 0x10 ++ DEVLINK_ATTR_SB_POOL_INDEX = 0x11 ++ DEVLINK_ATTR_SB_POOL_TYPE = 0x12 ++ DEVLINK_ATTR_SB_POOL_SIZE = 0x13 ++ DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE = 0x14 ++ DEVLINK_ATTR_SB_THRESHOLD = 0x15 ++ DEVLINK_ATTR_SB_TC_INDEX = 0x16 ++ DEVLINK_ATTR_SB_OCC_CUR = 0x17 ++ DEVLINK_ATTR_SB_OCC_MAX = 0x18 ++ DEVLINK_ATTR_ESWITCH_MODE = 0x19 ++ DEVLINK_ATTR_ESWITCH_INLINE_MODE = 0x1a ++ DEVLINK_ATTR_DPIPE_TABLES = 0x1b ++ DEVLINK_ATTR_DPIPE_TABLE = 0x1c ++ DEVLINK_ATTR_DPIPE_TABLE_NAME = 0x1d ++ DEVLINK_ATTR_DPIPE_TABLE_SIZE = 0x1e ++ DEVLINK_ATTR_DPIPE_TABLE_MATCHES = 0x1f ++ DEVLINK_ATTR_DPIPE_TABLE_ACTIONS = 0x20 ++ DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED = 0x21 ++ DEVLINK_ATTR_DPIPE_ENTRIES = 0x22 ++ DEVLINK_ATTR_DPIPE_ENTRY = 0x23 ++ DEVLINK_ATTR_DPIPE_ENTRY_INDEX = 0x24 ++ DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES = 0x25 ++ DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES = 0x26 ++ DEVLINK_ATTR_DPIPE_ENTRY_COUNTER = 0x27 ++ DEVLINK_ATTR_DPIPE_MATCH = 0x28 ++ DEVLINK_ATTR_DPIPE_MATCH_VALUE = 0x29 ++ DEVLINK_ATTR_DPIPE_MATCH_TYPE = 0x2a ++ DEVLINK_ATTR_DPIPE_ACTION = 0x2b ++ DEVLINK_ATTR_DPIPE_ACTION_VALUE = 0x2c ++ DEVLINK_ATTR_DPIPE_ACTION_TYPE = 0x2d ++ DEVLINK_ATTR_DPIPE_VALUE = 0x2e ++ DEVLINK_ATTR_DPIPE_VALUE_MASK = 0x2f ++ DEVLINK_ATTR_DPIPE_VALUE_MAPPING = 0x30 ++ DEVLINK_ATTR_DPIPE_HEADERS = 0x31 ++ DEVLINK_ATTR_DPIPE_HEADER = 0x32 ++ DEVLINK_ATTR_DPIPE_HEADER_NAME = 0x33 ++ DEVLINK_ATTR_DPIPE_HEADER_ID = 0x34 ++ DEVLINK_ATTR_DPIPE_HEADER_FIELDS = 0x35 ++ DEVLINK_ATTR_DPIPE_HEADER_GLOBAL = 0x36 ++ DEVLINK_ATTR_DPIPE_HEADER_INDEX = 0x37 ++ DEVLINK_ATTR_DPIPE_FIELD = 0x38 ++ DEVLINK_ATTR_DPIPE_FIELD_NAME = 0x39 ++ DEVLINK_ATTR_DPIPE_FIELD_ID = 0x3a ++ DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH = 0x3b ++ DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE = 0x3c ++ DEVLINK_ATTR_PAD = 0x3d ++ DEVLINK_ATTR_ESWITCH_ENCAP_MODE = 0x3e ++ DEVLINK_ATTR_RESOURCE_LIST = 0x3f ++ DEVLINK_ATTR_RESOURCE = 0x40 ++ DEVLINK_ATTR_RESOURCE_NAME = 0x41 ++ DEVLINK_ATTR_RESOURCE_ID = 0x42 ++ DEVLINK_ATTR_RESOURCE_SIZE = 0x43 ++ DEVLINK_ATTR_RESOURCE_SIZE_NEW = 0x44 ++ DEVLINK_ATTR_RESOURCE_SIZE_VALID = 0x45 ++ DEVLINK_ATTR_RESOURCE_SIZE_MIN = 0x46 ++ DEVLINK_ATTR_RESOURCE_SIZE_MAX = 0x47 ++ DEVLINK_ATTR_RESOURCE_SIZE_GRAN = 0x48 ++ DEVLINK_ATTR_RESOURCE_UNIT = 0x49 ++ DEVLINK_ATTR_RESOURCE_OCC = 0x4a ++ DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID = 0x4b ++ DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_UNITS = 0x4c ++ DEVLINK_ATTR_PORT_FLAVOUR = 0x4d ++ DEVLINK_ATTR_PORT_NUMBER = 0x4e ++ DEVLINK_ATTR_PORT_SPLIT_SUBPORT_NUMBER = 0x4f ++ DEVLINK_ATTR_PARAM = 0x50 ++ DEVLINK_ATTR_PARAM_NAME = 0x51 ++ DEVLINK_ATTR_PARAM_GENERIC = 0x52 ++ DEVLINK_ATTR_PARAM_TYPE = 0x53 ++ DEVLINK_ATTR_PARAM_VALUES_LIST = 0x54 ++ DEVLINK_ATTR_PARAM_VALUE = 0x55 ++ DEVLINK_ATTR_PARAM_VALUE_DATA = 0x56 ++ DEVLINK_ATTR_PARAM_VALUE_CMODE = 0x57 ++ DEVLINK_ATTR_REGION_NAME = 0x58 ++ DEVLINK_ATTR_REGION_SIZE = 0x59 ++ DEVLINK_ATTR_REGION_SNAPSHOTS = 0x5a ++ DEVLINK_ATTR_REGION_SNAPSHOT = 0x5b ++ DEVLINK_ATTR_REGION_SNAPSHOT_ID = 0x5c ++ DEVLINK_ATTR_REGION_CHUNKS = 0x5d ++ DEVLINK_ATTR_REGION_CHUNK = 0x5e ++ DEVLINK_ATTR_REGION_CHUNK_DATA = 0x5f ++ DEVLINK_ATTR_REGION_CHUNK_ADDR = 0x60 ++ DEVLINK_ATTR_REGION_CHUNK_LEN = 0x61 ++ DEVLINK_ATTR_INFO_DRIVER_NAME = 0x62 ++ DEVLINK_ATTR_INFO_SERIAL_NUMBER = 0x63 ++ DEVLINK_ATTR_INFO_VERSION_FIXED = 0x64 ++ DEVLINK_ATTR_INFO_VERSION_RUNNING = 0x65 ++ DEVLINK_ATTR_INFO_VERSION_STORED = 0x66 ++ DEVLINK_ATTR_INFO_VERSION_NAME = 0x67 ++ DEVLINK_ATTR_INFO_VERSION_VALUE = 0x68 ++ DEVLINK_ATTR_SB_POOL_CELL_SIZE = 0x69 ++ DEVLINK_ATTR_FMSG = 0x6a ++ DEVLINK_ATTR_FMSG_OBJ_NEST_START = 0x6b ++ DEVLINK_ATTR_FMSG_PAIR_NEST_START = 0x6c ++ DEVLINK_ATTR_FMSG_ARR_NEST_START = 0x6d ++ DEVLINK_ATTR_FMSG_NEST_END = 0x6e ++ DEVLINK_ATTR_FMSG_OBJ_NAME = 0x6f ++ DEVLINK_ATTR_FMSG_OBJ_VALUE_TYPE = 0x70 ++ DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA = 0x71 ++ DEVLINK_ATTR_HEALTH_REPORTER = 0x72 ++ DEVLINK_ATTR_HEALTH_REPORTER_NAME = 0x73 ++ DEVLINK_ATTR_HEALTH_REPORTER_STATE = 0x74 ++ DEVLINK_ATTR_HEALTH_REPORTER_ERR_COUNT = 0x75 ++ DEVLINK_ATTR_HEALTH_REPORTER_RECOVER_COUNT = 0x76 ++ DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS = 0x77 ++ DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD = 0x78 ++ DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER = 0x79 ++ DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME = 0x7a ++ DEVLINK_ATTR_FLASH_UPDATE_COMPONENT = 0x7b ++ DEVLINK_ATTR_FLASH_UPDATE_STATUS_MSG = 0x7c ++ DEVLINK_ATTR_FLASH_UPDATE_STATUS_DONE = 0x7d ++ DEVLINK_ATTR_FLASH_UPDATE_STATUS_TOTAL = 0x7e ++ DEVLINK_ATTR_PORT_PCI_PF_NUMBER = 0x7f ++ DEVLINK_ATTR_PORT_PCI_VF_NUMBER = 0x80 ++ DEVLINK_ATTR_STATS = 0x81 ++ DEVLINK_ATTR_TRAP_NAME = 0x82 ++ DEVLINK_ATTR_TRAP_ACTION = 0x83 ++ DEVLINK_ATTR_TRAP_TYPE = 0x84 ++ DEVLINK_ATTR_TRAP_GENERIC = 0x85 ++ DEVLINK_ATTR_TRAP_METADATA = 0x86 ++ DEVLINK_ATTR_TRAP_GROUP_NAME = 0x87 ++ DEVLINK_ATTR_RELOAD_FAILED = 0x88 ++ DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS_NS = 0x89 ++ DEVLINK_ATTR_NETNS_FD = 0x8a ++ DEVLINK_ATTR_NETNS_PID = 0x8b ++ DEVLINK_ATTR_NETNS_ID = 0x8c ++ DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP = 0x8d ++ DEVLINK_ATTR_TRAP_POLICER_ID = 0x8e ++ DEVLINK_ATTR_TRAP_POLICER_RATE = 0x8f ++ DEVLINK_ATTR_TRAP_POLICER_BURST = 0x90 ++ DEVLINK_ATTR_PORT_FUNCTION = 0x91 ++ DEVLINK_ATTR_INFO_BOARD_SERIAL_NUMBER = 0x92 ++ DEVLINK_ATTR_PORT_LANES = 0x93 ++ DEVLINK_ATTR_PORT_SPLITTABLE = 0x94 ++ DEVLINK_ATTR_PORT_EXTERNAL = 0x95 ++ DEVLINK_ATTR_PORT_CONTROLLER_NUMBER = 0x96 ++ DEVLINK_ATTR_FLASH_UPDATE_STATUS_TIMEOUT = 0x97 ++ DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK = 0x98 ++ DEVLINK_ATTR_RELOAD_ACTION = 0x99 ++ DEVLINK_ATTR_RELOAD_ACTIONS_PERFORMED = 0x9a ++ DEVLINK_ATTR_RELOAD_LIMITS = 0x9b ++ DEVLINK_ATTR_DEV_STATS = 0x9c ++ DEVLINK_ATTR_RELOAD_STATS = 0x9d ++ DEVLINK_ATTR_RELOAD_STATS_ENTRY = 0x9e ++ DEVLINK_ATTR_RELOAD_STATS_LIMIT = 0x9f ++ DEVLINK_ATTR_RELOAD_STATS_VALUE = 0xa0 ++ DEVLINK_ATTR_REMOTE_RELOAD_STATS = 0xa1 ++ DEVLINK_ATTR_RELOAD_ACTION_INFO = 0xa2 ++ DEVLINK_ATTR_RELOAD_ACTION_STATS = 0xa3 ++ ++ DEVLINK_ATTR_LINECARD_INDEX = 0xab ++ DEVLINK_ATTR_LINECARD_STATE = 0xac ++ DEVLINK_ATTR_LINECARD_TYPE = 0xad ++ DEVLINK_ATTR_LINECARD_SUPPORTED_TYPES = 0xae ++ DEVLINK_ATTR_NESTED_DEVLINK = 0xaf ++ DEVLINK_ATTR_SELFTESTS = 0xb0 ++ DEVLINK_ATTR_MAX = 0xb3 ++ DEVLINK_DPIPE_FIELD_MAPPING_TYPE_NONE = 0x0 ++ DEVLINK_DPIPE_FIELD_MAPPING_TYPE_IFINDEX = 0x1 ++ DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT = 0x0 ++ DEVLINK_DPIPE_ACTION_TYPE_FIELD_MODIFY = 0x0 ++ DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC = 0x0 ++ DEVLINK_DPIPE_FIELD_IPV4_DST_IP = 0x0 ++ DEVLINK_DPIPE_FIELD_IPV6_DST_IP = 0x0 ++ DEVLINK_DPIPE_HEADER_ETHERNET = 0x0 ++ DEVLINK_DPIPE_HEADER_IPV4 = 0x1 ++ DEVLINK_DPIPE_HEADER_IPV6 = 0x2 ++ DEVLINK_RESOURCE_UNIT_ENTRY = 0x0 ++ DEVLINK_PORT_FUNCTION_ATTR_UNSPEC = 0x0 ++ DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR = 0x1 ++ ++ DEVLINK_PORT_FN_ATTR_CAPS = 0x4 ++ DEVLINK_PORT_FUNCTION_ATTR_MAX = 0x4 ++) ++ ++type FsverityDigest struct { ++ Algorithm uint16 ++ Size uint16 ++} ++ ++type FsverityEnableArg struct { ++ Version uint32 ++ Hash_algorithm uint32 ++ Block_size uint32 ++ Salt_size uint32 ++ Salt_ptr uint64 ++ Sig_size uint32 ++ _ uint32 ++ Sig_ptr uint64 ++ _ [11]uint64 ++} ++ ++type Nhmsg struct { ++ Family uint8 ++ Scope uint8 ++ Protocol uint8 ++ Resvd uint8 ++ Flags uint32 ++} ++ ++type NexthopGrp struct { ++ Id uint32 ++ Weight uint8 ++ Resvd1 uint8 ++ Resvd2 uint16 ++} ++ ++const ( ++ NHA_UNSPEC = 0x0 ++ NHA_ID = 0x1 ++ NHA_GROUP = 0x2 ++ NHA_GROUP_TYPE = 0x3 ++ NHA_BLACKHOLE = 0x4 ++ NHA_OIF = 0x5 ++ NHA_GATEWAY = 0x6 ++ NHA_ENCAP_TYPE = 0x7 ++ NHA_ENCAP = 0x8 ++ NHA_GROUPS = 0x9 ++ NHA_MASTER = 0xa ++) ++ ++const ( ++ CAN_RAW_FILTER = 0x1 ++ CAN_RAW_ERR_FILTER = 0x2 ++ CAN_RAW_LOOPBACK = 0x3 ++ CAN_RAW_RECV_OWN_MSGS = 0x4 ++ CAN_RAW_FD_FRAMES = 0x5 ++ CAN_RAW_JOIN_FILTERS = 0x6 ++) ++ ++type WatchdogInfo struct { ++ Options uint32 ++ Version uint32 ++ Identity [32]uint8 ++} ++ ++type PPSFData struct { ++ Info PPSKInfo ++ Timeout PPSKTime ++} ++ ++type PPSKParams struct { ++ Api_version int32 ++ Mode int32 ++ Assert_off_tu PPSKTime ++ Clear_off_tu PPSKTime ++} ++ ++type PPSKInfo struct { ++ Assert_sequence uint32 ++ Clear_sequence uint32 ++ Assert_tu PPSKTime ++ Clear_tu PPSKTime ++ Current_mode int32 ++ _ [4]byte ++} ++ ++type PPSKTime struct { ++ Sec int64 ++ Nsec int32 ++ Flags uint32 ++} ++ ++const ( ++ PPS_GETPARAMS = 0x400870a1 ++ PPS_SETPARAMS = 0x800870a2 ++ PPS_GETCAP = 0x400870a3 ++ PPS_FETCH = 0xc00870a4 ++) ++ ++const ( ++ LWTUNNEL_ENCAP_NONE = 0x0 ++ LWTUNNEL_ENCAP_MPLS = 0x1 ++ LWTUNNEL_ENCAP_IP = 0x2 ++ LWTUNNEL_ENCAP_ILA = 0x3 ++ LWTUNNEL_ENCAP_IP6 = 0x4 ++ LWTUNNEL_ENCAP_SEG6 = 0x5 ++ LWTUNNEL_ENCAP_BPF = 0x6 ++ LWTUNNEL_ENCAP_SEG6_LOCAL = 0x7 ++ LWTUNNEL_ENCAP_RPL = 0x8 ++ ++ LWTUNNEL_ENCAP_XFRM = 0xa ++ LWTUNNEL_ENCAP_MAX = 0xa ++ ++ MPLS_IPTUNNEL_UNSPEC = 0x0 ++ MPLS_IPTUNNEL_DST = 0x1 ++ MPLS_IPTUNNEL_TTL = 0x2 ++ MPLS_IPTUNNEL_MAX = 0x2 ++) ++ ++const ( ++ ETHTOOL_ID_UNSPEC = 0x0 ++ ETHTOOL_RX_COPYBREAK = 0x1 ++ ETHTOOL_TX_COPYBREAK = 0x2 ++ ETHTOOL_PFC_PREVENTION_TOUT = 0x3 ++ ETHTOOL_TUNABLE_UNSPEC = 0x0 ++ ETHTOOL_TUNABLE_U8 = 0x1 ++ ETHTOOL_TUNABLE_U16 = 0x2 ++ ETHTOOL_TUNABLE_U32 = 0x3 ++ ETHTOOL_TUNABLE_U64 = 0x4 ++ ETHTOOL_TUNABLE_STRING = 0x5 ++ ETHTOOL_TUNABLE_S8 = 0x6 ++ ETHTOOL_TUNABLE_S16 = 0x7 ++ ETHTOOL_TUNABLE_S32 = 0x8 ++ ETHTOOL_TUNABLE_S64 = 0x9 ++ ETHTOOL_PHY_ID_UNSPEC = 0x0 ++ ETHTOOL_PHY_DOWNSHIFT = 0x1 ++ ETHTOOL_PHY_FAST_LINK_DOWN = 0x2 ++ ETHTOOL_PHY_EDPD = 0x3 ++ ETHTOOL_LINK_EXT_STATE_AUTONEG = 0x0 ++ ETHTOOL_LINK_EXT_STATE_LINK_TRAINING_FAILURE = 0x1 ++ ETHTOOL_LINK_EXT_STATE_LINK_LOGICAL_MISMATCH = 0x2 ++ ETHTOOL_LINK_EXT_STATE_BAD_SIGNAL_INTEGRITY = 0x3 ++ ETHTOOL_LINK_EXT_STATE_NO_CABLE = 0x4 ++ ETHTOOL_LINK_EXT_STATE_CABLE_ISSUE = 0x5 ++ ETHTOOL_LINK_EXT_STATE_EEPROM_ISSUE = 0x6 ++ ETHTOOL_LINK_EXT_STATE_CALIBRATION_FAILURE = 0x7 ++ ETHTOOL_LINK_EXT_STATE_POWER_BUDGET_EXCEEDED = 0x8 ++ ETHTOOL_LINK_EXT_STATE_OVERHEAT = 0x9 ++ ETHTOOL_LINK_EXT_SUBSTATE_AN_NO_PARTNER_DETECTED = 0x1 ++ ETHTOOL_LINK_EXT_SUBSTATE_AN_ACK_NOT_RECEIVED = 0x2 ++ ETHTOOL_LINK_EXT_SUBSTATE_AN_NEXT_PAGE_EXCHANGE_FAILED = 0x3 ++ ETHTOOL_LINK_EXT_SUBSTATE_AN_NO_PARTNER_DETECTED_FORCE_MODE = 0x4 ++ ETHTOOL_LINK_EXT_SUBSTATE_AN_FEC_MISMATCH_DURING_OVERRIDE = 0x5 ++ ETHTOOL_LINK_EXT_SUBSTATE_AN_NO_HCD = 0x6 ++ ETHTOOL_LINK_EXT_SUBSTATE_LT_KR_FRAME_LOCK_NOT_ACQUIRED = 0x1 ++ ETHTOOL_LINK_EXT_SUBSTATE_LT_KR_LINK_INHIBIT_TIMEOUT = 0x2 ++ ETHTOOL_LINK_EXT_SUBSTATE_LT_KR_LINK_PARTNER_DID_NOT_SET_RECEIVER_READY = 0x3 ++ ETHTOOL_LINK_EXT_SUBSTATE_LT_REMOTE_FAULT = 0x4 ++ ETHTOOL_LINK_EXT_SUBSTATE_LLM_PCS_DID_NOT_ACQUIRE_BLOCK_LOCK = 0x1 ++ ETHTOOL_LINK_EXT_SUBSTATE_LLM_PCS_DID_NOT_ACQUIRE_AM_LOCK = 0x2 ++ ETHTOOL_LINK_EXT_SUBSTATE_LLM_PCS_DID_NOT_GET_ALIGN_STATUS = 0x3 ++ ETHTOOL_LINK_EXT_SUBSTATE_LLM_FC_FEC_IS_NOT_LOCKED = 0x4 ++ ETHTOOL_LINK_EXT_SUBSTATE_LLM_RS_FEC_IS_NOT_LOCKED = 0x5 ++ ETHTOOL_LINK_EXT_SUBSTATE_BSI_LARGE_NUMBER_OF_PHYSICAL_ERRORS = 0x1 ++ ETHTOOL_LINK_EXT_SUBSTATE_BSI_UNSUPPORTED_RATE = 0x2 ++ ETHTOOL_LINK_EXT_SUBSTATE_CI_UNSUPPORTED_CABLE = 0x1 ++ ETHTOOL_LINK_EXT_SUBSTATE_CI_CABLE_TEST_FAILURE = 0x2 ++ ETHTOOL_FLASH_ALL_REGIONS = 0x0 ++ ETHTOOL_F_UNSUPPORTED__BIT = 0x0 ++ ETHTOOL_F_WISH__BIT = 0x1 ++ ETHTOOL_F_COMPAT__BIT = 0x2 ++ ETHTOOL_FEC_NONE_BIT = 0x0 ++ ETHTOOL_FEC_AUTO_BIT = 0x1 ++ ETHTOOL_FEC_OFF_BIT = 0x2 ++ ETHTOOL_FEC_RS_BIT = 0x3 ++ ETHTOOL_FEC_BASER_BIT = 0x4 ++ ETHTOOL_FEC_LLRS_BIT = 0x5 ++ ETHTOOL_LINK_MODE_10baseT_Half_BIT = 0x0 ++ ETHTOOL_LINK_MODE_10baseT_Full_BIT = 0x1 ++ ETHTOOL_LINK_MODE_100baseT_Half_BIT = 0x2 ++ ETHTOOL_LINK_MODE_100baseT_Full_BIT = 0x3 ++ ETHTOOL_LINK_MODE_1000baseT_Half_BIT = 0x4 ++ ETHTOOL_LINK_MODE_1000baseT_Full_BIT = 0x5 ++ ETHTOOL_LINK_MODE_Autoneg_BIT = 0x6 ++ ETHTOOL_LINK_MODE_TP_BIT = 0x7 ++ ETHTOOL_LINK_MODE_AUI_BIT = 0x8 ++ ETHTOOL_LINK_MODE_MII_BIT = 0x9 ++ ETHTOOL_LINK_MODE_FIBRE_BIT = 0xa ++ ETHTOOL_LINK_MODE_BNC_BIT = 0xb ++ ETHTOOL_LINK_MODE_10000baseT_Full_BIT = 0xc ++ ETHTOOL_LINK_MODE_Pause_BIT = 0xd ++ ETHTOOL_LINK_MODE_Asym_Pause_BIT = 0xe ++ ETHTOOL_LINK_MODE_2500baseX_Full_BIT = 0xf ++ ETHTOOL_LINK_MODE_Backplane_BIT = 0x10 ++ ETHTOOL_LINK_MODE_1000baseKX_Full_BIT = 0x11 ++ ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT = 0x12 ++ ETHTOOL_LINK_MODE_10000baseKR_Full_BIT = 0x13 ++ ETHTOOL_LINK_MODE_10000baseR_FEC_BIT = 0x14 ++ ETHTOOL_LINK_MODE_20000baseMLD2_Full_BIT = 0x15 ++ ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT = 0x16 ++ ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT = 0x17 ++ ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT = 0x18 ++ ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT = 0x19 ++ ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT = 0x1a ++ ETHTOOL_LINK_MODE_56000baseKR4_Full_BIT = 0x1b ++ ETHTOOL_LINK_MODE_56000baseCR4_Full_BIT = 0x1c ++ ETHTOOL_LINK_MODE_56000baseSR4_Full_BIT = 0x1d ++ ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT = 0x1e ++ ETHTOOL_LINK_MODE_25000baseCR_Full_BIT = 0x1f ++ ETHTOOL_LINK_MODE_25000baseKR_Full_BIT = 0x20 ++ ETHTOOL_LINK_MODE_25000baseSR_Full_BIT = 0x21 ++ ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT = 0x22 ++ ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT = 0x23 ++ ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT = 0x24 ++ ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT = 0x25 ++ ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT = 0x26 ++ ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT = 0x27 ++ ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT = 0x28 ++ ETHTOOL_LINK_MODE_1000baseX_Full_BIT = 0x29 ++ ETHTOOL_LINK_MODE_10000baseCR_Full_BIT = 0x2a ++ ETHTOOL_LINK_MODE_10000baseSR_Full_BIT = 0x2b ++ ETHTOOL_LINK_MODE_10000baseLR_Full_BIT = 0x2c ++ ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT = 0x2d ++ ETHTOOL_LINK_MODE_10000baseER_Full_BIT = 0x2e ++ ETHTOOL_LINK_MODE_2500baseT_Full_BIT = 0x2f ++ ETHTOOL_LINK_MODE_5000baseT_Full_BIT = 0x30 ++ ETHTOOL_LINK_MODE_FEC_NONE_BIT = 0x31 ++ ETHTOOL_LINK_MODE_FEC_RS_BIT = 0x32 ++ ETHTOOL_LINK_MODE_FEC_BASER_BIT = 0x33 ++ ETHTOOL_LINK_MODE_50000baseKR_Full_BIT = 0x34 ++ ETHTOOL_LINK_MODE_50000baseSR_Full_BIT = 0x35 ++ ETHTOOL_LINK_MODE_50000baseCR_Full_BIT = 0x36 ++ ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT = 0x37 ++ ETHTOOL_LINK_MODE_50000baseDR_Full_BIT = 0x38 ++ ETHTOOL_LINK_MODE_100000baseKR2_Full_BIT = 0x39 ++ ETHTOOL_LINK_MODE_100000baseSR2_Full_BIT = 0x3a ++ ETHTOOL_LINK_MODE_100000baseCR2_Full_BIT = 0x3b ++ ETHTOOL_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT = 0x3c ++ ETHTOOL_LINK_MODE_100000baseDR2_Full_BIT = 0x3d ++ ETHTOOL_LINK_MODE_200000baseKR4_Full_BIT = 0x3e ++ ETHTOOL_LINK_MODE_200000baseSR4_Full_BIT = 0x3f ++ ETHTOOL_LINK_MODE_200000baseLR4_ER4_FR4_Full_BIT = 0x40 ++ ETHTOOL_LINK_MODE_200000baseDR4_Full_BIT = 0x41 ++ ETHTOOL_LINK_MODE_200000baseCR4_Full_BIT = 0x42 ++ ETHTOOL_LINK_MODE_100baseT1_Full_BIT = 0x43 ++ ETHTOOL_LINK_MODE_1000baseT1_Full_BIT = 0x44 ++ ETHTOOL_LINK_MODE_400000baseKR8_Full_BIT = 0x45 ++ ETHTOOL_LINK_MODE_400000baseSR8_Full_BIT = 0x46 ++ ETHTOOL_LINK_MODE_400000baseLR8_ER8_FR8_Full_BIT = 0x47 ++ ETHTOOL_LINK_MODE_400000baseDR8_Full_BIT = 0x48 ++ ETHTOOL_LINK_MODE_400000baseCR8_Full_BIT = 0x49 ++ ETHTOOL_LINK_MODE_FEC_LLRS_BIT = 0x4a ++ ETHTOOL_LINK_MODE_100000baseKR_Full_BIT = 0x4b ++ ETHTOOL_LINK_MODE_100000baseSR_Full_BIT = 0x4c ++ ETHTOOL_LINK_MODE_100000baseLR_ER_FR_Full_BIT = 0x4d ++ ETHTOOL_LINK_MODE_100000baseCR_Full_BIT = 0x4e ++ ETHTOOL_LINK_MODE_100000baseDR_Full_BIT = 0x4f ++ ETHTOOL_LINK_MODE_200000baseKR2_Full_BIT = 0x50 ++ ETHTOOL_LINK_MODE_200000baseSR2_Full_BIT = 0x51 ++ ETHTOOL_LINK_MODE_200000baseLR2_ER2_FR2_Full_BIT = 0x52 ++ ETHTOOL_LINK_MODE_200000baseDR2_Full_BIT = 0x53 ++ ETHTOOL_LINK_MODE_200000baseCR2_Full_BIT = 0x54 ++ ETHTOOL_LINK_MODE_400000baseKR4_Full_BIT = 0x55 ++ ETHTOOL_LINK_MODE_400000baseSR4_Full_BIT = 0x56 ++ ETHTOOL_LINK_MODE_400000baseLR4_ER4_FR4_Full_BIT = 0x57 ++ ETHTOOL_LINK_MODE_400000baseDR4_Full_BIT = 0x58 ++ ETHTOOL_LINK_MODE_400000baseCR4_Full_BIT = 0x59 ++ ETHTOOL_LINK_MODE_100baseFX_Half_BIT = 0x5a ++ ETHTOOL_LINK_MODE_100baseFX_Full_BIT = 0x5b ++ ++ ETHTOOL_MSG_USER_NONE = 0x0 ++ ETHTOOL_MSG_STRSET_GET = 0x1 ++ ETHTOOL_MSG_LINKINFO_GET = 0x2 ++ ETHTOOL_MSG_LINKINFO_SET = 0x3 ++ ETHTOOL_MSG_LINKMODES_GET = 0x4 ++ ETHTOOL_MSG_LINKMODES_SET = 0x5 ++ ETHTOOL_MSG_LINKSTATE_GET = 0x6 ++ ETHTOOL_MSG_DEBUG_GET = 0x7 ++ ETHTOOL_MSG_DEBUG_SET = 0x8 ++ ETHTOOL_MSG_WOL_GET = 0x9 ++ ETHTOOL_MSG_WOL_SET = 0xa ++ ETHTOOL_MSG_FEATURES_GET = 0xb ++ ETHTOOL_MSG_FEATURES_SET = 0xc ++ ETHTOOL_MSG_PRIVFLAGS_GET = 0xd ++ ETHTOOL_MSG_PRIVFLAGS_SET = 0xe ++ ETHTOOL_MSG_RINGS_GET = 0xf ++ ETHTOOL_MSG_RINGS_SET = 0x10 ++ ETHTOOL_MSG_CHANNELS_GET = 0x11 ++ ETHTOOL_MSG_CHANNELS_SET = 0x12 ++ ETHTOOL_MSG_COALESCE_GET = 0x13 ++ ETHTOOL_MSG_COALESCE_SET = 0x14 ++ ETHTOOL_MSG_PAUSE_GET = 0x15 ++ ETHTOOL_MSG_PAUSE_SET = 0x16 ++ ETHTOOL_MSG_EEE_GET = 0x17 ++ ETHTOOL_MSG_EEE_SET = 0x18 ++ ETHTOOL_MSG_TSINFO_GET = 0x19 ++ ETHTOOL_MSG_CABLE_TEST_ACT = 0x1a ++ ETHTOOL_MSG_CABLE_TEST_TDR_ACT = 0x1b ++ ETHTOOL_MSG_TUNNEL_INFO_GET = 0x1c ++ ++ ETHTOOL_MSG_PSE_GET = 0x24 ++ ETHTOOL_MSG_PSE_SET = 0x25 ++ ETHTOOL_MSG_RSS_GET = 0x26 ++ ETHTOOL_MSG_USER_MAX = 0x2b ++ ETHTOOL_MSG_KERNEL_NONE = 0x0 ++ ETHTOOL_MSG_STRSET_GET_REPLY = 0x1 ++ ETHTOOL_MSG_LINKINFO_GET_REPLY = 0x2 ++ ETHTOOL_MSG_LINKINFO_NTF = 0x3 ++ ETHTOOL_MSG_LINKMODES_GET_REPLY = 0x4 ++ ETHTOOL_MSG_LINKMODES_NTF = 0x5 ++ ETHTOOL_MSG_LINKSTATE_GET_REPLY = 0x6 ++ ETHTOOL_MSG_DEBUG_GET_REPLY = 0x7 ++ ETHTOOL_MSG_DEBUG_NTF = 0x8 ++ ETHTOOL_MSG_WOL_GET_REPLY = 0x9 ++ ETHTOOL_MSG_WOL_NTF = 0xa ++ ETHTOOL_MSG_FEATURES_GET_REPLY = 0xb ++ ETHTOOL_MSG_FEATURES_SET_REPLY = 0xc ++ ETHTOOL_MSG_FEATURES_NTF = 0xd ++ ETHTOOL_MSG_PRIVFLAGS_GET_REPLY = 0xe ++ ETHTOOL_MSG_PRIVFLAGS_NTF = 0xf ++ ETHTOOL_MSG_RINGS_GET_REPLY = 0x10 ++ ETHTOOL_MSG_RINGS_NTF = 0x11 ++ ETHTOOL_MSG_CHANNELS_GET_REPLY = 0x12 ++ ETHTOOL_MSG_CHANNELS_NTF = 0x13 ++ ETHTOOL_MSG_COALESCE_GET_REPLY = 0x14 ++ ETHTOOL_MSG_COALESCE_NTF = 0x15 ++ ETHTOOL_MSG_PAUSE_GET_REPLY = 0x16 ++ ETHTOOL_MSG_PAUSE_NTF = 0x17 ++ ETHTOOL_MSG_EEE_GET_REPLY = 0x18 ++ ETHTOOL_MSG_EEE_NTF = 0x19 ++ ETHTOOL_MSG_TSINFO_GET_REPLY = 0x1a ++ ETHTOOL_MSG_CABLE_TEST_NTF = 0x1b ++ ETHTOOL_MSG_CABLE_TEST_TDR_NTF = 0x1c ++ ETHTOOL_MSG_TUNNEL_INFO_GET_REPLY = 0x1d ++ ++ ETHTOOL_MSG_PSE_GET_REPLY = 0x25 ++ ETHTOOL_MSG_RSS_GET_REPLY = 0x26 ++ ETHTOOL_MSG_KERNEL_MAX = 0x2b ++ ETHTOOL_FLAG_COMPACT_BITSETS = 0x1 ++ ETHTOOL_FLAG_OMIT_REPLY = 0x2 ++ ETHTOOL_FLAG_STATS = 0x4 ++ ETHTOOL_A_HEADER_UNSPEC = 0x0 ++ ETHTOOL_A_HEADER_DEV_INDEX = 0x1 ++ ETHTOOL_A_HEADER_DEV_NAME = 0x2 ++ ETHTOOL_A_HEADER_FLAGS = 0x3 ++ ETHTOOL_A_HEADER_MAX = 0x3 ++ ETHTOOL_A_BITSET_BIT_UNSPEC = 0x0 ++ ETHTOOL_A_BITSET_BIT_INDEX = 0x1 ++ ETHTOOL_A_BITSET_BIT_NAME = 0x2 ++ ETHTOOL_A_BITSET_BIT_VALUE = 0x3 ++ ETHTOOL_A_BITSET_BIT_MAX = 0x3 ++ ETHTOOL_A_BITSET_BITS_UNSPEC = 0x0 ++ ETHTOOL_A_BITSET_BITS_BIT = 0x1 ++ ETHTOOL_A_BITSET_BITS_MAX = 0x1 ++ ETHTOOL_A_BITSET_UNSPEC = 0x0 ++ ETHTOOL_A_BITSET_NOMASK = 0x1 ++ ETHTOOL_A_BITSET_SIZE = 0x2 ++ ETHTOOL_A_BITSET_BITS = 0x3 ++ ETHTOOL_A_BITSET_VALUE = 0x4 ++ ETHTOOL_A_BITSET_MASK = 0x5 ++ ETHTOOL_A_BITSET_MAX = 0x5 ++ ETHTOOL_A_STRING_UNSPEC = 0x0 ++ ETHTOOL_A_STRING_INDEX = 0x1 ++ ETHTOOL_A_STRING_VALUE = 0x2 ++ ETHTOOL_A_STRING_MAX = 0x2 ++ ETHTOOL_A_STRINGS_UNSPEC = 0x0 ++ ETHTOOL_A_STRINGS_STRING = 0x1 ++ ETHTOOL_A_STRINGS_MAX = 0x1 ++ ETHTOOL_A_STRINGSET_UNSPEC = 0x0 ++ ETHTOOL_A_STRINGSET_ID = 0x1 ++ ETHTOOL_A_STRINGSET_COUNT = 0x2 ++ ETHTOOL_A_STRINGSET_STRINGS = 0x3 ++ ETHTOOL_A_STRINGSET_MAX = 0x3 ++ ETHTOOL_A_STRINGSETS_UNSPEC = 0x0 ++ ETHTOOL_A_STRINGSETS_STRINGSET = 0x1 ++ ETHTOOL_A_STRINGSETS_MAX = 0x1 ++ ETHTOOL_A_STRSET_UNSPEC = 0x0 ++ ETHTOOL_A_STRSET_HEADER = 0x1 ++ ETHTOOL_A_STRSET_STRINGSETS = 0x2 ++ ETHTOOL_A_STRSET_COUNTS_ONLY = 0x3 ++ ETHTOOL_A_STRSET_MAX = 0x3 ++ ETHTOOL_A_LINKINFO_UNSPEC = 0x0 ++ ETHTOOL_A_LINKINFO_HEADER = 0x1 ++ ETHTOOL_A_LINKINFO_PORT = 0x2 ++ ETHTOOL_A_LINKINFO_PHYADDR = 0x3 ++ ETHTOOL_A_LINKINFO_TP_MDIX = 0x4 ++ ETHTOOL_A_LINKINFO_TP_MDIX_CTRL = 0x5 ++ ETHTOOL_A_LINKINFO_TRANSCEIVER = 0x6 ++ ETHTOOL_A_LINKINFO_MAX = 0x6 ++ ETHTOOL_A_LINKMODES_UNSPEC = 0x0 ++ ETHTOOL_A_LINKMODES_HEADER = 0x1 ++ ETHTOOL_A_LINKMODES_AUTONEG = 0x2 ++ ETHTOOL_A_LINKMODES_OURS = 0x3 ++ ETHTOOL_A_LINKMODES_PEER = 0x4 ++ ETHTOOL_A_LINKMODES_SPEED = 0x5 ++ ETHTOOL_A_LINKMODES_DUPLEX = 0x6 ++ ETHTOOL_A_LINKMODES_MASTER_SLAVE_CFG = 0x7 ++ ETHTOOL_A_LINKMODES_MASTER_SLAVE_STATE = 0x8 ++ ++ ETHTOOL_A_LINKMODES_RATE_MATCHING = 0xa ++ ETHTOOL_A_LINKMODES_MAX = 0xa ++ ETHTOOL_A_LINKSTATE_UNSPEC = 0x0 ++ ETHTOOL_A_LINKSTATE_HEADER = 0x1 ++ ETHTOOL_A_LINKSTATE_LINK = 0x2 ++ ETHTOOL_A_LINKSTATE_SQI = 0x3 ++ ETHTOOL_A_LINKSTATE_SQI_MAX = 0x4 ++ ETHTOOL_A_LINKSTATE_EXT_STATE = 0x5 ++ ETHTOOL_A_LINKSTATE_EXT_SUBSTATE = 0x6 ++ ETHTOOL_A_LINKSTATE_EXT_DOWN_CNT = 0x7 ++ ETHTOOL_A_LINKSTATE_MAX = 0x7 ++ ETHTOOL_A_DEBUG_UNSPEC = 0x0 ++ ETHTOOL_A_DEBUG_HEADER = 0x1 ++ ETHTOOL_A_DEBUG_MSGMASK = 0x2 ++ ETHTOOL_A_DEBUG_MAX = 0x2 ++ ETHTOOL_A_WOL_UNSPEC = 0x0 ++ ETHTOOL_A_WOL_HEADER = 0x1 ++ ETHTOOL_A_WOL_MODES = 0x2 ++ ETHTOOL_A_WOL_SOPASS = 0x3 ++ ETHTOOL_A_WOL_MAX = 0x3 ++ ETHTOOL_A_FEATURES_UNSPEC = 0x0 ++ ETHTOOL_A_FEATURES_HEADER = 0x1 ++ ETHTOOL_A_FEATURES_HW = 0x2 ++ ETHTOOL_A_FEATURES_WANTED = 0x3 ++ ETHTOOL_A_FEATURES_ACTIVE = 0x4 ++ ETHTOOL_A_FEATURES_NOCHANGE = 0x5 ++ ETHTOOL_A_FEATURES_MAX = 0x5 ++ ETHTOOL_A_PRIVFLAGS_UNSPEC = 0x0 ++ ETHTOOL_A_PRIVFLAGS_HEADER = 0x1 ++ ETHTOOL_A_PRIVFLAGS_FLAGS = 0x2 ++ ETHTOOL_A_PRIVFLAGS_MAX = 0x2 ++ ETHTOOL_A_RINGS_UNSPEC = 0x0 ++ ETHTOOL_A_RINGS_HEADER = 0x1 ++ ETHTOOL_A_RINGS_RX_MAX = 0x2 ++ ETHTOOL_A_RINGS_RX_MINI_MAX = 0x3 ++ ETHTOOL_A_RINGS_RX_JUMBO_MAX = 0x4 ++ ETHTOOL_A_RINGS_TX_MAX = 0x5 ++ ETHTOOL_A_RINGS_RX = 0x6 ++ ETHTOOL_A_RINGS_RX_MINI = 0x7 ++ ETHTOOL_A_RINGS_RX_JUMBO = 0x8 ++ ETHTOOL_A_RINGS_TX = 0x9 ++ ++ ETHTOOL_A_RINGS_MAX = 0x10 ++ ETHTOOL_A_CHANNELS_UNSPEC = 0x0 ++ ETHTOOL_A_CHANNELS_HEADER = 0x1 ++ ETHTOOL_A_CHANNELS_RX_MAX = 0x2 ++ ETHTOOL_A_CHANNELS_TX_MAX = 0x3 ++ ETHTOOL_A_CHANNELS_OTHER_MAX = 0x4 ++ ETHTOOL_A_CHANNELS_COMBINED_MAX = 0x5 ++ ETHTOOL_A_CHANNELS_RX_COUNT = 0x6 ++ ETHTOOL_A_CHANNELS_TX_COUNT = 0x7 ++ ETHTOOL_A_CHANNELS_OTHER_COUNT = 0x8 ++ ETHTOOL_A_CHANNELS_COMBINED_COUNT = 0x9 ++ ETHTOOL_A_CHANNELS_MAX = 0x9 ++ ETHTOOL_A_COALESCE_UNSPEC = 0x0 ++ ETHTOOL_A_COALESCE_HEADER = 0x1 ++ ETHTOOL_A_COALESCE_RX_USECS = 0x2 ++ ETHTOOL_A_COALESCE_RX_MAX_FRAMES = 0x3 ++ ETHTOOL_A_COALESCE_RX_USECS_IRQ = 0x4 ++ ETHTOOL_A_COALESCE_RX_MAX_FRAMES_IRQ = 0x5 ++ ETHTOOL_A_COALESCE_TX_USECS = 0x6 ++ ETHTOOL_A_COALESCE_TX_MAX_FRAMES = 0x7 ++ ETHTOOL_A_COALESCE_TX_USECS_IRQ = 0x8 ++ ETHTOOL_A_COALESCE_TX_MAX_FRAMES_IRQ = 0x9 ++ ETHTOOL_A_COALESCE_STATS_BLOCK_USECS = 0xa ++ ETHTOOL_A_COALESCE_USE_ADAPTIVE_RX = 0xb ++ ETHTOOL_A_COALESCE_USE_ADAPTIVE_TX = 0xc ++ ETHTOOL_A_COALESCE_PKT_RATE_LOW = 0xd ++ ETHTOOL_A_COALESCE_RX_USECS_LOW = 0xe ++ ETHTOOL_A_COALESCE_RX_MAX_FRAMES_LOW = 0xf ++ ETHTOOL_A_COALESCE_TX_USECS_LOW = 0x10 ++ ETHTOOL_A_COALESCE_TX_MAX_FRAMES_LOW = 0x11 ++ ETHTOOL_A_COALESCE_PKT_RATE_HIGH = 0x12 ++ ETHTOOL_A_COALESCE_RX_USECS_HIGH = 0x13 ++ ETHTOOL_A_COALESCE_RX_MAX_FRAMES_HIGH = 0x14 ++ ETHTOOL_A_COALESCE_TX_USECS_HIGH = 0x15 ++ ETHTOOL_A_COALESCE_TX_MAX_FRAMES_HIGH = 0x16 ++ ETHTOOL_A_COALESCE_RATE_SAMPLE_INTERVAL = 0x17 ++ ++ ETHTOOL_A_COALESCE_MAX = 0x1c ++ ETHTOOL_A_PAUSE_UNSPEC = 0x0 ++ ETHTOOL_A_PAUSE_HEADER = 0x1 ++ ETHTOOL_A_PAUSE_AUTONEG = 0x2 ++ ETHTOOL_A_PAUSE_RX = 0x3 ++ ETHTOOL_A_PAUSE_TX = 0x4 ++ ETHTOOL_A_PAUSE_STATS = 0x5 ++ ETHTOOL_A_PAUSE_MAX = 0x6 ++ ETHTOOL_A_PAUSE_STAT_UNSPEC = 0x0 ++ ETHTOOL_A_PAUSE_STAT_PAD = 0x1 ++ ETHTOOL_A_PAUSE_STAT_TX_FRAMES = 0x2 ++ ETHTOOL_A_PAUSE_STAT_RX_FRAMES = 0x3 ++ ETHTOOL_A_PAUSE_STAT_MAX = 0x3 ++ ETHTOOL_A_EEE_UNSPEC = 0x0 ++ ETHTOOL_A_EEE_HEADER = 0x1 ++ ETHTOOL_A_EEE_MODES_OURS = 0x2 ++ ETHTOOL_A_EEE_MODES_PEER = 0x3 ++ ETHTOOL_A_EEE_ACTIVE = 0x4 ++ ETHTOOL_A_EEE_ENABLED = 0x5 ++ ETHTOOL_A_EEE_TX_LPI_ENABLED = 0x6 ++ ETHTOOL_A_EEE_TX_LPI_TIMER = 0x7 ++ ETHTOOL_A_EEE_MAX = 0x7 ++ ETHTOOL_A_TSINFO_UNSPEC = 0x0 ++ ETHTOOL_A_TSINFO_HEADER = 0x1 ++ ETHTOOL_A_TSINFO_TIMESTAMPING = 0x2 ++ ETHTOOL_A_TSINFO_TX_TYPES = 0x3 ++ ETHTOOL_A_TSINFO_RX_FILTERS = 0x4 ++ ETHTOOL_A_TSINFO_PHC_INDEX = 0x5 ++ ETHTOOL_A_TSINFO_MAX = 0x5 ++ ETHTOOL_A_CABLE_TEST_UNSPEC = 0x0 ++ ETHTOOL_A_CABLE_TEST_HEADER = 0x1 ++ ETHTOOL_A_CABLE_TEST_MAX = 0x1 ++ ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC = 0x0 ++ ETHTOOL_A_CABLE_RESULT_CODE_OK = 0x1 ++ ETHTOOL_A_CABLE_RESULT_CODE_OPEN = 0x2 ++ ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT = 0x3 ++ ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT = 0x4 ++ ETHTOOL_A_CABLE_PAIR_A = 0x0 ++ ETHTOOL_A_CABLE_PAIR_B = 0x1 ++ ETHTOOL_A_CABLE_PAIR_C = 0x2 ++ ETHTOOL_A_CABLE_PAIR_D = 0x3 ++ ETHTOOL_A_CABLE_RESULT_UNSPEC = 0x0 ++ ETHTOOL_A_CABLE_RESULT_PAIR = 0x1 ++ ETHTOOL_A_CABLE_RESULT_CODE = 0x2 ++ ETHTOOL_A_CABLE_RESULT_MAX = 0x2 ++ ETHTOOL_A_CABLE_FAULT_LENGTH_UNSPEC = 0x0 ++ ETHTOOL_A_CABLE_FAULT_LENGTH_PAIR = 0x1 ++ ETHTOOL_A_CABLE_FAULT_LENGTH_CM = 0x2 ++ ETHTOOL_A_CABLE_FAULT_LENGTH_MAX = 0x2 ++ ETHTOOL_A_CABLE_TEST_NTF_STATUS_UNSPEC = 0x0 ++ ETHTOOL_A_CABLE_TEST_NTF_STATUS_STARTED = 0x1 ++ ETHTOOL_A_CABLE_TEST_NTF_STATUS_COMPLETED = 0x2 ++ ETHTOOL_A_CABLE_NEST_UNSPEC = 0x0 ++ ETHTOOL_A_CABLE_NEST_RESULT = 0x1 ++ ETHTOOL_A_CABLE_NEST_FAULT_LENGTH = 0x2 ++ ETHTOOL_A_CABLE_NEST_MAX = 0x2 ++ ETHTOOL_A_CABLE_TEST_NTF_UNSPEC = 0x0 ++ ETHTOOL_A_CABLE_TEST_NTF_HEADER = 0x1 ++ ETHTOOL_A_CABLE_TEST_NTF_STATUS = 0x2 ++ ETHTOOL_A_CABLE_TEST_NTF_NEST = 0x3 ++ ETHTOOL_A_CABLE_TEST_NTF_MAX = 0x3 ++ ETHTOOL_A_CABLE_TEST_TDR_CFG_UNSPEC = 0x0 ++ ETHTOOL_A_CABLE_TEST_TDR_CFG_FIRST = 0x1 ++ ETHTOOL_A_CABLE_TEST_TDR_CFG_LAST = 0x2 ++ ETHTOOL_A_CABLE_TEST_TDR_CFG_STEP = 0x3 ++ ETHTOOL_A_CABLE_TEST_TDR_CFG_PAIR = 0x4 ++ ETHTOOL_A_CABLE_TEST_TDR_CFG_MAX = 0x4 ++ ETHTOOL_A_CABLE_TEST_TDR_UNSPEC = 0x0 ++ ETHTOOL_A_CABLE_TEST_TDR_HEADER = 0x1 ++ ETHTOOL_A_CABLE_TEST_TDR_CFG = 0x2 ++ ETHTOOL_A_CABLE_TEST_TDR_MAX = 0x2 ++ ETHTOOL_A_CABLE_AMPLITUDE_UNSPEC = 0x0 ++ ETHTOOL_A_CABLE_AMPLITUDE_PAIR = 0x1 ++ ETHTOOL_A_CABLE_AMPLITUDE_mV = 0x2 ++ ETHTOOL_A_CABLE_AMPLITUDE_MAX = 0x2 ++ ETHTOOL_A_CABLE_PULSE_UNSPEC = 0x0 ++ ETHTOOL_A_CABLE_PULSE_mV = 0x1 ++ ETHTOOL_A_CABLE_PULSE_MAX = 0x1 ++ ETHTOOL_A_CABLE_STEP_UNSPEC = 0x0 ++ ETHTOOL_A_CABLE_STEP_FIRST_DISTANCE = 0x1 ++ ETHTOOL_A_CABLE_STEP_LAST_DISTANCE = 0x2 ++ ETHTOOL_A_CABLE_STEP_STEP_DISTANCE = 0x3 ++ ETHTOOL_A_CABLE_STEP_MAX = 0x3 ++ ETHTOOL_A_CABLE_TDR_NEST_UNSPEC = 0x0 ++ ETHTOOL_A_CABLE_TDR_NEST_STEP = 0x1 ++ ETHTOOL_A_CABLE_TDR_NEST_AMPLITUDE = 0x2 ++ ETHTOOL_A_CABLE_TDR_NEST_PULSE = 0x3 ++ ETHTOOL_A_CABLE_TDR_NEST_MAX = 0x3 ++ ETHTOOL_A_CABLE_TEST_TDR_NTF_UNSPEC = 0x0 ++ ETHTOOL_A_CABLE_TEST_TDR_NTF_HEADER = 0x1 ++ ETHTOOL_A_CABLE_TEST_TDR_NTF_STATUS = 0x2 ++ ETHTOOL_A_CABLE_TEST_TDR_NTF_NEST = 0x3 ++ ETHTOOL_A_CABLE_TEST_TDR_NTF_MAX = 0x3 ++ ETHTOOL_UDP_TUNNEL_TYPE_VXLAN = 0x0 ++ ETHTOOL_UDP_TUNNEL_TYPE_GENEVE = 0x1 ++ ETHTOOL_UDP_TUNNEL_TYPE_VXLAN_GPE = 0x2 ++ ETHTOOL_A_TUNNEL_UDP_ENTRY_UNSPEC = 0x0 ++ ETHTOOL_A_TUNNEL_UDP_ENTRY_PORT = 0x1 ++ ETHTOOL_A_TUNNEL_UDP_ENTRY_TYPE = 0x2 ++ ETHTOOL_A_TUNNEL_UDP_ENTRY_MAX = 0x2 ++ ETHTOOL_A_TUNNEL_UDP_TABLE_UNSPEC = 0x0 ++ ETHTOOL_A_TUNNEL_UDP_TABLE_SIZE = 0x1 ++ ETHTOOL_A_TUNNEL_UDP_TABLE_TYPES = 0x2 ++ ETHTOOL_A_TUNNEL_UDP_TABLE_ENTRY = 0x3 ++ ETHTOOL_A_TUNNEL_UDP_TABLE_MAX = 0x3 ++ ETHTOOL_A_TUNNEL_UDP_UNSPEC = 0x0 ++ ETHTOOL_A_TUNNEL_UDP_TABLE = 0x1 ++ ETHTOOL_A_TUNNEL_UDP_MAX = 0x1 ++ ETHTOOL_A_TUNNEL_INFO_UNSPEC = 0x0 ++ ETHTOOL_A_TUNNEL_INFO_HEADER = 0x1 ++ ETHTOOL_A_TUNNEL_INFO_UDP_PORTS = 0x2 ++ ETHTOOL_A_TUNNEL_INFO_MAX = 0x2 ++) ++ ++const SPEED_UNKNOWN = -0x1 ++ ++type EthtoolDrvinfo struct { ++ Cmd uint32 ++ Driver [32]byte ++ Version [32]byte ++ Fw_version [32]byte ++ Bus_info [32]byte ++ Erom_version [32]byte ++ Reserved2 [12]byte ++ N_priv_flags uint32 ++ N_stats uint32 ++ Testinfo_len uint32 ++ Eedump_len uint32 ++ Regdump_len uint32 ++} ++ ++type EthtoolTsInfo struct { ++ Cmd uint32 ++ So_timestamping uint32 ++ Phc_index int32 ++ Tx_types uint32 ++ Tx_reserved [3]uint32 ++ Rx_filters uint32 ++ Rx_reserved [3]uint32 ++} ++ ++type HwTstampConfig struct { ++ Flags int32 ++ Tx_type int32 ++ Rx_filter int32 ++} ++ ++const ( ++ HWTSTAMP_FILTER_NONE = 0x0 ++ HWTSTAMP_FILTER_ALL = 0x1 ++ HWTSTAMP_FILTER_SOME = 0x2 ++ HWTSTAMP_FILTER_PTP_V1_L4_EVENT = 0x3 ++ HWTSTAMP_FILTER_PTP_V2_L4_EVENT = 0x6 ++ HWTSTAMP_FILTER_PTP_V2_L2_EVENT = 0x9 ++ HWTSTAMP_FILTER_PTP_V2_EVENT = 0xc ++) ++ ++const ( ++ HWTSTAMP_TX_OFF = 0x0 ++ HWTSTAMP_TX_ON = 0x1 ++ HWTSTAMP_TX_ONESTEP_SYNC = 0x2 ++) ++ ++type ( ++ PtpClockCaps struct { ++ Max_adj int32 ++ N_alarm int32 ++ N_ext_ts int32 ++ N_per_out int32 ++ Pps int32 ++ N_pins int32 ++ Cross_timestamping int32 ++ Adjust_phase int32 ++ Max_phase_adj int32 ++ Rsv [11]int32 ++ } ++ PtpClockTime struct { ++ Sec int64 ++ Nsec uint32 ++ Reserved uint32 ++ } ++ PtpExttsEvent struct { ++ T PtpClockTime ++ Index uint32 ++ Flags uint32 ++ Rsv [2]uint32 ++ } ++ PtpExttsRequest struct { ++ Index uint32 ++ Flags uint32 ++ Rsv [2]uint32 ++ } ++ PtpPeroutRequest struct { ++ StartOrPhase PtpClockTime ++ Period PtpClockTime ++ Index uint32 ++ Flags uint32 ++ On PtpClockTime ++ } ++ PtpPinDesc struct { ++ Name [64]byte ++ Index uint32 ++ Func uint32 ++ Chan uint32 ++ Rsv [5]uint32 ++ } ++ PtpSysOffset struct { ++ Samples uint32 ++ Rsv [3]uint32 ++ Ts [51]PtpClockTime ++ } ++ PtpSysOffsetExtended struct { ++ Samples uint32 ++ Rsv [3]uint32 ++ Ts [25][3]PtpClockTime ++ } ++ PtpSysOffsetPrecise struct { ++ Device PtpClockTime ++ Realtime PtpClockTime ++ Monoraw PtpClockTime ++ Rsv [4]uint32 ++ } ++) ++ ++const ( ++ PTP_PF_NONE = 0x0 ++ PTP_PF_EXTTS = 0x1 ++ PTP_PF_PEROUT = 0x2 ++ PTP_PF_PHYSYNC = 0x3 ++) ++ ++type ( ++ HIDRawReportDescriptor struct { ++ Size uint32 ++ Value [4096]uint8 ++ } ++ HIDRawDevInfo struct { ++ Bustype uint32 ++ Vendor int16 ++ Product int16 ++ } ++) ++ ++const ( ++ CLOSE_RANGE_UNSHARE = 0x2 ++ CLOSE_RANGE_CLOEXEC = 0x4 ++) ++ ++const ( ++ NLMSGERR_ATTR_MSG = 0x1 ++ NLMSGERR_ATTR_OFFS = 0x2 ++ NLMSGERR_ATTR_COOKIE = 0x3 ++) ++ ++type ( ++ EraseInfo struct { ++ Start uint32 ++ Length uint32 ++ } ++ EraseInfo64 struct { ++ Start uint64 ++ Length uint64 ++ } ++ MtdOobBuf struct { ++ Start uint32 ++ Length uint32 ++ Ptr *uint8 ++ } ++ MtdOobBuf64 struct { ++ Start uint64 ++ Pad uint32 ++ Length uint32 ++ Ptr uint64 ++ } ++ MtdWriteReq struct { ++ Start uint64 ++ Len uint64 ++ Ooblen uint64 ++ Data uint64 ++ Oob uint64 ++ Mode uint8 ++ _ [7]uint8 ++ } ++ MtdInfo struct { ++ Type uint8 ++ Flags uint32 ++ Size uint32 ++ Erasesize uint32 ++ Writesize uint32 ++ Oobsize uint32 ++ _ uint64 ++ } ++ RegionInfo struct { ++ Offset uint32 ++ Erasesize uint32 ++ Numblocks uint32 ++ Regionindex uint32 ++ } ++ OtpInfo struct { ++ Start uint32 ++ Length uint32 ++ Locked uint32 ++ } ++ NandOobinfo struct { ++ Useecc uint32 ++ Eccbytes uint32 ++ Oobfree [8][2]uint32 ++ Eccpos [32]uint32 ++ } ++ NandOobfree struct { ++ Offset uint32 ++ Length uint32 ++ } ++ NandEcclayout struct { ++ Eccbytes uint32 ++ Eccpos [64]uint32 ++ Oobavail uint32 ++ Oobfree [8]NandOobfree ++ } ++ MtdEccStats struct { ++ Corrected uint32 ++ Failed uint32 ++ Badblocks uint32 ++ Bbtblocks uint32 ++ } ++) ++ ++const ( ++ MTD_OPS_PLACE_OOB = 0x0 ++ MTD_OPS_AUTO_OOB = 0x1 ++ MTD_OPS_RAW = 0x2 ++) ++ ++const ( ++ MTD_FILE_MODE_NORMAL = 0x0 ++ MTD_FILE_MODE_OTP_FACTORY = 0x1 ++ MTD_FILE_MODE_OTP_USER = 0x2 ++ MTD_FILE_MODE_RAW = 0x3 ++) ++ ++const ( ++ NFC_CMD_UNSPEC = 0x0 ++ NFC_CMD_GET_DEVICE = 0x1 ++ NFC_CMD_DEV_UP = 0x2 ++ NFC_CMD_DEV_DOWN = 0x3 ++ NFC_CMD_DEP_LINK_UP = 0x4 ++ NFC_CMD_DEP_LINK_DOWN = 0x5 ++ NFC_CMD_START_POLL = 0x6 ++ NFC_CMD_STOP_POLL = 0x7 ++ NFC_CMD_GET_TARGET = 0x8 ++ NFC_EVENT_TARGETS_FOUND = 0x9 ++ NFC_EVENT_DEVICE_ADDED = 0xa ++ NFC_EVENT_DEVICE_REMOVED = 0xb ++ NFC_EVENT_TARGET_LOST = 0xc ++ NFC_EVENT_TM_ACTIVATED = 0xd ++ NFC_EVENT_TM_DEACTIVATED = 0xe ++ NFC_CMD_LLC_GET_PARAMS = 0xf ++ NFC_CMD_LLC_SET_PARAMS = 0x10 ++ NFC_CMD_ENABLE_SE = 0x11 ++ NFC_CMD_DISABLE_SE = 0x12 ++ NFC_CMD_LLC_SDREQ = 0x13 ++ NFC_EVENT_LLC_SDRES = 0x14 ++ NFC_CMD_FW_DOWNLOAD = 0x15 ++ NFC_EVENT_SE_ADDED = 0x16 ++ NFC_EVENT_SE_REMOVED = 0x17 ++ NFC_EVENT_SE_CONNECTIVITY = 0x18 ++ NFC_EVENT_SE_TRANSACTION = 0x19 ++ NFC_CMD_GET_SE = 0x1a ++ NFC_CMD_SE_IO = 0x1b ++ NFC_CMD_ACTIVATE_TARGET = 0x1c ++ NFC_CMD_VENDOR = 0x1d ++ NFC_CMD_DEACTIVATE_TARGET = 0x1e ++ NFC_ATTR_UNSPEC = 0x0 ++ NFC_ATTR_DEVICE_INDEX = 0x1 ++ NFC_ATTR_DEVICE_NAME = 0x2 ++ NFC_ATTR_PROTOCOLS = 0x3 ++ NFC_ATTR_TARGET_INDEX = 0x4 ++ NFC_ATTR_TARGET_SENS_RES = 0x5 ++ NFC_ATTR_TARGET_SEL_RES = 0x6 ++ NFC_ATTR_TARGET_NFCID1 = 0x7 ++ NFC_ATTR_TARGET_SENSB_RES = 0x8 ++ NFC_ATTR_TARGET_SENSF_RES = 0x9 ++ NFC_ATTR_COMM_MODE = 0xa ++ NFC_ATTR_RF_MODE = 0xb ++ NFC_ATTR_DEVICE_POWERED = 0xc ++ NFC_ATTR_IM_PROTOCOLS = 0xd ++ NFC_ATTR_TM_PROTOCOLS = 0xe ++ NFC_ATTR_LLC_PARAM_LTO = 0xf ++ NFC_ATTR_LLC_PARAM_RW = 0x10 ++ NFC_ATTR_LLC_PARAM_MIUX = 0x11 ++ NFC_ATTR_SE = 0x12 ++ NFC_ATTR_LLC_SDP = 0x13 ++ NFC_ATTR_FIRMWARE_NAME = 0x14 ++ NFC_ATTR_SE_INDEX = 0x15 ++ NFC_ATTR_SE_TYPE = 0x16 ++ NFC_ATTR_SE_AID = 0x17 ++ NFC_ATTR_FIRMWARE_DOWNLOAD_STATUS = 0x18 ++ NFC_ATTR_SE_APDU = 0x19 ++ NFC_ATTR_TARGET_ISO15693_DSFID = 0x1a ++ NFC_ATTR_TARGET_ISO15693_UID = 0x1b ++ NFC_ATTR_SE_PARAMS = 0x1c ++ NFC_ATTR_VENDOR_ID = 0x1d ++ NFC_ATTR_VENDOR_SUBCMD = 0x1e ++ NFC_ATTR_VENDOR_DATA = 0x1f ++ NFC_SDP_ATTR_UNSPEC = 0x0 ++ NFC_SDP_ATTR_URI = 0x1 ++ NFC_SDP_ATTR_SAP = 0x2 ++) ++ ++type LandlockRulesetAttr struct{} ++ ++type LandlockPathBeneathAttr struct{} ++ ++const ( ++ PIDFD_NONBLOCK = 0x4 ++) ++ ++type SysvIpcPerm struct { ++ Key int32 ++ Uid uint32 ++ Gid uint32 ++ Cuid uint32 ++ Cgid uint32 ++ Mode uint32 ++ _ [0]uint8 ++ Seq uint16 ++ _ uint16 ++ _ uint64 ++ _ uint64 ++} ++type SysvShmDesc struct { ++ Perm SysvIpcPerm ++ Segsz uint64 ++ Atime int64 ++ Dtime int64 ++ Ctime int64 ++ Cpid int32 ++ Lpid int32 ++ Nattch uint64 ++ _ uint64 ++ _ uint64 ++} ++ ++const ( ++ IPC_CREAT = 0x200 ++ IPC_EXCL = 0x400 ++ IPC_NOWAIT = 0x800 ++ IPC_PRIVATE = 0x0 ++ ++ ipc_64 = 0x100 ++) ++ ++const ( ++ IPC_RMID = 0x0 ++ IPC_SET = 0x1 ++ IPC_STAT = 0x2 ++) ++ ++const ( ++ SHM_RDONLY = 0x1000 ++ SHM_RND = 0x2000 ++) ++ ++type MountAttr struct { ++ Attr_set uint64 ++ Attr_clr uint64 ++ Propagation uint64 ++ Userns_fd uint64 ++} ++ ++const ( ++ WG_CMD_GET_DEVICE = 0x0 ++ WG_CMD_SET_DEVICE = 0x1 ++ WGDEVICE_F_REPLACE_PEERS = 0x1 ++ WGDEVICE_A_UNSPEC = 0x0 ++ WGDEVICE_A_IFINDEX = 0x1 ++ WGDEVICE_A_IFNAME = 0x2 ++ WGDEVICE_A_PRIVATE_KEY = 0x3 ++ WGDEVICE_A_PUBLIC_KEY = 0x4 ++ WGDEVICE_A_FLAGS = 0x5 ++ WGDEVICE_A_LISTEN_PORT = 0x6 ++ WGDEVICE_A_FWMARK = 0x7 ++ WGDEVICE_A_PEERS = 0x8 ++ WGPEER_F_REMOVE_ME = 0x1 ++ WGPEER_F_REPLACE_ALLOWEDIPS = 0x2 ++ WGPEER_F_UPDATE_ONLY = 0x4 ++ WGPEER_A_UNSPEC = 0x0 ++ WGPEER_A_PUBLIC_KEY = 0x1 ++ WGPEER_A_PRESHARED_KEY = 0x2 ++ WGPEER_A_FLAGS = 0x3 ++ WGPEER_A_ENDPOINT = 0x4 ++ WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL = 0x5 ++ WGPEER_A_LAST_HANDSHAKE_TIME = 0x6 ++ WGPEER_A_RX_BYTES = 0x7 ++ WGPEER_A_TX_BYTES = 0x8 ++ WGPEER_A_ALLOWEDIPS = 0x9 ++ WGPEER_A_PROTOCOL_VERSION = 0xa ++ WGALLOWEDIP_A_UNSPEC = 0x0 ++ WGALLOWEDIP_A_FAMILY = 0x1 ++ WGALLOWEDIP_A_IPADDR = 0x2 ++ WGALLOWEDIP_A_CIDR_MASK = 0x3 ++) ++ ++const ( ++ NL_ATTR_TYPE_INVALID = 0x0 ++ NL_ATTR_TYPE_FLAG = 0x1 ++ NL_ATTR_TYPE_U8 = 0x2 ++ NL_ATTR_TYPE_U16 = 0x3 ++ NL_ATTR_TYPE_U32 = 0x4 ++ NL_ATTR_TYPE_U64 = 0x5 ++ NL_ATTR_TYPE_S8 = 0x6 ++ NL_ATTR_TYPE_S16 = 0x7 ++ NL_ATTR_TYPE_S32 = 0x8 ++ NL_ATTR_TYPE_S64 = 0x9 ++ NL_ATTR_TYPE_BINARY = 0xa ++ NL_ATTR_TYPE_STRING = 0xb ++ NL_ATTR_TYPE_NUL_STRING = 0xc ++ NL_ATTR_TYPE_NESTED = 0xd ++ NL_ATTR_TYPE_NESTED_ARRAY = 0xe ++ NL_ATTR_TYPE_BITFIELD32 = 0xf ++ ++ NL_POLICY_TYPE_ATTR_UNSPEC = 0x0 ++ NL_POLICY_TYPE_ATTR_TYPE = 0x1 ++ NL_POLICY_TYPE_ATTR_MIN_VALUE_S = 0x2 ++ NL_POLICY_TYPE_ATTR_MAX_VALUE_S = 0x3 ++ NL_POLICY_TYPE_ATTR_MIN_VALUE_U = 0x4 ++ NL_POLICY_TYPE_ATTR_MAX_VALUE_U = 0x5 ++ NL_POLICY_TYPE_ATTR_MIN_LENGTH = 0x6 ++ NL_POLICY_TYPE_ATTR_MAX_LENGTH = 0x7 ++ NL_POLICY_TYPE_ATTR_POLICY_IDX = 0x8 ++ NL_POLICY_TYPE_ATTR_POLICY_MAXTYPE = 0x9 ++ NL_POLICY_TYPE_ATTR_BITFIELD32_MASK = 0xa ++ NL_POLICY_TYPE_ATTR_PAD = 0xb ++ NL_POLICY_TYPE_ATTR_MASK = 0xc ++ NL_POLICY_TYPE_ATTR_MAX = 0xc ++) ++ ++type CANBitTiming struct { ++ Bitrate uint32 ++ Sample_point uint32 ++ Tq uint32 ++ Prop_seg uint32 ++ Phase_seg1 uint32 ++ Phase_seg2 uint32 ++ Sjw uint32 ++ Brp uint32 ++} ++ ++type CANBitTimingConst struct { ++ Name [16]uint8 ++ Tseg1_min uint32 ++ Tseg1_max uint32 ++ Tseg2_min uint32 ++ Tseg2_max uint32 ++ Sjw_max uint32 ++ Brp_min uint32 ++ Brp_max uint32 ++ Brp_inc uint32 ++} ++ ++type CANClock struct { ++ Freq uint32 ++} ++ ++type CANBusErrorCounters struct { ++ Txerr uint16 ++ Rxerr uint16 ++} ++ ++type CANCtrlMode struct { ++ Mask uint32 ++ Flags uint32 ++} ++ ++type CANDeviceStats struct { ++ Bus_error uint32 ++ Error_warning uint32 ++ Error_passive uint32 ++ Bus_off uint32 ++ Arbitration_lost uint32 ++ Restarts uint32 ++} ++ ++const ( ++ CAN_STATE_ERROR_ACTIVE = 0x0 ++ CAN_STATE_ERROR_WARNING = 0x1 ++ CAN_STATE_ERROR_PASSIVE = 0x2 ++ CAN_STATE_BUS_OFF = 0x3 ++ CAN_STATE_STOPPED = 0x4 ++ CAN_STATE_SLEEPING = 0x5 ++ CAN_STATE_MAX = 0x6 ++) ++ ++const ( ++ IFLA_CAN_UNSPEC = 0x0 ++ IFLA_CAN_BITTIMING = 0x1 ++ IFLA_CAN_BITTIMING_CONST = 0x2 ++ IFLA_CAN_CLOCK = 0x3 ++ IFLA_CAN_STATE = 0x4 ++ IFLA_CAN_CTRLMODE = 0x5 ++ IFLA_CAN_RESTART_MS = 0x6 ++ IFLA_CAN_RESTART = 0x7 ++ IFLA_CAN_BERR_COUNTER = 0x8 ++ IFLA_CAN_DATA_BITTIMING = 0x9 ++ IFLA_CAN_DATA_BITTIMING_CONST = 0xa ++ IFLA_CAN_TERMINATION = 0xb ++ IFLA_CAN_TERMINATION_CONST = 0xc ++ IFLA_CAN_BITRATE_CONST = 0xd ++ IFLA_CAN_DATA_BITRATE_CONST = 0xe ++ IFLA_CAN_BITRATE_MAX = 0xf ++) ++ ++type KCMAttach struct { ++ Fd int32 ++ Bpf_fd int32 ++} ++ ++type KCMUnattach struct { ++ Fd int32 ++} ++ ++type KCMClone struct { ++ Fd int32 ++} ++ ++const ( ++ NL80211_AC_BE = 0x2 ++ NL80211_AC_BK = 0x3 ++ NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED = 0x0 ++ NL80211_ACL_POLICY_DENY_UNLESS_LISTED = 0x1 ++ NL80211_AC_VI = 0x1 ++ NL80211_AC_VO = 0x0 ++ NL80211_AP_SETTINGS_EXTERNAL_AUTH_SUPPORT = 0x1 ++ NL80211_AP_SETTINGS_SA_QUERY_OFFLOAD_SUPPORT = 0x2 ++ NL80211_AP_SME_SA_QUERY_OFFLOAD = 0x1 ++ NL80211_ATTR_4ADDR = 0x53 ++ NL80211_ATTR_ACK = 0x5c ++ NL80211_ATTR_ACK_SIGNAL = 0x107 ++ NL80211_ATTR_ACL_POLICY = 0xa5 ++ NL80211_ATTR_ADMITTED_TIME = 0xd4 ++ NL80211_ATTR_AIRTIME_WEIGHT = 0x112 ++ NL80211_ATTR_AKM_SUITES = 0x4c ++ NL80211_ATTR_AP_ISOLATE = 0x60 ++ NL80211_ATTR_AP_SETTINGS_FLAGS = 0x135 ++ NL80211_ATTR_AUTH_DATA = 0x9c ++ NL80211_ATTR_AUTH_TYPE = 0x35 ++ NL80211_ATTR_BANDS = 0xef ++ NL80211_ATTR_BEACON_HEAD = 0xe ++ NL80211_ATTR_BEACON_INTERVAL = 0xc ++ NL80211_ATTR_BEACON_TAIL = 0xf ++ NL80211_ATTR_BG_SCAN_PERIOD = 0x98 ++ NL80211_ATTR_BSS_BASIC_RATES = 0x24 ++ NL80211_ATTR_BSS = 0x2f ++ NL80211_ATTR_BSS_CTS_PROT = 0x1c ++ NL80211_ATTR_BSS_HT_OPMODE = 0x6d ++ NL80211_ATTR_BSSID = 0xf5 ++ NL80211_ATTR_BSS_SELECT = 0xe3 ++ NL80211_ATTR_BSS_SHORT_PREAMBLE = 0x1d ++ NL80211_ATTR_BSS_SHORT_SLOT_TIME = 0x1e ++ NL80211_ATTR_CENTER_FREQ1 = 0xa0 ++ NL80211_ATTR_CENTER_FREQ1_OFFSET = 0x123 ++ NL80211_ATTR_CENTER_FREQ2 = 0xa1 ++ NL80211_ATTR_CHANNEL_WIDTH = 0x9f ++ NL80211_ATTR_CH_SWITCH_BLOCK_TX = 0xb8 ++ NL80211_ATTR_CH_SWITCH_COUNT = 0xb7 ++ NL80211_ATTR_CIPHER_SUITE_GROUP = 0x4a ++ NL80211_ATTR_CIPHER_SUITES = 0x39 ++ NL80211_ATTR_CIPHER_SUITES_PAIRWISE = 0x49 ++ NL80211_ATTR_CNTDWN_OFFS_BEACON = 0xba ++ NL80211_ATTR_CNTDWN_OFFS_PRESP = 0xbb ++ NL80211_ATTR_COALESCE_RULE = 0xb6 ++ NL80211_ATTR_COALESCE_RULE_CONDITION = 0x2 ++ NL80211_ATTR_COALESCE_RULE_DELAY = 0x1 ++ NL80211_ATTR_COALESCE_RULE_MAX = 0x3 ++ NL80211_ATTR_COALESCE_RULE_PKT_PATTERN = 0x3 ++ NL80211_ATTR_COLOR_CHANGE_COLOR = 0x130 ++ NL80211_ATTR_COLOR_CHANGE_COUNT = 0x12f ++ NL80211_ATTR_COLOR_CHANGE_ELEMS = 0x131 ++ NL80211_ATTR_CONN_FAILED_REASON = 0x9b ++ NL80211_ATTR_CONTROL_PORT = 0x44 ++ NL80211_ATTR_CONTROL_PORT_ETHERTYPE = 0x66 ++ NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT = 0x67 ++ NL80211_ATTR_CONTROL_PORT_NO_PREAUTH = 0x11e ++ NL80211_ATTR_CONTROL_PORT_OVER_NL80211 = 0x108 ++ NL80211_ATTR_COOKIE = 0x58 ++ NL80211_ATTR_CQM_BEACON_LOSS_EVENT = 0x8 ++ NL80211_ATTR_CQM = 0x5e ++ NL80211_ATTR_CQM_MAX = 0x9 ++ NL80211_ATTR_CQM_PKT_LOSS_EVENT = 0x4 ++ NL80211_ATTR_CQM_RSSI_HYST = 0x2 ++ NL80211_ATTR_CQM_RSSI_LEVEL = 0x9 ++ NL80211_ATTR_CQM_RSSI_THOLD = 0x1 ++ NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT = 0x3 ++ NL80211_ATTR_CQM_TXE_INTVL = 0x7 ++ NL80211_ATTR_CQM_TXE_PKTS = 0x6 ++ NL80211_ATTR_CQM_TXE_RATE = 0x5 ++ NL80211_ATTR_CRIT_PROT_ID = 0xb3 ++ NL80211_ATTR_CSA_C_OFF_BEACON = 0xba ++ NL80211_ATTR_CSA_C_OFF_PRESP = 0xbb ++ NL80211_ATTR_CSA_C_OFFSETS_TX = 0xcd ++ NL80211_ATTR_CSA_IES = 0xb9 ++ NL80211_ATTR_DEVICE_AP_SME = 0x8d ++ NL80211_ATTR_DFS_CAC_TIME = 0x7 ++ NL80211_ATTR_DFS_REGION = 0x92 ++ NL80211_ATTR_DISABLE_EHT = 0x137 ++ ++ NL80211_ATTR_DISABLE_HT = 0x93 ++ NL80211_ATTR_DISABLE_VHT = 0xaf ++ NL80211_ATTR_DISCONNECTED_BY_AP = 0x47 ++ NL80211_ATTR_DONT_WAIT_FOR_ACK = 0x8e ++ NL80211_ATTR_DTIM_PERIOD = 0xd ++ NL80211_ATTR_DURATION = 0x57 ++ NL80211_ATTR_EHT_CAPABILITY = 0x136 ++ NL80211_ATTR_EML_CAPABILITY = 0x13d ++ NL80211_ATTR_EXT_CAPA = 0xa9 ++ NL80211_ATTR_EXT_CAPA_MASK = 0xaa ++ NL80211_ATTR_EXTERNAL_AUTH_ACTION = 0x104 ++ NL80211_ATTR_EXTERNAL_AUTH_SUPPORT = 0x105 ++ NL80211_ATTR_EXT_FEATURES = 0xd9 ++ NL80211_ATTR_FEATURE_FLAGS = 0x8f ++ NL80211_ATTR_FILS_CACHE_ID = 0xfd ++ NL80211_ATTR_FILS_DISCOVERY = 0x126 ++ NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM = 0xfb ++ NL80211_ATTR_FILS_ERP_REALM = 0xfa ++ NL80211_ATTR_FILS_ERP_RRK = 0xfc ++ NL80211_ATTR_FILS_ERP_USERNAME = 0xf9 ++ NL80211_ATTR_FILS_KEK = 0xf2 ++ NL80211_ATTR_FILS_NONCES = 0xf3 ++ NL80211_ATTR_FRAME = 0x33 ++ NL80211_ATTR_FRAME_MATCH = 0x5b ++ NL80211_ATTR_FRAME_TYPE = 0x65 ++ NL80211_ATTR_FREQ_AFTER = 0x3b ++ NL80211_ATTR_FREQ_BEFORE = 0x3a ++ NL80211_ATTR_FREQ_FIXED = 0x3c ++ NL80211_ATTR_FREQ_RANGE_END = 0x3 ++ NL80211_ATTR_FREQ_RANGE_MAX_BW = 0x4 ++ NL80211_ATTR_FREQ_RANGE_START = 0x2 ++ NL80211_ATTR_FTM_RESPONDER = 0x10e ++ NL80211_ATTR_FTM_RESPONDER_STATS = 0x10f ++ NL80211_ATTR_GENERATION = 0x2e ++ NL80211_ATTR_HANDLE_DFS = 0xbf ++ NL80211_ATTR_HE_6GHZ_CAPABILITY = 0x125 ++ NL80211_ATTR_HE_BSS_COLOR = 0x11b ++ NL80211_ATTR_HE_CAPABILITY = 0x10d ++ NL80211_ATTR_HE_OBSS_PD = 0x117 ++ NL80211_ATTR_HIDDEN_SSID = 0x7e ++ NL80211_ATTR_HT_CAPABILITY = 0x1f ++ NL80211_ATTR_HT_CAPABILITY_MASK = 0x94 ++ NL80211_ATTR_IE_ASSOC_RESP = 0x80 ++ NL80211_ATTR_IE = 0x2a ++ NL80211_ATTR_IE_PROBE_RESP = 0x7f ++ NL80211_ATTR_IE_RIC = 0xb2 ++ NL80211_ATTR_IFACE_SOCKET_OWNER = 0xcc ++ NL80211_ATTR_IFINDEX = 0x3 ++ NL80211_ATTR_IFNAME = 0x4 ++ NL80211_ATTR_IFTYPE_AKM_SUITES = 0x11c ++ NL80211_ATTR_IFTYPE = 0x5 ++ NL80211_ATTR_IFTYPE_EXT_CAPA = 0xe6 ++ NL80211_ATTR_INACTIVITY_TIMEOUT = 0x96 ++ NL80211_ATTR_INTERFACE_COMBINATIONS = 0x78 ++ NL80211_ATTR_KEY_CIPHER = 0x9 ++ NL80211_ATTR_KEY = 0x50 ++ NL80211_ATTR_KEY_DATA = 0x7 ++ NL80211_ATTR_KEY_DEFAULT = 0xb ++ NL80211_ATTR_KEY_DEFAULT_MGMT = 0x28 ++ NL80211_ATTR_KEY_DEFAULT_TYPES = 0x6e ++ NL80211_ATTR_KEY_IDX = 0x8 ++ NL80211_ATTR_KEYS = 0x51 ++ NL80211_ATTR_KEY_SEQ = 0xa ++ NL80211_ATTR_KEY_TYPE = 0x37 ++ NL80211_ATTR_LOCAL_MESH_POWER_MODE = 0xa4 ++ NL80211_ATTR_LOCAL_STATE_CHANGE = 0x5f ++ NL80211_ATTR_MAC_ACL_MAX = 0xa7 ++ NL80211_ATTR_MAC_ADDRS = 0xa6 ++ NL80211_ATTR_MAC = 0x6 ++ NL80211_ATTR_MAC_HINT = 0xc8 ++ NL80211_ATTR_MAC_MASK = 0xd7 ++ NL80211_ATTR_MAX_AP_ASSOC_STA = 0xca ++ NL80211_ATTR_MAX = 0x146 ++ NL80211_ATTR_MAX_CRIT_PROT_DURATION = 0xb4 ++ NL80211_ATTR_MAX_CSA_COUNTERS = 0xce ++ NL80211_ATTR_MAX_MATCH_SETS = 0x85 ++ NL80211_ATTR_MAX_NUM_AKM_SUITES = 0x13c ++ NL80211_ATTR_MAX_NUM_PMKIDS = 0x56 ++ NL80211_ATTR_MAX_NUM_SCAN_SSIDS = 0x2b ++ NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS = 0xde ++ NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS = 0x7b ++ NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION = 0x6f ++ NL80211_ATTR_MAX_SCAN_IE_LEN = 0x38 ++ NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL = 0xdf ++ NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS = 0xe0 ++ NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN = 0x7c ++ NL80211_ATTR_MBSSID_CONFIG = 0x132 ++ NL80211_ATTR_MBSSID_ELEMS = 0x133 ++ NL80211_ATTR_MCAST_RATE = 0x6b ++ NL80211_ATTR_MDID = 0xb1 ++ NL80211_ATTR_MEASUREMENT_DURATION = 0xeb ++ NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY = 0xec ++ NL80211_ATTR_MESH_CONFIG = 0x23 ++ NL80211_ATTR_MESH_ID = 0x18 ++ NL80211_ATTR_MESH_PEER_AID = 0xed ++ NL80211_ATTR_MESH_SETUP = 0x70 ++ NL80211_ATTR_MGMT_SUBTYPE = 0x29 ++ NL80211_ATTR_MLD_ADDR = 0x13a ++ NL80211_ATTR_MLD_CAPA_AND_OPS = 0x13e ++ NL80211_ATTR_MLO_LINK_ID = 0x139 ++ NL80211_ATTR_MLO_LINKS = 0x138 ++ NL80211_ATTR_MLO_SUPPORT = 0x13b ++ NL80211_ATTR_MNTR_FLAGS = 0x17 ++ NL80211_ATTR_MPATH_INFO = 0x1b ++ NL80211_ATTR_MPATH_NEXT_HOP = 0x1a ++ NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED = 0xf4 ++ NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR = 0xe8 ++ NL80211_ATTR_MU_MIMO_GROUP_DATA = 0xe7 ++ NL80211_ATTR_NAN_FUNC = 0xf0 ++ NL80211_ATTR_NAN_MASTER_PREF = 0xee ++ NL80211_ATTR_NAN_MATCH = 0xf1 ++ NL80211_ATTR_NETNS_FD = 0xdb ++ NL80211_ATTR_NOACK_MAP = 0x95 ++ NL80211_ATTR_NSS = 0x106 ++ NL80211_ATTR_OBSS_COLOR_BITMAP = 0x12e ++ NL80211_ATTR_OFFCHANNEL_TX_OK = 0x6c ++ NL80211_ATTR_OPER_CLASS = 0xd6 ++ NL80211_ATTR_OPMODE_NOTIF = 0xc2 ++ NL80211_ATTR_P2P_CTWINDOW = 0xa2 ++ NL80211_ATTR_P2P_OPPPS = 0xa3 ++ NL80211_ATTR_PAD = 0xe5 ++ NL80211_ATTR_PBSS = 0xe2 ++ NL80211_ATTR_PEER_AID = 0xb5 ++ NL80211_ATTR_PEER_MEASUREMENTS = 0x111 ++ NL80211_ATTR_PID = 0x52 ++ NL80211_ATTR_PMK = 0xfe ++ NL80211_ATTR_PMKID = 0x55 ++ NL80211_ATTR_PMK_LIFETIME = 0x11f ++ NL80211_ATTR_PMKR0_NAME = 0x102 ++ NL80211_ATTR_PMK_REAUTH_THRESHOLD = 0x120 ++ NL80211_ATTR_PMKSA_CANDIDATE = 0x86 ++ NL80211_ATTR_PORT_AUTHORIZED = 0x103 ++ NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN = 0x5 ++ NL80211_ATTR_POWER_RULE_MAX_EIRP = 0x6 ++ NL80211_ATTR_PREV_BSSID = 0x4f ++ NL80211_ATTR_PRIVACY = 0x46 ++ NL80211_ATTR_PROBE_RESP = 0x91 ++ NL80211_ATTR_PROBE_RESP_OFFLOAD = 0x90 ++ NL80211_ATTR_PROTOCOL_FEATURES = 0xad ++ NL80211_ATTR_PS_STATE = 0x5d ++ NL80211_ATTR_QOS_MAP = 0xc7 ++ NL80211_ATTR_RADAR_BACKGROUND = 0x134 ++ NL80211_ATTR_RADAR_EVENT = 0xa8 ++ NL80211_ATTR_REASON_CODE = 0x36 ++ NL80211_ATTR_RECEIVE_MULTICAST = 0x121 ++ ++ NL80211_ATTR_REG_ALPHA2 = 0x21 ++ NL80211_ATTR_REG_INDOOR = 0xdd ++ NL80211_ATTR_REG_INITIATOR = 0x30 ++ NL80211_ATTR_REG_RULE_FLAGS = 0x1 ++ NL80211_ATTR_REG_RULES = 0x22 ++ NL80211_ATTR_REG_TYPE = 0x31 ++ NL80211_ATTR_REKEY_DATA = 0x7a ++ NL80211_ATTR_REQ_IE = 0x4d ++ NL80211_ATTR_RESP_IE = 0x4e ++ NL80211_ATTR_ROAM_SUPPORT = 0x83 ++ NL80211_ATTR_RX_FRAME_TYPES = 0x64 ++ NL80211_ATTR_RX_HW_TIMESTAMP = 0x140 ++ NL80211_ATTR_RXMGMT_FLAGS = 0xbc ++ NL80211_ATTR_RX_SIGNAL_DBM = 0x97 ++ NL80211_ATTR_S1G_CAPABILITY = 0x128 ++ NL80211_ATTR_S1G_CAPABILITY_MASK = 0x129 ++ NL80211_ATTR_SAE_DATA = 0x9c ++ NL80211_ATTR_SAE_PASSWORD = 0x115 ++ ++ NL80211_ATTR_SCAN_FLAGS = 0x9e ++ NL80211_ATTR_SCAN_FREQ_KHZ = 0x124 ++ NL80211_ATTR_SCAN_FREQUENCIES = 0x2c ++ NL80211_ATTR_SCAN_GENERATION = 0x2e ++ NL80211_ATTR_SCAN_SSIDS = 0x2d ++ NL80211_ATTR_SCAN_START_TIME_TSF_BSSID = 0xea ++ NL80211_ATTR_SCAN_START_TIME_TSF = 0xe9 ++ NL80211_ATTR_SCAN_SUPP_RATES = 0x7d ++ NL80211_ATTR_SCHED_SCAN_DELAY = 0xdc ++ NL80211_ATTR_SCHED_SCAN_INTERVAL = 0x77 ++ NL80211_ATTR_SCHED_SCAN_MATCH = 0x84 ++ NL80211_ATTR_SCHED_SCAN_MATCH_SSID = 0x1 ++ NL80211_ATTR_SCHED_SCAN_MAX_REQS = 0x100 ++ NL80211_ATTR_SCHED_SCAN_MULTI = 0xff ++ NL80211_ATTR_SCHED_SCAN_PLANS = 0xe1 ++ NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI = 0xf6 ++ NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST = 0xf7 ++ NL80211_ATTR_SMPS_MODE = 0xd5 ++ NL80211_ATTR_SOCKET_OWNER = 0xcc ++ NL80211_ATTR_SOFTWARE_IFTYPES = 0x79 ++ NL80211_ATTR_SPLIT_WIPHY_DUMP = 0xae ++ NL80211_ATTR_SSID = 0x34 ++ NL80211_ATTR_STA_AID = 0x10 ++ NL80211_ATTR_STA_CAPABILITY = 0xab ++ NL80211_ATTR_STA_EXT_CAPABILITY = 0xac ++ NL80211_ATTR_STA_FLAGS2 = 0x43 ++ NL80211_ATTR_STA_FLAGS = 0x11 ++ NL80211_ATTR_STA_INFO = 0x15 ++ NL80211_ATTR_STA_LISTEN_INTERVAL = 0x12 ++ NL80211_ATTR_STA_PLINK_ACTION = 0x19 ++ NL80211_ATTR_STA_PLINK_STATE = 0x74 ++ NL80211_ATTR_STA_SUPPORTED_CHANNELS = 0xbd ++ NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES = 0xbe ++ NL80211_ATTR_STA_SUPPORTED_RATES = 0x13 ++ NL80211_ATTR_STA_SUPPORT_P2P_PS = 0xe4 ++ NL80211_ATTR_STATUS_CODE = 0x48 ++ NL80211_ATTR_STA_TX_POWER = 0x114 ++ NL80211_ATTR_STA_TX_POWER_SETTING = 0x113 ++ NL80211_ATTR_STA_VLAN = 0x14 ++ NL80211_ATTR_STA_WME = 0x81 ++ NL80211_ATTR_SUPPORT_10_MHZ = 0xc1 ++ NL80211_ATTR_SUPPORT_5_MHZ = 0xc0 ++ NL80211_ATTR_SUPPORT_AP_UAPSD = 0x82 ++ NL80211_ATTR_SUPPORTED_COMMANDS = 0x32 ++ NL80211_ATTR_SUPPORTED_IFTYPES = 0x20 ++ NL80211_ATTR_SUPPORT_IBSS_RSN = 0x68 ++ NL80211_ATTR_SUPPORT_MESH_AUTH = 0x73 ++ NL80211_ATTR_SURVEY_INFO = 0x54 ++ NL80211_ATTR_SURVEY_RADIO_STATS = 0xda ++ NL80211_ATTR_TD_BITMAP = 0x141 ++ NL80211_ATTR_TDLS_ACTION = 0x88 ++ NL80211_ATTR_TDLS_DIALOG_TOKEN = 0x89 ++ NL80211_ATTR_TDLS_EXTERNAL_SETUP = 0x8c ++ NL80211_ATTR_TDLS_INITIATOR = 0xcf ++ NL80211_ATTR_TDLS_OPERATION = 0x8a ++ NL80211_ATTR_TDLS_PEER_CAPABILITY = 0xcb ++ NL80211_ATTR_TDLS_SUPPORT = 0x8b ++ NL80211_ATTR_TESTDATA = 0x45 ++ NL80211_ATTR_TID_CONFIG = 0x11d ++ NL80211_ATTR_TIMED_OUT = 0x41 ++ NL80211_ATTR_TIMEOUT = 0x110 ++ NL80211_ATTR_TIMEOUT_REASON = 0xf8 ++ NL80211_ATTR_TSID = 0xd2 ++ NL80211_ATTR_TWT_RESPONDER = 0x116 ++ NL80211_ATTR_TX_FRAME_TYPES = 0x63 ++ NL80211_ATTR_TX_HW_TIMESTAMP = 0x13f ++ NL80211_ATTR_TX_NO_CCK_RATE = 0x87 ++ NL80211_ATTR_TXQ_LIMIT = 0x10a ++ NL80211_ATTR_TXQ_MEMORY_LIMIT = 0x10b ++ NL80211_ATTR_TXQ_QUANTUM = 0x10c ++ NL80211_ATTR_TXQ_STATS = 0x109 ++ NL80211_ATTR_TX_RATES = 0x5a ++ NL80211_ATTR_UNSOL_BCAST_PROBE_RESP = 0x127 ++ NL80211_ATTR_UNSPEC = 0x0 ++ NL80211_ATTR_USE_MFP = 0x42 ++ NL80211_ATTR_USER_PRIO = 0xd3 ++ NL80211_ATTR_USER_REG_HINT_TYPE = 0x9a ++ NL80211_ATTR_USE_RRM = 0xd0 ++ NL80211_ATTR_VENDOR_DATA = 0xc5 ++ NL80211_ATTR_VENDOR_EVENTS = 0xc6 ++ NL80211_ATTR_VENDOR_ID = 0xc3 ++ NL80211_ATTR_VENDOR_SUBCMD = 0xc4 ++ NL80211_ATTR_VHT_CAPABILITY = 0x9d ++ NL80211_ATTR_VHT_CAPABILITY_MASK = 0xb0 ++ NL80211_ATTR_VLAN_ID = 0x11a ++ NL80211_ATTR_WANT_1X_4WAY_HS = 0x101 ++ NL80211_ATTR_WDEV = 0x99 ++ NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX = 0x72 ++ NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX = 0x71 ++ NL80211_ATTR_WIPHY_ANTENNA_RX = 0x6a ++ NL80211_ATTR_WIPHY_ANTENNA_TX = 0x69 ++ NL80211_ATTR_WIPHY_BANDS = 0x16 ++ NL80211_ATTR_WIPHY_CHANNEL_TYPE = 0x27 ++ NL80211_ATTR_WIPHY = 0x1 ++ NL80211_ATTR_WIPHY_COVERAGE_CLASS = 0x59 ++ NL80211_ATTR_WIPHY_DYN_ACK = 0xd1 ++ NL80211_ATTR_WIPHY_EDMG_BW_CONFIG = 0x119 ++ NL80211_ATTR_WIPHY_EDMG_CHANNELS = 0x118 ++ NL80211_ATTR_WIPHY_FRAG_THRESHOLD = 0x3f ++ NL80211_ATTR_WIPHY_FREQ = 0x26 ++ NL80211_ATTR_WIPHY_FREQ_HINT = 0xc9 ++ NL80211_ATTR_WIPHY_FREQ_OFFSET = 0x122 ++ NL80211_ATTR_WIPHY_NAME = 0x2 ++ NL80211_ATTR_WIPHY_RETRY_LONG = 0x3e ++ NL80211_ATTR_WIPHY_RETRY_SHORT = 0x3d ++ NL80211_ATTR_WIPHY_RTS_THRESHOLD = 0x40 ++ NL80211_ATTR_WIPHY_SELF_MANAGED_REG = 0xd8 ++ NL80211_ATTR_WIPHY_TX_POWER_LEVEL = 0x62 ++ NL80211_ATTR_WIPHY_TX_POWER_SETTING = 0x61 ++ NL80211_ATTR_WIPHY_TXQ_PARAMS = 0x25 ++ NL80211_ATTR_WOWLAN_TRIGGERS = 0x75 ++ NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED = 0x76 ++ NL80211_ATTR_WPA_VERSIONS = 0x4b ++ NL80211_AUTHTYPE_AUTOMATIC = 0x8 ++ NL80211_AUTHTYPE_FILS_PK = 0x7 ++ NL80211_AUTHTYPE_FILS_SK = 0x5 ++ NL80211_AUTHTYPE_FILS_SK_PFS = 0x6 ++ NL80211_AUTHTYPE_FT = 0x2 ++ NL80211_AUTHTYPE_MAX = 0x7 ++ NL80211_AUTHTYPE_NETWORK_EAP = 0x3 ++ NL80211_AUTHTYPE_OPEN_SYSTEM = 0x0 ++ NL80211_AUTHTYPE_SAE = 0x4 ++ NL80211_AUTHTYPE_SHARED_KEY = 0x1 ++ NL80211_BAND_2GHZ = 0x0 ++ NL80211_BAND_5GHZ = 0x1 ++ NL80211_BAND_60GHZ = 0x2 ++ NL80211_BAND_6GHZ = 0x3 ++ NL80211_BAND_ATTR_EDMG_BW_CONFIG = 0xb ++ NL80211_BAND_ATTR_EDMG_CHANNELS = 0xa ++ NL80211_BAND_ATTR_FREQS = 0x1 ++ NL80211_BAND_ATTR_HT_AMPDU_DENSITY = 0x6 ++ NL80211_BAND_ATTR_HT_AMPDU_FACTOR = 0x5 ++ NL80211_BAND_ATTR_HT_CAPA = 0x4 ++ NL80211_BAND_ATTR_HT_MCS_SET = 0x3 ++ NL80211_BAND_ATTR_IFTYPE_DATA = 0x9 ++ NL80211_BAND_ATTR_MAX = 0xd ++ NL80211_BAND_ATTR_RATES = 0x2 ++ NL80211_BAND_ATTR_VHT_CAPA = 0x8 ++ NL80211_BAND_ATTR_VHT_MCS_SET = 0x7 ++ NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MAC = 0x8 ++ NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MCS_SET = 0xa ++ NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY = 0x9 ++ NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PPE = 0xb ++ NL80211_BAND_IFTYPE_ATTR_HE_6GHZ_CAPA = 0x6 ++ NL80211_BAND_IFTYPE_ATTR_HE_CAP_MAC = 0x2 ++ NL80211_BAND_IFTYPE_ATTR_HE_CAP_MCS_SET = 0x4 ++ NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY = 0x3 ++ NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE = 0x5 ++ NL80211_BAND_IFTYPE_ATTR_IFTYPES = 0x1 ++ NL80211_BAND_IFTYPE_ATTR_MAX = 0xb ++ NL80211_BAND_IFTYPE_ATTR_VENDOR_ELEMS = 0x7 ++ NL80211_BAND_LC = 0x5 ++ NL80211_BAND_S1GHZ = 0x4 ++ NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE = 0x2 ++ NL80211_BITRATE_ATTR_MAX = 0x2 ++ NL80211_BITRATE_ATTR_RATE = 0x1 ++ NL80211_BSS_BEACON_IES = 0xb ++ NL80211_BSS_BEACON_INTERVAL = 0x4 ++ NL80211_BSS_BEACON_TSF = 0xd ++ NL80211_BSS_BSSID = 0x1 ++ NL80211_BSS_CAPABILITY = 0x5 ++ NL80211_BSS_CHAIN_SIGNAL = 0x13 ++ NL80211_BSS_CHAN_WIDTH_10 = 0x1 ++ NL80211_BSS_CHAN_WIDTH_1 = 0x3 ++ NL80211_BSS_CHAN_WIDTH_20 = 0x0 ++ NL80211_BSS_CHAN_WIDTH_2 = 0x4 ++ NL80211_BSS_CHAN_WIDTH_5 = 0x2 ++ NL80211_BSS_CHAN_WIDTH = 0xc ++ NL80211_BSS_FREQUENCY = 0x2 ++ NL80211_BSS_FREQUENCY_OFFSET = 0x14 ++ NL80211_BSS_INFORMATION_ELEMENTS = 0x6 ++ NL80211_BSS_LAST_SEEN_BOOTTIME = 0xf ++ NL80211_BSS_MAX = 0x16 ++ NL80211_BSS_MLD_ADDR = 0x16 ++ NL80211_BSS_MLO_LINK_ID = 0x15 ++ NL80211_BSS_PAD = 0x10 ++ NL80211_BSS_PARENT_BSSID = 0x12 ++ NL80211_BSS_PARENT_TSF = 0x11 ++ NL80211_BSS_PRESP_DATA = 0xe ++ NL80211_BSS_SEEN_MS_AGO = 0xa ++ NL80211_BSS_SELECT_ATTR_BAND_PREF = 0x2 ++ NL80211_BSS_SELECT_ATTR_MAX = 0x3 ++ NL80211_BSS_SELECT_ATTR_RSSI_ADJUST = 0x3 ++ NL80211_BSS_SELECT_ATTR_RSSI = 0x1 ++ NL80211_BSS_SIGNAL_MBM = 0x7 ++ NL80211_BSS_SIGNAL_UNSPEC = 0x8 ++ NL80211_BSS_STATUS_ASSOCIATED = 0x1 ++ NL80211_BSS_STATUS_AUTHENTICATED = 0x0 ++ NL80211_BSS_STATUS = 0x9 ++ NL80211_BSS_STATUS_IBSS_JOINED = 0x2 ++ NL80211_BSS_TSF = 0x3 ++ NL80211_CHAN_HT20 = 0x1 ++ NL80211_CHAN_HT40MINUS = 0x2 ++ NL80211_CHAN_HT40PLUS = 0x3 ++ NL80211_CHAN_NO_HT = 0x0 ++ NL80211_CHAN_WIDTH_10 = 0x7 ++ NL80211_CHAN_WIDTH_160 = 0x5 ++ NL80211_CHAN_WIDTH_16 = 0xc ++ NL80211_CHAN_WIDTH_1 = 0x8 ++ NL80211_CHAN_WIDTH_20 = 0x1 ++ NL80211_CHAN_WIDTH_20_NOHT = 0x0 ++ NL80211_CHAN_WIDTH_2 = 0x9 ++ NL80211_CHAN_WIDTH_320 = 0xd ++ NL80211_CHAN_WIDTH_40 = 0x2 ++ NL80211_CHAN_WIDTH_4 = 0xa ++ NL80211_CHAN_WIDTH_5 = 0x6 ++ NL80211_CHAN_WIDTH_80 = 0x3 ++ NL80211_CHAN_WIDTH_80P80 = 0x4 ++ NL80211_CHAN_WIDTH_8 = 0xb ++ NL80211_CMD_ABORT_SCAN = 0x72 ++ NL80211_CMD_ACTION = 0x3b ++ NL80211_CMD_ACTION_TX_STATUS = 0x3c ++ NL80211_CMD_ADD_LINK = 0x94 ++ NL80211_CMD_ADD_LINK_STA = 0x96 ++ NL80211_CMD_ADD_NAN_FUNCTION = 0x75 ++ NL80211_CMD_ADD_TX_TS = 0x69 ++ NL80211_CMD_ASSOC_COMEBACK = 0x93 ++ NL80211_CMD_ASSOCIATE = 0x26 ++ NL80211_CMD_AUTHENTICATE = 0x25 ++ NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL = 0x38 ++ NL80211_CMD_CHANGE_NAN_CONFIG = 0x77 ++ NL80211_CMD_CHANNEL_SWITCH = 0x66 ++ NL80211_CMD_CH_SWITCH_NOTIFY = 0x58 ++ NL80211_CMD_CH_SWITCH_STARTED_NOTIFY = 0x6e ++ NL80211_CMD_COLOR_CHANGE_ABORTED = 0x90 ++ NL80211_CMD_COLOR_CHANGE_COMPLETED = 0x91 ++ NL80211_CMD_COLOR_CHANGE_REQUEST = 0x8e ++ NL80211_CMD_COLOR_CHANGE_STARTED = 0x8f ++ NL80211_CMD_CONNECT = 0x2e ++ NL80211_CMD_CONN_FAILED = 0x5b ++ NL80211_CMD_CONTROL_PORT_FRAME = 0x81 ++ NL80211_CMD_CONTROL_PORT_FRAME_TX_STATUS = 0x8b ++ NL80211_CMD_CRIT_PROTOCOL_START = 0x62 ++ NL80211_CMD_CRIT_PROTOCOL_STOP = 0x63 ++ NL80211_CMD_DEAUTHENTICATE = 0x27 ++ NL80211_CMD_DEL_BEACON = 0x10 ++ NL80211_CMD_DEL_INTERFACE = 0x8 ++ NL80211_CMD_DEL_KEY = 0xc ++ NL80211_CMD_DEL_MPATH = 0x18 ++ NL80211_CMD_DEL_NAN_FUNCTION = 0x76 ++ NL80211_CMD_DEL_PMK = 0x7c ++ NL80211_CMD_DEL_PMKSA = 0x35 ++ NL80211_CMD_DEL_STATION = 0x14 ++ NL80211_CMD_DEL_TX_TS = 0x6a ++ NL80211_CMD_DEL_WIPHY = 0x4 ++ NL80211_CMD_DISASSOCIATE = 0x28 ++ NL80211_CMD_DISCONNECT = 0x30 ++ NL80211_CMD_EXTERNAL_AUTH = 0x7f ++ NL80211_CMD_FLUSH_PMKSA = 0x36 ++ NL80211_CMD_FRAME = 0x3b ++ NL80211_CMD_FRAME_TX_STATUS = 0x3c ++ NL80211_CMD_FRAME_WAIT_CANCEL = 0x43 ++ NL80211_CMD_FT_EVENT = 0x61 ++ NL80211_CMD_GET_BEACON = 0xd ++ NL80211_CMD_GET_COALESCE = 0x64 ++ NL80211_CMD_GET_FTM_RESPONDER_STATS = 0x82 ++ NL80211_CMD_GET_INTERFACE = 0x5 ++ NL80211_CMD_GET_KEY = 0x9 ++ NL80211_CMD_GET_MESH_CONFIG = 0x1c ++ NL80211_CMD_GET_MESH_PARAMS = 0x1c ++ NL80211_CMD_GET_MPATH = 0x15 ++ NL80211_CMD_GET_MPP = 0x6b ++ NL80211_CMD_GET_POWER_SAVE = 0x3e ++ NL80211_CMD_GET_PROTOCOL_FEATURES = 0x5f ++ NL80211_CMD_GET_REG = 0x1f ++ NL80211_CMD_GET_SCAN = 0x20 ++ NL80211_CMD_GET_STATION = 0x11 ++ NL80211_CMD_GET_SURVEY = 0x32 ++ NL80211_CMD_GET_WIPHY = 0x1 ++ NL80211_CMD_GET_WOWLAN = 0x49 ++ NL80211_CMD_JOIN_IBSS = 0x2b ++ NL80211_CMD_JOIN_MESH = 0x44 ++ NL80211_CMD_JOIN_OCB = 0x6c ++ NL80211_CMD_LEAVE_IBSS = 0x2c ++ NL80211_CMD_LEAVE_MESH = 0x45 ++ NL80211_CMD_LEAVE_OCB = 0x6d ++ NL80211_CMD_MAX = 0x9a ++ NL80211_CMD_MICHAEL_MIC_FAILURE = 0x29 ++ NL80211_CMD_MODIFY_LINK_STA = 0x97 ++ NL80211_CMD_NAN_MATCH = 0x78 ++ NL80211_CMD_NEW_BEACON = 0xf ++ NL80211_CMD_NEW_INTERFACE = 0x7 ++ NL80211_CMD_NEW_KEY = 0xb ++ NL80211_CMD_NEW_MPATH = 0x17 ++ NL80211_CMD_NEW_PEER_CANDIDATE = 0x48 ++ NL80211_CMD_NEW_SCAN_RESULTS = 0x22 ++ NL80211_CMD_NEW_STATION = 0x13 ++ NL80211_CMD_NEW_SURVEY_RESULTS = 0x33 ++ NL80211_CMD_NEW_WIPHY = 0x3 ++ NL80211_CMD_NOTIFY_CQM = 0x40 ++ NL80211_CMD_NOTIFY_RADAR = 0x86 ++ NL80211_CMD_OBSS_COLOR_COLLISION = 0x8d ++ NL80211_CMD_PEER_MEASUREMENT_COMPLETE = 0x85 ++ NL80211_CMD_PEER_MEASUREMENT_RESULT = 0x84 ++ NL80211_CMD_PEER_MEASUREMENT_START = 0x83 ++ NL80211_CMD_PMKSA_CANDIDATE = 0x50 ++ NL80211_CMD_PORT_AUTHORIZED = 0x7d ++ NL80211_CMD_PROBE_CLIENT = 0x54 ++ NL80211_CMD_PROBE_MESH_LINK = 0x88 ++ NL80211_CMD_RADAR_DETECT = 0x5e ++ NL80211_CMD_REG_BEACON_HINT = 0x2a ++ NL80211_CMD_REG_CHANGE = 0x24 ++ NL80211_CMD_REGISTER_ACTION = 0x3a ++ NL80211_CMD_REGISTER_BEACONS = 0x55 ++ NL80211_CMD_REGISTER_FRAME = 0x3a ++ NL80211_CMD_RELOAD_REGDB = 0x7e ++ NL80211_CMD_REMAIN_ON_CHANNEL = 0x37 ++ NL80211_CMD_REMOVE_LINK = 0x95 ++ NL80211_CMD_REMOVE_LINK_STA = 0x98 ++ NL80211_CMD_REQ_SET_REG = 0x1b ++ NL80211_CMD_ROAM = 0x2f ++ NL80211_CMD_SCAN_ABORTED = 0x23 ++ NL80211_CMD_SCHED_SCAN_RESULTS = 0x4d ++ NL80211_CMD_SCHED_SCAN_STOPPED = 0x4e ++ NL80211_CMD_SET_BEACON = 0xe ++ NL80211_CMD_SET_BSS = 0x19 ++ NL80211_CMD_SET_CHANNEL = 0x41 ++ NL80211_CMD_SET_COALESCE = 0x65 ++ NL80211_CMD_SET_CQM = 0x3f ++ NL80211_CMD_SET_FILS_AAD = 0x92 ++ NL80211_CMD_SET_INTERFACE = 0x6 ++ NL80211_CMD_SET_KEY = 0xa ++ NL80211_CMD_SET_MAC_ACL = 0x5d ++ NL80211_CMD_SET_MCAST_RATE = 0x5c ++ NL80211_CMD_SET_MESH_CONFIG = 0x1d ++ NL80211_CMD_SET_MESH_PARAMS = 0x1d ++ NL80211_CMD_SET_MGMT_EXTRA_IE = 0x1e ++ NL80211_CMD_SET_MPATH = 0x16 ++ NL80211_CMD_SET_MULTICAST_TO_UNICAST = 0x79 ++ NL80211_CMD_SET_NOACK_MAP = 0x57 ++ NL80211_CMD_SET_PMK = 0x7b ++ NL80211_CMD_SET_PMKSA = 0x34 ++ NL80211_CMD_SET_POWER_SAVE = 0x3d ++ NL80211_CMD_SET_QOS_MAP = 0x68 ++ NL80211_CMD_SET_REG = 0x1a ++ NL80211_CMD_SET_REKEY_OFFLOAD = 0x4f ++ ++ NL80211_CMD_SET_STATION = 0x12 ++ NL80211_CMD_SET_TID_CONFIG = 0x89 ++ NL80211_CMD_SET_TX_BITRATE_MASK = 0x39 ++ NL80211_CMD_SET_WDS_PEER = 0x42 ++ NL80211_CMD_SET_WIPHY = 0x2 ++ NL80211_CMD_SET_WIPHY_NETNS = 0x31 ++ NL80211_CMD_SET_WOWLAN = 0x4a ++ NL80211_CMD_STA_OPMODE_CHANGED = 0x80 ++ NL80211_CMD_START_AP = 0xf ++ NL80211_CMD_START_NAN = 0x73 ++ NL80211_CMD_START_P2P_DEVICE = 0x59 ++ NL80211_CMD_START_SCHED_SCAN = 0x4b ++ NL80211_CMD_STOP_AP = 0x10 ++ NL80211_CMD_STOP_NAN = 0x74 ++ NL80211_CMD_STOP_P2P_DEVICE = 0x5a ++ NL80211_CMD_STOP_SCHED_SCAN = 0x4c ++ NL80211_CMD_TDLS_CANCEL_CHANNEL_SWITCH = 0x70 ++ NL80211_CMD_TDLS_CHANNEL_SWITCH = 0x6f ++ NL80211_CMD_TDLS_MGMT = 0x52 ++ NL80211_CMD_TDLS_OPER = 0x51 ++ NL80211_CMD_TESTMODE = 0x2d ++ NL80211_CMD_TRIGGER_SCAN = 0x21 ++ NL80211_CMD_UNEXPECTED_4ADDR_FRAME = 0x56 ++ NL80211_CMD_UNEXPECTED_FRAME = 0x53 ++ NL80211_CMD_UNPROT_BEACON = 0x8a ++ NL80211_CMD_UNPROT_DEAUTHENTICATE = 0x46 ++ NL80211_CMD_UNPROT_DISASSOCIATE = 0x47 ++ NL80211_CMD_UNSPEC = 0x0 ++ NL80211_CMD_UPDATE_CONNECT_PARAMS = 0x7a ++ NL80211_CMD_UPDATE_FT_IES = 0x60 ++ NL80211_CMD_UPDATE_OWE_INFO = 0x87 ++ NL80211_CMD_VENDOR = 0x67 ++ NL80211_CMD_WIPHY_REG_CHANGE = 0x71 ++ NL80211_COALESCE_CONDITION_MATCH = 0x0 ++ NL80211_COALESCE_CONDITION_NO_MATCH = 0x1 ++ NL80211_CONN_FAIL_BLOCKED_CLIENT = 0x1 ++ NL80211_CONN_FAIL_MAX_CLIENTS = 0x0 ++ NL80211_CQM_RSSI_BEACON_LOSS_EVENT = 0x2 ++ NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH = 0x1 ++ NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW = 0x0 ++ NL80211_CQM_TXE_MAX_INTVL = 0x708 ++ NL80211_CRIT_PROTO_APIPA = 0x3 ++ NL80211_CRIT_PROTO_DHCP = 0x1 ++ NL80211_CRIT_PROTO_EAPOL = 0x2 ++ NL80211_CRIT_PROTO_MAX_DURATION = 0x1388 ++ NL80211_CRIT_PROTO_UNSPEC = 0x0 ++ NL80211_DFS_AVAILABLE = 0x2 ++ NL80211_DFS_ETSI = 0x2 ++ NL80211_DFS_FCC = 0x1 ++ NL80211_DFS_JP = 0x3 ++ NL80211_DFS_UNAVAILABLE = 0x1 ++ NL80211_DFS_UNSET = 0x0 ++ NL80211_DFS_USABLE = 0x0 ++ NL80211_EDMG_BW_CONFIG_MAX = 0xf ++ NL80211_EDMG_BW_CONFIG_MIN = 0x4 ++ NL80211_EDMG_CHANNELS_MAX = 0x3c ++ NL80211_EDMG_CHANNELS_MIN = 0x1 ++ NL80211_EHT_MAX_CAPABILITY_LEN = 0x33 ++ NL80211_EHT_MIN_CAPABILITY_LEN = 0xd ++ NL80211_EXTERNAL_AUTH_ABORT = 0x1 ++ NL80211_EXTERNAL_AUTH_START = 0x0 ++ NL80211_EXT_FEATURE_4WAY_HANDSHAKE_AP_PSK = 0x32 ++ NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X = 0x10 ++ NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK = 0xf ++ NL80211_EXT_FEATURE_ACCEPT_BCAST_PROBE_RESP = 0x12 ++ NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT = 0x1b ++ NL80211_EXT_FEATURE_AIRTIME_FAIRNESS = 0x21 ++ NL80211_EXT_FEATURE_AP_PMKSA_CACHING = 0x22 ++ NL80211_EXT_FEATURE_AQL = 0x28 ++ NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT = 0x2e ++ NL80211_EXT_FEATURE_BEACON_PROTECTION = 0x29 ++ ++ NL80211_EXT_FEATURE_BEACON_RATE_HT = 0x7 ++ NL80211_EXT_FEATURE_BEACON_RATE_LEGACY = 0x6 ++ NL80211_EXT_FEATURE_BEACON_RATE_VHT = 0x8 ++ NL80211_EXT_FEATURE_BSS_COLOR = 0x3a ++ NL80211_EXT_FEATURE_BSS_PARENT_TSF = 0x4 ++ NL80211_EXT_FEATURE_CAN_REPLACE_PTK0 = 0x1f ++ NL80211_EXT_FEATURE_CONTROL_PORT_NO_PREAUTH = 0x2a ++ NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211 = 0x1a ++ NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211_TX_STATUS = 0x30 ++ NL80211_EXT_FEATURE_CQM_RSSI_LIST = 0xd ++ NL80211_EXT_FEATURE_DATA_ACK_SIGNAL_SUPPORT = 0x1b ++ NL80211_EXT_FEATURE_DEL_IBSS_STA = 0x2c ++ NL80211_EXT_FEATURE_DFS_OFFLOAD = 0x19 ++ NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER = 0x20 ++ NL80211_EXT_FEATURE_EXT_KEY_ID = 0x24 ++ NL80211_EXT_FEATURE_FILS_CRYPTO_OFFLOAD = 0x3b ++ NL80211_EXT_FEATURE_FILS_DISCOVERY = 0x34 ++ NL80211_EXT_FEATURE_FILS_MAX_CHANNEL_TIME = 0x11 ++ NL80211_EXT_FEATURE_FILS_SK_OFFLOAD = 0xe ++ NL80211_EXT_FEATURE_FILS_STA = 0x9 ++ NL80211_EXT_FEATURE_HIGH_ACCURACY_SCAN = 0x18 ++ NL80211_EXT_FEATURE_LOW_POWER_SCAN = 0x17 ++ NL80211_EXT_FEATURE_LOW_SPAN_SCAN = 0x16 ++ NL80211_EXT_FEATURE_MFP_OPTIONAL = 0x15 ++ NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA = 0xa ++ NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA_CONNECTED = 0xb ++ NL80211_EXT_FEATURE_MULTICAST_REGISTRATIONS = 0x2d ++ NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER = 0x2 ++ NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION = 0x14 ++ NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE = 0x13 ++ NL80211_EXT_FEATURE_OPERATING_CHANNEL_VALIDATION = 0x31 ++ NL80211_EXT_FEATURE_POWERED_ADDR_CHANGE = 0x3d ++ NL80211_EXT_FEATURE_PROTECTED_TWT = 0x2b ++ ++ NL80211_EXT_FEATURE_RADAR_BACKGROUND = 0x3c ++ NL80211_EXT_FEATURE_RRM = 0x1 ++ NL80211_EXT_FEATURE_SAE_OFFLOAD_AP = 0x33 ++ NL80211_EXT_FEATURE_SAE_OFFLOAD = 0x26 ++ NL80211_EXT_FEATURE_SCAN_FREQ_KHZ = 0x2f ++ NL80211_EXT_FEATURE_SCAN_MIN_PREQ_CONTENT = 0x1e ++ NL80211_EXT_FEATURE_SCAN_RANDOM_SN = 0x1d ++ NL80211_EXT_FEATURE_SCAN_START_TIME = 0x3 ++ NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD = 0x23 ++ NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI = 0xc ++ ++ NL80211_EXT_FEATURE_SET_SCAN_DWELL = 0x5 ++ NL80211_EXT_FEATURE_STA_TX_PWR = 0x25 ++ NL80211_EXT_FEATURE_TXQS = 0x1c ++ NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP = 0x35 ++ NL80211_EXT_FEATURE_VHT_IBSS = 0x0 ++ NL80211_EXT_FEATURE_VLAN_OFFLOAD = 0x27 ++ NL80211_FEATURE_ACKTO_ESTIMATION = 0x800000 ++ NL80211_FEATURE_ACTIVE_MONITOR = 0x20000 ++ NL80211_FEATURE_ADVERTISE_CHAN_LIMITS = 0x4000 ++ NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE = 0x40000 ++ NL80211_FEATURE_AP_SCAN = 0x100 ++ NL80211_FEATURE_CELL_BASE_REG_HINTS = 0x8 ++ NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES = 0x80000 ++ NL80211_FEATURE_DYNAMIC_SMPS = 0x2000000 ++ NL80211_FEATURE_FULL_AP_CLIENT_STATE = 0x8000 ++ NL80211_FEATURE_HT_IBSS = 0x2 ++ NL80211_FEATURE_INACTIVITY_TIMER = 0x4 ++ NL80211_FEATURE_LOW_PRIORITY_SCAN = 0x40 ++ NL80211_FEATURE_MAC_ON_CREATE = 0x8000000 ++ NL80211_FEATURE_ND_RANDOM_MAC_ADDR = 0x80000000 ++ NL80211_FEATURE_NEED_OBSS_SCAN = 0x400 ++ NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL = 0x10 ++ NL80211_FEATURE_P2P_GO_CTWIN = 0x800 ++ NL80211_FEATURE_P2P_GO_OPPPS = 0x1000 ++ NL80211_FEATURE_QUIET = 0x200000 ++ NL80211_FEATURE_SAE = 0x20 ++ NL80211_FEATURE_SCAN_FLUSH = 0x80 ++ NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR = 0x20000000 ++ NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR = 0x40000000 ++ NL80211_FEATURE_SK_TX_STATUS = 0x1 ++ NL80211_FEATURE_STATIC_SMPS = 0x1000000 ++ NL80211_FEATURE_SUPPORTS_WMM_ADMISSION = 0x4000000 ++ NL80211_FEATURE_TDLS_CHANNEL_SWITCH = 0x10000000 ++ NL80211_FEATURE_TX_POWER_INSERTION = 0x400000 ++ NL80211_FEATURE_USERSPACE_MPM = 0x10000 ++ NL80211_FEATURE_VIF_TXPOWER = 0x200 ++ NL80211_FEATURE_WFA_TPC_IE_IN_PROBES = 0x100000 ++ NL80211_FILS_DISCOVERY_ATTR_INT_MAX = 0x2 ++ NL80211_FILS_DISCOVERY_ATTR_INT_MIN = 0x1 ++ NL80211_FILS_DISCOVERY_ATTR_MAX = 0x3 ++ NL80211_FILS_DISCOVERY_ATTR_TMPL = 0x3 ++ NL80211_FILS_DISCOVERY_TMPL_MIN_LEN = 0x2a ++ NL80211_FREQUENCY_ATTR_16MHZ = 0x19 ++ NL80211_FREQUENCY_ATTR_1MHZ = 0x15 ++ NL80211_FREQUENCY_ATTR_2MHZ = 0x16 ++ NL80211_FREQUENCY_ATTR_4MHZ = 0x17 ++ NL80211_FREQUENCY_ATTR_8MHZ = 0x18 ++ NL80211_FREQUENCY_ATTR_DFS_CAC_TIME = 0xd ++ NL80211_FREQUENCY_ATTR_DFS_STATE = 0x7 ++ NL80211_FREQUENCY_ATTR_DFS_TIME = 0x8 ++ NL80211_FREQUENCY_ATTR_DISABLED = 0x2 ++ NL80211_FREQUENCY_ATTR_FREQ = 0x1 ++ NL80211_FREQUENCY_ATTR_GO_CONCURRENT = 0xf ++ NL80211_FREQUENCY_ATTR_INDOOR_ONLY = 0xe ++ NL80211_FREQUENCY_ATTR_IR_CONCURRENT = 0xf ++ NL80211_FREQUENCY_ATTR_MAX = 0x1b ++ NL80211_FREQUENCY_ATTR_MAX_TX_POWER = 0x6 ++ NL80211_FREQUENCY_ATTR_NO_10MHZ = 0x11 ++ NL80211_FREQUENCY_ATTR_NO_160MHZ = 0xc ++ NL80211_FREQUENCY_ATTR_NO_20MHZ = 0x10 ++ NL80211_FREQUENCY_ATTR_NO_320MHZ = 0x1a ++ NL80211_FREQUENCY_ATTR_NO_80MHZ = 0xb ++ NL80211_FREQUENCY_ATTR_NO_EHT = 0x1b ++ NL80211_FREQUENCY_ATTR_NO_HE = 0x13 ++ NL80211_FREQUENCY_ATTR_NO_HT40_MINUS = 0x9 ++ NL80211_FREQUENCY_ATTR_NO_HT40_PLUS = 0xa ++ NL80211_FREQUENCY_ATTR_NO_IBSS = 0x3 ++ NL80211_FREQUENCY_ATTR_NO_IR = 0x3 ++ NL80211_FREQUENCY_ATTR_OFFSET = 0x14 ++ NL80211_FREQUENCY_ATTR_PASSIVE_SCAN = 0x3 ++ NL80211_FREQUENCY_ATTR_RADAR = 0x5 ++ NL80211_FREQUENCY_ATTR_WMM = 0x12 ++ NL80211_FTM_RESP_ATTR_CIVICLOC = 0x3 ++ NL80211_FTM_RESP_ATTR_ENABLED = 0x1 ++ NL80211_FTM_RESP_ATTR_LCI = 0x2 ++ NL80211_FTM_RESP_ATTR_MAX = 0x3 ++ NL80211_FTM_STATS_ASAP_NUM = 0x4 ++ NL80211_FTM_STATS_FAILED_NUM = 0x3 ++ NL80211_FTM_STATS_MAX = 0xa ++ NL80211_FTM_STATS_NON_ASAP_NUM = 0x5 ++ NL80211_FTM_STATS_OUT_OF_WINDOW_TRIGGERS_NUM = 0x9 ++ NL80211_FTM_STATS_PAD = 0xa ++ NL80211_FTM_STATS_PARTIAL_NUM = 0x2 ++ NL80211_FTM_STATS_RESCHEDULE_REQUESTS_NUM = 0x8 ++ NL80211_FTM_STATS_SUCCESS_NUM = 0x1 ++ NL80211_FTM_STATS_TOTAL_DURATION_MSEC = 0x6 ++ NL80211_FTM_STATS_UNKNOWN_TRIGGERS_NUM = 0x7 ++ NL80211_GENL_NAME = "nl80211" ++ NL80211_HE_BSS_COLOR_ATTR_COLOR = 0x1 ++ NL80211_HE_BSS_COLOR_ATTR_DISABLED = 0x2 ++ NL80211_HE_BSS_COLOR_ATTR_MAX = 0x3 ++ NL80211_HE_BSS_COLOR_ATTR_PARTIAL = 0x3 ++ NL80211_HE_MAX_CAPABILITY_LEN = 0x36 ++ NL80211_HE_MIN_CAPABILITY_LEN = 0x10 ++ NL80211_HE_NSS_MAX = 0x8 ++ NL80211_HE_OBSS_PD_ATTR_BSS_COLOR_BITMAP = 0x4 ++ NL80211_HE_OBSS_PD_ATTR_MAX = 0x6 ++ NL80211_HE_OBSS_PD_ATTR_MAX_OFFSET = 0x2 ++ NL80211_HE_OBSS_PD_ATTR_MIN_OFFSET = 0x1 ++ NL80211_HE_OBSS_PD_ATTR_NON_SRG_MAX_OFFSET = 0x3 ++ NL80211_HE_OBSS_PD_ATTR_PARTIAL_BSSID_BITMAP = 0x5 ++ NL80211_HE_OBSS_PD_ATTR_SR_CTRL = 0x6 ++ NL80211_HIDDEN_SSID_NOT_IN_USE = 0x0 ++ NL80211_HIDDEN_SSID_ZERO_CONTENTS = 0x2 ++ NL80211_HIDDEN_SSID_ZERO_LEN = 0x1 ++ NL80211_HT_CAPABILITY_LEN = 0x1a ++ NL80211_IFACE_COMB_BI_MIN_GCD = 0x7 ++ NL80211_IFACE_COMB_LIMITS = 0x1 ++ NL80211_IFACE_COMB_MAXNUM = 0x2 ++ NL80211_IFACE_COMB_NUM_CHANNELS = 0x4 ++ NL80211_IFACE_COMB_RADAR_DETECT_REGIONS = 0x6 ++ NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS = 0x5 ++ NL80211_IFACE_COMB_STA_AP_BI_MATCH = 0x3 ++ NL80211_IFACE_COMB_UNSPEC = 0x0 ++ NL80211_IFACE_LIMIT_MAX = 0x1 ++ NL80211_IFACE_LIMIT_TYPES = 0x2 ++ NL80211_IFACE_LIMIT_UNSPEC = 0x0 ++ NL80211_IFTYPE_ADHOC = 0x1 ++ NL80211_IFTYPE_AKM_ATTR_IFTYPES = 0x1 ++ NL80211_IFTYPE_AKM_ATTR_MAX = 0x2 ++ NL80211_IFTYPE_AKM_ATTR_SUITES = 0x2 ++ NL80211_IFTYPE_AP = 0x3 ++ NL80211_IFTYPE_AP_VLAN = 0x4 ++ NL80211_IFTYPE_MAX = 0xc ++ NL80211_IFTYPE_MESH_POINT = 0x7 ++ NL80211_IFTYPE_MONITOR = 0x6 ++ NL80211_IFTYPE_NAN = 0xc ++ NL80211_IFTYPE_OCB = 0xb ++ NL80211_IFTYPE_P2P_CLIENT = 0x8 ++ NL80211_IFTYPE_P2P_DEVICE = 0xa ++ NL80211_IFTYPE_P2P_GO = 0x9 ++ NL80211_IFTYPE_STATION = 0x2 ++ NL80211_IFTYPE_UNSPECIFIED = 0x0 ++ NL80211_IFTYPE_WDS = 0x5 ++ NL80211_KCK_EXT_LEN = 0x18 ++ NL80211_KCK_LEN = 0x10 ++ NL80211_KEK_EXT_LEN = 0x20 ++ NL80211_KEK_LEN = 0x10 ++ NL80211_KEY_CIPHER = 0x3 ++ NL80211_KEY_DATA = 0x1 ++ NL80211_KEY_DEFAULT_BEACON = 0xa ++ NL80211_KEY_DEFAULT = 0x5 ++ NL80211_KEY_DEFAULT_MGMT = 0x6 ++ NL80211_KEY_DEFAULT_TYPE_MULTICAST = 0x2 ++ NL80211_KEY_DEFAULT_TYPES = 0x8 ++ NL80211_KEY_DEFAULT_TYPE_UNICAST = 0x1 ++ NL80211_KEY_IDX = 0x2 ++ NL80211_KEY_MAX = 0xa ++ NL80211_KEY_MODE = 0x9 ++ NL80211_KEY_NO_TX = 0x1 ++ NL80211_KEY_RX_TX = 0x0 ++ NL80211_KEY_SEQ = 0x4 ++ NL80211_KEY_SET_TX = 0x2 ++ NL80211_KEY_TYPE = 0x7 ++ NL80211_KEYTYPE_GROUP = 0x0 ++ NL80211_KEYTYPE_PAIRWISE = 0x1 ++ NL80211_KEYTYPE_PEERKEY = 0x2 ++ NL80211_MAX_NR_AKM_SUITES = 0x2 ++ NL80211_MAX_NR_CIPHER_SUITES = 0x5 ++ NL80211_MAX_SUPP_HT_RATES = 0x4d ++ NL80211_MAX_SUPP_RATES = 0x20 ++ NL80211_MAX_SUPP_REG_RULES = 0x80 ++ NL80211_MBSSID_CONFIG_ATTR_EMA = 0x5 ++ NL80211_MBSSID_CONFIG_ATTR_INDEX = 0x3 ++ NL80211_MBSSID_CONFIG_ATTR_MAX = 0x5 ++ NL80211_MBSSID_CONFIG_ATTR_MAX_EMA_PROFILE_PERIODICITY = 0x2 ++ NL80211_MBSSID_CONFIG_ATTR_MAX_INTERFACES = 0x1 ++ NL80211_MBSSID_CONFIG_ATTR_TX_IFINDEX = 0x4 ++ NL80211_MESHCONF_ATTR_MAX = 0x1f ++ NL80211_MESHCONF_AUTO_OPEN_PLINKS = 0x7 ++ NL80211_MESHCONF_AWAKE_WINDOW = 0x1b ++ NL80211_MESHCONF_CONFIRM_TIMEOUT = 0x2 ++ NL80211_MESHCONF_CONNECTED_TO_AS = 0x1f ++ NL80211_MESHCONF_CONNECTED_TO_GATE = 0x1d ++ NL80211_MESHCONF_ELEMENT_TTL = 0xf ++ NL80211_MESHCONF_FORWARDING = 0x13 ++ NL80211_MESHCONF_GATE_ANNOUNCEMENTS = 0x11 ++ NL80211_MESHCONF_HOLDING_TIMEOUT = 0x3 ++ NL80211_MESHCONF_HT_OPMODE = 0x16 ++ NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT = 0xb ++ NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL = 0x19 ++ NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES = 0x8 ++ NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME = 0xd ++ NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT = 0x17 ++ NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL = 0x12 ++ NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL = 0xc ++ NL80211_MESHCONF_HWMP_RANN_INTERVAL = 0x10 ++ NL80211_MESHCONF_HWMP_ROOT_INTERVAL = 0x18 ++ NL80211_MESHCONF_HWMP_ROOTMODE = 0xe ++ NL80211_MESHCONF_MAX_PEER_LINKS = 0x4 ++ NL80211_MESHCONF_MAX_RETRIES = 0x5 ++ NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT = 0xa ++ NL80211_MESHCONF_NOLEARN = 0x1e ++ NL80211_MESHCONF_PATH_REFRESH_TIME = 0x9 ++ NL80211_MESHCONF_PLINK_TIMEOUT = 0x1c ++ NL80211_MESHCONF_POWER_MODE = 0x1a ++ NL80211_MESHCONF_RETRY_TIMEOUT = 0x1 ++ NL80211_MESHCONF_RSSI_THRESHOLD = 0x14 ++ NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR = 0x15 ++ NL80211_MESHCONF_TTL = 0x6 ++ NL80211_MESH_POWER_ACTIVE = 0x1 ++ NL80211_MESH_POWER_DEEP_SLEEP = 0x3 ++ NL80211_MESH_POWER_LIGHT_SLEEP = 0x2 ++ NL80211_MESH_POWER_MAX = 0x3 ++ NL80211_MESH_POWER_UNKNOWN = 0x0 ++ NL80211_MESH_SETUP_ATTR_MAX = 0x8 ++ NL80211_MESH_SETUP_AUTH_PROTOCOL = 0x8 ++ NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC = 0x2 ++ NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL = 0x1 ++ NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC = 0x6 ++ NL80211_MESH_SETUP_IE = 0x3 ++ NL80211_MESH_SETUP_USERSPACE_AMPE = 0x5 ++ NL80211_MESH_SETUP_USERSPACE_AUTH = 0x4 ++ NL80211_MESH_SETUP_USERSPACE_MPM = 0x7 ++ NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE = 0x3 ++ NL80211_MFP_NO = 0x0 ++ NL80211_MFP_OPTIONAL = 0x2 ++ NL80211_MFP_REQUIRED = 0x1 ++ NL80211_MIN_REMAIN_ON_CHANNEL_TIME = 0xa ++ NL80211_MNTR_FLAG_ACTIVE = 0x6 ++ NL80211_MNTR_FLAG_CONTROL = 0x3 ++ NL80211_MNTR_FLAG_COOK_FRAMES = 0x5 ++ NL80211_MNTR_FLAG_FCSFAIL = 0x1 ++ NL80211_MNTR_FLAG_MAX = 0x6 ++ NL80211_MNTR_FLAG_OTHER_BSS = 0x4 ++ NL80211_MNTR_FLAG_PLCPFAIL = 0x2 ++ NL80211_MPATH_FLAG_ACTIVE = 0x1 ++ NL80211_MPATH_FLAG_FIXED = 0x8 ++ NL80211_MPATH_FLAG_RESOLVED = 0x10 ++ NL80211_MPATH_FLAG_RESOLVING = 0x2 ++ NL80211_MPATH_FLAG_SN_VALID = 0x4 ++ NL80211_MPATH_INFO_DISCOVERY_RETRIES = 0x7 ++ NL80211_MPATH_INFO_DISCOVERY_TIMEOUT = 0x6 ++ NL80211_MPATH_INFO_EXPTIME = 0x4 ++ NL80211_MPATH_INFO_FLAGS = 0x5 ++ NL80211_MPATH_INFO_FRAME_QLEN = 0x1 ++ NL80211_MPATH_INFO_HOP_COUNT = 0x8 ++ NL80211_MPATH_INFO_MAX = 0x9 ++ NL80211_MPATH_INFO_METRIC = 0x3 ++ NL80211_MPATH_INFO_PATH_CHANGE = 0x9 ++ NL80211_MPATH_INFO_SN = 0x2 ++ NL80211_MULTICAST_GROUP_CONFIG = "config" ++ NL80211_MULTICAST_GROUP_MLME = "mlme" ++ NL80211_MULTICAST_GROUP_NAN = "nan" ++ NL80211_MULTICAST_GROUP_REG = "regulatory" ++ NL80211_MULTICAST_GROUP_SCAN = "scan" ++ NL80211_MULTICAST_GROUP_TESTMODE = "testmode" ++ NL80211_MULTICAST_GROUP_VENDOR = "vendor" ++ NL80211_NAN_FUNC_ATTR_MAX = 0x10 ++ NL80211_NAN_FUNC_CLOSE_RANGE = 0x9 ++ NL80211_NAN_FUNC_FOLLOW_UP = 0x2 ++ NL80211_NAN_FUNC_FOLLOW_UP_DEST = 0x8 ++ NL80211_NAN_FUNC_FOLLOW_UP_ID = 0x6 ++ NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID = 0x7 ++ NL80211_NAN_FUNC_INSTANCE_ID = 0xf ++ NL80211_NAN_FUNC_MAX_TYPE = 0x2 ++ NL80211_NAN_FUNC_PUBLISH_BCAST = 0x4 ++ NL80211_NAN_FUNC_PUBLISH = 0x0 ++ NL80211_NAN_FUNC_PUBLISH_TYPE = 0x3 ++ NL80211_NAN_FUNC_RX_MATCH_FILTER = 0xd ++ NL80211_NAN_FUNC_SERVICE_ID = 0x2 ++ NL80211_NAN_FUNC_SERVICE_ID_LEN = 0x6 ++ NL80211_NAN_FUNC_SERVICE_INFO = 0xb ++ NL80211_NAN_FUNC_SERVICE_SPEC_INFO_MAX_LEN = 0xff ++ NL80211_NAN_FUNC_SRF = 0xc ++ NL80211_NAN_FUNC_SRF_MAX_LEN = 0xff ++ NL80211_NAN_FUNC_SUBSCRIBE_ACTIVE = 0x5 ++ NL80211_NAN_FUNC_SUBSCRIBE = 0x1 ++ NL80211_NAN_FUNC_TERM_REASON = 0x10 ++ NL80211_NAN_FUNC_TERM_REASON_ERROR = 0x2 ++ NL80211_NAN_FUNC_TERM_REASON_TTL_EXPIRED = 0x1 ++ NL80211_NAN_FUNC_TERM_REASON_USER_REQUEST = 0x0 ++ NL80211_NAN_FUNC_TTL = 0xa ++ NL80211_NAN_FUNC_TX_MATCH_FILTER = 0xe ++ NL80211_NAN_FUNC_TYPE = 0x1 ++ NL80211_NAN_MATCH_ATTR_MAX = 0x2 ++ NL80211_NAN_MATCH_FUNC_LOCAL = 0x1 ++ NL80211_NAN_MATCH_FUNC_PEER = 0x2 ++ NL80211_NAN_SOLICITED_PUBLISH = 0x1 ++ NL80211_NAN_SRF_ATTR_MAX = 0x4 ++ NL80211_NAN_SRF_BF = 0x2 ++ NL80211_NAN_SRF_BF_IDX = 0x3 ++ NL80211_NAN_SRF_INCLUDE = 0x1 ++ NL80211_NAN_SRF_MAC_ADDRS = 0x4 ++ NL80211_NAN_UNSOLICITED_PUBLISH = 0x2 ++ NL80211_NUM_ACS = 0x4 ++ NL80211_P2P_PS_SUPPORTED = 0x1 ++ NL80211_P2P_PS_UNSUPPORTED = 0x0 ++ NL80211_PKTPAT_MASK = 0x1 ++ NL80211_PKTPAT_OFFSET = 0x3 ++ NL80211_PKTPAT_PATTERN = 0x2 ++ NL80211_PLINK_ACTION_BLOCK = 0x2 ++ NL80211_PLINK_ACTION_NO_ACTION = 0x0 ++ NL80211_PLINK_ACTION_OPEN = 0x1 ++ NL80211_PLINK_BLOCKED = 0x6 ++ NL80211_PLINK_CNF_RCVD = 0x3 ++ NL80211_PLINK_ESTAB = 0x4 ++ NL80211_PLINK_HOLDING = 0x5 ++ NL80211_PLINK_LISTEN = 0x0 ++ NL80211_PLINK_OPN_RCVD = 0x2 ++ NL80211_PLINK_OPN_SNT = 0x1 ++ NL80211_PMKSA_CANDIDATE_BSSID = 0x2 ++ NL80211_PMKSA_CANDIDATE_INDEX = 0x1 ++ NL80211_PMKSA_CANDIDATE_PREAUTH = 0x3 ++ NL80211_PMSR_ATTR_MAX = 0x5 ++ NL80211_PMSR_ATTR_MAX_PEERS = 0x1 ++ NL80211_PMSR_ATTR_PEERS = 0x5 ++ NL80211_PMSR_ATTR_RANDOMIZE_MAC_ADDR = 0x3 ++ NL80211_PMSR_ATTR_REPORT_AP_TSF = 0x2 ++ NL80211_PMSR_ATTR_TYPE_CAPA = 0x4 ++ NL80211_PMSR_FTM_CAPA_ATTR_ASAP = 0x1 ++ NL80211_PMSR_FTM_CAPA_ATTR_BANDWIDTHS = 0x6 ++ NL80211_PMSR_FTM_CAPA_ATTR_MAX_BURSTS_EXPONENT = 0x7 ++ NL80211_PMSR_FTM_CAPA_ATTR_MAX = 0xa ++ NL80211_PMSR_FTM_CAPA_ATTR_MAX_FTMS_PER_BURST = 0x8 ++ NL80211_PMSR_FTM_CAPA_ATTR_NON_ASAP = 0x2 ++ NL80211_PMSR_FTM_CAPA_ATTR_NON_TRIGGER_BASED = 0xa ++ NL80211_PMSR_FTM_CAPA_ATTR_PREAMBLES = 0x5 ++ NL80211_PMSR_FTM_CAPA_ATTR_REQ_CIVICLOC = 0x4 ++ NL80211_PMSR_FTM_CAPA_ATTR_REQ_LCI = 0x3 ++ NL80211_PMSR_FTM_CAPA_ATTR_TRIGGER_BASED = 0x9 ++ NL80211_PMSR_FTM_FAILURE_BAD_CHANGED_PARAMS = 0x7 ++ NL80211_PMSR_FTM_FAILURE_INVALID_TIMESTAMP = 0x5 ++ NL80211_PMSR_FTM_FAILURE_NO_RESPONSE = 0x1 ++ NL80211_PMSR_FTM_FAILURE_PEER_BUSY = 0x6 ++ NL80211_PMSR_FTM_FAILURE_PEER_NOT_CAPABLE = 0x4 ++ NL80211_PMSR_FTM_FAILURE_REJECTED = 0x2 ++ NL80211_PMSR_FTM_FAILURE_UNSPECIFIED = 0x0 ++ NL80211_PMSR_FTM_FAILURE_WRONG_CHANNEL = 0x3 ++ NL80211_PMSR_FTM_REQ_ATTR_ASAP = 0x1 ++ NL80211_PMSR_FTM_REQ_ATTR_BSS_COLOR = 0xd ++ NL80211_PMSR_FTM_REQ_ATTR_BURST_DURATION = 0x5 ++ NL80211_PMSR_FTM_REQ_ATTR_BURST_PERIOD = 0x4 ++ NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST = 0x6 ++ ++ NL80211_PMSR_FTM_REQ_ATTR_MAX = 0xd ++ NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED = 0xb ++ NL80211_PMSR_FTM_REQ_ATTR_NUM_BURSTS_EXP = 0x3 ++ NL80211_PMSR_FTM_REQ_ATTR_NUM_FTMR_RETRIES = 0x7 ++ NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE = 0x2 ++ NL80211_PMSR_FTM_REQ_ATTR_REQUEST_CIVICLOC = 0x9 ++ NL80211_PMSR_FTM_REQ_ATTR_REQUEST_LCI = 0x8 ++ NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED = 0xa ++ NL80211_PMSR_FTM_RESP_ATTR_BURST_DURATION = 0x7 ++ NL80211_PMSR_FTM_RESP_ATTR_BURST_INDEX = 0x2 ++ NL80211_PMSR_FTM_RESP_ATTR_BUSY_RETRY_TIME = 0x5 ++ NL80211_PMSR_FTM_RESP_ATTR_CIVICLOC = 0x14 ++ NL80211_PMSR_FTM_RESP_ATTR_DIST_AVG = 0x10 ++ NL80211_PMSR_FTM_RESP_ATTR_DIST_SPREAD = 0x12 ++ NL80211_PMSR_FTM_RESP_ATTR_DIST_VARIANCE = 0x11 ++ NL80211_PMSR_FTM_RESP_ATTR_FAIL_REASON = 0x1 ++ NL80211_PMSR_FTM_RESP_ATTR_FTMS_PER_BURST = 0x8 ++ NL80211_PMSR_FTM_RESP_ATTR_LCI = 0x13 ++ NL80211_PMSR_FTM_RESP_ATTR_MAX = 0x15 ++ NL80211_PMSR_FTM_RESP_ATTR_NUM_BURSTS_EXP = 0x6 ++ NL80211_PMSR_FTM_RESP_ATTR_NUM_FTMR_ATTEMPTS = 0x3 ++ NL80211_PMSR_FTM_RESP_ATTR_NUM_FTMR_SUCCESSES = 0x4 ++ NL80211_PMSR_FTM_RESP_ATTR_PAD = 0x15 ++ NL80211_PMSR_FTM_RESP_ATTR_RSSI_AVG = 0x9 ++ NL80211_PMSR_FTM_RESP_ATTR_RSSI_SPREAD = 0xa ++ NL80211_PMSR_FTM_RESP_ATTR_RTT_AVG = 0xd ++ NL80211_PMSR_FTM_RESP_ATTR_RTT_SPREAD = 0xf ++ NL80211_PMSR_FTM_RESP_ATTR_RTT_VARIANCE = 0xe ++ NL80211_PMSR_FTM_RESP_ATTR_RX_RATE = 0xc ++ NL80211_PMSR_FTM_RESP_ATTR_TX_RATE = 0xb ++ NL80211_PMSR_PEER_ATTR_ADDR = 0x1 ++ NL80211_PMSR_PEER_ATTR_CHAN = 0x2 ++ NL80211_PMSR_PEER_ATTR_MAX = 0x4 ++ NL80211_PMSR_PEER_ATTR_REQ = 0x3 ++ NL80211_PMSR_PEER_ATTR_RESP = 0x4 ++ NL80211_PMSR_REQ_ATTR_DATA = 0x1 ++ NL80211_PMSR_REQ_ATTR_GET_AP_TSF = 0x2 ++ NL80211_PMSR_REQ_ATTR_MAX = 0x2 ++ NL80211_PMSR_RESP_ATTR_AP_TSF = 0x4 ++ NL80211_PMSR_RESP_ATTR_DATA = 0x1 ++ NL80211_PMSR_RESP_ATTR_FINAL = 0x5 ++ NL80211_PMSR_RESP_ATTR_HOST_TIME = 0x3 ++ NL80211_PMSR_RESP_ATTR_MAX = 0x6 ++ NL80211_PMSR_RESP_ATTR_PAD = 0x6 ++ NL80211_PMSR_RESP_ATTR_STATUS = 0x2 ++ NL80211_PMSR_STATUS_FAILURE = 0x3 ++ NL80211_PMSR_STATUS_REFUSED = 0x1 ++ NL80211_PMSR_STATUS_SUCCESS = 0x0 ++ NL80211_PMSR_STATUS_TIMEOUT = 0x2 ++ NL80211_PMSR_TYPE_FTM = 0x1 ++ NL80211_PMSR_TYPE_INVALID = 0x0 ++ NL80211_PMSR_TYPE_MAX = 0x1 ++ NL80211_PREAMBLE_DMG = 0x3 ++ NL80211_PREAMBLE_HE = 0x4 ++ NL80211_PREAMBLE_HT = 0x1 ++ NL80211_PREAMBLE_LEGACY = 0x0 ++ NL80211_PREAMBLE_VHT = 0x2 ++ NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U = 0x8 ++ NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P = 0x4 ++ NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 = 0x2 ++ NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS = 0x1 ++ NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP = 0x1 ++ NL80211_PS_DISABLED = 0x0 ++ NL80211_PS_ENABLED = 0x1 ++ NL80211_RADAR_CAC_ABORTED = 0x2 ++ NL80211_RADAR_CAC_FINISHED = 0x1 ++ NL80211_RADAR_CAC_STARTED = 0x5 ++ NL80211_RADAR_DETECTED = 0x0 ++ NL80211_RADAR_NOP_FINISHED = 0x3 ++ NL80211_RADAR_PRE_CAC_EXPIRED = 0x4 ++ NL80211_RATE_INFO_10_MHZ_WIDTH = 0xb ++ NL80211_RATE_INFO_160_MHZ_WIDTH = 0xa ++ NL80211_RATE_INFO_320_MHZ_WIDTH = 0x12 ++ NL80211_RATE_INFO_40_MHZ_WIDTH = 0x3 ++ NL80211_RATE_INFO_5_MHZ_WIDTH = 0xc ++ NL80211_RATE_INFO_80_MHZ_WIDTH = 0x8 ++ NL80211_RATE_INFO_80P80_MHZ_WIDTH = 0x9 ++ NL80211_RATE_INFO_BITRATE32 = 0x5 ++ NL80211_RATE_INFO_BITRATE = 0x1 ++ NL80211_RATE_INFO_EHT_GI_0_8 = 0x0 ++ NL80211_RATE_INFO_EHT_GI_1_6 = 0x1 ++ NL80211_RATE_INFO_EHT_GI_3_2 = 0x2 ++ NL80211_RATE_INFO_EHT_GI = 0x15 ++ NL80211_RATE_INFO_EHT_MCS = 0x13 ++ NL80211_RATE_INFO_EHT_NSS = 0x14 ++ NL80211_RATE_INFO_EHT_RU_ALLOC_106 = 0x3 ++ NL80211_RATE_INFO_EHT_RU_ALLOC_106P26 = 0x4 ++ NL80211_RATE_INFO_EHT_RU_ALLOC_242 = 0x5 ++ NL80211_RATE_INFO_EHT_RU_ALLOC_26 = 0x0 ++ NL80211_RATE_INFO_EHT_RU_ALLOC_2x996 = 0xb ++ NL80211_RATE_INFO_EHT_RU_ALLOC_2x996P484 = 0xc ++ NL80211_RATE_INFO_EHT_RU_ALLOC_3x996 = 0xd ++ NL80211_RATE_INFO_EHT_RU_ALLOC_3x996P484 = 0xe ++ NL80211_RATE_INFO_EHT_RU_ALLOC_484 = 0x6 ++ NL80211_RATE_INFO_EHT_RU_ALLOC_484P242 = 0x7 ++ NL80211_RATE_INFO_EHT_RU_ALLOC_4x996 = 0xf ++ NL80211_RATE_INFO_EHT_RU_ALLOC_52 = 0x1 ++ NL80211_RATE_INFO_EHT_RU_ALLOC_52P26 = 0x2 ++ NL80211_RATE_INFO_EHT_RU_ALLOC_996 = 0x8 ++ NL80211_RATE_INFO_EHT_RU_ALLOC_996P484 = 0x9 ++ NL80211_RATE_INFO_EHT_RU_ALLOC_996P484P242 = 0xa ++ NL80211_RATE_INFO_EHT_RU_ALLOC = 0x16 ++ NL80211_RATE_INFO_HE_1XLTF = 0x0 ++ NL80211_RATE_INFO_HE_2XLTF = 0x1 ++ NL80211_RATE_INFO_HE_4XLTF = 0x2 ++ NL80211_RATE_INFO_HE_DCM = 0x10 ++ NL80211_RATE_INFO_HE_GI_0_8 = 0x0 ++ NL80211_RATE_INFO_HE_GI_1_6 = 0x1 ++ NL80211_RATE_INFO_HE_GI_3_2 = 0x2 ++ NL80211_RATE_INFO_HE_GI = 0xf ++ NL80211_RATE_INFO_HE_MCS = 0xd ++ NL80211_RATE_INFO_HE_NSS = 0xe ++ NL80211_RATE_INFO_HE_RU_ALLOC_106 = 0x2 ++ NL80211_RATE_INFO_HE_RU_ALLOC_242 = 0x3 ++ NL80211_RATE_INFO_HE_RU_ALLOC_26 = 0x0 ++ NL80211_RATE_INFO_HE_RU_ALLOC_2x996 = 0x6 ++ NL80211_RATE_INFO_HE_RU_ALLOC_484 = 0x4 ++ NL80211_RATE_INFO_HE_RU_ALLOC_52 = 0x1 ++ NL80211_RATE_INFO_HE_RU_ALLOC_996 = 0x5 ++ NL80211_RATE_INFO_HE_RU_ALLOC = 0x11 ++ NL80211_RATE_INFO_MAX = 0x1d ++ NL80211_RATE_INFO_MCS = 0x2 ++ NL80211_RATE_INFO_SHORT_GI = 0x4 ++ NL80211_RATE_INFO_VHT_MCS = 0x6 ++ NL80211_RATE_INFO_VHT_NSS = 0x7 ++ NL80211_REGDOM_SET_BY_CORE = 0x0 ++ NL80211_REGDOM_SET_BY_COUNTRY_IE = 0x3 ++ NL80211_REGDOM_SET_BY_DRIVER = 0x2 ++ NL80211_REGDOM_SET_BY_USER = 0x1 ++ NL80211_REGDOM_TYPE_COUNTRY = 0x0 ++ NL80211_REGDOM_TYPE_CUSTOM_WORLD = 0x2 ++ NL80211_REGDOM_TYPE_INTERSECTION = 0x3 ++ NL80211_REGDOM_TYPE_WORLD = 0x1 ++ NL80211_REG_RULE_ATTR_MAX = 0x7 ++ NL80211_REKEY_DATA_AKM = 0x4 ++ NL80211_REKEY_DATA_KCK = 0x2 ++ NL80211_REKEY_DATA_KEK = 0x1 ++ NL80211_REKEY_DATA_REPLAY_CTR = 0x3 ++ NL80211_REPLAY_CTR_LEN = 0x8 ++ NL80211_RRF_AUTO_BW = 0x800 ++ NL80211_RRF_DFS = 0x10 ++ NL80211_RRF_GO_CONCURRENT = 0x1000 ++ NL80211_RRF_IR_CONCURRENT = 0x1000 ++ NL80211_RRF_NO_160MHZ = 0x10000 ++ NL80211_RRF_NO_320MHZ = 0x40000 ++ NL80211_RRF_NO_80MHZ = 0x8000 ++ NL80211_RRF_NO_CCK = 0x2 ++ NL80211_RRF_NO_HE = 0x20000 ++ NL80211_RRF_NO_HT40 = 0x6000 ++ NL80211_RRF_NO_HT40MINUS = 0x2000 ++ NL80211_RRF_NO_HT40PLUS = 0x4000 ++ NL80211_RRF_NO_IBSS = 0x80 ++ NL80211_RRF_NO_INDOOR = 0x4 ++ NL80211_RRF_NO_IR_ALL = 0x180 ++ NL80211_RRF_NO_IR = 0x80 ++ NL80211_RRF_NO_OFDM = 0x1 ++ NL80211_RRF_NO_OUTDOOR = 0x8 ++ NL80211_RRF_PASSIVE_SCAN = 0x80 ++ NL80211_RRF_PTMP_ONLY = 0x40 ++ NL80211_RRF_PTP_ONLY = 0x20 ++ NL80211_RXMGMT_FLAG_ANSWERED = 0x1 ++ NL80211_RXMGMT_FLAG_EXTERNAL_AUTH = 0x2 ++ ++ NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP = 0x20 ++ NL80211_SCAN_FLAG_AP = 0x4 ++ NL80211_SCAN_FLAG_COLOCATED_6GHZ = 0x4000 ++ NL80211_SCAN_FLAG_FILS_MAX_CHANNEL_TIME = 0x10 ++ NL80211_SCAN_FLAG_FLUSH = 0x2 ++ NL80211_SCAN_FLAG_FREQ_KHZ = 0x2000 ++ NL80211_SCAN_FLAG_HIGH_ACCURACY = 0x400 ++ NL80211_SCAN_FLAG_LOW_POWER = 0x200 ++ NL80211_SCAN_FLAG_LOW_PRIORITY = 0x1 ++ NL80211_SCAN_FLAG_LOW_SPAN = 0x100 ++ NL80211_SCAN_FLAG_MIN_PREQ_CONTENT = 0x1000 ++ NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION = 0x80 ++ NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE = 0x40 ++ NL80211_SCAN_FLAG_RANDOM_ADDR = 0x8 ++ NL80211_SCAN_FLAG_RANDOM_SN = 0x800 ++ NL80211_SCAN_RSSI_THOLD_OFF = -0x12c ++ NL80211_SCHED_SCAN_MATCH_ATTR_BSSID = 0x5 ++ NL80211_SCHED_SCAN_MATCH_ATTR_MAX = 0x6 ++ NL80211_SCHED_SCAN_MATCH_ATTR_RELATIVE_RSSI = 0x3 ++ NL80211_SCHED_SCAN_MATCH_ATTR_RSSI_ADJUST = 0x4 ++ NL80211_SCHED_SCAN_MATCH_ATTR_RSSI = 0x2 ++ NL80211_SCHED_SCAN_MATCH_ATTR_SSID = 0x1 ++ NL80211_SCHED_SCAN_MATCH_PER_BAND_RSSI = 0x6 ++ NL80211_SCHED_SCAN_PLAN_INTERVAL = 0x1 ++ NL80211_SCHED_SCAN_PLAN_ITERATIONS = 0x2 ++ NL80211_SCHED_SCAN_PLAN_MAX = 0x2 ++ NL80211_SMPS_DYNAMIC = 0x2 ++ NL80211_SMPS_MAX = 0x2 ++ NL80211_SMPS_OFF = 0x0 ++ NL80211_SMPS_STATIC = 0x1 ++ NL80211_STA_BSS_PARAM_BEACON_INTERVAL = 0x5 ++ NL80211_STA_BSS_PARAM_CTS_PROT = 0x1 ++ NL80211_STA_BSS_PARAM_DTIM_PERIOD = 0x4 ++ NL80211_STA_BSS_PARAM_MAX = 0x5 ++ NL80211_STA_BSS_PARAM_SHORT_PREAMBLE = 0x2 ++ NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME = 0x3 ++ NL80211_STA_FLAG_ASSOCIATED = 0x7 ++ NL80211_STA_FLAG_AUTHENTICATED = 0x5 ++ NL80211_STA_FLAG_AUTHORIZED = 0x1 ++ NL80211_STA_FLAG_MAX = 0x7 ++ NL80211_STA_FLAG_MAX_OLD_API = 0x6 ++ NL80211_STA_FLAG_MFP = 0x4 ++ NL80211_STA_FLAG_SHORT_PREAMBLE = 0x2 ++ NL80211_STA_FLAG_TDLS_PEER = 0x6 ++ NL80211_STA_FLAG_WME = 0x3 ++ NL80211_STA_INFO_ACK_SIGNAL_AVG = 0x23 ++ NL80211_STA_INFO_ACK_SIGNAL = 0x22 ++ NL80211_STA_INFO_AIRTIME_LINK_METRIC = 0x29 ++ NL80211_STA_INFO_AIRTIME_WEIGHT = 0x28 ++ NL80211_STA_INFO_ASSOC_AT_BOOTTIME = 0x2a ++ NL80211_STA_INFO_BEACON_LOSS = 0x12 ++ NL80211_STA_INFO_BEACON_RX = 0x1d ++ NL80211_STA_INFO_BEACON_SIGNAL_AVG = 0x1e ++ NL80211_STA_INFO_BSS_PARAM = 0xf ++ NL80211_STA_INFO_CHAIN_SIGNAL_AVG = 0x1a ++ NL80211_STA_INFO_CHAIN_SIGNAL = 0x19 ++ NL80211_STA_INFO_CONNECTED_TIME = 0x10 ++ NL80211_STA_INFO_CONNECTED_TO_AS = 0x2b ++ NL80211_STA_INFO_CONNECTED_TO_GATE = 0x26 ++ NL80211_STA_INFO_DATA_ACK_SIGNAL_AVG = 0x23 ++ NL80211_STA_INFO_EXPECTED_THROUGHPUT = 0x1b ++ NL80211_STA_INFO_FCS_ERROR_COUNT = 0x25 ++ NL80211_STA_INFO_INACTIVE_TIME = 0x1 ++ NL80211_STA_INFO_LLID = 0x4 ++ NL80211_STA_INFO_LOCAL_PM = 0x14 ++ NL80211_STA_INFO_MAX = 0x2b ++ NL80211_STA_INFO_NONPEER_PM = 0x16 ++ NL80211_STA_INFO_PAD = 0x21 ++ NL80211_STA_INFO_PEER_PM = 0x15 ++ NL80211_STA_INFO_PLID = 0x5 ++ NL80211_STA_INFO_PLINK_STATE = 0x6 ++ NL80211_STA_INFO_RX_BITRATE = 0xe ++ NL80211_STA_INFO_RX_BYTES64 = 0x17 ++ NL80211_STA_INFO_RX_BYTES = 0x2 ++ NL80211_STA_INFO_RX_DROP_MISC = 0x1c ++ NL80211_STA_INFO_RX_DURATION = 0x20 ++ NL80211_STA_INFO_RX_MPDUS = 0x24 ++ NL80211_STA_INFO_RX_PACKETS = 0x9 ++ NL80211_STA_INFO_SIGNAL_AVG = 0xd ++ NL80211_STA_INFO_SIGNAL = 0x7 ++ NL80211_STA_INFO_STA_FLAGS = 0x11 ++ NL80211_STA_INFO_TID_STATS = 0x1f ++ NL80211_STA_INFO_T_OFFSET = 0x13 ++ NL80211_STA_INFO_TX_BITRATE = 0x8 ++ NL80211_STA_INFO_TX_BYTES64 = 0x18 ++ NL80211_STA_INFO_TX_BYTES = 0x3 ++ NL80211_STA_INFO_TX_DURATION = 0x27 ++ NL80211_STA_INFO_TX_FAILED = 0xc ++ NL80211_STA_INFO_TX_PACKETS = 0xa ++ NL80211_STA_INFO_TX_RETRIES = 0xb ++ NL80211_STA_WME_MAX = 0x2 ++ NL80211_STA_WME_MAX_SP = 0x2 ++ NL80211_STA_WME_UAPSD_QUEUES = 0x1 ++ NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY = 0x5 ++ NL80211_SURVEY_INFO_CHANNEL_TIME = 0x4 ++ NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY = 0x6 ++ NL80211_SURVEY_INFO_CHANNEL_TIME_RX = 0x7 ++ NL80211_SURVEY_INFO_CHANNEL_TIME_TX = 0x8 ++ NL80211_SURVEY_INFO_FREQUENCY = 0x1 ++ NL80211_SURVEY_INFO_FREQUENCY_OFFSET = 0xc ++ NL80211_SURVEY_INFO_IN_USE = 0x3 ++ NL80211_SURVEY_INFO_MAX = 0xc ++ NL80211_SURVEY_INFO_NOISE = 0x2 ++ NL80211_SURVEY_INFO_PAD = 0xa ++ NL80211_SURVEY_INFO_TIME_BSS_RX = 0xb ++ NL80211_SURVEY_INFO_TIME_BUSY = 0x5 ++ NL80211_SURVEY_INFO_TIME = 0x4 ++ NL80211_SURVEY_INFO_TIME_EXT_BUSY = 0x6 ++ NL80211_SURVEY_INFO_TIME_RX = 0x7 ++ NL80211_SURVEY_INFO_TIME_SCAN = 0x9 ++ NL80211_SURVEY_INFO_TIME_TX = 0x8 ++ NL80211_TDLS_DISABLE_LINK = 0x4 ++ NL80211_TDLS_DISCOVERY_REQ = 0x0 ++ NL80211_TDLS_ENABLE_LINK = 0x3 ++ ++ NL80211_TDLS_PEER_HT = 0x1 ++ NL80211_TDLS_PEER_VHT = 0x2 ++ NL80211_TDLS_PEER_WMM = 0x4 ++ NL80211_TDLS_SETUP = 0x1 ++ NL80211_TDLS_TEARDOWN = 0x2 ++ NL80211_TID_CONFIG_ATTR_AMPDU_CTRL = 0x9 ++ NL80211_TID_CONFIG_ATTR_AMSDU_CTRL = 0xb ++ NL80211_TID_CONFIG_ATTR_MAX = 0xd ++ NL80211_TID_CONFIG_ATTR_NOACK = 0x6 ++ NL80211_TID_CONFIG_ATTR_OVERRIDE = 0x4 ++ NL80211_TID_CONFIG_ATTR_PAD = 0x1 ++ NL80211_TID_CONFIG_ATTR_PEER_SUPP = 0x3 ++ NL80211_TID_CONFIG_ATTR_RETRY_LONG = 0x8 ++ NL80211_TID_CONFIG_ATTR_RETRY_SHORT = 0x7 ++ NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL = 0xa ++ NL80211_TID_CONFIG_ATTR_TIDS = 0x5 ++ NL80211_TID_CONFIG_ATTR_TX_RATE = 0xd ++ NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE = 0xc ++ NL80211_TID_CONFIG_ATTR_VIF_SUPP = 0x2 ++ NL80211_TID_CONFIG_DISABLE = 0x1 ++ NL80211_TID_CONFIG_ENABLE = 0x0 ++ NL80211_TID_STATS_MAX = 0x6 ++ NL80211_TID_STATS_PAD = 0x5 ++ NL80211_TID_STATS_RX_MSDU = 0x1 ++ NL80211_TID_STATS_TX_MSDU = 0x2 ++ NL80211_TID_STATS_TX_MSDU_FAILED = 0x4 ++ NL80211_TID_STATS_TX_MSDU_RETRIES = 0x3 ++ NL80211_TID_STATS_TXQ_STATS = 0x6 ++ NL80211_TIMEOUT_ASSOC = 0x3 ++ NL80211_TIMEOUT_AUTH = 0x2 ++ NL80211_TIMEOUT_SCAN = 0x1 ++ NL80211_TIMEOUT_UNSPECIFIED = 0x0 ++ NL80211_TKIP_DATA_OFFSET_ENCR_KEY = 0x0 ++ NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY = 0x18 ++ NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY = 0x10 ++ NL80211_TX_POWER_AUTOMATIC = 0x0 ++ NL80211_TX_POWER_FIXED = 0x2 ++ NL80211_TX_POWER_LIMITED = 0x1 ++ NL80211_TXQ_ATTR_AC = 0x1 ++ NL80211_TXQ_ATTR_AIFS = 0x5 ++ NL80211_TXQ_ATTR_CWMAX = 0x4 ++ NL80211_TXQ_ATTR_CWMIN = 0x3 ++ NL80211_TXQ_ATTR_MAX = 0x5 ++ NL80211_TXQ_ATTR_QUEUE = 0x1 ++ NL80211_TXQ_ATTR_TXOP = 0x2 ++ NL80211_TXQ_Q_BE = 0x2 ++ NL80211_TXQ_Q_BK = 0x3 ++ NL80211_TXQ_Q_VI = 0x1 ++ NL80211_TXQ_Q_VO = 0x0 ++ NL80211_TXQ_STATS_BACKLOG_BYTES = 0x1 ++ NL80211_TXQ_STATS_BACKLOG_PACKETS = 0x2 ++ NL80211_TXQ_STATS_COLLISIONS = 0x8 ++ NL80211_TXQ_STATS_DROPS = 0x4 ++ NL80211_TXQ_STATS_ECN_MARKS = 0x5 ++ NL80211_TXQ_STATS_FLOWS = 0x3 ++ NL80211_TXQ_STATS_MAX = 0xb ++ NL80211_TXQ_STATS_MAX_FLOWS = 0xb ++ NL80211_TXQ_STATS_OVERLIMIT = 0x6 ++ NL80211_TXQ_STATS_OVERMEMORY = 0x7 ++ NL80211_TXQ_STATS_TX_BYTES = 0x9 ++ NL80211_TXQ_STATS_TX_PACKETS = 0xa ++ NL80211_TX_RATE_AUTOMATIC = 0x0 ++ NL80211_TXRATE_DEFAULT_GI = 0x0 ++ NL80211_TX_RATE_FIXED = 0x2 ++ NL80211_TXRATE_FORCE_LGI = 0x2 ++ NL80211_TXRATE_FORCE_SGI = 0x1 ++ NL80211_TXRATE_GI = 0x4 ++ NL80211_TXRATE_HE = 0x5 ++ NL80211_TXRATE_HE_GI = 0x6 ++ NL80211_TXRATE_HE_LTF = 0x7 ++ NL80211_TXRATE_HT = 0x2 ++ NL80211_TXRATE_LEGACY = 0x1 ++ NL80211_TX_RATE_LIMITED = 0x1 ++ NL80211_TXRATE_MAX = 0x7 ++ NL80211_TXRATE_MCS = 0x2 ++ NL80211_TXRATE_VHT = 0x3 ++ NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_INT = 0x1 ++ NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_MAX = 0x2 ++ NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_TMPL = 0x2 ++ NL80211_USER_REG_HINT_CELL_BASE = 0x1 ++ NL80211_USER_REG_HINT_INDOOR = 0x2 ++ NL80211_USER_REG_HINT_USER = 0x0 ++ NL80211_VENDOR_ID_IS_LINUX = 0x80000000 ++ NL80211_VHT_CAPABILITY_LEN = 0xc ++ NL80211_VHT_NSS_MAX = 0x8 ++ NL80211_WIPHY_NAME_MAXLEN = 0x40 ++ NL80211_WMMR_AIFSN = 0x3 ++ NL80211_WMMR_CW_MAX = 0x2 ++ NL80211_WMMR_CW_MIN = 0x1 ++ NL80211_WMMR_MAX = 0x4 ++ NL80211_WMMR_TXOP = 0x4 ++ NL80211_WOWLAN_PKTPAT_MASK = 0x1 ++ NL80211_WOWLAN_PKTPAT_OFFSET = 0x3 ++ NL80211_WOWLAN_PKTPAT_PATTERN = 0x2 ++ NL80211_WOWLAN_TCP_DATA_INTERVAL = 0x9 ++ NL80211_WOWLAN_TCP_DATA_PAYLOAD = 0x6 ++ NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ = 0x7 ++ NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN = 0x8 ++ NL80211_WOWLAN_TCP_DST_IPV4 = 0x2 ++ NL80211_WOWLAN_TCP_DST_MAC = 0x3 ++ NL80211_WOWLAN_TCP_DST_PORT = 0x5 ++ NL80211_WOWLAN_TCP_SRC_IPV4 = 0x1 ++ NL80211_WOWLAN_TCP_SRC_PORT = 0x4 ++ NL80211_WOWLAN_TCP_WAKE_MASK = 0xb ++ NL80211_WOWLAN_TCP_WAKE_PAYLOAD = 0xa ++ NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE = 0x8 ++ NL80211_WOWLAN_TRIG_ANY = 0x1 ++ NL80211_WOWLAN_TRIG_DISCONNECT = 0x2 ++ NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST = 0x7 ++ NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE = 0x6 ++ NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED = 0x5 ++ NL80211_WOWLAN_TRIG_MAGIC_PKT = 0x3 ++ NL80211_WOWLAN_TRIG_NET_DETECT = 0x12 ++ NL80211_WOWLAN_TRIG_NET_DETECT_RESULTS = 0x13 ++ NL80211_WOWLAN_TRIG_PKT_PATTERN = 0x4 ++ NL80211_WOWLAN_TRIG_RFKILL_RELEASE = 0x9 ++ NL80211_WOWLAN_TRIG_TCP_CONNECTION = 0xe ++ NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211 = 0xa ++ NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211_LEN = 0xb ++ NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023 = 0xc ++ NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023_LEN = 0xd ++ NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST = 0x10 ++ NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH = 0xf ++ NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS = 0x11 ++ NL80211_WPA_VERSION_1 = 0x1 ++ NL80211_WPA_VERSION_2 = 0x2 ++ NL80211_WPA_VERSION_3 = 0x4 ++) ++ ++const ( ++ FRA_UNSPEC = 0x0 ++ FRA_DST = 0x1 ++ FRA_SRC = 0x2 ++ FRA_IIFNAME = 0x3 ++ FRA_GOTO = 0x4 ++ FRA_UNUSED2 = 0x5 ++ FRA_PRIORITY = 0x6 ++ FRA_UNUSED3 = 0x7 ++ FRA_UNUSED4 = 0x8 ++ FRA_UNUSED5 = 0x9 ++ FRA_FWMARK = 0xa ++ FRA_FLOW = 0xb ++ FRA_TUN_ID = 0xc ++ FRA_SUPPRESS_IFGROUP = 0xd ++ FRA_SUPPRESS_PREFIXLEN = 0xe ++ FRA_TABLE = 0xf ++ FRA_FWMASK = 0x10 ++ FRA_OIFNAME = 0x11 ++ FRA_PAD = 0x12 ++ FRA_L3MDEV = 0x13 ++ FRA_UID_RANGE = 0x14 ++ FRA_PROTOCOL = 0x15 ++ FRA_IP_PROTO = 0x16 ++ FRA_SPORT_RANGE = 0x17 ++ FRA_DPORT_RANGE = 0x18 ++ FR_ACT_UNSPEC = 0x0 ++ FR_ACT_TO_TBL = 0x1 ++ FR_ACT_GOTO = 0x2 ++ FR_ACT_NOP = 0x3 ++ FR_ACT_RES3 = 0x4 ++ FR_ACT_RES4 = 0x5 ++ FR_ACT_BLACKHOLE = 0x6 ++ FR_ACT_UNREACHABLE = 0x7 ++ FR_ACT_PROHIBIT = 0x8 ++) ++ ++const ( ++ AUDIT_NLGRP_NONE = 0x0 ++ AUDIT_NLGRP_READLOG = 0x1 ++) ++ ++const ( ++ TUN_F_CSUM = 0x1 ++ TUN_F_TSO4 = 0x2 ++ TUN_F_TSO6 = 0x4 ++ TUN_F_TSO_ECN = 0x8 ++ TUN_F_UFO = 0x10 ++ TUN_F_USO4 = 0x20 ++ TUN_F_USO6 = 0x40 ++) ++ ++const ( ++ VIRTIO_NET_HDR_F_NEEDS_CSUM = 0x1 ++ VIRTIO_NET_HDR_F_DATA_VALID = 0x2 ++ VIRTIO_NET_HDR_F_RSC_INFO = 0x4 ++) ++ ++const ( ++ VIRTIO_NET_HDR_GSO_NONE = 0x0 ++ VIRTIO_NET_HDR_GSO_TCPV4 = 0x1 ++ VIRTIO_NET_HDR_GSO_UDP = 0x3 ++ VIRTIO_NET_HDR_GSO_TCPV6 = 0x4 ++ VIRTIO_NET_HDR_GSO_UDP_L4 = 0x5 ++ VIRTIO_NET_HDR_GSO_ECN = 0x80 ++) ++ ++const ( ++ RISCV_HWPROBE_KEY_MVENDORID = 0x0 ++ RISCV_HWPROBE_KEY_MARCHID = 0x1 ++ RISCV_HWPROBE_KEY_MIMPID = 0x2 ++ RISCV_HWPROBE_KEY_BASE_BEHAVIOR = 0x3 ++ RISCV_HWPROBE_BASE_BEHAVIOR_IMA = 0x1 ++ RISCV_HWPROBE_KEY_IMA_EXT_0 = 0x4 ++ RISCV_HWPROBE_IMA_FD = 0x1 ++ RISCV_HWPROBE_IMA_C = 0x2 ++ RISCV_HWPROBE_IMA_V = 0x4 ++ RISCV_HWPROBE_EXT_ZBA = 0x8 ++ RISCV_HWPROBE_EXT_ZBB = 0x10 ++ RISCV_HWPROBE_EXT_ZBS = 0x20 ++ RISCV_HWPROBE_EXT_ZICBOZ = 0x40 ++ RISCV_HWPROBE_EXT_ZBC = 0x80 ++ RISCV_HWPROBE_EXT_ZBKB = 0x100 ++ RISCV_HWPROBE_EXT_ZBKC = 0x200 ++ RISCV_HWPROBE_EXT_ZBKX = 0x400 ++ RISCV_HWPROBE_EXT_ZKND = 0x800 ++ RISCV_HWPROBE_EXT_ZKNE = 0x1000 ++ RISCV_HWPROBE_EXT_ZKNH = 0x2000 ++ RISCV_HWPROBE_EXT_ZKSED = 0x4000 ++ RISCV_HWPROBE_EXT_ZKSH = 0x8000 ++ RISCV_HWPROBE_EXT_ZKT = 0x10000 ++ RISCV_HWPROBE_EXT_ZVBB = 0x20000 ++ RISCV_HWPROBE_EXT_ZVBC = 0x40000 ++ RISCV_HWPROBE_EXT_ZVKB = 0x80000 ++ RISCV_HWPROBE_EXT_ZVKG = 0x100000 ++ RISCV_HWPROBE_EXT_ZVKNED = 0x200000 ++ RISCV_HWPROBE_EXT_ZVKNHA = 0x400000 ++ RISCV_HWPROBE_EXT_ZVKNHB = 0x800000 ++ RISCV_HWPROBE_EXT_ZVKSED = 0x1000000 ++ RISCV_HWPROBE_EXT_ZVKSH = 0x2000000 ++ RISCV_HWPROBE_EXT_ZVKT = 0x4000000 ++ RISCV_HWPROBE_EXT_ZFH = 0x8000000 ++ RISCV_HWPROBE_EXT_ZFHMIN = 0x10000000 ++ RISCV_HWPROBE_EXT_ZIHINTNTL = 0x20000000 ++ RISCV_HWPROBE_EXT_ZVFH = 0x40000000 ++ RISCV_HWPROBE_EXT_ZVFHMIN = 0x80000000 ++ RISCV_HWPROBE_EXT_ZFA = 0x100000000 ++ RISCV_HWPROBE_EXT_ZTSO = 0x200000000 ++ RISCV_HWPROBE_EXT_ZACAS = 0x400000000 ++ RISCV_HWPROBE_EXT_ZICOND = 0x800000000 ++ RISCV_HWPROBE_EXT_ZIHINTPAUSE = 0x1000000000 ++ RISCV_HWPROBE_KEY_CPUPERF_0 = 0x5 ++ RISCV_HWPROBE_MISALIGNED_UNKNOWN = 0x0 ++ RISCV_HWPROBE_MISALIGNED_EMULATED = 0x1 ++ RISCV_HWPROBE_MISALIGNED_SLOW = 0x2 ++ RISCV_HWPROBE_MISALIGNED_FAST = 0x3 ++ RISCV_HWPROBE_MISALIGNED_UNSUPPORTED = 0x4 ++ RISCV_HWPROBE_MISALIGNED_MASK = 0x7 ++ RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE = 0x6 ++ RISCV_HWPROBE_WHICH_CPUS = 0x1 ++) ++ ++type SchedAttr struct { ++ Size uint32 ++ Policy uint32 ++ Flags uint64 ++ Nice int32 ++ Priority uint32 ++ Runtime uint64 ++ Deadline uint64 ++ Period uint64 ++ Util_min uint32 ++ Util_max uint32 ++} ++ ++const SizeofSchedAttr = 0x38 ++ ++type Cachestat_t struct { ++ Cache uint64 ++ Dirty uint64 ++ Writeback uint64 ++ Evicted uint64 ++ Recently_evicted uint64 ++} ++type CachestatRange struct { ++ Off uint64 ++ Len uint64 ++} ++ ++const ( ++ SK_MEMINFO_RMEM_ALLOC = 0x0 ++ SK_MEMINFO_RCVBUF = 0x1 ++ SK_MEMINFO_WMEM_ALLOC = 0x2 ++ SK_MEMINFO_SNDBUF = 0x3 ++ SK_MEMINFO_FWD_ALLOC = 0x4 ++ SK_MEMINFO_WMEM_QUEUED = 0x5 ++ SK_MEMINFO_OPTMEM = 0x6 ++ SK_MEMINFO_BACKLOG = 0x7 ++ SK_MEMINFO_DROPS = 0x8 ++ SK_MEMINFO_VARS = 0x9 ++ SKNLGRP_NONE = 0x0 ++ SKNLGRP_INET_TCP_DESTROY = 0x1 ++ SKNLGRP_INET_UDP_DESTROY = 0x2 ++ SKNLGRP_INET6_TCP_DESTROY = 0x3 ++ SKNLGRP_INET6_UDP_DESTROY = 0x4 ++ SK_DIAG_BPF_STORAGE_REQ_NONE = 0x0 ++ SK_DIAG_BPF_STORAGE_REQ_MAP_FD = 0x1 ++ SK_DIAG_BPF_STORAGE_REP_NONE = 0x0 ++ SK_DIAG_BPF_STORAGE = 0x1 ++ SK_DIAG_BPF_STORAGE_NONE = 0x0 ++ SK_DIAG_BPF_STORAGE_PAD = 0x1 ++ SK_DIAG_BPF_STORAGE_MAP_ID = 0x2 ++ SK_DIAG_BPF_STORAGE_MAP_VALUE = 0x3 ++) ++ ++type SockDiagReq struct { ++ Family uint8 ++ Protocol uint8 ++} +diff --git a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/asmdecl/asmdecl.go b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/asmdecl/asmdecl.go +index b622dfdf3a..2c4e290f88 100644 +--- a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/asmdecl/asmdecl.go ++++ b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/asmdecl/asmdecl.go +@@ -99,6 +99,7 @@ var ( + asmArchS390X = asmArch{name: "s390x", bigEndian: true, stack: "R15", lr: true} + asmArchWasm = asmArch{name: "wasm", bigEndian: false, stack: "SP", lr: false} + asmArchLoong64 = asmArch{name: "loong64", bigEndian: false, stack: "R3", lr: true, retRegs: []string{"R4", "F0"}, writeResult: []string{"SYSCALL"}} ++ asmArchSW64 = asmArch{name: "sw64", bigEndian: false, stack: "R30", lr: true} + + arches = []*asmArch{ + &asmArch386, +@@ -115,6 +116,7 @@ var ( + &asmArchS390X, + &asmArchWasm, + &asmArchLoong64, ++ &asmArchSW64, + } + ) + +@@ -753,6 +755,27 @@ func asmCheckVar(badf func(string, ...interface{}), fn *asmFunc, line, expr stri + case "MOVV", "MOVD": + src = 8 + } ++ case "sw64": ++ switch op { ++ // On sw64, load/store insts's second arg ++ // is a disp(rb) addr ++ case "LDBU", "STB": ++ src = 1 ++ dst = 8 ++ addr = true ++ case "LDHU", "STH": ++ src = 2 ++ dst = 8 ++ addr = true ++ case "LDW", "STW", "FLDS", "FSTS": ++ src = 4 ++ dst = 8 ++ addr = true ++ case "LDL", "LDL_U", "STL", "STL_U", "FLDD", "FSTD": ++ src = 8 ++ dst = 8 ++ addr = true ++ } + case "s390x": + switch op { + case "MOVB", "MOVBZ": +diff --git a/src/vendor/golang.org/x/sys/cpu/byteorder.go b/src/vendor/golang.org/x/sys/cpu/byteorder.go +index 271055be0b..a1d69f2a92 100644 +--- a/src/vendor/golang.org/x/sys/cpu/byteorder.go ++++ b/src/vendor/golang.org/x/sys/cpu/byteorder.go +@@ -51,7 +51,8 @@ func hostByteOrder() byteOrder { + "nios2", + "ppc64le", + "riscv", "riscv64", +- "sh": ++ "sh", ++ "sw64": + return littleEndian{} + case "armbe", "arm64be", + "m68k", +diff --git a/src/vendor/golang.org/x/sys/cpu/cpu_linux_noinit.go b/src/vendor/golang.org/x/sys/cpu/cpu_linux_noinit.go +index 7d902b6847..9c72d768bc 100644 +--- a/src/vendor/golang.org/x/sys/cpu/cpu_linux_noinit.go ++++ b/src/vendor/golang.org/x/sys/cpu/cpu_linux_noinit.go +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build linux && !arm && !arm64 && !mips64 && !mips64le && !ppc64 && !ppc64le && !s390x && !riscv64 ++//go:build linux && !arm && !arm64 && !mips64 && !mips64le && !ppc64 && !ppc64le && !s390x && !riscv64 && !sw64 + + package cpu + +diff --git a/src/vendor/golang.org/x/sys/cpu/cpu_linux_sw64.go b/src/vendor/golang.org/x/sys/cpu/cpu_linux_sw64.go +new file mode 100644 +index 0000000000..5ba384ef7f +--- /dev/null ++++ b/src/vendor/golang.org/x/sys/cpu/cpu_linux_sw64.go +@@ -0,0 +1,12 @@ ++// 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 linux && sw64 ++// +build linux ++// +build sw64 ++ ++package cpu ++ ++func doinit() { ++} +diff --git a/src/vendor/golang.org/x/sys/cpu/cpu_sw64.go b/src/vendor/golang.org/x/sys/cpu/cpu_sw64.go +new file mode 100644 +index 0000000000..e4c24c997e +--- /dev/null ++++ b/src/vendor/golang.org/x/sys/cpu/cpu_sw64.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. ++ ++//go:build linux && sw64 ++// +build sw64 ++ ++package cpu ++ ++const cacheLineSize = 128 ++ ++func initOptions() { ++} +diff --git a/src/vendor/golang.org/x/sys/cpu/endian_little.go b/src/vendor/golang.org/x/sys/cpu/endian_little.go +index 48eccc4c79..182c3f467c 100644 +--- a/src/vendor/golang.org/x/sys/cpu/endian_little.go ++++ b/src/vendor/golang.org/x/sys/cpu/endian_little.go +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build 386 || amd64 || amd64p32 || alpha || arm || arm64 || loong64 || mipsle || mips64le || mips64p32le || nios2 || ppc64le || riscv || riscv64 || sh || wasm ++//go:build 386 || amd64 || amd64p32 || alpha || arm || arm64 || loong64 || mipsle || mips64le || mips64p32le || nios2 || ppc64le || riscv || riscv64 || sh || wasm || sw64 + + package cpu + diff --git a/0010-internal-bytealg-adjust-the-format-of-assembly-files.patch b/0010-internal-bytealg-adjust-the-format-of-assembly-files.patch new file mode 100644 index 0000000000000000000000000000000000000000..85a21d39280a660722421eccf9ed74d018375699 --- /dev/null +++ b/0010-internal-bytealg-adjust-the-format-of-assembly-files.patch @@ -0,0 +1,583 @@ +From 14ffec301d84da6bcd5ef5757d6cd6445351225e Mon Sep 17 00:00:00 2001 +From: Huang Qiqi +Date: Mon, 3 Jun 2024 15:43:32 +0800 +Subject: [PATCH 10/44] internal/bytealg: adjust the format of assembly files + {count, equal, index, indexbyte}_loong64.s + +Change-Id: I19e6650e6595148e449da7a82be6e735c6f01ab6 +--- + src/internal/bytealg/count_loong64.s | 92 +++++++------- + src/internal/bytealg/equal_loong64.s | 42 ++++--- + src/internal/bytealg/index_loong64.s | 148 +++++++++++------------ + src/internal/bytealg/indexbyte_loong64.s | 52 ++++---- + 4 files changed, 169 insertions(+), 165 deletions(-) + +diff --git a/src/internal/bytealg/count_loong64.s b/src/internal/bytealg/count_loong64.s +index ca19c5f343..db8ba2cb24 100644 +--- a/src/internal/bytealg/count_loong64.s ++++ b/src/internal/bytealg/count_loong64.s +@@ -1,4 +1,4 @@ +-// Copyright 2020 The Go Authors. All rights reserved. ++// Copyright 2024 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. + +@@ -9,77 +9,77 @@ TEXT ·Count(SB),NOSPLIT,$0-40 + // R4 = b_base + // R5 = b_len + // R6 = b_cap (unused) +- // R7 = byte to count (want in R6) +- AND $0xff, R7, R6 +- JMP countbody<>(SB) ++ // R7 = byte to count ++ AND $0xff, R7, R6 ++ JMP countbody<>(SB) + + TEXT ·CountString(SB),NOSPLIT,$0-32 + // R4 = s_base + // R5 = s_len + // R6 = byte to count +- AND $0xff, R6 +- JMP countbody<>(SB) ++ AND $0xff, R6 ++ JMP countbody<>(SB) + + // input: + // R4 = s_base + // R5 = s_len + // R6 = byte to count + TEXT countbody<>(SB),NOSPLIT,$0 +- MOVV R0, R7 // count +- ADDV R4, R5 // end +- MOVV $1, R17 ++ MOVV R0, R7 // count ++ ADDV R4, R5 // end ++ MOVV $1, R17 + + loop: + ADDV $8, R4, R9 +- BLT R5, R9, tail ++ BLT R5, R9, tail + MOVV (R4), R8 + +- AND $0xff, R8, R10 +- WORD $0xcf210b // bstrpick.w r11, r8, 15, 8 +- XOR R6, R10, R10 +- XOR R6, R11, R11 +- MASKNEZ R10, R17, R12 +- MASKNEZ R11, R17, R13 +- ADDV R7, R12, R7 +- ADDV R7, R13, R7 ++ AND $0xff, R8, R10 ++ WORD $0xcf210b // bstrpick.w r11, r8, 15, 8 ++ XOR R6, R10, R10 ++ XOR R6, R11, R11 ++ MASKNEZ R10, R17, R12 ++ MASKNEZ R11, R17, R13 ++ ADDV R7, R12, R7 ++ ADDV R7, R13, R7 + +- WORD $0xd7410a // bstrpick.w r10, r8, 23, 16 +- WORD $0xdf610b // bstrpick.w r11, r8, 31, 24 +- XOR R6, R10, R10 +- XOR R6, R11, R11 +- MASKNEZ R10, R17, R12 +- MASKNEZ R11, R17, R13 +- ADDV R7, R12, R7 +- ADDV R7, R13, R7 ++ WORD $0xd7410a // bstrpick.w r10, r8, 23, 16 ++ WORD $0xdf610b // bstrpick.w r11, r8, 31, 24 ++ XOR R6, R10, R10 ++ XOR R6, R11, R11 ++ MASKNEZ R10, R17, R12 ++ MASKNEZ R11, R17, R13 ++ ADDV R7, R12, R7 ++ ADDV R7, R13, R7 + +- WORD $0xe7810a // bstrpick.w r10, r8, 39, 32 +- WORD $0xefa10b // bstrpick.w r11, r8, 47, 40 +- XOR R6, R10, R10 +- XOR R6, R11, R11 +- MASKNEZ R10, R17, R12 +- MASKNEZ R11, R17, R13 +- ADDV R7, R12, R7 +- ADDV R7, R13, R7 ++ WORD $0xe7810a // bstrpick.w r10, r8, 39, 32 ++ WORD $0xefa10b // bstrpick.w r11, r8, 47, 40 ++ XOR R6, R10, R10 ++ XOR R6, R11, R11 ++ MASKNEZ R10, R17, R12 ++ MASKNEZ R11, R17, R13 ++ ADDV R7, R12, R7 ++ ADDV R7, R13, R7 + +- WORD $0xf7c10a // bstrpick.w r10, r8, 55, 48 +- WORD $0xffe10b // bstrpick.w r11, r8, 63, 56 +- XOR R6, R10, R10 +- XOR R6, R11, R11 +- MASKNEZ R10, R17, R12 +- MASKNEZ R11, R17, R13 +- ADDV R7, R12, R7 +- ADDV R7, R13, R7 ++ WORD $0xf7c10a // bstrpick.w r10, r8, 55, 48 ++ WORD $0xffe10b // bstrpick.w r11, r8, 63, 56 ++ XOR R6, R10, R10 ++ XOR R6, R11, R11 ++ MASKNEZ R10, R17, R12 ++ MASKNEZ R11, R17, R13 ++ ADDV R7, R12, R7 ++ ADDV R7, R13, R7 + + MOVV R9, R4 +- JMP loop ++ JMP loop + + tail: +- BEQ R4, R5, done ++ BEQ R4, R5, done + MOVBU (R4), R8 + ADDV $1, R4 +- BNE R6, R8, tail ++ BNE R6, R8, tail + ADDV $1, R7 +- JMP tail ++ JMP tail + + done: + MOVV R7, R4 +diff --git a/src/internal/bytealg/equal_loong64.s b/src/internal/bytealg/equal_loong64.s +index 4cc31d5e46..5d5d591a2c 100644 +--- a/src/internal/bytealg/equal_loong64.s ++++ b/src/internal/bytealg/equal_loong64.s +@@ -12,57 +12,61 @@ TEXT runtime·memequal(SB),NOSPLIT|NOFRAME,$0-25 + // R4 = a_base + // R5 = b_base + // R6 = size +- JMP equalbody<>(SB) ++ JMP equalbody<>(SB) + + // memequal_varlen(a, b unsafe.Pointer) bool + TEXT runtime·memequal_varlen(SB),NOSPLIT,$0-17 + // R4 = a_base + // R5 = b_base +- MOVV 8(REGCTXT), R6 // compiler stores size at offset 8 in the closure +- JMP equalbody<>(SB) ++ MOVV 8(REGCTXT), R6 // compiler stores size at offset 8 in the closure ++ JMP equalbody<>(SB) + ++// input: ++// R4 = a_base ++// R5 = b_base ++// R6 = size + TEXT equalbody<>(SB),NOSPLIT|NOFRAME,$0 +- BEQ R4, R5, eq +- ADDV R4, R6, R6 // end ++ BEQ R4, R5, eq ++ ADDV R4, R6, R6 // end + + loop_16byte: +- ADDV $16, R4, R9 +- BLT R6, R9, load8byte ++ ADDV $16, R4, R9 ++ BLT R6, R9, load8byte + MOVV (R4), R7 + MOVV (R5), R8 + MOVV 8(R4), R10 + MOVV 8(R5), R11 + MOVV R9, R4 +- XOR R7, R8, R7 +- XOR R10, R11, R10 +- OR R10, R7, R7 ++ XOR R7, R8, R7 ++ XOR R10, R11, R10 ++ OR R10, R7, R7 + ADDV $16, R5 +- BEQ R7, loop_16byte ++ BEQ R7, loop_16byte + +- MOVB R0, R4 ++ MOVB R0, R4 + RET + + load8byte: +- ADDV $8, R4, R9 +- BLT R6, R9, tail ++ ADDV $8, R4, R9 ++ BLT R6, R9, tail + MOVV (R4), R7 + MOVV (R5), R8 + MOVV R9, R4 + ADDV $8, R5 +- BEQ R7, R8, tail ++ BEQ R7, R8, tail + +- MOVB R0, R4 ++ MOVB R0, R4 + RET + + tail: +- BEQ R4, R6, eq ++ BEQ R4, R6, eq + MOVBU (R4), R7 + MOVBU (R5), R8 + ADDV $1, R4 + ADDV $1, R5 +- BEQ R7, R8, tail ++ BEQ R7, R8, tail + +- MOVB R0, R4 ++ MOVB R0, R4 + RET + + eq: +diff --git a/src/internal/bytealg/index_loong64.s b/src/internal/bytealg/index_loong64.s +index 221d0332a4..7f7190b3be 100644 +--- a/src/internal/bytealg/index_loong64.s ++++ b/src/internal/bytealg/index_loong64.s +@@ -1,4 +1,4 @@ +-// Copyright 2018 The Go Authors. All rights reserved. ++// Copyright 2024 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. + +@@ -6,12 +6,12 @@ + #include "textflag.h" + + TEXT ·Index(SB),NOSPLIT,$0-56 +- MOVV R7, R6 // R6 = separator pointer +- MOVV R8, R7 // R7 = separator length +- JMP indexbody<>(SB) ++ MOVV R7, R6 // R6 = separator pointer ++ MOVV R8, R7 // R7 = separator length ++ JMP indexbody<>(SB) + + TEXT ·IndexString(SB),NOSPLIT,$0-40 +- JMP indexbody<>(SB) ++ JMP indexbody<>(SB) + + // input: + // R4 = string +@@ -23,108 +23,108 @@ TEXT indexbody<>(SB),NOSPLIT,$0 + // to avoid repeatedly re-load it again and again + // for sebsequent substring comparisons + SUBV R7, R5, R8 +- ADDV $1, R4, R9 // store base for later ++ ADDV $1, R4, R9 // store base for later + MOVV $8, R5 +- ADDV R4, R8 // end +- BLT R5, R7, len_gt_8 ++ ADDV R4, R8 // end ++ BLT R5, R7, len_gt_8 + + len_le_8: +- AND $0x8, R7, R5 +- BNE R5, len_8 +- AND $0x4, R7, R5 +- BNE R5, len_4_7 ++ AND $0x8, R7, R5 ++ BNE R5, len_8 ++ AND $0x4, R7, R5 ++ BNE R5, len_4_7 + + len_2_3: +- AND $0x1, R7, R5 +- BNE R5, len_3 ++ AND $0x1, R7, R5 ++ BNE R5, len_3 + + len_2: +- MOVHU (R6), R10 ++ MOVHU (R6), R10 + loop_2: +- BLT R8, R4, not_found +- MOVHU (R4), R11 ++ BLT R8, R4, not_found ++ MOVHU (R4), R11 + ADDV $1, R4 +- BNE R10, R11, loop_2 +- JMP found ++ BNE R10, R11, loop_2 ++ JMP found + + len_3: + MOVHU (R6), R10 + MOVBU 2(R6), R11 + loop_3: +- BLT R8, R4, not_found +- MOVHU (R4), R12 ++ BLT R8, R4, not_found ++ MOVHU (R4), R12 + ADDV $1, R4 +- BNE R10, R12, loop_3 +- MOVBU 1(R4), R12 +- BNE R11, R12, loop_3 +- JMP found ++ BNE R10, R12, loop_3 ++ MOVBU 1(R4), R12 ++ BNE R11, R12, loop_3 ++ JMP found + + len_4_7: +- AND $0x2, R7, R5 +- BNE R5, len_6_7 +- AND $0x1, R7, R5 +- BNE R5, len_5 ++ AND $0x2, R7, R5 ++ BNE R5, len_6_7 ++ AND $0x1, R7, R5 ++ BNE R5, len_5 + + len_4: +- MOVWU (R6), R10 ++ MOVWU (R6), R10 + loop_4: +- BLT R8, R4, not_found +- MOVWU (R4), R11 ++ BLT R8, R4, not_found ++ MOVWU (R4), R11 + ADDV $1, R4 +- BNE R10, R11, loop_4 +- JMP found ++ BNE R10, R11, loop_4 ++ JMP found + len_5: + MOVWU (R6), R10 + MOVBU 4(R6), R11 + loop_5: +- BLT R8, R4, not_found +- MOVWU (R4), R12 ++ BLT R8, R4, not_found ++ MOVWU (R4), R12 + ADDV $1, R4 +- BNE R10, R12, loop_5 +- MOVBU 3(R4), R12 +- BNE R11, R12, loop_5 +- JMP found ++ BNE R10, R12, loop_5 ++ MOVBU 3(R4), R12 ++ BNE R11, R12, loop_5 ++ JMP found + + len_6_7: +- AND $0x1, R7, R5 +- BNE R5, len_7 ++ AND $0x1, R7, R5 ++ BNE R5, len_7 + + len_6: + MOVWU (R6), R10 + MOVHU 4(R6), R11 + loop_6: +- BLT R8, R4, not_found +- MOVWU (R4), R12 ++ BLT R8, R4, not_found ++ MOVWU (R4), R12 + ADDV $1, R4 +- BNE R10, R12, loop_6 +- MOVHU 3(R4), R12 +- BNE R11, R12, loop_6 +- JMP found ++ BNE R10, R12, loop_6 ++ MOVHU 3(R4), R12 ++ BNE R11, R12, loop_6 ++ JMP found + + len_7: + MOVWU (R6), R10 + MOVWU 3(R6), R11 + loop_7: +- BLT R8, R4, not_found +- MOVWU (R4), R12 ++ BLT R8, R4, not_found ++ MOVWU (R4), R12 + ADDV $1, R4 +- BNE R10, R12, loop_7 +- MOVWU 2(R4), R12 +- BNE R11, R12, loop_7 +- JMP found ++ BNE R10, R12, loop_7 ++ MOVWU 2(R4), R12 ++ BNE R11, R12, loop_7 ++ JMP found + + len_8: + MOVV (R6), R10 + loop_8: +- BLT R8, R4, not_found ++ BLT R8, R4, not_found + MOVV (R4), R11 + ADDV $1, R4 +- BNE R10, R11, loop_8 +- JMP found ++ BNE R10, R11, loop_8 ++ JMP found + + len_gt_8: + MOVV $16, R5 +- BLT R5, R7, len_gt_16 ++ BLT R5, R7, len_gt_16 + + len_9_16: + MOVV (R6), R10 +@@ -132,17 +132,17 @@ len_9_16: + MOVV (R6)(R7), R11 + SUBV $1, R7 + loop_9_16: +- BLT R8, R4, not_found ++ BLT R8, R4, not_found + MOVV (R4), R12 + ADDV $1, R4 +- BNE R10, R12, loop_9_16 ++ BNE R10, R12, loop_9_16 + MOVV (R4)(R7), R12 +- BNE R11, R12, loop_9_16 +- JMP found ++ BNE R11, R12, loop_9_16 ++ JMP found + + len_gt_16: + MOVV $24, R5 +- BLT R5, R7, len_25_32 ++ BLT R5, R7, len_25_32 + + len_17_24: + MOVV (R6), R10 +@@ -151,15 +151,15 @@ len_17_24: + MOVV (R6)(R7), R12 + SUBV $1, R7 + loop_17_24: +- BLT R8, R4, not_found ++ BLT R8, R4, not_found + MOVV (R4), R13 + ADDV $1, R4 +- BNE R10, R13, loop_17_24 ++ BNE R10, R13, loop_17_24 + MOVV 7(R4), R13 +- BNE R11, R13, loop_17_24 ++ BNE R11, R13, loop_17_24 + MOVV (R4)(R7), R13 +- BNE R12, R13, loop_17_24 +- JMP found ++ BNE R12, R13, loop_17_24 ++ JMP found + + len_25_32: + MOVV (R6), R10 +@@ -169,17 +169,17 @@ len_25_32: + MOVV (R6)(R7), R13 + SUBV $1, R7 + loop_25_32: +- BLT R8, R4, not_found ++ BLT R8, R4, not_found + MOVV (R4), R14 + ADDV $1, R4 +- BNE R10, R14, loop_25_32 ++ BNE R10, R14, loop_25_32 + MOVV 7(R4), R14 +- BNE R11, R14, loop_25_32 ++ BNE R11, R14, loop_25_32 + MOVV 15(R4), R14 +- BNE R12, R14, loop_25_32 ++ BNE R12, R14, loop_25_32 + MOVV (R4)(R7), R14 +- BNE R13, R14, loop_25_32 +- JMP found ++ BNE R13, R14, loop_25_32 ++ JMP found + + found: + SUBV R9, R4 +diff --git a/src/internal/bytealg/indexbyte_loong64.s b/src/internal/bytealg/indexbyte_loong64.s +index 7811741423..b5f8f9cdbc 100644 +--- a/src/internal/bytealg/indexbyte_loong64.s ++++ b/src/internal/bytealg/indexbyte_loong64.s +@@ -12,17 +12,17 @@ TEXT ·IndexByte(SB),NOSPLIT,$0-40 + // R7 = byte to find + ADDV R4, R5 // end + MOVV R4, R6 // store base for later +- AND $0xff, R7 +- JMP indexbytebody<>(SB) ++ AND $0xff, R7 ++ JMP indexbytebody<>(SB) + + TEXT ·IndexByteString(SB),NOSPLIT,$0-32 + // R4 = s_base + // R5 = s_len + // R6 = byte to find +- AND $0xff, R6, R7 ++ AND $0xff, R6, R7 + ADDV R4, R5 // end + MOVV R4, R6 // store base for later +- JMP indexbytebody<>(SB) ++ JMP indexbytebody<>(SB) + + // input: + // R4: b_base +@@ -32,42 +32,42 @@ TEXT ·IndexByteString(SB),NOSPLIT,$0-32 + TEXT indexbytebody<>(SB),NOSPLIT,$0 + loop: + ADDV $8, R4, R10 +- BLT R5, R10, tail ++ BLT R5, R10, tail + MOVV (R4), R8 + +- AND $0xff, R8, R9 +- BEQ R7, R9, found ++ AND $0xff, R8, R9 ++ BEQ R7, R9, found + +- WORD $0xcf2109 // bstrpick.w r9, r8, 15, 8 +- BEQ R7, R9, byte_1th ++ WORD $0xcf2109 // bstrpick.w r9, r8, 15, 8 ++ BEQ R7, R9, byte_1th + +- WORD $0xd74109 // bstrpick.w r9, r8, 23, 16 +- BEQ R7, R9, byte_2th ++ WORD $0xd74109 // bstrpick.w r9, r8, 23, 16 ++ BEQ R7, R9, byte_2th + +- WORD $0xdf6109 // bstrpick.w r9, r8, 31, 24 +- BEQ R7, R9, byte_3th ++ WORD $0xdf6109 // bstrpick.w r9, r8, 31, 24 ++ BEQ R7, R9, byte_3th + +- WORD $0xe78109 // bstrpick.w r9, r8, 39, 32 +- BEQ R7, R9, byte_4th ++ WORD $0xe78109 // bstrpick.w r9, r8, 39, 32 ++ BEQ R7, R9, byte_4th + +- WORD $0xefa109 // bstrpick.w r9, r8, 47, 40 +- BEQ R7, R9, byte_5th ++ WORD $0xefa109 // bstrpick.w r9, r8, 47, 40 ++ BEQ R7, R9, byte_5th + +- WORD $0xf7c109 // bstrpick.w r9, r8, 55, 48 +- BEQ R7, R9, byte_6th ++ WORD $0xf7c109 // bstrpick.w r9, r8, 55, 48 ++ BEQ R7, R9, byte_6th + +- WORD $0xffe109 // bstrpick.w r9, r8, 63, 56 +- BEQ R7, R9, byte_7th ++ WORD $0xffe109 // bstrpick.w r9, r8, 63, 56 ++ BEQ R7, R9, byte_7th + + MOVV R10, R4 +- JMP loop ++ JMP loop + + tail: +- BEQ R4, R5, notfound +- MOVBU (R4), R8 +- BEQ R7, R8, found ++ BEQ R4, R5, notfound ++ MOVBU (R4), R8 ++ BEQ R7, R8, found + ADDV $1, R4 +- JMP tail ++ JMP tail + + byte_1th: + ADDV $1, R4 +-- +2.38.1 + diff --git a/0011-cmd-go-go-Add-sw64-port.patch b/0011-cmd-go-go-Add-sw64-port.patch new file mode 100644 index 0000000000000000000000000000000000000000..57636634afc9b1679511c8f5d0f1029e62d97736 --- /dev/null +++ b/0011-cmd-go-go-Add-sw64-port.patch @@ -0,0 +1,64 @@ +diff --git a/src/cmd/go/internal/cfg/cfg.go b/src/cmd/go/internal/cfg/cfg.go +index 3b9f27e91d..d4edb67c56 100644 +--- a/src/cmd/go/internal/cfg/cfg.go ++++ b/src/cmd/go/internal/cfg/cfg.go +@@ -438,6 +438,7 @@ var ( + GOMIPS64, goMIPS64Changed = EnvOrAndChanged("GOMIPS64", buildcfg.DefaultGOMIPS64) + GOPPC64, goPPC64Changed = EnvOrAndChanged("GOPPC64", buildcfg.DefaultGOPPC64) + GORISCV64, goRISCV64Changed = EnvOrAndChanged("GORISCV64", buildcfg.DefaultGORISCV64) ++ GOSW64, goSW64Changed = EnvOrAndChanged("GOSW64", fmt.Sprintf("%s%d", "core", buildcfg.GOSW64)) + GOWASM, goWASMChanged = EnvOrAndChanged("GOWASM", fmt.Sprint(buildcfg.GOWASM)) + + GOFIPS140, GOFIPS140Changed = EnvOrAndChanged("GOFIPS140", buildcfg.DefaultGOFIPS140) +diff --git a/src/cmd/go/testdata/mod/golang.org_toolchain_v0.0.1-go1.999testmod.linux-sw64.txt b/src/cmd/go/testdata/mod/golang.org_toolchain_v0.0.1-go1.999testmod.linux-sw64.txt +new file mode 100644 +index 0000000000..a38c0f0a48 +--- /dev/null ++++ b/src/cmd/go/testdata/mod/golang.org_toolchain_v0.0.1-go1.999testmod.linux-sw64.txt +@@ -0,0 +1,15 @@ ++golang.org/toolchain@v0.0.1-go1.999testmod.linux-sw64 ++ ++-- .mod -- ++module golang.org/toolchain ++-- .info -- ++{"Version":"v0.0.1-go1.999testmod.linux-sw64"} ++-- go.mod -- ++module golang.org/toolchain ++-- bin/go -- ++#!/bin/sh ++echo go1.999testmod here! ++-- bin/gofmt -- ++echo i am unused ++-- pkg/tool/fake -- ++-- lib/wasm/go_js_wasm_exec -- +diff --git a/src/go/types/gccgosizes.go b/src/go/types/gccgosizes.go +index 6aa9e1e586..8579373f01 100644 +--- a/src/go/types/gccgosizes.go ++++ b/src/go/types/gccgosizes.go +@@ -41,4 +41,5 @@ var gccgoArchSizes = map[string]*StdSizes{ + "sparc": {4, 8}, + "sparc64": {8, 8}, + "wasm": {8, 8}, ++ "sw64": {8, 8}, + } +diff --git a/src/go/types/sizes.go b/src/go/types/sizes.go +index 51ea224f0b..7a29b1bf88 100644 +--- a/src/go/types/sizes.go ++++ b/src/go/types/sizes.go +@@ -247,6 +247,7 @@ var gcArchSizes = map[string]*gcSizes{ + "s390x": {8, 8}, + "sparc64": {8, 8}, + "wasm": {8, 8}, ++ "sw64": {8, 8}, + // When adding more architectures here, + // update the doc string of SizesFor below. + } +@@ -256,7 +257,7 @@ var gcArchSizes = map[string]*gcSizes{ + // + // Supported architectures for compiler "gc": + // "386", "amd64", "amd64p32", "arm", "arm64", "loong64", "mips", "mipsle", +-// "mips64", "mips64le", "ppc64", "ppc64le", "riscv64", "s390x", "sparc64", "wasm". ++// "mips64", "mips64le", "ppc64", "ppc64le", "riscv64", "s390x", "sparc64", "wasm", "sw64". + func SizesFor(compiler, arch string) Sizes { + switch compiler { + case "gc": diff --git a/0011-cmd-internal-obj-loong64-optimize-immediate-loading.patch b/0011-cmd-internal-obj-loong64-optimize-immediate-loading.patch new file mode 100644 index 0000000000000000000000000000000000000000..6136b63a2a511b369295c0585254d7237caab0fc --- /dev/null +++ b/0011-cmd-internal-obj-loong64-optimize-immediate-loading.patch @@ -0,0 +1,776 @@ +From a08a479c526bcc63bf24e69ff7fa1d37a1179e1f Mon Sep 17 00:00:00 2001 +From: limeidan +Date: Thu, 11 Jul 2024 21:03:45 +0800 +Subject: [PATCH 11/44] cmd/internal/obj/loong64: optimize immediate loading +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + + | old | new | + | sec/op | sec/op vs base | +BinaryTree17 11.08 ± 2% 11.16 ± 1% ~ (p=0.529 n=10) +Fannkuch11 2.716 ± 0% 2.737 ± 0% +0.79% (p=0.000 n=10) +FmtFprintfEmpty 67.37n ± 0% 66.42n ± 0% -1.41% (p=0.000 n=10) +FmtFprintfString 95.28n ± 0% 90.85n ± 0% -4.64% (p=0.000 n=10) +FmtFprintfInt 97.69n ± 0% 98.06n ± 0% +0.38% (p=0.000 n=10) +FmtFprintfIntInt 149.1n ± 0% 147.4n ± 0% -1.14% (p=0.000 n=10) +FmtFprintfPrefixedInt 223.6n ± 0% 196.5n ± 0% -12.10% (p=0.000 n=10) +FmtFprintfFloat 290.9n ± 0% 281.6n ± 1% -3.21% (p=0.000 n=10) +FmtManyArgs 670.6n ± 0% 642.6n ± 0% -4.18% (p=0.000 n=10) +GobDecode 10.26m ± 1% 10.23m ± 1% ~ (p=0.105 n=10) +GobEncode 12.09m ± 1% 11.94m ± 1% -1.24% (p=0.000 n=10) +Gzip 316.9m ± 0% 315.9m ± 0% -0.32% (p=0.001 n=10) +Gunzip 65.48m ± 0% 59.77m ± 0% -8.72% (p=0.000 n=10) +HTTPClientServer 70.36µ ± 0% 68.72µ ± 0% -2.34% (p=0.000 n=10) +JSONEncode 13.61m ± 1% 13.19m ± 1% -3.13% (p=0.000 n=10) +JSONDecode 57.52m ± 1% 54.15m ± 1% -5.86% (p=0.000 n=10) +Mandelbrot200 4.577m ± 0% 4.572m ± 0% -0.10% (p=0.002 n=10) +GoParse 6.466m ± 0% 6.363m ± 0% -1.58% (p=0.000 n=10) +RegexpMatchEasy0_32 89.20n ± 0% 87.72n ± 0% -1.65% (p=0.000 n=10) +RegexpMatchEasy0_1K 748.6n ± 0% 907.6n ± 0% +21.22% (p=0.000 n=10) +RegexpMatchEasy1_32 94.14n ± 0% 93.81n ± 0% -0.35% (p=0.000 n=10) +RegexpMatchEasy1_1K 832.1n ± 0% 953.6n ± 0% +14.59% (p=0.000 n=10) +RegexpMatchMedium_32 982.7n ± 0% 1018.0n ± 0% +3.59% (p=0.000 n=10) +RegexpMatchMedium_1K 30.51µ ± 0% 30.00µ ± 0% -1.65% (p=0.000 n=10) +RegexpMatchHard_32 1.721µ ± 0% 1.664µ ± 0% -3.34% (p=0.000 n=10) +RegexpMatchHard_1K 50.76µ ± 0% 50.92µ ± 0% +0.32% (p=0.000 n=10) +Revcomp 870.5m ± 0% 710.5m ± 0% -18.38% (p=0.000 n=10) +Template 93.18m ± 1% 93.67m ± 1% ~ (p=0.123 n=10) +TimeParse 309.2n ± 0% 307.8n ± 0% -0.45% (p=0.000 n=10) +TimeFormat 401.5n ± 0% 394.2n ± 0% -1.82% (p=0.000 n=10) +geomean 72.73µ 71.70µ -1.41% + +Change-Id: Id8d342ef3bb82a420434b2b841674683efef67be +--- + src/cmd/asm/internal/asm/endtoend_test.go | 2 + + .../asm/internal/asm/testdata/loong64enc1.s | 24 ++ + .../asm/internal/asm/testdata/loong64enc2.s | 46 +++ + .../asm/internal/asm/testdata/loong64enc3.s | 65 ++++ + .../asm/internal/asm/testdata/loong64enc4.s | 42 +++ + .../asm/internal/asm/testdata/loong64enc5.s | 17 + + src/cmd/internal/obj/loong64/a.out.go | 54 ++- + src/cmd/internal/obj/loong64/asm.go | 321 +++++++++++++++++- + src/cmd/internal/obj/loong64/cnames.go | 14 + + 9 files changed, 579 insertions(+), 6 deletions(-) + create mode 100644 src/cmd/asm/internal/asm/testdata/loong64enc4.s + create mode 100644 src/cmd/asm/internal/asm/testdata/loong64enc5.s + +diff --git a/src/cmd/asm/internal/asm/endtoend_test.go b/src/cmd/asm/internal/asm/endtoend_test.go +index 6e1aa1cd95..3760b77625 100644 +--- a/src/cmd/asm/internal/asm/endtoend_test.go ++++ b/src/cmd/asm/internal/asm/endtoend_test.go +@@ -465,6 +465,8 @@ func TestLOONG64Encoder(t *testing.T) { + testEndToEnd(t, "loong64", "loong64enc1") + testEndToEnd(t, "loong64", "loong64enc2") + testEndToEnd(t, "loong64", "loong64enc3") ++ testEndToEnd(t, "loong64", "loong64enc4") ++ testEndToEnd(t, "loong64", "loong64enc5") + testEndToEnd(t, "loong64", "loong64") + } + +diff --git a/src/cmd/asm/internal/asm/testdata/loong64enc1.s b/src/cmd/asm/internal/asm/testdata/loong64enc1.s +index 4a88aca031..3a3eb10a74 100644 +--- a/src/cmd/asm/internal/asm/testdata/loong64enc1.s ++++ b/src/cmd/asm/internal/asm/testdata/loong64enc1.s +@@ -516,3 +516,27 @@ lable2: + XVPCNTH X3, X2 // 62249c76 + XVPCNTW X3, X2 // 62289c76 + XVPCNTV X3, X2 // 622c9c76 ++ ++ // MOVV C_DCON12_0, r ++ MOVV $0x7a90000000000000, R4 // MOVV $8831558869273542656, R4 // 04a41e03 ++ MOVV $0xea90000000000000, R4 // MOVV $-1544734672188080128, R4 // 04a43a03 ++ ++ // MOVV C_UCON, r ++ MOVV $0x54321000, R4 // MOVV $1412567040, R4 // 2464a814 ++ MOVV $0xffffffff8432f000, R4 // MOVV $-2077036544, R4 // e4650815 ++ ++ // MOVV C_ADDCON, r ++ MOVV $0xfffffffffffff821, R4 // MOVV $-2015, R4 // 0484e002 ++ ++ // MOVV C_ANDCON, r ++ MOVV $0x821, R4 // MOVV $2081, R4 // 0484a003 ++ ++ // ADDV C_SCON, [r1], r2 ++ ADDV $0x321, R4 // ADDV $801, R4 // 8484cc02 ++ ADDV $0x321, R5, R4 // ADDV $801, R5, R4 // a484cc02 ++ ADDV $0xfffffffffffffc21, R4 // ADDV $-991, R4 // 8484f002 ++ ADDV $0xfffffffffffffc21, R5, R4 // ADDV $-991, R5, R4 // a484f002 ++ ++ // AND C_SCON, [r1], r2 ++ AND $0x321, R4 // AND $801, R4 // 84844c03 ++ AND $0x321, R5, R4 // AND $801, R5, R4 // a4844c03 +diff --git a/src/cmd/asm/internal/asm/testdata/loong64enc2.s b/src/cmd/asm/internal/asm/testdata/loong64enc2.s +index e497b83627..ee3bad74b1 100644 +--- a/src/cmd/asm/internal/asm/testdata/loong64enc2.s ++++ b/src/cmd/asm/internal/asm/testdata/loong64enc2.s +@@ -77,3 +77,49 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0 + MOVH name(SB), R4 // 1e00001ac4034028 + MOVHU R4, name(SB) // 1e00001ac4034029 + MOVHU name(SB), R4 // 1e00001ac403402a ++ ++ // MOVV C_DCON12_20S, r ++ MOVV $0x273fffff80000000, R4 // MOVV $2828260563841187840, R4 // 0400001584cc0903 ++ MOVV $0xf73fffff80000000, R4 // MOVV $-630503949979353088, R4 // 0400001584cc3d03 ++ ++ // MOVV C_DCON20S_20, r ++ MOVV $0xfff800000f000000, R4 // MOVV $-2251799562027008, R4 // 04001e1404000017 ++ ++ // MOVV C_DCON12_12S, r ++ MOVV $0x273ffffffffff800, R4 // MOVV $2828260565988669440, R4 // 0400e00284cc0903 ++ MOVV $0xf73ffffffffff800, R4 // MOVV $-630503947831871488, R4 // 0400e00284cc3d03 ++ ++ // MOVV C_DCON20S_12S, r ++ MOVV $0xfff80000fffff800, R4 // MOVV $-2251795518720000, R4 // 0400a00204000017 ++ MOVV $0xfff8000000000000, R4 // MOVV $-2251799813685248, R4 // 0400800204000017 ++ ++ // MOVV C_DCON12_12U, r ++ MOVV $0x2730000000000800, R4 // MOVV $2823756966361303040, R4 // 0400a00384cc0903 ++ MOVV $0xf730000000000800, R4 // MOVV $-635007547459237888, R4 // 0400a00384cc3d03 ++ ++ // MOVV C_DCON20S_12U, r ++ MOVV $0xfff8000000000800, R4 // MOVV $-2251799813683200, R4 // 0400a00304000017 ++ ++ // ADDV/AND C_DCON12_0, [r1], r2 ++ ADDV $0x3210000000000000, R4 // ADDV $3607383301523767296, R4 // 1e840c0384f81000 ++ ADDV $0x3210000000000000, R5, R4 // ADDV $3607383301523767296, R5, R4 // 1e840c03a4f81000 ++ ADDV $0xc210000000000000, R4 // ADDV $-4463067230724161536, R4 // 1e84300384f81000 ++ ADDV $0xc210000000000000, R5, R4 // ADDV $-4463067230724161536, R5, R4 // 1e843003a4f81000 ++ AND $0x3210000000000000, R4 // AND $3607383301523767296, R4 // 1e840c0384f81400 ++ AND $0x3210000000000000, R5, R4 // AND $3607383301523767296, R5, R4 // 1e840c03a4f81400 ++ AND $0xc210000000000000, R4 // AND $-4463067230724161536, R4 // 1e84300384f81400 ++ AND $0xc210000000000000, R5, R4 // AND $-4463067230724161536, R5, R4 // 1e843003a4f81400 ++ ++ // ADDV/AND C_UCON, [r1], r2 ++ ADDV $0x43210000, R4 // ADDV $1126236160, R4 // 1e42861484f81000 ++ ADDV $0x43210000, R5, R4 // ADDV $1126236160, R5, R4 // 1e428614a4f81000 ++ ADDV $0xffffffffc3210000, R4 // ADDV $-1021247488, R4 // 1e42861584f81000 ++ ADDV $0xffffffffc3210000, R5, R4 // ADDV $-1021247488, R5, R4 // 1e428615a4f81000 ++ AND $0x43210000, R4 // AND $1126236160, R4 // 1e42861484f81400 ++ AND $0x43210000, R5, R4 // AND $1126236160, R5, R4 // 1e428614a4f81400 ++ AND $0xffffffffc3210000, R4 // AND $-1021247488, R4 // 1e42861584f81400 ++ AND $0xffffffffc3210000, R5, R4 // AND $-1021247488, R5, R4 // 1e428615a4f81400 ++ ++ // AND C_ADDCON, [r1], r2 ++ AND $0xfffffffffffffc21, R4 // AND $-991, R4 // 1e84b00284f81400 ++ AND $0xfffffffffffffc21, R5, R4 // AND $-991, R5, R4 // 1e84b002a4f81400 +diff --git a/src/cmd/asm/internal/asm/testdata/loong64enc3.s b/src/cmd/asm/internal/asm/testdata/loong64enc3.s +index 2600884309..2d83bd719a 100644 +--- a/src/cmd/asm/internal/asm/testdata/loong64enc3.s ++++ b/src/cmd/asm/internal/asm/testdata/loong64enc3.s +@@ -121,3 +121,68 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0 + XOR $74565, R4, R5 // 5e020014de178d0385f81500 + XOR $4097, R4 // 3e000014de07800384f81500 + XOR $4097, R4, R5 // 3e000014de07800385f81500 ++ ++ // MOVV C_DCON32_12S, r ++ MOVV $0x27312345fffff800, R4 // MOVV $2824077224892692480, R4 // 0400a002a468241684cc0903 ++ MOVV $0xf7312345fffff800, R4 // MOVV $-634687288927848448, R4 // 0400a002a468241684cc3d03 ++ ++ // MOVV C_DCON32_0, r ++ MOVV $0x2731234500000000, R4 // MOVV $2824077220597727232, R4 // 04008002a468241684cc0903 ++ MOVV $0xf731234500000000, R4 // MOVV $-634687293222813696, R4 // 04008002a468241684cc3d03 ++ ++ // MOVV C_DCON32_20, r ++ MOVV $0x2731234512345000, R4 // MOVV $2824077220903145472, R4 // a4682414a468241684cc0903 ++ MOVV $0xf731234512345000, R4 // MOVV $-634687292917395456, R4 // a4682414a468241684cc3d03 ++ ++ // MOVV C_DCON12_32S, r ++ MOVV $0x273fffff80000800, R4 // MOVV $2828260563841189888, R4 // 040000158400a00384cc0903 ++ MOVV $0xf73fffff80000800, R4 // MOVV $-630503949979351040, R4 // 040000158400a00384cc3d03 ++ ++ // MOVV C_DCON20S_32, r ++ MOVV $0xfff8000080000800, R4 // MOVV $-2251797666199552, R4 // 040000158400a00304000017 ++ ++ // MOVV C_DCON32_12U, r ++ MOVV $0x2731234500000800, R4 // MOVV $2824077220597729280, R4 // 0400a003a468241684cc0903 ++ MOVV $0xf731234500000800, R4 // MOVV $-634687293222811648, R4 // 0400a003a468241684cc3d03 ++ ++ // ADDV/AND C_DCON12_20S, [r1], r2 ++ ADDV $0x273fffff80000000, R4 // ADDV $2828260563841187840, R4 // 1e000015decf090384f81000 ++ ADDV $0x273fffff80000000, R4, R5 // ADDV $2828260563841187840, R4, R5 // 1e000015decf090385f81000 ++ AND $0x273fffff80000000, R4 // AND $2828260563841187840, R4 // 1e000015decf090384f81400 ++ AND $0x273fffff80000000, R4, R5 // AND $2828260563841187840, R4, R5 // 1e000015decf090385f81400 ++ ++ // ADDV/AND C_DCON20S_20, [r1], r2 ++ ADDV $0xfff800000f000000, R4 // ADDV $-2251799562027008, R4 // 1e001e141e00001784f81000 ++ ADDV $0xfff800000f000000, R4, R5 // ADDV $-2251799562027008, R4, R5 // 1e001e141e00001785f81000 ++ AND $0xfff800000f000000, R4 // AND $-2251799562027008, R4 // 1e001e141e00001784f81400 ++ AND $0xfff800000f000000, R4, R5 // AND $-2251799562027008, R4, R5 // 1e001e141e00001785f81400 ++ ++ // ADDV/AND C_DCON12_12S, [r1], r2 ++ ADDV $0x273ffffffffff800, R4 // ADDV $2828260565988669440, R4 // 1e00e002decf090384f81000 ++ ADDV $0x273ffffffffff800, R4, R5 // ADDV $2828260565988669440, R4, R5 // 1e00e002decf090385f81000 ++ AND $0x273ffffffffff800, R4 // AND $2828260565988669440, R4 // 1e00e002decf090384f81400 ++ AND $0x273ffffffffff800, R4, R5 // AND $2828260565988669440, R4, R5 // 1e00e002decf090385f81400 ++ ++ // ADDV/AND C_DCON20S_12S, [r1], r2 ++ ADDV $0xfff80000fffff800, R4 // ADDV $-2251795518720000, R4 // 1e00a0021e00001784f81000 ++ ADDV $0xfff80000fffff800, R4, R5 // ADDV $-2251795518720000, R4, R5 // 1e00a0021e00001785f81000 ++ AND $0xfff80000fffff800, R4 // AND $-2251795518720000, R4 // 1e00a0021e00001784f81400 ++ AND $0xfff80000fffff800, R4, R5 // AND $-2251795518720000, R4, R5 // 1e00a0021e00001785f81400 ++ ++ // ADDV/AND C_DCON20S_0, [r1], r2 ++ ADDV $0xfff8000000000000, R4 // ADDV $-2251799813685248, R4 // 1e0080021e00001784f81000 ++ ADDV $0xfff8000000000000, R4, R5 // ADDV $-2251799813685248, R4, R5 // 1e0080021e00001785f81000 ++ AND $0xfff8000000000000, R4 // AND $-2251799813685248, R4 // 1e0080021e00001784f81400 ++ AND $0xfff8000000000000, R4, R5 // AND $-2251799813685248, R4, R5 // 1e0080021e00001785f81400 ++ ++ // ADDV/AND C_DCON12_12U, [r1], r2 ++ ADDV $0x2730000000000800, R4 // ADDV $2823756966361303040, R4 // 1e00a003decf090384f81000 ++ ADDV $0x2730000000000800, R4, R5 // ADDV $2823756966361303040, R4, R5 // 1e00a003decf090385f81000 ++ AND $0x2730000000000800, R4 // AND $2823756966361303040, R4 // 1e00a003decf090384f81400 ++ AND $0x2730000000000800, R4, R5 // AND $2823756966361303040, R4, R5 // 1e00a003decf090385f81400 ++ ++ // ADDV/AND C_DCON20S_12U, [r1], r2 ++ ADDV $0xfff8000000000800, R4 // ADDV $-2251799813683200, R4 // 1e00a0031e00001784f81000 ++ ADDV $0xfff8000000000800, R4, R5 // ADDV $-2251799813683200, R4, R5 // 1e00a0031e00001785f81000 ++ AND $0xfff8000000000800, R4 // AND $-2251799813683200, R4 // 1e00a0031e00001784f81400 ++ AND $0xfff8000000000800, R4, R5 // AND $-2251799813683200, R4, R5 // 1e00a0031e00001785f81400 +diff --git a/src/cmd/asm/internal/asm/testdata/loong64enc4.s b/src/cmd/asm/internal/asm/testdata/loong64enc4.s +new file mode 100644 +index 0000000000..16c06a3501 +--- /dev/null ++++ b/src/cmd/asm/internal/asm/testdata/loong64enc4.s +@@ -0,0 +1,42 @@ ++// Copyright 2024 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++ ++#include "../../../../../runtime/textflag.h" ++ ++TEXT asmtest(SB),DUPOK|NOSPLIT,$0 ++ // ADDV/AND C_DCON32_12S, [r1], r2 ++ ADDV $0x27312345fffff800, R4 // ADDV $2824077224892692480, R4 // 1e00a002be682416decf090384f81000 ++ ADDV $0x27312345fffff800, R4, R5 // ADDV $2824077224892692480, R4, R5 // 1e00a002be682416decf090385f81000 ++ AND $0x27312345fffff800, R4 // AND $2824077224892692480, R4 // 1e00a002be682416decf090384f81400 ++ AND $0x27312345fffff800, R4, R5 // AND $2824077224892692480, R4, R5 // 1e00a002be682416decf090385f81400 ++ ++ // ADDV/AND C_DCON32_0, [r1], r2 ++ ADDV $0x2731234500000000, R4 // ADDV $2824077220597727232, R4 // 1e008002be682416decf090384f81000 ++ ADDV $0x2731234500000000, R4, R5 // ADDV $2824077220597727232, R4, R5 // 1e008002be682416decf090385f81000 ++ AND $0x2731234500000000, R4 // AND $2824077220597727232, R4 // 1e008002be682416decf090384f81400 ++ AND $0x2731234500000000, R4, R5 // AND $2824077220597727232, R4, R5 // 1e008002be682416decf090385f81400 ++ ++ // ADDV/AND C_DCON32_20, [r1], r2 ++ ADDV $0x2731234512345000, R4 // ADDV $2824077220903145472, R4 // be682414be682416decf090384f81000 ++ ADDV $0x2731234512345000, R4, R5 // ADDV $2824077220903145472, R4, R5 // be682414be682416decf090385f81000 ++ AND $0x2731234512345000, R4 // AND $2824077220903145472, R4 // be682414be682416decf090384f81400 ++ AND $0x2731234512345000, R4, R5 // AND $2824077220903145472, R4, R5 // be682414be682416decf090385f81400 ++ ++ // ADDV/AND C_DCON12_32S, [r1], r2 ++ ADDV $0x273fffff80000800, R4 // ADDV $2828260563841189888, R4 // 1e000015de03a003decf090384f81000 ++ ADDV $0x273fffff80000800, R4, R5 // ADDV $2828260563841189888, R4, R5 // 1e000015de03a003decf090385f81000 ++ AND $0x273fffff80000800, R4 // AND $2828260563841189888, R4 // 1e000015de03a003decf090384f81400 ++ AND $0x273fffff80000800, R4, R5 // AND $2828260563841189888, R4, R5 // 1e000015de03a003decf090385f81400 ++ ++ // ADDV/AND C_DCON20S_32, [r1], r2 ++ ADDV $0xfff8000080000800, R4 // ADDV $-2251797666199552, R4 // 1e000015de03a0031e00001784f81000 ++ ADDV $0xfff8000080000800, R4, R5 // ADDV $-2251797666199552, R4, R5 // 1e000015de03a0031e00001785f81000 ++ AND $0xfff8000080000800, R4 // AND $-2251797666199552, R4 // 1e000015de03a0031e00001784f81400 ++ AND $0xfff8000080000800, R4, R5 // AND $-2251797666199552, R4, R5 // 1e000015de03a0031e00001785f81400 ++ ++ // ADDV/AND C_DCON32_12U, [r1], r2 ++ ADDV $0x2731234500000800, R4 // ADDV $2824077220597729280, R4 // 1e00a003be682416decf090384f81000 ++ ADDV $0x2731234500000800, R4, R5 // ADDV $2824077220597729280, R4, R5 // 1e00a003be682416decf090385f81000 ++ AND $0x2731234500000800, R4 // AND $2824077220597729280, R4 // 1e00a003be682416decf090384f81400 ++ AND $0x2731234500000800, R4, R5 // AND $2824077220597729280, R4, R5 // 1e00a003be682416decf090385f81400 +diff --git a/src/cmd/asm/internal/asm/testdata/loong64enc5.s b/src/cmd/asm/internal/asm/testdata/loong64enc5.s +new file mode 100644 +index 0000000000..423e5c3b01 +--- /dev/null ++++ b/src/cmd/asm/internal/asm/testdata/loong64enc5.s +@@ -0,0 +1,17 @@ ++// Copyright 2024 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++ ++#include "../../../../../runtime/textflag.h" ++ ++TEXT asmtest(SB),DUPOK|NOSPLIT,$0 ++ // ADDV/AND C_DCON, [r1], r2 ++ ADDV $0xfedcba9876543210, R4 // ADDV $-81985529216486896, R4 // 7ea8ec14de4388031e539717deb73f0384f81000 ++ ADDV $0xfedcba9876543210, R5, R4 // ADDV $-81985529216486896, R5, R4 // 7ea8ec14de4388031e539717deb73f03a4f81000 ++ ADDV $0x4edcba9876543210, R4 // ADDV $5682621993817747984, R4 // 7ea8ec14de4388031e539717deb7130384f81000 ++ ADDV $0x4edcba9876543210, R5, R4 // ADDV $5682621993817747984, R5, R4 // 7ea8ec14de4388031e539717deb71303a4f81000 ++ AND $0x4edcba9876543210, R4 // AND $5682621993817747984, R4 // 7ea8ec14de4388031e539717deb7130384f81400 ++ AND $0x4edcba9876543210, R5, R4 // AND $5682621993817747984, R5, R4 // 7ea8ec14de4388031e539717deb71303a4f81400 ++ AND $0xfedcba9876543210, R4 // AND $-81985529216486896, R4 // 7ea8ec14de4388031e539717deb73f0384f81400 ++ AND $0xfedcba9876543210, R5, R4 // AND $-81985529216486896, R5, R4 // 7ea8ec14de4388031e539717deb73f03a4f81400 ++ +diff --git a/src/cmd/internal/obj/loong64/a.out.go b/src/cmd/internal/obj/loong64/a.out.go +index 53b005af4d..b2207c2523 100644 +--- a/src/cmd/internal/obj/loong64/a.out.go ++++ b/src/cmd/internal/obj/loong64/a.out.go +@@ -328,12 +328,58 @@ const ( + C_ZCON + C_SCON // 12 bit signed + C_UCON // 32 bit signed, low 12 bits 0 ++ ++ // When the immediate value is SCON, it can choose either the ADDCON implementation ++ // or the ANDCON implementation, using ADD0CON/AND0CON to distinguish them, so that ++ // the program can choose the implementation with fewer instructions. + C_ADD0CON + C_AND0CON +- C_ADDCON // -0x800 <= v < 0 +- C_ANDCON // 0 < v <= 0xFFF +- C_LCON // other 32 +- C_DCON // other 64 (could subdivide further) ++ ++ C_ADDCON // -0x800 <= v < 0 ++ C_ANDCON // 0 < v <= 0xFFF ++ C_LCON // other 32 ++ ++ // 64 bit signed, lo32 bits 0, hi20 bits are not 0, hi12 bits can ++ // be obtained by sign extension of the hi20 bits. ++ C_DCON20S_0 ++ // 64 bit signed, lo52 bits 0, hi12 bits are not 0. ++ C_DCON12_0 ++ // 64 bit signed, lo32 bits 0, hi32 bits are not 0. ++ C_DCON32_0 ++ // 64 bit signed, lo12 bits 0, lo20 bits are not 0, hi20 bits can be ++ // obtained by sign extension of the lo20 bits, other bits are not 0. ++ C_DCON12_20S ++ // 64 bit signed, lo12 bits 0, hi20 bits are not 0, hi12 bits can be ++ // obtained by sign extension of the hi20 bits, other bits are not 0. ++ C_DCON20S_20 ++ // 64 bit signed, lo12 bits 0, other bits are not 0. ++ C_DCON32_20 ++ // 64 bit signed, lo12 bits are not 0, 12~51 bits can be obtained ++ // by sign extension of the lo12 bits, other bits are not 0. ++ C_DCON12_12S ++ // 64 bit signed, hi20 bits and lo12 bits are not 0, hi12 bits can ++ // be obtained by sign extension of the hi20 bits, lo20 bits can ++ // be obtained by sign extension of the lo12 bits. ++ C_DCON20S_12S ++ // 64 bit signed, lo12 bits are not 0, lo20 bits can be obtained by sign ++ // extension of the lo12 bits, other bits are not 0. ++ C_DCON32_12S ++ // 64 bit signed, lo20 and lo12 bits are not 0, hi20 bits can be obtained by sign ++ // extension of the lo20 bits. other bits are not 0. ++ C_DCON12_32S ++ // 64 bit signed, hi20 bits are not 0, hi12 bits can be obtained by sign ++ // extension of the hi20 bits, lo32 bits are not 0. ++ C_DCON20S_32 ++ // 64 bit signed, 12~51 bits 0, other bits are not 0. ++ C_DCON12_12U ++ // 64 bit signed, lo20 bits 0, hi20 bits are not 0, hi12 bits can be ++ // obtained by sign extension of the hi20 bits, lo12 bits are not 0. ++ C_DCON20S_12U ++ // 64 bit signed, lo20 bits 0, other bits are not 0. ++ C_DCON32_12U ++ // other 64 ++ C_DCON ++ + C_SACON // $n(REG) where n <= int12 + C_LACON // $n(REG) where int12 < n <= int32 + C_DACON // $n(REG) where int32 < n +diff --git a/src/cmd/internal/obj/loong64/asm.go b/src/cmd/internal/obj/loong64/asm.go +index 9024c5e53e..5757c3c452 100644 +--- a/src/cmd/internal/obj/loong64/asm.go ++++ b/src/cmd/internal/obj/loong64/asm.go +@@ -9,6 +9,7 @@ import ( + "cmd/internal/objabi" + "fmt" + "log" ++ "math/bits" + "slices" + ) + +@@ -192,6 +193,9 @@ var optab = []Optab{ + {AMOVV, C_UCON, C_NONE, C_NONE, C_REG, C_NONE, 24, 4, 0, 0}, + {AMOVW, C_LCON, C_NONE, C_NONE, C_REG, C_NONE, 19, 8, 0, NOTUSETMP}, + {AMOVV, C_LCON, C_NONE, C_NONE, C_REG, C_NONE, 19, 8, 0, NOTUSETMP}, ++ {AMOVV, C_DCON12_0, C_NONE, C_NONE, C_REG, C_NONE, 67, 4, 0, NOTUSETMP}, ++ {AMOVV, C_DCON12_20S, C_NONE, C_NONE, C_REG, C_NONE, 68, 8, 0, NOTUSETMP}, ++ {AMOVV, C_DCON32_12S, C_NONE, C_NONE, C_REG, C_NONE, 69, 12, 0, NOTUSETMP}, + {AMOVV, C_DCON, C_NONE, C_NONE, C_REG, C_NONE, 59, 16, 0, NOTUSETMP}, + + {AADD, C_ADD0CON, C_REG, C_NONE, C_REG, C_NONE, 4, 4, 0, 0}, +@@ -225,6 +229,20 @@ var optab = []Optab{ + + {AADDV, C_DCON, C_NONE, C_NONE, C_REG, C_NONE, 60, 20, 0, 0}, + {AADDV, C_DCON, C_REG, C_NONE, C_REG, C_NONE, 60, 20, 0, 0}, ++ {AAND, C_DCON, C_NONE, C_NONE, C_REG, C_NONE, 60, 20, 0, 0}, ++ {AAND, C_DCON, C_REG, C_NONE, C_REG, C_NONE, 60, 20, 0, 0}, ++ {AADDV, C_DCON12_0, C_NONE, C_NONE, C_REG, C_NONE, 70, 8, 0, 0}, ++ {AADDV, C_DCON12_0, C_REG, C_NONE, C_REG, C_NONE, 70, 8, 0, 0}, ++ {AAND, C_DCON12_0, C_NONE, C_NONE, C_REG, C_NONE, 70, 8, 0, 0}, ++ {AAND, C_DCON12_0, C_REG, C_NONE, C_REG, C_NONE, 70, 8, 0, 0}, ++ {AADDV, C_DCON12_20S, C_NONE, C_NONE, C_REG, C_NONE, 71, 12, 0, 0}, ++ {AADDV, C_DCON12_20S, C_REG, C_NONE, C_REG, C_NONE, 71, 12, 0, 0}, ++ {AAND, C_DCON12_20S, C_NONE, C_NONE, C_REG, C_NONE, 71, 12, 0, 0}, ++ {AAND, C_DCON12_20S, C_REG, C_NONE, C_REG, C_NONE, 71, 12, 0, 0}, ++ {AADDV, C_DCON32_12S, C_NONE, C_NONE, C_REG, C_NONE, 72, 16, 0, 0}, ++ {AADDV, C_DCON32_12S, C_REG, C_NONE, C_REG, C_NONE, 72, 16, 0, 0}, ++ {AAND, C_DCON32_12S, C_NONE, C_NONE, C_REG, C_NONE, 72, 16, 0, 0}, ++ {AAND, C_DCON32_12S, C_REG, C_NONE, C_REG, C_NONE, 72, 16, 0, 0}, + + {ASLL, C_SCON, C_REG, C_NONE, C_REG, C_NONE, 16, 4, 0, 0}, + {ASLL, C_SCON, C_NONE, C_NONE, C_REG, C_NONE, 16, 4, 0, 0}, +@@ -790,7 +808,7 @@ func (c *ctxt0) aclass(a *obj.Addr) int { + } + + if c.instoffset != int64(int32(c.instoffset)) { +- return C_DCON ++ return dconClass(c.instoffset) + } + + if c.instoffset >= 0 { +@@ -830,6 +848,159 @@ func (c *ctxt0) aclass(a *obj.Addr) int { + return C_GOK + } + ++// The constants here define the data characteristics within the bit field range. ++// ++// ALL1: The data in the bit field is all 1 ++// ALL0: The data in the bit field is all 0 ++// ST1: The data in the bit field starts with 1, but not all 1 ++// ST0: The data in the bit field starts with 0, but not all 0 ++const ( ++ ALL1 = iota ++ ALL0 ++ ST1 ++ ST0 ++) ++ ++// mask returns the mask of the specified bit field, which is used to help determine ++// the data characteristics of the immediate value at the specified bit. ++func mask(suf int8, len int8) (uint64, uint64) { ++ if len == 12 { ++ if suf == 0 { ++ return 0xfff, 0x800 ++ } else { // suf == 52 ++ return 0xfff0000000000000, 0x8000000000000000 ++ } ++ } else { // len == 20 ++ if suf == 12 { ++ return 0xfffff000, 0x80000000 ++ } else { // suf == 32 ++ return 0xfffff00000000, 0x8000000000000 ++ } ++ } ++} ++ ++// bitField return a number represent status of val in bit field ++// ++// suf: The starting bit of the bit field ++// len: The length of the bit field ++func bitField(val int64, suf int8, len int8) int8 { ++ mask1, mask2 := mask(suf, len) ++ if uint64(val)&mask1 == mask1 { ++ return ALL1 ++ } else if uint64(val)&mask1 == 0x0 { ++ return ALL0 ++ } else if uint64(val)&mask2 == mask2 { ++ return ST1 ++ } else { ++ return ST0 ++ } ++} ++ ++// Loading an immediate value larger than 32 bits requires four instructions ++// on loong64 (lu12i.w + ori + lu32i.d + lu52i.d), but in some special cases, ++// we can use the sign extension and zero extension features of the instruction ++// to fill in the high-order data (all 0 or all 1), which can save one to ++// three instructions. ++// ++// | 63 ~ 52 | 51 ~ 32 | 31 ~ 12 | 11 ~ 0 | ++// | lu52i.d | lu32i.d | lu12i.w | ori | ++func dconClass(offset int64) int { ++ tzb := bits.TrailingZeros64(uint64(offset)) ++ hi12 := bitField(offset, 52, 12) ++ hi20 := bitField(offset, 32, 20) ++ lo20 := bitField(offset, 12, 20) ++ lo12 := bitField(offset, 0, 12) ++ if tzb >= 52 { ++ return C_DCON12_0 // lu52i.d ++ } ++ if tzb >= 32 { ++ if ((hi20 == ALL1 || hi20 == ST1) && hi12 == ALL1) || ((hi20 == ALL0 || hi20 == ST0) && hi12 == ALL0) { ++ return C_DCON20S_0 // addi.w + lu32i.d ++ } ++ return C_DCON32_0 // addi.w + lu32i.d + lu52i.d ++ } ++ if tzb >= 12 { ++ if lo20 == ST1 || lo20 == ALL1 { ++ if hi20 == ALL1 { ++ return C_DCON12_20S // lu12i.w + lu52i.d ++ } ++ if (hi20 == ST1 && hi12 == ALL1) || ((hi20 == ST0 || hi20 == ALL0) && hi12 == ALL0) { ++ return C_DCON20S_20 // lu12i.w + lu32i.d ++ } ++ return C_DCON32_20 // lu12i.w + lu32i.d + lu52i.d ++ } ++ if hi20 == ALL0 { ++ return C_DCON12_20S // lu12i.w + lu52i.d ++ } ++ if (hi20 == ST0 && hi12 == ALL0) || ((hi20 == ST1 || hi20 == ALL1) && hi12 == ALL1) { ++ return C_DCON20S_20 // lu12i.w + lu32i.d ++ } ++ return C_DCON32_20 // lu12i.w + lu32i.d + lu52i.d ++ } ++ if lo12 == ST1 || lo12 == ALL1 { ++ if lo20 == ALL1 { ++ if hi20 == ALL1 { ++ return C_DCON12_12S // addi.d + lu52i.d ++ } ++ if (hi20 == ST1 && hi12 == ALL1) || ((hi20 == ST0 || hi20 == ALL0) && hi12 == ALL0) { ++ return C_DCON20S_12S // addi.w + lu32i.d ++ } ++ return C_DCON32_12S // addi.w + lu32i.d + lu52i.d ++ } ++ if lo20 == ST1 { ++ if hi20 == ALL1 { ++ ++ return C_DCON12_32S // lu12i.w + ori + lu52i.d ++ } ++ if (hi20 == ST1 && hi12 == ALL1) || ((hi20 == ST0 || hi20 == ALL0) && hi12 == ALL0) { ++ return C_DCON20S_32 // lu12i.w + ori + lu32i.d ++ } ++ return C_DCON // lu12i.w + ori + lu32i.d + lu52i.d ++ } ++ if lo20 == ALL0 { ++ if hi20 == ALL0 { ++ return C_DCON12_12U // ori + lu52i.d ++ } ++ if ((hi20 == ST1 || hi20 == ALL1) && hi12 == ALL1) || (hi20 == ST0 && hi12 == ALL0) { ++ return C_DCON20S_12U // ori + lu32i.d ++ } ++ return C_DCON32_12U // ori + lu32i.d + lu52i.d ++ } ++ if hi20 == ALL0 { ++ return C_DCON12_32S // lu12i.w + ori + lu52i.d ++ } ++ if ((hi20 == ST1 || hi20 == ALL1) && hi12 == ALL1) || (hi20 == ST0 && hi12 == ALL0) { ++ return C_DCON20S_32 // lu12i.w + ori + lu32i.d ++ } ++ return C_DCON // lu12i.w + ori + lu32i.d + lu52i.d ++ } ++ if lo20 == ALL0 { ++ if hi20 == ALL0 { ++ return C_DCON12_12U // ori + lu52i.d ++ } ++ if ((hi20 == ST1 || hi20 == ALL1) && hi12 == ALL1) || (hi20 == ST0 && hi12 == ALL0) { ++ return C_DCON20S_12U // ori + lu32i.d ++ } ++ return C_DCON32_12U // ori + lu32i.d + lu52i.d ++ } ++ if lo20 == ST1 || lo20 == ALL1 { ++ if hi20 == ALL1 { ++ return C_DCON12_32S // lu12i.w + ori + lu52i.d ++ } ++ if (hi20 == ST1 && hi12 == ALL1) || ((hi20 == ST0 || hi20 == ALL0) && hi12 == ALL0) { ++ return C_DCON20S_32 // lu12i.w + ori + lu32i.d ++ } ++ return C_DCON ++ } ++ if hi20 == ALL0 { ++ return C_DCON12_32S // lu12i.w + ori + lu52i.d ++ } ++ if ((hi20 == ST1 || hi20 == ALL1) && hi12 == ALL1) || (hi20 == ST0 && hi12 == ALL0) { ++ return C_DCON20S_32 // lu12i.w + ori + lu32i.d ++ } ++ return C_DCON ++} ++ + // In Loong64,there are 8 CFRs, denoted as fcc0-fcc7. + // There are 4 FCSRs, denoted as fcsr0-fcsr3. + func (c *ctxt0) rclass(r int16) int { +@@ -935,7 +1106,14 @@ func cmp(a int, b int) bool { + } + switch a { + case C_DCON: +- if b == C_LCON { ++ if b == C_LCON || b == C_DCON32_0 || ++ b == C_DCON12_0 || b == C_DCON20S_0 || ++ b == C_DCON12_20S || b == C_DCON12_12S || ++ b == C_DCON20S_20 || b == C_DCON32_20 || ++ b == C_DCON20S_12S || b == C_DCON32_12S || ++ b == C_DCON12_32S || b == C_DCON20S_32 || ++ b == C_DCON12_12U || b == C_DCON20S_12U || ++ b == C_DCON32_12U { + return true + } + fallthrough +@@ -944,6 +1122,22 @@ func cmp(a int, b int) bool { + return true + } + ++ case C_DCON12_0: ++ ++ case C_DCON12_20S: ++ if b == C_DCON20S_20 || b == C_DCON12_12S || ++ b == C_DCON20S_12S || b == C_DCON12_12U || ++ b == C_DCON20S_12U || b == C_DCON20S_0 { ++ return true ++ } ++ ++ case C_DCON32_12S: ++ if b == C_DCON32_20 || b == C_DCON12_32S || ++ b == C_DCON20S_32 || b == C_DCON32_12U || ++ b == C_DCON32_0 { ++ return true ++ } ++ + case C_ADD0CON: + if b == C_ADDCON { + return true +@@ -2015,6 +2209,129 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) { + c.ctxt.Diag("illegal register combination: %v\n", p) + } + o1 = OP_RRR(atomicInst[p.As], uint32(rk), uint32(rj), uint32(rd)) ++ ++ case 67: // mov $dcon12_0, r ++ v := c.vregoff(&p.From) ++ o1 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(0), uint32(p.To.Reg)) ++ ++ case 68: // mov $dcon12_20S, r ++ v := c.vregoff(&p.From) ++ contype := c.aclass(&p.From) ++ switch contype { ++ default: // C_DCON12_20S ++ o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(p.To.Reg)) ++ o2 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(p.To.Reg), uint32(p.To.Reg)) ++ case C_DCON20S_20: ++ o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(p.To.Reg)) ++ o2 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(p.To.Reg)) ++ case C_DCON12_12S: ++ o1 = OP_12IRR(c.opirr(AADDV), uint32(v), uint32(0), uint32(p.To.Reg)) ++ o2 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(p.To.Reg), uint32(p.To.Reg)) ++ case C_DCON20S_12S, C_DCON20S_0: ++ o1 = OP_12IRR(c.opirr(AADD), uint32(v), uint32(0), uint32(p.To.Reg)) ++ o2 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(p.To.Reg)) ++ case C_DCON12_12U: ++ o1 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(0), uint32(p.To.Reg)) ++ o2 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(p.To.Reg), uint32(p.To.Reg)) ++ case C_DCON20S_12U: ++ o1 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(0), uint32(p.To.Reg)) ++ o2 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(p.To.Reg)) ++ } ++ ++ case 69: // mov $dcon32_12S, r ++ v := c.vregoff(&p.From) ++ contype := c.aclass(&p.From) ++ switch contype { ++ default: // C_DCON32_12S, C_DCON32_0 ++ o1 = OP_12IRR(c.opirr(AADD), uint32(v), uint32(0), uint32(p.To.Reg)) ++ o2 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(p.To.Reg)) ++ o3 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(p.To.Reg), uint32(p.To.Reg)) ++ case C_DCON32_20: ++ o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(p.To.Reg)) ++ o2 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(p.To.Reg)) ++ o3 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(p.To.Reg), uint32(p.To.Reg)) ++ case C_DCON12_32S: ++ o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(p.To.Reg)) ++ o2 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(p.To.Reg), uint32(p.To.Reg)) ++ o3 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(p.To.Reg), uint32(p.To.Reg)) ++ case C_DCON20S_32: ++ o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(p.To.Reg)) ++ o2 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(p.To.Reg), uint32(p.To.Reg)) ++ o3 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(p.To.Reg)) ++ case C_DCON32_12U: ++ o1 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(0), uint32(p.To.Reg)) ++ o2 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(p.To.Reg)) ++ o3 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(p.To.Reg), uint32(p.To.Reg)) ++ } ++ ++ case 70: // add $dcon12_0,[r1],r2 ++ v := c.vregoff(&p.From) ++ r := int(p.Reg) ++ if r == 0 { ++ r = int(p.To.Reg) ++ } ++ o1 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(0), uint32(REGTMP)) ++ o2 = OP_RRR(c.oprrr(p.As), uint32(REGTMP), uint32(r), uint32(p.To.Reg)) ++ ++ case 71: // add $dcon12_20S,[r1],r2 ++ v := c.vregoff(&p.From) ++ r := int(p.Reg) ++ if r == 0 { ++ r = int(p.To.Reg) ++ } ++ contype := c.aclass(&p.From) ++ switch contype { ++ default: // C_DCON12_20S ++ o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(REGTMP)) ++ o2 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(REGTMP), uint32(REGTMP)) ++ case C_DCON20S_20: ++ o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(REGTMP)) ++ o2 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(REGTMP)) ++ case C_DCON12_12S: ++ o1 = OP_12IRR(c.opirr(AADDV), uint32(v), uint32(0), uint32(REGTMP)) ++ o2 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(REGTMP), uint32(REGTMP)) ++ case C_DCON20S_12S, C_DCON20S_0: ++ o1 = OP_12IRR(c.opirr(AADD), uint32(v), uint32(0), uint32(REGTMP)) ++ o2 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(REGTMP)) ++ case C_DCON12_12U: ++ o1 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(0), uint32(REGTMP)) ++ o2 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(REGTMP), uint32(REGTMP)) ++ case C_DCON20S_12U: ++ o1 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(0), uint32(REGTMP)) ++ o2 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(REGTMP)) ++ } ++ o3 = OP_RRR(c.oprrr(p.As), uint32(REGTMP), uint32(r), uint32(p.To.Reg)) ++ ++ case 72: // add $dcon32_12S,[r1],r2 ++ v := c.vregoff(&p.From) ++ r := int(p.Reg) ++ if r == 0 { ++ r = int(p.To.Reg) ++ } ++ contype := c.aclass(&p.From) ++ switch contype { ++ default: // C_DCON32_12S, C_DCON32_0 ++ o1 = OP_12IRR(c.opirr(AADD), uint32(v), uint32(0), uint32(REGTMP)) ++ o2 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(REGTMP)) ++ o3 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(REGTMP), uint32(REGTMP)) ++ case C_DCON32_20: ++ o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(REGTMP)) ++ o2 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(REGTMP)) ++ o3 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(REGTMP), uint32(REGTMP)) ++ case C_DCON12_32S: ++ o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(REGTMP)) ++ o2 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(REGTMP), uint32(REGTMP)) ++ o3 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(REGTMP), uint32(REGTMP)) ++ case C_DCON20S_32: ++ o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(REGTMP)) ++ o2 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(REGTMP), uint32(REGTMP)) ++ o3 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(REGTMP)) ++ case C_DCON32_12U: ++ o1 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(0), uint32(REGTMP)) ++ o2 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(REGTMP)) ++ o3 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(REGTMP), uint32(REGTMP)) ++ } ++ o4 = OP_RRR(c.oprrr(p.As), uint32(REGTMP), uint32(r), uint32(p.To.Reg)) + } + + out[0] = o1 +diff --git a/src/cmd/internal/obj/loong64/cnames.go b/src/cmd/internal/obj/loong64/cnames.go +index ce76109d2a..a2f04a22ee 100644 +--- a/src/cmd/internal/obj/loong64/cnames.go ++++ b/src/cmd/internal/obj/loong64/cnames.go +@@ -21,6 +21,20 @@ var cnames0 = []string{ + "ADDCON", + "ANDCON", + "LCON", ++ "DCON20S_0", ++ "DCON12_0", ++ "DCON32_0", ++ "DCON12_20S", ++ "DCON20S_20", ++ "DCON32_20", ++ "DCON12_12S", ++ "DCON20S_12S", ++ "DCON32_12S", ++ "DCON12_32S", ++ "DCON20S_32", ++ "DCON12_12U", ++ "DCON20S_12U", ++ "DCON32_12U", + "DCON", + "SACON", + "LACON", +-- +2.38.1 + diff --git a/0012-math-big-optimize-addVV-function-for-loong64.patch b/0012-math-big-optimize-addVV-function-for-loong64.patch new file mode 100644 index 0000000000000000000000000000000000000000..8d91ab457176ba0293acd53bab799992c13f77ce --- /dev/null +++ b/0012-math-big-optimize-addVV-function-for-loong64.patch @@ -0,0 +1,85 @@ +From a7a4eb8120aaf7d5f8d2146f190c64118c7e1235 Mon Sep 17 00:00:00 2001 +From: Huang Qiqi +Date: Thu, 6 Jun 2024 15:30:20 +0800 +Subject: [PATCH 12/44] math/big: optimize addVV function for loong64 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Benchmark results on Loongson 3C5000 (which is an LA464 implementation): + +goos: linux +goarch: loong64 +pkg: math/big +cpu: Loongson-3C5000 @ 2200.00MHz + │ test/old_3c5000_addvv.log │ test/new_3c5000_addvv.log │ + │ sec/op │ sec/op vs base │ +AddVV/1 10.920n ± 0% 7.671n ± 0% -29.75% (p=0.000 n=20) +AddVV/2 14.100n ± 0% 8.849n ± 0% -37.24% (p=0.000 n=20) +AddVV/3 16.38n ± 0% 11.07n ± 0% -32.42% (p=0.000 n=20) +AddVV/4 18.65n ± 0% 12.86n ± 0% -31.05% (p=0.000 n=20) +AddVV/5 20.93n ± 0% 15.01n ± 0% -28.28% (p=0.000 n=20) +AddVV/10 31.84n ± 0% 22.75n ± 0% -28.53% (p=0.000 n=20) +AddVV/100 242.4n ± 0% 149.7n ± 0% -38.24% (p=0.000 n=20) +AddVV/1000 2.290µ ± 0% 1.378µ ± 0% -39.83% (p=0.000 n=20) +AddVV/10000 32.73µ ± 0% 19.36µ ± 0% -40.84% (p=0.000 n=20) +AddVV/100000 340.9µ ± 0% 238.5µ ± 0% -30.03% (p=0.000 n=20) +geomean 213.2n 141.2n -33.79% + +Change-Id: I7983a93d9b97d4e9ebe96a49107ec6db9194b013 +--- + src/math/big/arith_loong64.s | 31 +++++++++++++++++++++++++++++-- + 1 file changed, 29 insertions(+), 2 deletions(-) + +diff --git a/src/math/big/arith_loong64.s b/src/math/big/arith_loong64.s +index 847e3127fb..bd7204cf06 100644 +--- a/src/math/big/arith_loong64.s ++++ b/src/math/big/arith_loong64.s +@@ -2,15 +2,42 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build !math_big_pure_go && loong64 ++//go:build !math_big_pure_go + + #include "textflag.h" + + // This file provides fast assembly versions for the elementary + // arithmetic operations on vectors implemented in arith.go. + ++// func addVV(z, x, y []Word) (c Word) + TEXT ·addVV(SB),NOSPLIT,$0 +- JMP ·addVV_g(SB) ++ // input: ++ // R4: z ++ // R5: z_len ++ // R7: x ++ // R10: y ++ MOVV z+0(FP), R4 ++ MOVV z_len+8(FP), R5 ++ MOVV x+24(FP), R7 ++ MOVV y+48(FP), R10 ++ MOVV $0, R6 ++ SLLV $3, R5 ++ MOVV $0, R8 ++loop: ++ BEQ R5, R6, done ++ MOVV (R6)(R7), R9 ++ MOVV (R6)(R10), R11 ++ ADDV R9, R11, R11 // x1 + y1 = z1', if z1' < x1 then z1' overflow ++ ADDV R8, R11, R12 // z1' + c0 = z1, if z1 < z1' then z1 overflow ++ SGTU R9, R11, R9 ++ SGTU R11, R12, R11 ++ MOVV R12, (R6)(R4) ++ OR R9, R11, R8 ++ ADDV $8, R6 ++ JMP loop ++done: ++ MOVV R8, c+72(FP) ++ RET + + TEXT ·subVV(SB),NOSPLIT,$0 + JMP ·subVV_g(SB) +-- +2.38.1 + diff --git a/0012-src-internal-Add-sw64-port.patch b/0012-src-internal-Add-sw64-port.patch new file mode 100644 index 0000000000000000000000000000000000000000..070f05aebee5209a0efcb63c0c937497230e8d85 --- /dev/null +++ b/0012-src-internal-Add-sw64-port.patch @@ -0,0 +1,1809 @@ +diff --git a/src/internal/abi/abi_sw64.go b/src/internal/abi/abi_sw64.go +new file mode 100644 +index 0000000000..49127465e1 +--- /dev/null ++++ b/src/internal/abi/abi_sw64.go +@@ -0,0 +1,19 @@ ++// 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 goexperiment.regabiargs && sw64 ++ ++package abi ++ ++const ( ++ // See abi_generic.go. ++ ++ // R16 - R24. ++ IntArgRegs = 9 ++ ++ // F16 - F24. ++ FloatArgRegs = 9 ++ ++ EffectiveFloatRegSize = 8 ++) +diff --git a/src/internal/abi/switch.go b/src/internal/abi/switch.go +index 9669fe51d5..eab8ef8e90 100644 +--- a/src/internal/abi/switch.go ++++ b/src/internal/abi/switch.go +@@ -36,7 +36,7 @@ func UseInterfaceSwitchCache(goarch string) bool { + // We need an atomic load instruction to make the cache multithreaded-safe. + // (AtomicLoadPtr needs to be implemented in cmd/compile/internal/ssa/_gen/ARCH.rules.) + switch goarch { +- case "amd64", "arm64", "loong64", "mips", "mipsle", "mips64", "mips64le", "ppc64", "ppc64le", "riscv64", "s390x": ++ case "amd64", "arm64", "loong64", "mips", "mipsle", "mips64", "mips64le", "ppc64", "ppc64le", "riscv64", "s390x", "sw64": + return true + default: + return false +diff --git a/src/internal/buildcfg/cfg.go b/src/internal/buildcfg/cfg.go +index fca09bf8d3..2c2c5c7e51 100644 +--- a/src/internal/buildcfg/cfg.go ++++ b/src/internal/buildcfg/cfg.go +@@ -31,6 +31,7 @@ var ( + GOMIPS64 = gomips64() + GOPPC64 = goppc64() + GORISCV64 = goriscv64() ++ GOSW64 = gosw64() + GOWASM = gowasm() + ToolTags = toolTags() + GO_LDSO = defaultGO_LDSO +@@ -317,6 +318,19 @@ func goriscv64() int { + return year + } + ++func gosw64() int { ++ switch v := envOr("GOSW64", defaultGOSW64); v { ++ case "swv3": ++ return 3 ++ case "swv4": ++ return 4 ++ case "swv5": ++ return 5 ++ } ++ Error = fmt.Errorf("Invalid SW64 value. Must be swv3 or swv4.") ++ return int(defaultGOSW64[len("swv")] - '0') ++} ++ + type gowasmFeatures struct { + SatConv bool + SignExt bool +diff --git a/src/internal/buildcfg/exp.go b/src/internal/buildcfg/exp.go +index 332c9afa57..0bfbe8257a 100644 +--- a/src/internal/buildcfg/exp.go ++++ b/src/internal/buildcfg/exp.go +@@ -65,6 +65,8 @@ func ParseGOEXPERIMENT(goos, goarch, goexp string) (*ExperimentFlags, error) { + case "amd64", "arm64", "loong64", "ppc64le", "ppc64", "riscv64": + regabiAlwaysOn = true + regabiSupported = true ++ case "sw64": ++ regabiSupported = true + } + + var haveXchg8 bool +diff --git a/src/internal/bytealg/compare_generic.go b/src/internal/bytealg/compare_generic.go +index 614ae8b8cf..94fd4ad07f 100644 +--- a/src/internal/bytealg/compare_generic.go ++++ b/src/internal/bytealg/compare_generic.go +@@ -2,7 +2,7 @@ + // 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 ++//go:build !386 && !amd64 && !s390x && !arm && !arm64 && !loong64 && !ppc64 && !ppc64le && !mips && !mipsle && !wasm && !mips64 && !mips64le && !riscv64 && !sw64 + + package bytealg + +diff --git a/src/internal/bytealg/compare_native.go b/src/internal/bytealg/compare_native.go +index 983ab069db..8672f10a70 100644 +--- a/src/internal/bytealg/compare_native.go ++++ b/src/internal/bytealg/compare_native.go +@@ -2,7 +2,7 @@ + // 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 ++//go:build 386 || amd64 || s390x || arm || arm64 || loong64 || ppc64 || ppc64le || mips || mipsle || wasm || mips64 || mips64le || riscv64 || sw64 + + package bytealg + +diff --git a/src/internal/bytealg/compare_sw64.s b/src/internal/bytealg/compare_sw64.s +new file mode 100644 +index 0000000000..f5b10630ac +--- /dev/null ++++ b/src/internal/bytealg/compare_sw64.s +@@ -0,0 +1,93 @@ ++// 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 sw64 ++// +build sw64 ++ ++#include "go_asm.h" ++#include "textflag.h" ++ ++TEXT ·Compare(SB),NOFRAME|NOSPLIT,$0-56 ++#ifdef GOEXPERIMENT_regabiargs ++ // R16 = a_base (want in R16) ++ // R17 = a_len (want in R17) ++ // R18 = a_cap (unused) ++ // R19 = b_base (want in R18) ++ // R20 = b_len (want in R19) ++ // R21 = b_cap (unused) ++ LDI R18, R19 ++ LDI R19, R20 ++#else ++ LDL R16, a_base+0(FP) ++ LDL R17, a_len+8(FP) ++ LDL R18, b_base+24(FP) ++ LDL R19, b_len+32(FP) ++#endif ++ CMPEQ R16, R18, R4 ++ BNE R4, samebytes ++ CMPULT R17, R19, R4 ++ SELEQ R4, R19, R17, R5 // R5 is min(R0,R1) ++ ++ ADDL R5, R16, R5 ++loop: ++ CMPEQ R5, R16, R8 ++ BNE R8, samebytes // all compared bytes were the same; compare lengths ++ LDBU R6, (R16) ++ ADDL R16, $1, R16 ++ LDBU R7, (R18) ++ ADDL R18, $1, R18 ++ CMPEQ R6, R7, R8 ++ BNE R8, loop ++ // bytes differed ++ CMPULT R7, R6, R8 ++ LDI R6, $-1 ++ SELEQ R8, R6, R8, R16 ++ JMP cmp_ret ++samebytes: ++ CMPULT R19, R17, R6 ++ CMPULT R17, R19, R7 ++ SUBL R6, R7, R16 ++cmp_ret: ++#ifndef GOEXPERIMENT_regabiargs ++ STL R16, ret+48(FP) ++#endif ++ RET ++ ++TEXT runtime·cmpstring(SB),NOFRAME|NOSPLIT,$0-40 ++#ifndef GOEXPERIMENT_regabiargs ++ LDL R16, a_base+0(FP) ++ LDL R17, a_len+8(FP) ++ LDL R18, b_base+16(FP) ++ LDL R19, b_len+24(FP) ++#endif ++ CMPEQ R16, R18, R4 ++ BNE R4, samebytes ++ CMPULT R17, R19, R4 ++ SELEQ R4, R19, R17, R5 // R5 is min(R0,R1) ++ ++ ADDL R5, R16, R5 ++loop: ++ CMPEQ R5, R16, R8 ++ BNE R8, samebytes // all compared bytes were the same; compare lengths ++ ++ LDBU R6, (R16) ++ ADDL R16, $1, R16 ++ LDBU R7, (R18) ++ ADDL R18, $1, R18 ++ CMPEQ R6, R7, R8 ++ BNE R8, loop ++ // bytes differed ++ CMPULT R7, R6, R8 ++ LDI R6, $-1 ++ SELEQ R8, R6, R8, R16 ++ JMP cmp_ret ++samebytes: ++ CMPULT R19, R17, R6 ++ CMPULT R17, R19, R7 ++ SUBL R6, R7, R16 ++cmp_ret: ++#ifndef GOEXPERIMENT_regabiargs ++ STL R16, ret+32(FP) ++#endif ++ RET +diff --git a/src/internal/bytealg/count_generic.go b/src/internal/bytealg/count_generic.go +index 932a7c584c..1721316f8e 100644 +--- a/src/internal/bytealg/count_generic.go ++++ b/src/internal/bytealg/count_generic.go +@@ -2,7 +2,7 @@ + // 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 && !loong64 && !ppc64le && !ppc64 && !riscv64 && !s390x ++//go:build !amd64 && !arm && !arm64 && !loong64 && !ppc64le && !ppc64 && !riscv64 && !s390x && !sw64 + + package bytealg + +diff --git a/src/internal/bytealg/count_native.go b/src/internal/bytealg/count_native.go +index 90189c9fe0..f49717723d 100644 +--- a/src/internal/bytealg/count_native.go ++++ b/src/internal/bytealg/count_native.go +@@ -2,7 +2,7 @@ + // 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 || loong64 || ppc64le || ppc64 || riscv64 || s390x ++//go:build amd64 || arm || arm64 || loong64 || ppc64le || ppc64 || riscv64 || s390x || sw64 + + package bytealg + +diff --git a/src/internal/bytealg/count_sw64.s b/src/internal/bytealg/count_sw64.s +new file mode 100644 +index 0000000000..c67a989a29 +--- /dev/null ++++ b/src/internal/bytealg/count_sw64.s +@@ -0,0 +1,112 @@ ++// 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 sw64 ++// +build sw64 ++ ++#include "go_asm.h" ++#include "textflag.h" ++ ++TEXT ·Count(SB),NOSPLIT,$0-40 ++ LDL R0, b_base+0(FP) ++ LDL R2, b_len+8(FP) ++ LDBU R1, c+24(FP) ++ LDI R8, $ret+32(FP) ++ BR countbytebody<>(SB) ++ ++TEXT ·CountString(SB),NOSPLIT,$0-32 ++ LDL R0, s_base+0(FP) ++ LDL R2, s_len+8(FP) ++ LDBU R1, c+16(FP) ++ LDI R8, $ret+24(FP) ++ BR countbytebody<>(SB) ++ ++// input: ++// R0: data ++// R2: data len ++// R1: byte to find ++// R8: address to put result ++TEXT countbytebody<>(SB),NOSPLIT,$0-0 ++ // R11 = count of byte to search ++ LDI R11, $0 ++ // short path to handle 0-byte case ++ BEQ R2, done ++ CMPULT R2, $0x10, R28 ++ // jump directly to tail if length < 32 ++ BNE R28, tail ++ ++ AND R0, $0xf, R9 ++ BEQ R9, chunk ++ // Work with not 32-byte aligned head ++ BIC R0, $0xf, R3 ++ ADDL R3, $0x10, R3 ++head_loop: ++ LDBU R5, (R0) ++ ADDL R0, $1, R0 ++ CMPEQ R5, R1, R28 ++ ADDL R11, R28, R11 ++ SUBL R2, $1, R2 ++ CMPEQ R0, R3, R28 ++ BEQ R28, head_loop ++ // Work with 32-byte aligned chunks ++chunk: ++ BIC R2, $0xf, R9 ++ // The first chunk can also be the last ++ BEQ R9, tail ++ // R3 = end of 32-byte chunks ++ ADDL R0, R9, R3 ++ // R2 = length of tail ++ SUBL R2, R9, R2 ++ // Duplicate R1 (byte to search) to 16 1-byte elements of V0 ++ XOR R7, R7, R7 ++ BIS R1, R7, R7 ++ SLL R7, $8, R7 ++ BIS R1, R7, R7 ++ SLL R7, $8, R7 ++ BIS R1, R7, R7 ++ SLL R7, $8, R7 ++ BIS R1, R7, R7 ++ SLL R7, $8, R7 ++ BIS R1, R7, R7 ++ SLL R7, $8, R7 ++ BIS R1, R7, R7 ++ SLL R7, $8, R7 ++ BIS R1, R7, R7 ++ SLL R7, $8, R7 ++ BIS R1, R7, R7 ++ ++ XOR R22, R22, R22 ++ // Count the target byte in 32-byte chunk ++chunk_loop: ++ LDL R16, (R0) ++ LDL R17, 8(R0) ++ ADDL R0, $16, R0 ++ CMPEQ R0, R3, R28 ++ //VCMPUEQB V0, V1, V3 ++ CMPGEB R7, R16, R18 ++ CMPGEB R7, R17, R19 ++ CMPGEB R16, R7, R16 ++ CMPGEB R17, R7, R17 ++ AND R16, R18, R16 ++ AND R17, R19, R17 ++ // Count lanes match the requested byte ++ CTPOP R16, R16 // 32B->16B ++ CTPOP R17, R17 ++ ADDL R16, R17, R16 ++ ADDL R16, R22, R22 ++ // Accumulate the count in low 64-bit element of V8 when inside the loop ++ BEQ R28, chunk_loop ++ ADDL R22, R11, R11 ++ BEQ R2, done ++tail: ++ // Work with tail shorter than 32 bytes ++ LDBU R5, (R0) ++ ADDL R0, $1, R0 ++ SUBL R2, $1, R2 ++ CMPEQ R5, R1, R28 ++ ADDL R11, R28, R11 ++ BNE R2, tail ++done: ++ STL R11, (R8) ++ RET +diff --git a/src/internal/bytealg/equal_sw64.s b/src/internal/bytealg/equal_sw64.s +new file mode 100644 +index 0000000000..2cba2ea6e6 +--- /dev/null ++++ b/src/internal/bytealg/equal_sw64.s +@@ -0,0 +1,70 @@ ++// 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 sw64 ++// +build sw64 ++ ++#include "go_asm.h" ++#include "textflag.h" ++ ++// memequal(a, b unsafe.Pointer, size uintptr) bool ++TEXT runtime·memequal(SB),NOSPLIT,$0-25 ++#ifndef GOEXPERIMENT_regabiargs ++ LDL R16, $p+0(FP) ++ LDL R17, $q+8(FP) ++ LDL R18, $size+16(FP) ++#endif ++ BEQ R18, eq ++ CMPEQ R16, R17, R3 ++ BNE R3, eq ++loop: ++ LDBU R3, (R16) ++ LDBU R4, (R17) ++ ++ CMPEQ R3, R4, R3 ++ BEQ R3, ne ++ ++ ADDL R16, $1, R16 ++ ADDL R17, $1, R17 ++ SUBL R18, $1, R18 ++ BNE R18, loop ++eq: ++ LDI R16, $1 ++#ifndef GOEXPERIMENT_regabiargs ++ STB R16, $ret+24(FP) ++#endif ++ RET ++ne: ++ LDI R16, ZERO ++#ifndef GOEXPERIMENT_regabiargs ++ STB R16, $ret+24(FP) ++#endif ++ RET ++ ++// memequal_varlen(a, b unsafe.Pointer) bool ++TEXT runtime·memequal_varlen(SB),NOSPLIT,$40-17 ++#ifndef GOEXPERIMENT_regabiargs ++ LDL R16, a+0(FP) ++ LDL R17, b+8(FP) ++#endif ++ CMPEQ R16, R17, R11 ++ BNE R11, eq ++ LDL R3, 8(REGCTXT) // compiler stores size at offset 8 in the closure ++ STL R16, 8(SP) ++ STL R17, 16(SP) ++ STL R3, 24(SP) ++ ++ CALL runtime·memequal(SB) ++ LDBU R16, 32(SP) ++#ifndef GOEXPERIMENT_regabiargs ++ STB R16, ret+16(FP) ++#endif ++ RET ++eq: ++ LDI R16, $1 ++#ifndef GOEXPERIMENT_regabiargs ++ STB R16, ret+16(FP) ++#endif ++ RET ++ +diff --git a/src/internal/bytealg/indexbyte_generic.go b/src/internal/bytealg/indexbyte_generic.go +index b7fffcf460..e4a3111d2a 100644 +--- a/src/internal/bytealg/indexbyte_generic.go ++++ b/src/internal/bytealg/indexbyte_generic.go +@@ -6,7 +6,7 @@ + // 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 ++//go:build !386 && (!amd64 || plan9) && !s390x && !arm && !arm64 && !loong64 && !ppc64 && !ppc64le && !mips && !mipsle && !mips64 && !mips64le && !riscv64 && !wasm && !sw64 + + package bytealg + +diff --git a/src/internal/bytealg/indexbyte_native.go b/src/internal/bytealg/indexbyte_native.go +index 8e46c31ff6..bf591bad14 100644 +--- a/src/internal/bytealg/indexbyte_native.go ++++ b/src/internal/bytealg/indexbyte_native.go +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build 386 || (amd64 && !plan9) || s390x || arm || arm64 || loong64 || ppc64 || ppc64le || mips || mipsle || mips64 || mips64le || riscv64 || wasm ++//go:build 386 || (amd64 && !plan9) || s390x || arm || arm64 || loong64 || ppc64 || ppc64le || mips || mipsle || mips64 || mips64le || riscv64 || wasm || sw64 + + package bytealg + +diff --git a/src/internal/bytealg/indexbyte_sw64.s b/src/internal/bytealg/indexbyte_sw64.s +new file mode 100644 +index 0000000000..f3b66b547e +--- /dev/null ++++ b/src/internal/bytealg/indexbyte_sw64.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. ++ ++//go:build sw64 ++// +build sw64 ++ ++#include "go_asm.h" ++#include "textflag.h" ++ ++TEXT ·IndexByte(SB),NOFRAME|NOSPLIT,$0-40 ++ LDL R1, b_base+0(FP) ++ LDL R2, b_len+8(FP) ++ BEQ R2, notfound ++ LDBU R3, c+24(FP) ++ LDI R4, R1 ++ ADDL R1, R2, R2 // end ++ SUBL R1, $1, R1 ++ ++loop: ++ ADDL R1, $1, R1 ++ CMPEQ R1, R2, R5 ++ BNE R5, notfound ++ ++ LDBU R6, (R1) ++ CMPEQ R6, R3, R6 ++ BEQ R6, loop ++ ++ SUBL R1, R4, R1 // remove base ++ STL R1, ret+32(FP) ++ RET ++ ++notfound: ++ LDI R1, $-1 ++ STL R1, ret+32(FP) ++ RET ++ ++TEXT ·IndexByteString(SB),NOFRAME|NOSPLIT,$0-32 ++ LDL R1, s_base+0(FP) ++ LDL R2, s_len+8(FP) ++ BEQ R2, notfound ++ LDBU R3, c+16(FP) ++ LDI R4, R1 ++ ADDL R1, R2, R2 // end ++ SUBL R1, $1, R1 ++ ++loop: ++ ADDL R1, $1, R1 ++ CMPEQ R1, R2, R5 ++ BNE R5, notfound ++ ++ LDBU R6, (R1) ++ CMPEQ R6, R3, R6 ++ BEQ R6, loop ++ ++ SUBL R1, R4, R1 // remove base ++ STL R1, ret+24(FP) ++ RET ++ ++notfound: ++ LDI R1, $-1 ++ STL R1, ret+24(FP) ++ RET +diff --git a/src/internal/bytealg/indexbyte_sw64_prototype.s b/src/internal/bytealg/indexbyte_sw64_prototype.s +new file mode 100644 +index 0000000000..faada62f18 +--- /dev/null ++++ b/src/internal/bytealg/indexbyte_sw64_prototype.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. ++ ++//go:build ignore ++// +build ignore ++ ++#include "go_asm.h" ++#include "textflag.h" ++ ++TEXT ·IndexByte(SB),NOSPLIT,$0-40 ++ LDL R0, b_base+0(FP) ++ LDL R2, b_len+8(FP) ++ LDBU R1, c+24(FP) ++ LDI R8, $ret+32(FP) ++ BR indexbytebody<>(SB) ++ ++TEXT ·IndexByteString(SB),NOSPLIT,$0-32 ++ LDL R0, s_base+0(FP) ++ LDL R2, s_len+8(FP) ++ LDBU R1, c+16(FP) ++ LDI R8, $ret+24(FP) ++ BR indexbytebody<>(SB) ++ ++// input: ++// R0: data ++// R1: byte to search ++// R2: data len ++// R8: address to put result ++TEXT indexbytebody<>(SB),NOSPLIT,$0 ++ BEQ R2, notfound ++ // short path to handle 0-byte case ++ CMPULT R2, $0x8, R28 ++ BIS R0, R0, R16 ++ ADDL R2, R0, R3 ++ // jump directly to tail if length < 32 ++ // mov orignal data ptr to R16 ++ // Work with 32-byte aligned chunks ++ XOR R7, R7, R7 ++ BIS R1, R7, R7 ++ SLL R7, $8, R7 ++ BIS R1, R7, R7 ++ SLL R7, $8, R7 ++ BIS R1, R7, R7 ++ SLL R7, $8, R7 ++ BIS R1, R7, R7 ++ SLL R7, $8, R7 ++ BIS R1, R7, R7 ++ SLL R7, $8, R7 ++ BIS R1, R7, R7 ++ SLL R7, $8, R7 ++ BIS R1, R7, R7 ++ SLL R7, $8, R7 ++ BIS R1, R7, R7 ++ SLL R7, $8, R7 ++ BIS R1, R7, R7 ++ BNE R28, small ++ // select page addr ++ //LDI R28, $8192 ++ ADDL R2, R0, R3 ++ SUBL R3, $8, R3 ++ ++chunk_loop: ++ LDL R5, (R0) ++ CMPGEB R5, R7, R6 ++ CMPGEB R7, R5, R4 ++ AND R6, R4, R5 ++ // Count lanes match the requested byte ++ BNE R5, found ++ // Accumulate the count in low 64-bit element of V8 when inside the loop ++ ADDL R0, $8, R0 ++ CMPLE R0, R3, R28 ++ BNE R28, chunk_loop ++ ++ LDI R0, R3 ++ LDL R5, (R3) ++ CMPGEB R5, R7, R6 ++ CMPGEB R7, R5, R4 ++ AND R6, R4, R5 ++ // Count lanes match the requested byte ++ BNE R5, found ++ ++notfound: ++ LDI R1, -1 ++ STL R1, (R8) ++ RET ++ ++small: ++ LDI R9, $8184 ++ ADDL R0, $8, R6 ++ AND R6, R9, R28 ++ BEQ R28, endofpage ++ // Work with tail shorter than 32 bytes ++ LDL R5, (R0) ++ CMPGEB R5, R7, R6 ++ CMPGEB R7, R5, R4 ++ AND R6, R4, R5 ++ BEQ R5, notfound ++ CTTZ R5, R5 ++ CMPLT R5, R2, R28 ++ BEQ R28, notfound ++ STL R5, (R8) ++ RET ++ ++found: ++ //SUBL R0, $8, R0 ++ CTTZ R5, R5 ++ SUBL R0, R16, R0 ++ ADDL R5, R0, R0 ++ CMPLT R0, R2, R28 ++ BEQ R28, notfound ++ STL R0, (R8) ++ RET ++ ++endofpage: ++ ADDL R0, R2, R3 ++ SUBL R3, $8, R3 ++ LDL R5, (R3) ++ CMPGEB R5, R7, R6 ++ CMPGEB R7, R5, R4 ++ AND R6, R4, R5 ++ ZAPNOT R2, $1, R9 ++ SLL R5, R9, R5 ++ SRL R5, $8, R5 ++ BEQ R5, notfound ++ CTTZ R5, R5 ++ STL R5, (R8) ++ RET ++ ++ +diff --git a/src/internal/cfg/cfg.go b/src/internal/cfg/cfg.go +index 9329769721..ddc15adcdd 100644 +--- a/src/internal/cfg/cfg.go ++++ b/src/internal/cfg/cfg.go +@@ -63,6 +63,7 @@ const KnownEnv = ` + GORISCV64 + GOROOT + GOSUMDB ++ GOSW64 + GOTMPDIR + GOTOOLCHAIN + GOTOOLDIR +diff --git a/src/internal/cpu/cpu.go b/src/internal/cpu/cpu.go +index cd3db10523..53598fe119 100644 +--- a/src/internal/cpu/cpu.go ++++ b/src/internal/cpu/cpu.go +@@ -110,6 +110,17 @@ var PPC64 struct { + _ CacheLinePad + } + ++var SW64 struct { ++ _ CacheLinePad ++ HasCRC bool // Hardware random number generator (requires kernel enablement) ++ HasSIMDV2 bool // Syscall vectored (requires kernel enablement) ++ HasPCREL bool // pc rel instruction ++ HasHDIV bool // hardware div/rem support ++ IsCore3 bool // ISA v3.00 (SW3231) ++ IsCore4 bool // ISA v4.00 (SW6432) ++ _ CacheLinePad ++} ++ + var S390X struct { + _ CacheLinePad + HasZARCH bool // z architecture mode is active [mandatory] +diff --git a/src/internal/cpu/cpu_sw64.go b/src/internal/cpu/cpu_sw64.go +new file mode 100644 +index 0000000000..0f83ffbfae +--- /dev/null ++++ b/src/internal/cpu/cpu_sw64.go +@@ -0,0 +1,17 @@ ++// 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. ++ ++// +build sw64 ++ ++package cpu ++ ++const CacheLinePadSize = 128 ++ ++func doinit() { ++ options = []option{ ++ {Name: "crc32", Feature: &SW64.HasCRC}, ++ } ++ // TODO: setting SW64 CRC test for now ++ SW64.HasCRC = false ++} +diff --git a/src/internal/goarch/goarch.go b/src/internal/goarch/goarch.go +index 3dda62fadc..58800272e6 100644 +--- a/src/internal/goarch/goarch.go ++++ b/src/internal/goarch/goarch.go +@@ -26,6 +26,7 @@ const ( + RISCV64 + S390X + WASM ++ SW64 + ) + + // PtrSize is the size of a pointer in bytes - unsafe.Sizeof(uintptr(0)) but as an ideal constant. +diff --git a/src/internal/goarch/goarch_sw64.go b/src/internal/goarch/goarch_sw64.go +new file mode 100644 +index 0000000000..b897784000 +--- /dev/null ++++ b/src/internal/goarch/goarch_sw64.go +@@ -0,0 +1,16 @@ ++// 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 sw64 ++ ++package goarch ++ ++const ( ++ _ArchFamily = SW64 ++ _BigEndian = false ++ _DefaultPhysPageSize = 8192 ++ _PCQuantum = 4 ++ _MinFrameSize = 8 ++ _StackAlign = PtrSize ++) +diff --git a/src/internal/goarch/zgoarch_386.go b/src/internal/goarch/zgoarch_386.go +index 4a9b0e67c4..065d6671b8 100644 +--- a/src/internal/goarch/zgoarch_386.go ++++ b/src/internal/goarch/zgoarch_386.go +@@ -30,3 +30,4 @@ const IsS390x = 0 + const IsSparc = 0 + const IsSparc64 = 0 + const IsWasm = 0 ++const IsSw64 = 0 +diff --git a/src/internal/goarch/zgoarch_amd64.go b/src/internal/goarch/zgoarch_amd64.go +index 7926392b77..6cfe216b9e 100644 +--- a/src/internal/goarch/zgoarch_amd64.go ++++ b/src/internal/goarch/zgoarch_amd64.go +@@ -30,3 +30,4 @@ const IsS390x = 0 + const IsSparc = 0 + const IsSparc64 = 0 + const IsWasm = 0 ++const IsSw64 = 0 +diff --git a/src/internal/goarch/zgoarch_arm.go b/src/internal/goarch/zgoarch_arm.go +index 6c03b8b060..6900d42634 100644 +--- a/src/internal/goarch/zgoarch_arm.go ++++ b/src/internal/goarch/zgoarch_arm.go +@@ -30,3 +30,4 @@ const IsS390x = 0 + const IsSparc = 0 + const IsSparc64 = 0 + const IsWasm = 0 ++const IsSw64 = 0 +diff --git a/src/internal/goarch/zgoarch_arm64.go b/src/internal/goarch/zgoarch_arm64.go +index ad342d79c9..b0be5d8ff6 100644 +--- a/src/internal/goarch/zgoarch_arm64.go ++++ b/src/internal/goarch/zgoarch_arm64.go +@@ -30,3 +30,4 @@ const IsS390x = 0 + const IsSparc = 0 + const IsSparc64 = 0 + const IsWasm = 0 ++const IsSw64 = 0 +diff --git a/src/internal/goarch/zgoarch_arm64be.go b/src/internal/goarch/zgoarch_arm64be.go +index 0f26003090..5c8f66ea36 100644 +--- a/src/internal/goarch/zgoarch_arm64be.go ++++ b/src/internal/goarch/zgoarch_arm64be.go +@@ -30,3 +30,4 @@ const IsS390x = 0 + const IsSparc = 0 + const IsSparc64 = 0 + const IsWasm = 0 ++const IsSw64 = 0 +diff --git a/src/internal/goarch/zgoarch_armbe.go b/src/internal/goarch/zgoarch_armbe.go +index 6092fee751..26640157a1 100644 +--- a/src/internal/goarch/zgoarch_armbe.go ++++ b/src/internal/goarch/zgoarch_armbe.go +@@ -30,3 +30,4 @@ const IsS390x = 0 + const IsSparc = 0 + const IsSparc64 = 0 + const IsWasm = 0 ++const IsSw64 = 0 +diff --git a/src/internal/goarch/zgoarch_loong64.go b/src/internal/goarch/zgoarch_loong64.go +index 21c67e1176..5204f28a7d 100644 +--- a/src/internal/goarch/zgoarch_loong64.go ++++ b/src/internal/goarch/zgoarch_loong64.go +@@ -30,3 +30,4 @@ const IsS390x = 0 + const IsSparc = 0 + const IsSparc64 = 0 + const IsWasm = 0 ++const IsSw64 = 0 +diff --git a/src/internal/goarch/zgoarch_mips.go b/src/internal/goarch/zgoarch_mips.go +index 0db1974655..43cb637e31 100644 +--- a/src/internal/goarch/zgoarch_mips.go ++++ b/src/internal/goarch/zgoarch_mips.go +@@ -30,3 +30,4 @@ const IsS390x = 0 + const IsSparc = 0 + const IsSparc64 = 0 + const IsWasm = 0 ++const IsSw64 = 0 +diff --git a/src/internal/goarch/zgoarch_mips64.go b/src/internal/goarch/zgoarch_mips64.go +index 738806f0ae..67a9ad7d82 100644 +--- a/src/internal/goarch/zgoarch_mips64.go ++++ b/src/internal/goarch/zgoarch_mips64.go +@@ -30,3 +30,4 @@ const IsS390x = 0 + const IsSparc = 0 + const IsSparc64 = 0 + const IsWasm = 0 ++const IsSw64 = 0 +diff --git a/src/internal/goarch/zgoarch_mips64le.go b/src/internal/goarch/zgoarch_mips64le.go +index 8de5beb881..719aa8c3c2 100644 +--- a/src/internal/goarch/zgoarch_mips64le.go ++++ b/src/internal/goarch/zgoarch_mips64le.go +@@ -30,3 +30,4 @@ const IsS390x = 0 + const IsSparc = 0 + const IsSparc64 = 0 + const IsWasm = 0 ++const IsSw64 = 0 +diff --git a/src/internal/goarch/zgoarch_mips64p32.go b/src/internal/goarch/zgoarch_mips64p32.go +index ea461bed70..4ba084f39d 100644 +--- a/src/internal/goarch/zgoarch_mips64p32.go ++++ b/src/internal/goarch/zgoarch_mips64p32.go +@@ -30,3 +30,4 @@ const IsS390x = 0 + const IsSparc = 0 + const IsSparc64 = 0 + const IsWasm = 0 ++const IsSw64 = 0 +diff --git a/src/internal/goarch/zgoarch_mips64p32le.go b/src/internal/goarch/zgoarch_mips64p32le.go +index 15473ce6c7..402495523b 100644 +--- a/src/internal/goarch/zgoarch_mips64p32le.go ++++ b/src/internal/goarch/zgoarch_mips64p32le.go +@@ -30,3 +30,4 @@ const IsS390x = 0 + const IsSparc = 0 + const IsSparc64 = 0 + const IsWasm = 0 ++const IsSw64 = 0 +diff --git a/src/internal/goarch/zgoarch_mipsle.go b/src/internal/goarch/zgoarch_mipsle.go +index 4955142e87..b0d61ff7d4 100644 +--- a/src/internal/goarch/zgoarch_mipsle.go ++++ b/src/internal/goarch/zgoarch_mipsle.go +@@ -30,3 +30,4 @@ const IsS390x = 0 + const IsSparc = 0 + const IsSparc64 = 0 + const IsWasm = 0 ++const IsSw64 = 0 +diff --git a/src/internal/goarch/zgoarch_ppc.go b/src/internal/goarch/zgoarch_ppc.go +index ec01763b3c..afd23b1647 100644 +--- a/src/internal/goarch/zgoarch_ppc.go ++++ b/src/internal/goarch/zgoarch_ppc.go +@@ -30,3 +30,4 @@ const IsS390x = 0 + const IsSparc = 0 + const IsSparc64 = 0 + const IsWasm = 0 ++const IsSw64 = 0 +diff --git a/src/internal/goarch/zgoarch_ppc64.go b/src/internal/goarch/zgoarch_ppc64.go +index 39be3925c8..0b516ecfff 100644 +--- a/src/internal/goarch/zgoarch_ppc64.go ++++ b/src/internal/goarch/zgoarch_ppc64.go +@@ -30,3 +30,4 @@ const IsS390x = 0 + const IsSparc = 0 + const IsSparc64 = 0 + const IsWasm = 0 ++const IsSw64 = 0 +diff --git a/src/internal/goarch/zgoarch_ppc64le.go b/src/internal/goarch/zgoarch_ppc64le.go +index 5f959e0e02..9541957582 100644 +--- a/src/internal/goarch/zgoarch_ppc64le.go ++++ b/src/internal/goarch/zgoarch_ppc64le.go +@@ -30,3 +30,4 @@ const IsS390x = 0 + const IsSparc = 0 + const IsSparc64 = 0 + const IsWasm = 0 ++const IsSw64 = 0 +diff --git a/src/internal/goarch/zgoarch_riscv.go b/src/internal/goarch/zgoarch_riscv.go +index 8d81a14dd9..bfb753f5e9 100644 +--- a/src/internal/goarch/zgoarch_riscv.go ++++ b/src/internal/goarch/zgoarch_riscv.go +@@ -30,3 +30,4 @@ const IsS390x = 0 + const IsSparc = 0 + const IsSparc64 = 0 + const IsWasm = 0 ++const IsSw64 = 0 +diff --git a/src/internal/goarch/zgoarch_riscv64.go b/src/internal/goarch/zgoarch_riscv64.go +index 1df989c2a6..fd5c1da2ad 100644 +--- a/src/internal/goarch/zgoarch_riscv64.go ++++ b/src/internal/goarch/zgoarch_riscv64.go +@@ -30,3 +30,4 @@ const IsS390x = 0 + const IsSparc = 0 + const IsSparc64 = 0 + const IsWasm = 0 ++const IsSw64 = 0 +diff --git a/src/internal/goarch/zgoarch_s390.go b/src/internal/goarch/zgoarch_s390.go +index 56815b9f43..45c5db44f2 100644 +--- a/src/internal/goarch/zgoarch_s390.go ++++ b/src/internal/goarch/zgoarch_s390.go +@@ -30,3 +30,4 @@ const IsS390x = 0 + const IsSparc = 0 + const IsSparc64 = 0 + const IsWasm = 0 ++const IsSw64 = 0 +diff --git a/src/internal/goarch/zgoarch_s390x.go b/src/internal/goarch/zgoarch_s390x.go +index e61e9bd593..deda7150ca 100644 +--- a/src/internal/goarch/zgoarch_s390x.go ++++ b/src/internal/goarch/zgoarch_s390x.go +@@ -30,3 +30,4 @@ const IsS390x = 1 + const IsSparc = 0 + const IsSparc64 = 0 + const IsWasm = 0 ++const IsSw64 = 0 +diff --git a/src/internal/goarch/zgoarch_sparc.go b/src/internal/goarch/zgoarch_sparc.go +index ee5b746566..59d5cbaa8e 100644 +--- a/src/internal/goarch/zgoarch_sparc.go ++++ b/src/internal/goarch/zgoarch_sparc.go +@@ -30,3 +30,4 @@ const IsS390x = 0 + const IsSparc = 1 + const IsSparc64 = 0 + const IsWasm = 0 ++const IsSw64 = 0 +diff --git a/src/internal/goarch/zgoarch_sparc64.go b/src/internal/goarch/zgoarch_sparc64.go +index 519aaa10c1..d940eb138d 100644 +--- a/src/internal/goarch/zgoarch_sparc64.go ++++ b/src/internal/goarch/zgoarch_sparc64.go +@@ -30,3 +30,4 @@ const IsS390x = 0 + const IsSparc = 0 + const IsSparc64 = 1 + const IsWasm = 0 ++const IsSw64 = 0 +diff --git a/src/internal/goarch/zgoarch_sw64.go b/src/internal/goarch/zgoarch_sw64.go +new file mode 100644 +index 0000000000..b576c686de +--- /dev/null ++++ b/src/internal/goarch/zgoarch_sw64.go +@@ -0,0 +1,33 @@ ++// Code generated by gengoarch.go using 'go generate'. DO NOT EDIT. ++ ++//go:build sw64 ++ ++package goarch ++ ++const GOARCH = `sw64` ++ ++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 = 0 ++const IsSw64 = 1 +diff --git a/src/internal/goarch/zgoarch_wasm.go b/src/internal/goarch/zgoarch_wasm.go +index 25567a1b64..15f6c36bcf 100644 +--- a/src/internal/goarch/zgoarch_wasm.go ++++ b/src/internal/goarch/zgoarch_wasm.go +@@ -30,3 +30,4 @@ const IsS390x = 0 + const IsSparc = 0 + const IsSparc64 = 0 + const IsWasm = 1 ++const IsSw64 = 0 +diff --git a/src/internal/platform/supported.go b/src/internal/platform/supported.go +index e864c37d68..e26d6795a1 100644 +--- a/src/internal/platform/supported.go ++++ b/src/internal/platform/supported.go +@@ -85,7 +85,8 @@ func FuzzInstrumented(goos, goarch string) bool { + func MustLinkExternal(goos, goarch string, withCgo bool) bool { + if withCgo { + switch goarch { +- case "mips", "mipsle", "mips64", "mips64le": ++ case "mips", "mipsle", "mips64", "mips64le", ++ "sw64": + // Internally linking cgo is incomplete on some architectures. + // https://go.dev/issue/14449 + return true +@@ -149,7 +150,7 @@ func BuildModeSupported(compiler, buildmode, goos, goarch string) bool { + return true + case "linux": + switch goarch { +- case "386", "amd64", "arm", "armbe", "arm64", "arm64be", "loong64", "ppc64le", "riscv64", "s390x": ++ case "386", "amd64", "arm", "armbe", "arm64", "arm64be", "loong64", "ppc64le", "riscv64", "s390x", "sw64": + // linux/ppc64 not supported because it does + // not support external linking mode yet. + return true +@@ -169,7 +170,7 @@ func BuildModeSupported(compiler, buildmode, goos, goarch string) bool { + + case "c-shared": + switch platform { +- case "linux/amd64", "linux/arm", "linux/arm64", "linux/loong64", "linux/386", "linux/ppc64le", "linux/riscv64", "linux/s390x", ++ case "linux/amd64", "linux/arm", "linux/arm64", "linux/loong64", "linux/386", "linux/ppc64le", "linux/riscv64", "linux/s390x", "linux/sw64", + "android/amd64", "android/arm", "android/arm64", "android/386", + "freebsd/amd64", + "darwin/amd64", "darwin/arm64", +@@ -208,7 +209,7 @@ func BuildModeSupported(compiler, buildmode, goos, goarch string) bool { + + case "plugin": + switch platform { +- case "linux/amd64", "linux/arm", "linux/arm64", "linux/386", "linux/loong64", "linux/s390x", "linux/ppc64le", ++ case "linux/amd64", "linux/arm", "linux/arm64", "linux/386", "linux/loong64", "linux/s390x", "linux/ppc64le", "linux/sw64", + "android/amd64", "android/386", + "darwin/amd64", "darwin/arm64", + "freebsd/amd64": +diff --git a/src/internal/platform/zosarch.go b/src/internal/platform/zosarch.go +index ebde978a23..ec429c8b01 100644 +--- a/src/internal/platform/zosarch.go ++++ b/src/internal/platform/zosarch.go +@@ -39,6 +39,7 @@ var List = []OSArch{ + {"linux", "riscv64"}, + {"linux", "s390x"}, + {"linux", "sparc64"}, ++ {"linux", "sw64"}, + {"netbsd", "386"}, + {"netbsd", "amd64"}, + {"netbsd", "arm"}, +@@ -93,6 +94,7 @@ var distInfo = map[OSArch]osArchInfo{ + {"linux", "riscv64"}: {CgoSupported: true}, + {"linux", "s390x"}: {CgoSupported: true}, + {"linux", "sparc64"}: {CgoSupported: true, Broken: true}, ++ {"linux", "sw64"}: {CgoSupported: true}, + {"netbsd", "386"}: {CgoSupported: true}, + {"netbsd", "amd64"}: {CgoSupported: true}, + {"netbsd", "arm"}: {CgoSupported: true}, +diff --git a/src/internal/runtime/atomic/atomic_sw64.go b/src/internal/runtime/atomic/atomic_sw64.go +new file mode 100644 +index 0000000000..86748b4758 +--- /dev/null ++++ b/src/internal/runtime/atomic/atomic_sw64.go +@@ -0,0 +1,102 @@ ++// 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 sw64 ++// +build sw64 ++ ++package atomic ++ ++import "unsafe" ++ ++//go:noescape ++func Xadd(ptr *uint32, delta int32) uint32 ++ ++//go:noescape ++func Xadd64(ptr *uint64, delta int64) uint64 ++ ++//go:noescape ++func Xadduintptr(ptr *uintptr, delta uintptr) uintptr ++ ++//go:noescape ++func Xchg(ptr *uint32, new uint32) uint32 ++ ++//go:noescape ++func Xchg64(ptr *uint64, new uint64) uint64 ++ ++//go:noescape ++func Xchguintptr(ptr *uintptr, new uintptr) uintptr ++ ++//go:noescape ++func Load(ptr *uint32) uint32 ++ ++//go:noescape ++func Load64(ptr *uint64) uint64 ++ ++// NO go:noescape annotation; *ptr escapes if result escapes (#31525) ++func Loadp(ptr unsafe.Pointer) unsafe.Pointer ++ ++//go:noescape ++func And8(ptr *uint8, val uint8) ++ ++//go:noescape ++func Or8(ptr *uint8, val uint8) ++ ++// NOTE: Do not add atomicxor8 (XOR is not idempotent). ++ ++//go:noescape ++func Cas64(ptr *uint64, old, new uint64) bool ++ ++//go:noescape ++func Store(ptr *uint32, val uint32) ++ ++//go:noescape ++func Store64(ptr *uint64, val uint64) ++ ++// NO go:noescape annotation; see atomic_pointer.go. ++func StorepNoWB(ptr unsafe.Pointer, val unsafe.Pointer) ++ ++//go:noescape ++func Load8(ptr *uint8) uint8 ++ ++//go:noescape ++func LoadAcq(ptr *uint32) uint32 ++ ++//go:noescape ++func LoadAcquintptr(ptr *uintptr) uintptr ++ ++//go:noescape ++func CasRel(ptr *uint32, old, new uint32) bool ++ ++//go:noescape ++func Store8(ptr *uint8, val uint8) ++ ++//go:noescape ++func StoreRel(ptr *uint32, val uint32) ++ ++//go:noescape ++func StoreReluintptr(ptr *uintptr, val uintptr) ++ ++//go:noescape ++func Or(ptr *uint32, val uint32) ++ ++//go:noescape ++func And(ptr *uint32, val uint32) ++ ++//go:noescape ++func And32(ptr *uint32, val uint32) uint32 ++ ++//go:noescape ++func Or32(ptr *uint32, val uint32) uint32 ++ ++//go:noescape ++func And64(ptr *uint64, val uint64) uint64 ++ ++//go:noescape ++func Or64(ptr *uint64, val uint64) uint64 ++ ++//go:noescape ++func Anduintptr(ptr *uintptr, val uintptr) uintptr ++ ++//go:noescape ++func Oruintptr(ptr *uintptr, val uintptr) uintptr +diff --git a/src/internal/runtime/atomic/atomic_sw64.s b/src/internal/runtime/atomic/atomic_sw64.s +new file mode 100644 +index 0000000000..9f0160d636 +--- /dev/null ++++ b/src/internal/runtime/atomic/atomic_sw64.s +@@ -0,0 +1,399 @@ ++// 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 sw64 ++ ++#include "textflag.h" ++ ++// bool Cas(uint32 *ptr, uint32 old, uint32 new) ++// Atomically: ++// if(*val == old){ ++// *val = new; ++// return 1; ++// } else ++// return 0; ++TEXT ·Cas(SB), NOSPLIT|NOFRAME, $0-17 ++ LDL R3, ptr+0(FP) ++ LDW R4, old+8(FP) ++ LDW R5, new+12(FP) ++ ++ MEMB ++ LLDW R6, 0(R3) ++ CMPEQ R6, R4, R6 ++ WR_F R6 ++ BIS R5, R31, R7 ++ LSTW R7, 0(R3) ++ RD_F R7 ++ BEQ R6, 2(PC) ++ BEQ R7, -7(PC) ++ STB R7, ret+16(FP) ++ RET ++ ++// bool Cas64(uint64 *ptr, uint64 old, uint64 new) ++// Atomically: ++// if(*val == *old){ ++// *val = new; ++// return 1; ++// } else { ++// return 0; ++// } ++TEXT ·Cas64(SB), NOFRAME|NOSPLIT, $0-25 ++ LDL R3, ptr+0(FP) ++ LDL R4, old+8(FP) ++ LDL R5, new+16(FP) ++ ++ MEMB ++ LLDL R6, 0(R3) ++ CMPEQ R6, R4, R6 ++ WR_F R6 ++ BIS R5, R31, R7 ++ LSTL R7, 0(R3) ++ RD_F R7 ++ BEQ R6, 2(PC) ++ BEQ R7, -7(PC) ++ STB R7, ret+24(FP) ++ RET ++ ++TEXT ·Casuintptr(SB), NOFRAME|NOSPLIT, $0-25 ++ JMP ·Cas64(SB) ++ ++TEXT ·Loaduintptr(SB), NOFRAME|NOSPLIT, $0-16 ++ JMP ·Load64(SB) ++ ++TEXT ·Loaduint(SB), NOFRAME|NOSPLIT, $0-16 ++ JMP ·Load64(SB) ++ ++TEXT ·Storeuintptr(SB), NOFRAME|NOSPLIT, $0-16 ++ JMP ·Store64(SB) ++ ++TEXT ·Xadduintptr(SB), NOFRAME|NOSPLIT, $0-24 ++ JMP ·Xadd64(SB) ++ ++TEXT ·Loadint64(SB), NOFRAME|NOSPLIT, $0-16 ++ JMP ·Load64(SB) ++ ++TEXT ·Xaddint64(SB), NOFRAME|NOSPLIT, $0-24 ++ JMP ·Xadd64(SB) ++ ++// bool casp(void **val, void *old, void *new) ++// Atomically: ++// if(*val == old){ ++// *val = new; ++// return 1; ++// } else ++// return 0; ++TEXT ·Casp1(SB), NOFRAME|NOSPLIT, $0-25 ++ JMP ·Cas64(SB) ++ ++// uint32 xadd(uint32 volatile *ptr, int32 delta) ++// Atomically: ++// *val += delta; ++// return *val; ++TEXT ·Xadd(SB), NOFRAME|NOSPLIT, $0-20 ++ LDL R4, ptr+0(FP) ++ LDW R5, delta+8(FP) ++ ++ MEMB ++ LLDW R6, 0(R4) ++ LDI R7, 1 ++ WR_F R7 ++ ADDW R6, R5, R7 ++ LSTW R7, 0(R4) ++ RD_F R7 ++ BEQ R7, -6(PC) ++ ++ ADDW R6, R5, R7 ++ STW R7, ret+16(FP) ++ RET ++ ++TEXT ·Xadd64(SB), NOFRAME|NOSPLIT, $0-24 ++ LDL R4, ptr+0(FP) ++ LDL R5, delta+8(FP) ++ ++ MEMB ++ LLDL R6, 0(R4) ++ LDI R7, 1 ++ WR_F R7 ++ ADDL R6, R5, R7 ++ LSTL R7, 0(R4) ++ RD_F R7 ++ BEQ R7, -6(PC) ++ ++ ADDL R6, R5, R7 ++ STL R7, ret+16(FP) ++ RET ++ ++TEXT ·Xchg(SB), NOFRAME|NOSPLIT, $0-20 ++ LDL R4, ptr+0(FP) ++ LDW R5, new+8(FP) ++ ++ MEMB ++ LLDW R6, 0(R4) ++ LDI R7, 1 ++ WR_F R7 ++ BIS R5, R31, R7 ++ LSTW R7, 0(R4) ++ RD_F R7 ++ BEQ R7, -6(PC) ++ ++ STW R6, ret+16(FP) ++ RET ++ ++TEXT ·Xchg64(SB), NOFRAME|NOSPLIT, $0-24 ++ LDL R4, ptr+0(FP) ++ LDL R5, new+8(FP) ++ ++ MEMB ++ LLDL R6, 0(R4) ++ LDI R7, 1 ++ WR_F R7 ++ BIS R5, R31, R7 ++ LSTL R7, 0(R4) ++ RD_F R7 ++ BEQ R7, -6(PC) ++ ++ STL R6, ret+16(FP) ++ RET ++ ++TEXT ·Xchguintptr(SB), NOFRAME|NOSPLIT, $0-24 ++ JMP ·Xchg64(SB) ++ ++ ++TEXT ·StorepNoWB(SB), NOFRAME|NOSPLIT, $0-16 ++ LDL R3, ptr+0(FP) ++ LDL R4, val+8(FP) ++ MEMB ++ STL R4, 0(R3) ++ MEMB ++ RET ++ ++TEXT ·Store(SB), NOFRAME|NOSPLIT, $0-12 ++ LDL R3, ptr+0(FP) ++ LDW R4, val+8(FP) ++ MEMB ++ STW R4, 0(R3) ++ MEMB ++ RET ++ ++TEXT ·Store64(SB), NOFRAME|NOSPLIT, $0-16 ++ LDL R3, ptr+0(FP) ++ LDL R4, val+8(FP) ++ MEMB ++ STL R4, 0(R3) ++ MEMB ++ RET ++ ++TEXT ·Storeint32(SB), NOSPLIT, $0-12 ++ JMP ·Store(SB) ++ ++TEXT ·Storeint64(SB), NOSPLIT, $0-16 ++ JMP ·Store64(SB) ++ ++// void ·And8(byte volatile*, byte); ++TEXT ·And8(SB), NOFRAME|NOSPLIT, $0-9 ++ LDL R1, ptr+0(FP) ++ LDBU R2, val+8(FP) ++ LDI R3, $-4 ++ AND R3, R1, R3 ++ AND R1, $3, R4 ++ SLL R4, $3, R4 ++ LDI R5, 0xFF ++ SLL R2, R4, R2 ++ SLL R5, R4, R5 ++ ORNOT R31, R5, R5 ++ BIS R2, R5, R2 ++ ++ MEMB ++ LLDW R4, (R3) ++ LDI R1, 1 ++ WR_F R1 ++ AND R4, R2, R1 ++ LSTW R1, (R3) ++ RD_F R1 ++ BEQ R1, -6(PC) ++ RET ++ ++// void ·Or8(byte volatile*, byte); ++TEXT ·Or8(SB), NOFRAME|NOSPLIT, $0-9 ++ LDL R1, ptr+0(FP) ++ LDBU R2, val+8(FP) ++ LDI R3, $-4 ++ AND R3, R1, R3 ++ AND R1, $3, R4 ++ SLL R4, $3, R4 ++ SLL R2, R4, R2 ++ ++ MEMB ++ LLDW R4, (R3) ++ LDI R1, 1 ++ WR_F R1 ++ BIS R4, R2, R1 ++ LSTW R1, (R3) ++ RD_F R1 ++ BEQ R1, -6(PC) ++ RET ++ ++// void func And(addr *uint32, v uint32) ++TEXT ·And(SB), NOFRAME|NOSPLIT, $0-12 ++ LDL R1, ptr+0(FP) ++ LDW R2, val+8(FP) ++ ++ MEMB ++ LLDW R4, (R1) ++ LDI R3, 1 ++ WR_F R3 ++ AND R4, R2, R4 ++ LSTW R4, (R1) ++ RD_F R4 ++ BEQ R4, -6(PC) ++ RET ++ ++// func Or(addr *uint32, v uint32) ++TEXT ·Or(SB), NOFRAME|NOSPLIT, $0-12 ++ LDL R1, ptr+0(FP) ++ LDW R2, val+8(FP) ++ ++ MEMB ++ LLDW R4, (R1) ++ LDI R3, 1 ++ WR_F R3 ++ BIS R4, R2, R4 ++ LSTW R4, (R1) ++ RD_F R4 ++ BEQ R4, -6(PC) ++ RET ++ ++// func Or32(addr *uint32, v uint32) old uint32 ++TEXT ·Or32(SB), NOFRAME|NOSPLIT, $0-20 ++ LDL R1, ptr+0(FP) ++ LDW R2, val+8(FP) ++ ++ MEMB ++ LLDW R4, (R1) ++ LDI R3, 1 ++ WR_F R3 ++ BIS R4, R2, R5 ++ LSTW R5, (R1) ++ RD_F R5 ++ BEQ R5, -6(PC) ++ STW R4, ret+16(FP) ++ RET ++ ++// func And32(addr *uint32, v uint32) old uint32 ++TEXT ·And32(SB), NOFRAME|NOSPLIT, $0-20 ++ LDL R1, ptr+0(FP) ++ LDW R2, val+8(FP) ++ ++ MEMB ++ LLDW R4, (R1) ++ LDI R3, 1 ++ WR_F R3 ++ AND R4, R2, R5 ++ LSTW R5, (R1) ++ RD_F R5 ++ BEQ R5, -6(PC) ++ STW R4, ret+16(FP) ++ RET ++ ++// func Or64(addr *uint64, v uint64) old uint64 ++TEXT ·Or64(SB), NOFRAME|NOSPLIT, $0-24 ++ LDL R1, ptr+0(FP) ++ LDL R2, val+8(FP) ++ ++ MEMB ++ LLDL R4, (R1) ++ LDI R3, 1 ++ WR_F R3 ++ BIS R4, R2, R5 ++ LSTL R5, (R1) ++ RD_F R5 ++ BEQ R5, -6(PC) ++ STL R4, ret+16(FP) ++ RET ++ ++// func And64(addr *uint64, v uint64) old uint64 ++TEXT ·And64(SB), NOFRAME|NOSPLIT, $0-24 ++ LDL R1, ptr+0(FP) ++ LDL R2, val+8(FP) ++ ++ MEMB ++ LLDL R4, (R1) ++ LDI R3, 1 ++ WR_F R3 ++ AND R4, R2, R5 ++ LSTL R5, (R1) ++ RD_F R5 ++ BEQ R5, -6(PC) ++ STL R4, ret+16(FP) ++ RET ++ ++// func Anduintptr(addr *uintptr, v uintptr) old uintptr ++TEXT ·Anduintptr(SB), NOSPLIT, $0-24 ++ JMP ·And64(SB) ++ ++// func Oruintptr(addr *uintptr, v uintptr) old uintptr ++TEXT ·Oruintptr(SB), NOSPLIT, $0-24 ++ JMP ·Or64(SB) ++ ++TEXT ·Store8(SB), NOFRAME|NOSPLIT, $0-9 ++ LDL R3, ptr+0(FP) ++ LDBU R4, val+8(FP) ++ MEMB ++ STB R4, 0(R3) ++ MEMB ++ RET ++ ++// uint32 ·Load(uint32 volatile* ptr) ++TEXT ·Load(SB), NOFRAME|NOSPLIT, $0-12 ++ LDL R3, ptr+0(FP) ++ MEMB ++ LDW R3, 0(R3) ++ MEMB ++ STW R3, ret+8(FP) ++ RET ++ ++// uint64 ·Load64(uint64 volatile* ptr) ++TEXT ·Load64(SB), NOFRAME|NOSPLIT, $0-16 ++ LDL R3, ptr+0(FP) ++ MEMB ++ LDL R3, 0(R3) ++ MEMB ++ STL R3, ret+8(FP) ++ RET ++ ++// void *·Loadp(void *volatile *ptr) ++TEXT ·Loadp(SB), NOFRAME|NOSPLIT, $0-16 ++ LDL R3, ptr+0(FP) ++ MEMB ++ LDL R3, 0(R3) ++ MEMB ++ STL R3, ret+8(FP) ++ RET ++ ++// uint8 ·Load8(uint8 volatile* ptr) ++TEXT ·Load8(SB), NOFRAME|NOSPLIT, $0-9 ++ LDL R3, ptr+0(FP) ++ MEMB ++ LDBU R3, 0(R3) ++ MEMB ++ STB R3, ret+8(FP) ++ RET ++ ++// uint32 ·LoadAcq(uint32 volatile* ptr) ++TEXT ·LoadAcq(SB),NOSPLIT|NOFRAME,$0-12 ++ JMP ·Load(SB) ++ ++// uint64 ·LoadAcquintptr(uintptr volatile* ptr) ++TEXT ·LoadAcquintptr(SB),NOSPLIT|NOFRAME,$0-16 ++ JMP ·Load64(SB) ++ ++ ++TEXT ·StoreRel(SB), NOSPLIT|NOFRAME, $0-12 ++ JMP ·Store(SB) ++ ++TEXT ·CasRel(SB), NOSPLIT|NOFRAME, $0-17 ++ JMP ·Cas(SB) ++ ++TEXT ·StoreReluintptr(SB), NOSPLIT|NOFRAME, $0-16 ++ JMP ·Store64(SB) +diff --git a/src/internal/runtime/syscall/asm_linux_sw64.s b/src/internal/runtime/syscall/asm_linux_sw64.s +new file mode 100644 +index 0000000000..3da79bc22d +--- /dev/null ++++ b/src/internal/runtime/syscall/asm_linux_sw64.s +@@ -0,0 +1,32 @@ ++// 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 linux && sw64 ++ ++#include "textflag.h" ++#define SYSCALL SYS_CALL_B $131 ++ ++// func Syscall6(num, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, errno uintptr) ++TEXT ·Syscall6(SB), NOSPLIT, $0-80 ++ LDL R0, num+0(FP) ++ LDL R16, a1+8(FP) ++ LDL R17, a2+16(FP) ++ LDL R18, a3+24(FP) ++ LDL R19, a4+32(FP) ++ LDL R20, a5+40(FP) ++ LDL R21, a6+48(FP) ++ SYSCALL ++ BEQ R19, ok ++ ++ LDI R1, $-1 ++ STL R1, r1+56(FP) ++ STL ZERO, r2+64(FP) ++ STL R0, errno+72(FP) ++ RET ++ok: ++ STL R0, r1+56(FP) ++ STL R20, r2+64(FP) ++ STL ZERO, errno+72(FP) ++ RET ++ +diff --git a/src/internal/runtime/syscall/defs_linux.go b/src/internal/runtime/syscall/defs_linux.go +index b2e36a244f..b9ee2e5e47 100644 +--- a/src/internal/runtime/syscall/defs_linux.go ++++ b/src/internal/runtime/syscall/defs_linux.go +@@ -2,6 +2,8 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + ++//go:build !sw64 ++ + package syscall + + const ( +diff --git a/src/internal/runtime/syscall/defs_linux_sw64.go b/src/internal/runtime/syscall/defs_linux_sw64.go +new file mode 100644 +index 0000000000..a462aeefef +--- /dev/null ++++ b/src/internal/runtime/syscall/defs_linux_sw64.go +@@ -0,0 +1,38 @@ ++// 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 linux && sw64 ++ ++package syscall ++ ++const ( ++ SYS_FCNTL = 92 ++ SYS_EPOLL_CTL = 408 ++ SYS_EPOLL_PWAIT = 474 ++ SYS_EPOLL_CREATE1 = 486 ++ SYS_EPOLL_PWAIT2 = 541 /* sw64 has not support this ++so this is just a temp number*/ ++ SYS_MPROTECT = 74 ++ SYS_EVENTFD2 = 485 ++ ++ EFD_NONBLOCK = 4 ++ ++ EPOLLIN = 0x1 ++ EPOLLOUT = 0x4 ++ EPOLLERR = 0x8 ++ EPOLLHUP = 0x10 ++ EPOLLRDHUP = 0x2000 ++ EPOLLET = 0x80000000 ++ EPOLL_CLOEXEC = 0x200000 ++ EPOLL_CTL_ADD = 0x1 ++ EPOLL_CTL_DEL = 0x2 ++ EPOLL_CTL_MOD = 0x3 ++ EFD_CLOEXEC = 0x200000 ++) ++ ++type EpollEvent struct { ++ Events uint32 ++ pad_cgo_0 [4]byte ++ Data uint64 ++} +diff --git a/src/internal/syscall/unix/at_sysnum_fstatat64_linux.go b/src/internal/syscall/unix/at_sysnum_fstatat64_linux.go +index 445b0c3854..cd54066d1e 100644 +--- a/src/internal/syscall/unix/at_sysnum_fstatat64_linux.go ++++ b/src/internal/syscall/unix/at_sysnum_fstatat64_linux.go +@@ -2,7 +2,7 @@ + // 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 ++//go:build arm || mips || mipsle || 386 || sw64 + + package unix + +diff --git a/src/internal/syscall/unix/getrandom_linux_sw64.go b/src/internal/syscall/unix/getrandom_linux_sw64.go +new file mode 100644 +index 0000000000..bd04bbca3e +--- /dev/null ++++ b/src/internal/syscall/unix/getrandom_linux_sw64.go +@@ -0,0 +1,9 @@ ++// 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 ++ ++// Linux getrandom system call number. ++// See GetRandom in getrandom_linux.go. ++const randomTrap uintptr = 511 +diff --git a/src/internal/syscall/unix/sysnum_linux_sw64.go b/src/internal/syscall/unix/sysnum_linux_sw64.go +new file mode 100644 +index 0000000000..f79d69fe4b +--- /dev/null ++++ b/src/internal/syscall/unix/sysnum_linux_sw64.go +@@ -0,0 +1,14 @@ ++// 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 sw64 ++ ++package unix ++ ++const ( ++ getrandomTrap uintptr = 511 ++ copyFileRangeTrap uintptr = 515 ++ pidfdSendSignalTrap uintptr = 271 ++ pidfdOpenTrap uintptr = 281 ++) +diff --git a/src/internal/syslist/syslist.go b/src/internal/syslist/syslist.go +index 2349b6ea64..6d58fd2b1f 100644 +--- a/src/internal/syslist/syslist.go ++++ b/src/internal/syslist/syslist.go +@@ -80,4 +80,5 @@ var KnownArch = map[string]bool{ + "sparc": true, + "sparc64": true, + "wasm": true, ++ "sw64": true, + } +diff --git a/src/cmd/internal/disasm/disasm.go b/src/cmd/internal/disasm/disasm.go +index 3ae8989b38..0a066d90c7 100644 +--- a/src/cmd/internal/disasm/disasm.go ++++ b/src/cmd/internal/disasm/disasm.go +@@ -31,6 +31,7 @@ import ( + "golang.org/x/arch/ppc64/ppc64asm" + "golang.org/x/arch/riscv64/riscv64asm" + "golang.org/x/arch/s390x/s390xasm" ++ "golang.org/x/arch/sw64/sw64asm" + "golang.org/x/arch/x86/x86asm" + ) + +@@ -439,6 +440,20 @@ func disasm_s390x(code []byte, pc uint64, lookup lookupFunc, _ binary.ByteOrder, + return text, size + } + ++func disasm_sw64(code []byte, pc uint64, lookup lookupFunc, byteOrder binary.ByteOrder, gnuAsm bool) (string, int) { ++ inst, err := sw64asm.Decode(code) ++ var text string ++ if err != nil { ++ text = "?" ++ } else if gnuAsm { ++ text = fmt.Sprintf("%-36s // %s", sw64asm.GoSyntax(inst, pc, lookup, textReader{code, pc}), sw64asm.GNUSyntax(inst)) ++ ++ } else { ++ text = sw64asm.GoSyntax(inst, pc, lookup, textReader{code, pc}) ++ } ++ return text, 4 ++} ++ + var disasms = map[string]disasmFunc{ + "386": disasm_386, + "amd64": disasm_amd64, +@@ -449,6 +464,7 @@ var disasms = map[string]disasmFunc{ + "ppc64le": disasm_ppc64, + "riscv64": disasm_riscv64, + "s390x": disasm_s390x, ++ "sw64": disasm_sw64, + } + + var byteOrders = map[string]binary.ByteOrder{ +@@ -461,4 +477,5 @@ var byteOrders = map[string]binary.ByteOrder{ + "ppc64le": binary.LittleEndian, + "riscv64": binary.LittleEndian, + "s390x": binary.BigEndian, ++ "sw64": binary.LittleEndian, + } +diff --git a/src/cmd/internal/sys/arch.go b/src/cmd/internal/sys/arch.go +index 2e35284137..43a3edb6e6 100644 +--- a/src/cmd/internal/sys/arch.go ++++ b/src/cmd/internal/sys/arch.go +@@ -23,6 +23,7 @@ const ( + RISCV64 + S390X + Wasm ++ SW64 + ) + + // Arch represents an individual architecture. +@@ -267,6 +268,20 @@ var ArchWasm = &Arch{ + FixedFrameSize: 0, + } + ++var ArchSW64 = &Arch{ ++ Name: "sw64", ++ Family: SW64, ++ ByteOrder: binary.LittleEndian, ++ PtrSize: 8, ++ RegSize: 8, ++ MinLC: 4, ++ Alignment: 8, ++ CanMergeLoads: false, ++ CanJumpTable: true, ++ HasLR: true, ++ FixedFrameSize: 8, ++} ++ + var Archs = [...]*Arch{ + Arch386, + ArchAMD64, +@@ -282,4 +297,5 @@ var Archs = [...]*Arch{ + ArchRISCV64, + ArchS390X, + ArchWasm, ++ ArchSW64, + } diff --git a/0013-crypto-hash-math-Add-sw64-port.patch b/0013-crypto-hash-math-Add-sw64-port.patch new file mode 100644 index 0000000000000000000000000000000000000000..c6bb8b8a8c96257503e60a4d62ca209ef3b29354 --- /dev/null +++ b/0013-crypto-hash-math-Add-sw64-port.patch @@ -0,0 +1,313 @@ +diff --git a/src/crypto/internal/fips140/subtle/xor_generic.go b/src/crypto/internal/fips140/subtle/xor_generic.go +index e575c35696..5461678b85 100644 +--- a/src/crypto/internal/fips140/subtle/xor_generic.go ++++ b/src/crypto/internal/fips140/subtle/xor_generic.go +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build (!amd64 && !arm64 && !loong64 && !ppc64 && !ppc64le) || purego ++//go:build (!amd64 && !arm64 && !loong64 && !ppc64 && !ppc64le && !sw64) || purego + + package subtle + +diff --git a/src/crypto/internal/fips140/subtle/xor_sw64.go b/src/crypto/internal/fips140/subtle/xor_sw64.go +new file mode 100644 +index 0000000000..65bab4c657 +--- /dev/null ++++ b/src/crypto/internal/fips140/subtle/xor_sw64.go +@@ -0,0 +1,10 @@ ++// 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 !purego ++ ++package subtle ++ ++//go:noescape ++func xorBytes(dst, a, b *byte, n int) +diff --git a/src/crypto/internal/fips140/subtle/xor_sw64.s b/src/crypto/internal/fips140/subtle/xor_sw64.s +new file mode 100644 +index 0000000000..cac809fcac +--- /dev/null ++++ b/src/crypto/internal/fips140/subtle/xor_sw64.s +@@ -0,0 +1,59 @@ ++// Copyright 2025 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 !purego ++ ++#include "textflag.h" ++ ++// func xorBytes(dst, a, b *byte n int) ++TEXT ·xorBytes(SB), NOSPLIT, $0 ++ LDL R0, dst+0(FP) ++ LDL R1, a+8(FP) ++ LDL R2, b+16(FP) ++ LDL R3, n+24(FP) ++ CMPLT R3, $8, R4 ++ BNE R4, less_than8 ++loop_8: ++ LDL R11, (R1) ++ LDL R12, (R2) ++ LDI R1, 8(R1) // addr(a) + 8 ++ LDI R2, 8(R2) // addr(b) + 8 ++ XOR R11, R12, R12 ++ STL R12, (R0) ++ LDI R0, 8(R0) // addr(dst) +8 ++ LDI R3, -8(R3) // n - 8 ++ CMPLT R3, $8, R4 ++ BEQ R4, loop_8 ++less_than8: ++ BEQ R3, end ++ CMPLT R3, $4, R4 ++ BNE R4, less_than4 ++ LDW R13, (R1) ++ LDW R14, (R2) ++ LDI R1, 4(R1) ++ LDI R2, 4(R2) ++ XOR R13, R14, R14 ++ STW R14, (R0) ++ LDI R0, 4(R0) ++ LDI R3, -4(R3) // n - 4 ++less_than4: ++ CMPLT R3, $2, R4 ++ BNE R4, less_than2 ++ LDHU R16, (R1) ++ LDHU R17, (R2) ++ LDI R1, 2(R1) ++ LDI R2, 2(R2) ++ XOR R16, R17, R17 ++ STH R17, (R0) ++ LDI R0, 2(R0) ++ LDI R3, -2(R3) // n - 2 ++less_than2: ++ BEQ R3, end ++ LDBU R18, (R1) ++ LDBU R19, (R2) ++ XOR R18, R19, R19 ++ STB R19, (R0) ++end: ++ RET ++ +diff --git a/src/hash/crc32/crc32_otherarch.go b/src/hash/crc32/crc32_otherarch.go +index f900968ad3..d28a3636d7 100644 +--- a/src/hash/crc32/crc32_otherarch.go ++++ b/src/hash/crc32/crc32_otherarch.go +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build !amd64 && !s390x && !ppc64le && !arm64 && !loong64 ++//go:build !amd64 && !s390x && !ppc64le && !arm64 && !loong64 && !sw64 + + package crc32 + +diff --git a/src/hash/crc32/crc32_sw64.go b/src/hash/crc32/crc32_sw64.go +new file mode 100644 +index 0000000000..92a05a22d1 +--- /dev/null ++++ b/src/hash/crc32/crc32_sw64.go +@@ -0,0 +1,50 @@ ++// 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. ++ ++// SW64-specific hardware-assisted CRC32 algorithms. See crc32.go for a ++// description of the interface that each architecture-specific file ++// implements. ++ ++package crc32 ++ ++import "internal/cpu" ++ ++func castagnoliUpdate(crc uint32, p []byte) uint32 ++func ieeeUpdate(crc uint32, p []byte) uint32 ++ ++func archAvailableCastagnoli() bool { ++ return cpu.SW64.HasCRC ++} ++ ++func archInitCastagnoli() { ++ if !cpu.SW64.HasCRC { ++ panic("arch-specific crc32 instruction for Catagnoli not available") ++ } ++} ++ ++func archUpdateCastagnoli(crc uint32, p []byte) uint32 { ++ if !cpu.SW64.HasCRC { ++ panic("arch-specific crc32 instruction for Castagnoli not available") ++ } ++ ++ return ^castagnoliUpdate(^crc, p) ++} ++ ++func archAvailableIEEE() bool { ++ return cpu.SW64.HasCRC ++} ++ ++func archInitIEEE() { ++ if !cpu.SW64.HasCRC { ++ panic("arch-specific crc32 instruction for IEEE not available") ++ } ++} ++ ++func archUpdateIEEE(crc uint32, p []byte) uint32 { ++ if !cpu.SW64.HasCRC { ++ panic("arch-specific crc32 instruction for IEEE not available") ++ } ++ ++ return ^ieeeUpdate(^crc, p) ++} +diff --git a/src/hash/crc32/crc32_sw64.s b/src/hash/crc32/crc32_sw64.s +new file mode 100644 +index 0000000000..6580364c58 +--- /dev/null ++++ b/src/hash/crc32/crc32_sw64.s +@@ -0,0 +1,103 @@ ++// 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. ++ ++#include "textflag.h" ++ ++// castagnoliUpdate updates the non-inverted crc with the given data. ++ ++// func castagnoliUpdate(crc uint32, p []byte) uint32 ++TEXT ·castagnoliUpdate(SB),NOSPLIT,$0-36 ++ LDW R9, crc+0(FP) // CRC value ++ LDL R13, p+8(FP) // data pointer ++ LDL R11, p_len+16(FP) // len(p) ++ ZAPNOT R9, $15, R9 ++ ++ CMPLT R11, $8, R8 ++ BNE R8, less_than_8 ++ ++update: ++ LDLA R10, 8(R13) ++ CRC32CL R9, R10, R9 ++ SUBL R11, $8, R11 ++ ++ CMPLT R11, $8, R8 ++ BNE R8, less_than_8 ++ ++ JMP update ++ ++less_than_8: ++ AND R11, $4, R8 ++ BEQ R8, less_than_4 ++ ++ LDWA R10, 4(R13) ++ ZAPNOT R10, $15, R10 ++ CRC32CW R9, R10, R9 ++ SUBL R11, $4, R11 ++ ++less_than_4: ++ AND R11, $2, R8 ++ BEQ R8, less_than_2 ++ ++ LDHUA R10, 2(R13) ++ CRC32CH R9, R10, R9 ++ SUBL R11, $2, R11 ++ ++less_than_2: ++ BEQ R11, done ++ ++ LDBU R10, (R13) ++ CRC32CB R9, R10, R9 ++ ++done: ++ STW R9, ret+32(FP) ++ RET ++ ++// ieeeUpdate updates the non-inverted crc with the given data. ++ ++// func ieeeUpdate(crc uint32, p []byte) uint32 ++TEXT ·ieeeUpdate(SB),NOSPLIT,$0-36 ++ LDW R9, crc+0(FP) // CRC value ++ LDL R13, p+8(FP) // data pointer ++ LDL R11, p_len+16(FP) // len(p) ++ ZAPNOT R9, $15, R9 ++ ++ CMPLT R11, $8, R8 ++ BNE R8, less_than_8 ++ ++update: ++ LDLA R10, 8(R13) ++ CRC32L R9, R10, R9 ++ SUBL R11, $8, R11 ++ ++ CMPLT R11, $8, R8 ++ BNE R8, less_than_8 ++ ++ JMP update ++ ++less_than_8: ++ CMPLT R11, $4, R8 ++ BNE R8, less_than_4 ++ ++ LDWA R10, 4(R13) ++ ZAPNOT R10, $15, R10 ++ CRC32W R9, R10, R9 ++ SUBL R11, $4, R11 ++ ++less_than_4: ++ CMPLT R11, $2, R8 ++ BNE R8, less_than_2 ++ ++ LDHUA R10, 2(R13) ++ CRC32H R9, R10, R9 ++ SUBL R11, $2, R11 ++ ++less_than_2: ++ BEQ R11, done ++ ++ LDBU R10, (R13) ++ CRC32B R9, R10, R9 ++ ++done: ++ STW R9, ret+32(FP) ++ RET +diff --git a/src/math/big/arith_sw64.s b/src/math/big/arith_sw64.s +new file mode 100644 +index 0000000000..cd85f240cd +--- /dev/null ++++ b/src/math/big/arith_sw64.s +@@ -0,0 +1,35 @@ ++// 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 sw64 && !math_big_pure_go ++// +build sw64,!math_big_pure_go ++ ++#include "textflag.h" ++ ++// This file provides fast assembly versions for the elementary ++// arithmetic operations on vectors implemented in arith.go. ++ ++TEXT ·addVV(SB), NOFRAME|NOSPLIT, $0 ++ JMP ·addVV_g(SB) ++ ++TEXT ·subVV(SB), NOFRAME|NOSPLIT, $0 ++ JMP ·subVV_g(SB) ++ ++TEXT ·addVW(SB), NOFRAME|NOSPLIT, $0 ++ JMP ·addVW_g(SB) ++ ++TEXT ·subVW(SB), NOFRAME|NOSPLIT, $0 ++ JMP ·subVW_g(SB) ++ ++TEXT ·shlVU(SB), NOFRAME|NOSPLIT, $0 ++ JMP ·shlVU_g(SB) ++ ++TEXT ·shrVU(SB), NOFRAME|NOSPLIT, $0 ++ JMP ·shrVU_g(SB) ++ ++TEXT ·mulAddVWW(SB), NOFRAME|NOSPLIT, $0 ++ JMP ·mulAddVWW_g(SB) ++ ++TEXT ·addMulVVW(SB), NOFRAME|NOSPLIT, $0 ++ JMP ·addMulVVW_g(SB) diff --git a/0013-math-big-optimize-addVW-function-for-loong64.patch b/0013-math-big-optimize-addVW-function-for-loong64.patch new file mode 100644 index 0000000000000000000000000000000000000000..853a0d43914daf3d1d20664bb8ea8f31f137c34e --- /dev/null +++ b/0013-math-big-optimize-addVW-function-for-loong64.patch @@ -0,0 +1,82 @@ +From 94a6bdcacffb17b8adf57ce0919a3d31ac70b646 Mon Sep 17 00:00:00 2001 +From: Huang Qiqi +Date: Tue, 11 Jun 2024 16:09:10 +0800 +Subject: [PATCH 13/44] math/big: optimize addVW function for loong64 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Benchmark results on Loongson 3C5000 (which is an LA464 implementation): + +goos: linux +goarch: loong64 +pkg: math/big +cpu: Loongson-3C5000 @ 2200.00MHz + │ test/old_3c5000_addvw.log │ test/new_3c5000_addvw.log │ + │ sec/op │ sec/op vs base │ +AddVW/1 9.555n ± 0% 5.915n ± 0% -38.09% (p=0.000 n=20) +AddVW/2 11.370n ± 0% 6.825n ± 0% -39.97% (p=0.000 n=20) +AddVW/3 12.485n ± 0% 7.970n ± 0% -36.16% (p=0.000 n=20) +AddVW/4 14.980n ± 0% 9.718n ± 0% -35.13% (p=0.000 n=20) +AddVW/5 16.73n ± 0% 10.63n ± 0% -36.46% (p=0.000 n=20) +AddVW/10 24.57n ± 0% 15.18n ± 0% -38.23% (p=0.000 n=20) +AddVW/100 184.9n ± 0% 102.4n ± 0% -44.62% (p=0.000 n=20) +AddVW/1000 1721.0n ± 0% 921.4n ± 0% -46.46% (p=0.000 n=20) +AddVW/10000 16.83µ ± 0% 11.68µ ± 0% -30.58% (p=0.000 n=20) +AddVW/100000 184.7µ ± 0% 131.3µ ± 0% -28.93% (p=0.000 n=20) +AddVWext/1 9.554n ± 0% 5.915n ± 0% -38.09% (p=0.000 n=20) +AddVWext/2 11.370n ± 0% 6.825n ± 0% -39.97% (p=0.000 n=20) +AddVWext/3 12.505n ± 0% 7.969n ± 0% -36.27% (p=0.000 n=20) +AddVWext/4 14.980n ± 0% 9.718n ± 0% -35.13% (p=0.000 n=20) +AddVWext/5 16.70n ± 0% 10.63n ± 0% -36.33% (p=0.000 n=20) +AddVWext/10 24.54n ± 0% 15.18n ± 0% -38.13% (p=0.000 n=20) +AddVWext/100 185.0n ± 0% 102.4n ± 0% -44.65% (p=0.000 n=20) +AddVWext/1000 1721.0n ± 0% 921.4n ± 0% -46.46% (p=0.000 n=20) +AddVWext/10000 16.83µ ± 0% 11.68µ ± 0% -30.60% (p=0.000 n=20) +AddVWext/100000 184.9µ ± 0% 130.4µ ± 0% -29.51% (p=0.000 n=20) +geomean 155.5n 96.87n -37.70% + +Change-Id: I824a90cb365e09d7d0d4a2c53ff4b30cf057a75e +--- + src/math/big/arith_loong64.s | 24 +++++++++++++++++++++++- + 1 file changed, 23 insertions(+), 1 deletion(-) + +diff --git a/src/math/big/arith_loong64.s b/src/math/big/arith_loong64.s +index bd7204cf06..bd6fec1b8d 100644 +--- a/src/math/big/arith_loong64.s ++++ b/src/math/big/arith_loong64.s +@@ -42,8 +42,30 @@ done: + TEXT ·subVV(SB),NOSPLIT,$0 + JMP ·subVV_g(SB) + ++// func addVW(z, x []Word, y Word) (c Word) + TEXT ·addVW(SB),NOSPLIT,$0 +- JMP ·addVW_g(SB) ++ // input: ++ // R4: z ++ // R5: z_len ++ // R7: x ++ // R10: y ++ MOVV z+0(FP), R4 ++ MOVV z_len+8(FP), R5 ++ MOVV x+24(FP), R7 ++ MOVV y+48(FP), R10 ++ MOVV $0, R6 ++ SLLV $3, R5 ++loop: ++ BEQ R5, R6, done ++ MOVV (R6)(R7), R8 ++ ADDV R8, R10, R9 // x1 + c = z1, if z1 < x1 then z1 overflow ++ SGTU R8, R9, R10 ++ MOVV R9, (R6)(R4) ++ ADDV $8, R6 ++ JMP loop ++done: ++ MOVV R10, c+56(FP) ++ RET + + TEXT ·subVW(SB),NOSPLIT,$0 + JMP ·subVW_g(SB) +-- +2.38.1 + diff --git a/0014-api-Add-sw64-port.patch b/0014-api-Add-sw64-port.patch new file mode 100644 index 0000000000000000000000000000000000000000..fdbcbf49b0cff0058d7b2903db19c8c2e1fd567a --- /dev/null +++ b/0014-api-Add-sw64-port.patch @@ -0,0 +1,120 @@ +diff --git a/api/go1.16.txt b/api/go1.16.txt +index e12a050939..ea2e022730 100644 +--- a/api/go1.16.txt ++++ b/api/go1.16.txt +@@ -219,6 +219,99 @@ pkg debug/elf, const PT_SUNWSTACK = 1879048187 + pkg debug/elf, const PT_SUNWSTACK ProgType + pkg debug/elf, const PT_SUNW_EH_FRAME = 1685382480 + pkg debug/elf, const PT_SUNW_EH_FRAME ProgType ++pkg debug/elf, const EM_SW64 = 39190 ++pkg debug/elf, const EM_SW64 Machine ++pkg debug/elf, const R_SW64_BR26ADDR = 42 ++pkg debug/elf, const R_SW64_BR26ADDR R_SW64 ++pkg debug/elf, const R_SW64_BRADDR = 7 ++pkg debug/elf, const R_SW64_BRADDR R_SW64 ++pkg debug/elf, const R_SW64_BRSGP = 28 ++pkg debug/elf, const R_SW64_BRSGP R_SW64 ++pkg debug/elf, const R_SW64_COPY = 24 ++pkg debug/elf, const R_SW64_COPY R_SW64 ++pkg debug/elf, const R_SW64_DTPMOD64 = 31 ++pkg debug/elf, const R_SW64_DTPMOD64 R_SW64 ++pkg debug/elf, const R_SW64_DTPREL16 = 36 ++pkg debug/elf, const R_SW64_DTPREL16 R_SW64 ++pkg debug/elf, const R_SW64_DTPREL64 = 33 ++pkg debug/elf, const R_SW64_DTPREL64 R_SW64 ++pkg debug/elf, const R_SW64_DTPRELHI = 34 ++pkg debug/elf, const R_SW64_DTPRELHI R_SW64 ++pkg debug/elf, const R_SW64_DTPRELLO = 35 ++pkg debug/elf, const R_SW64_DTPRELLO R_SW64 ++pkg debug/elf, const R_SW64_GLOB_DAT = 25 ++pkg debug/elf, const R_SW64_GLOB_DAT R_SW64 ++pkg debug/elf, const R_SW64_GOTDTPREL = 32 ++pkg debug/elf, const R_SW64_GOTDTPREL R_SW64 ++pkg debug/elf, const R_SW64_GOTTPREL = 37 ++pkg debug/elf, const R_SW64_GOTTPREL R_SW64 ++pkg debug/elf, const R_SW64_GPDISP = 6 ++pkg debug/elf, const R_SW64_GPDISP R_SW64 ++pkg debug/elf, const R_SW64_GPREL16 = 19 ++pkg debug/elf, const R_SW64_GPREL16 R_SW64 ++pkg debug/elf, const R_SW64_GPREL32 = 3 ++pkg debug/elf, const R_SW64_GPREL32 R_SW64 ++pkg debug/elf, const R_SW64_GPRELHIGH = 17 ++pkg debug/elf, const R_SW64_GPRELHIGH R_SW64 ++pkg debug/elf, const R_SW64_GPRELLOW = 18 ++pkg debug/elf, const R_SW64_GPRELLOW R_SW64 ++pkg debug/elf, const R_SW64_GPVALUE = 16 ++pkg debug/elf, const R_SW64_GPVALUE R_SW64 ++pkg debug/elf, const R_SW64_HINT = 8 ++pkg debug/elf, const R_SW64_HINT R_SW64 ++pkg debug/elf, const R_SW64_IMMED_BR_HI32 = 22 ++pkg debug/elf, const R_SW64_IMMED_BR_HI32 R_SW64 ++pkg debug/elf, const R_SW64_IMMED_GP_HI32 = 20 ++pkg debug/elf, const R_SW64_IMMED_GP_HI32 R_SW64 ++pkg debug/elf, const R_SW64_IMMED_LO32 = 23 ++pkg debug/elf, const R_SW64_IMMED_LO32 R_SW64 ++pkg debug/elf, const R_SW64_IMMED_SCN_HI32 = 21 ++pkg debug/elf, const R_SW64_IMMED_SCN_HI32 R_SW64 ++pkg debug/elf, const R_SW64_JMP_SLOT = 26 ++pkg debug/elf, const R_SW64_JMP_SLOT R_SW64 ++pkg debug/elf, const R_SW64_LITERAL = 4 ++pkg debug/elf, const R_SW64_LITERAL R_SW64 ++pkg debug/elf, const R_SW64_LITERAL_GOT = 43 ++pkg debug/elf, const R_SW64_LITERAL_GOT R_SW64 ++pkg debug/elf, const R_SW64_LITUSE = 5 ++pkg debug/elf, const R_SW64_LITUSE R_SW64 ++pkg debug/elf, const R_SW64_NONE = 0 ++pkg debug/elf, const R_SW64_NONE R_SW64 ++pkg debug/elf, const R_SW64_OP_PRSHIFT = 15 ++pkg debug/elf, const R_SW64_OP_PRSHIFT R_SW64 ++pkg debug/elf, const R_SW64_OP_PSUB = 14 ++pkg debug/elf, const R_SW64_OP_PSUB R_SW64 ++pkg debug/elf, const R_SW64_OP_PUSH = 12 ++pkg debug/elf, const R_SW64_OP_PUSH R_SW64 ++pkg debug/elf, const R_SW64_OP_STORE = 13 ++pkg debug/elf, const R_SW64_OP_STORE R_SW64 ++pkg debug/elf, const R_SW64_REFLONG = 1 ++pkg debug/elf, const R_SW64_REFLONG R_SW64 ++pkg debug/elf, const R_SW64_REFQUAD = 2 ++pkg debug/elf, const R_SW64_REFQUAD R_SW64 ++pkg debug/elf, const R_SW64_RELATIVE = 27 ++pkg debug/elf, const R_SW64_RELATIVE R_SW64 ++pkg debug/elf, const R_SW64_SREL16 = 9 ++pkg debug/elf, const R_SW64_SREL16 R_SW64 ++pkg debug/elf, const R_SW64_SREL32 = 10 ++pkg debug/elf, const R_SW64_SREL32 R_SW64 ++pkg debug/elf, const R_SW64_SREL64 = 11 ++pkg debug/elf, const R_SW64_SREL64 R_SW64 ++pkg debug/elf, const R_SW64_TLSGD = 29 ++pkg debug/elf, const R_SW64_TLSGD R_SW64 ++pkg debug/elf, const R_SW64_TLSLDM = 30 ++pkg debug/elf, const R_SW64_TLSLDM R_SW64 ++pkg debug/elf, const R_SW64_TPREL16 = 41 ++pkg debug/elf, const R_SW64_TPREL16 R_SW64 ++pkg debug/elf, const R_SW64_TPREL64 = 38 ++pkg debug/elf, const R_SW64_TPREL64 R_SW64 ++pkg debug/elf, const R_SW64_TPRELHI = 39 ++pkg debug/elf, const R_SW64_TPRELHI R_SW64 ++pkg debug/elf, const R_SW64_TPRELLO = 40 ++pkg debug/elf, const R_SW64_TPRELLO R_SW64 ++pkg debug/elf, method (R_SW64) GoString() string ++pkg debug/elf, method (R_SW64) String() string ++pkg debug/elf, type R_SW64 int + pkg embed, method (FS) Open(string) (fs.File, error) + pkg embed, method (FS) ReadDir(string) ([]fs.DirEntry, error) + pkg embed, method (FS) ReadFile(string) ([]uint8, error) +diff --git a/api/go1.18.txt b/api/go1.18.txt +index 5040c95de3..9f4fc91fd2 100644 +--- a/api/go1.18.txt ++++ b/api/go1.18.txt +@@ -251,3 +251,11 @@ pkg text/template/parse, type ContinueNode struct, Line int + pkg text/template/parse, type ContinueNode struct, embedded NodeType + pkg text/template/parse, type ContinueNode struct, embedded Pos + pkg unicode/utf8, func AppendRune([]uint8, int32) []uint8 ++pkg debug/elf, const R_SW64_ADD_ABS_LO_16 = 47 ++pkg debug/elf, const R_SW64_ADD_ABS_LO_16 R_SW64 ++pkg debug/elf, const R_SW64_ADD_PCREL_HI_13 = 45 ++pkg debug/elf, const R_SW64_ADD_PCREL_HI_13 R_SW64 ++pkg debug/elf, const R_SW64_ADD_PCREL_LO_13 = 46 ++pkg debug/elf, const R_SW64_ADD_PCREL_LO_13 R_SW64 ++pkg debug/elf, const R_SW64_CALL26 = 48 ++pkg debug/elf, const R_SW64_CALL26 R_SW64 diff --git a/0014-math-big-optimize-subVV-function-for-loong64.patch b/0014-math-big-optimize-subVV-function-for-loong64.patch new file mode 100644 index 0000000000000000000000000000000000000000..1a9c5dd8394467656a88cc5f1288e506562532a8 --- /dev/null +++ b/0014-math-big-optimize-subVV-function-for-loong64.patch @@ -0,0 +1,77 @@ +From 7939ebdcaa1156ef4e9d8f896f4877df88d7636c Mon Sep 17 00:00:00 2001 +From: Huang Qiqi +Date: Tue, 11 Jun 2024 19:06:29 +0800 +Subject: [PATCH 14/44] math/big: optimize subVV function for loong64 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Benchmark results on Loongson 3C5000 (which is an LA464 implementation): + +goos: linux +goarch: loong64 +pkg: math/big +cpu: Loongson-3C5000 @ 2200.00MHz + │ test/old_3c5000_subvv.log │ test/new_3c5000_subvv.log │ + │ sec/op │ sec/op vs base │ +SubVV/1 10.920n ± 0% 7.657n ± 0% -29.88% (p=0.000 n=20) +SubVV/2 14.100n ± 0% 8.841n ± 0% -37.30% (p=0.000 n=20) +SubVV/3 16.38n ± 0% 11.06n ± 0% -32.48% (p=0.000 n=20) +SubVV/4 18.65n ± 0% 12.85n ± 0% -31.10% (p=0.000 n=20) +SubVV/5 20.93n ± 0% 14.79n ± 0% -29.34% (p=0.000 n=20) +SubVV/10 32.30n ± 0% 22.29n ± 0% -30.99% (p=0.000 n=20) +SubVV/100 244.3n ± 0% 149.2n ± 0% -38.93% (p=0.000 n=20) +SubVV/1000 2.292µ ± 0% 1.378µ ± 0% -39.88% (p=0.000 n=20) +SubVV/10000 26.26µ ± 0% 25.64µ ± 0% -2.33% (p=0.000 n=20) +SubVV/100000 341.3µ ± 0% 238.0µ ± 0% -30.26% (p=0.000 n=20) +geomean 209.1n 144.5n -30.86% + +Change-Id: I3863c2c6728f1b0f8fecbf77de13254299c5b1cb +--- + src/math/big/arith_loong64.s | 29 ++++++++++++++++++++++++++++- + 1 file changed, 28 insertions(+), 1 deletion(-) + +diff --git a/src/math/big/arith_loong64.s b/src/math/big/arith_loong64.s +index bd6fec1b8d..8016c25207 100644 +--- a/src/math/big/arith_loong64.s ++++ b/src/math/big/arith_loong64.s +@@ -39,8 +39,35 @@ done: + MOVV R8, c+72(FP) + RET + ++// func subVV(z, x, y []Word) (c Word) + TEXT ·subVV(SB),NOSPLIT,$0 +- JMP ·subVV_g(SB) ++ // input: ++ // R4: z ++ // R5: z_len ++ // R7: x ++ // R10: y ++ MOVV z+0(FP), R4 ++ MOVV z_len+8(FP), R5 ++ MOVV x+24(FP), R7 ++ MOVV y+48(FP), R10 ++ MOVV $0, R6 ++ SLLV $3, R5 ++ MOVV $0, R8 ++loop: ++ BEQ R5, R6, done ++ MOVV (R6)(R7), R9 ++ MOVV (R6)(R10), R11 ++ SUBV R11, R9, R11 // x1 - y1 = z1', if z1' > x1 then overflow ++ SUBV R8, R11, R12 // z1' - c0 = z1, if z1 > z1' then overflow ++ SGTU R11, R9, R9 ++ SGTU R12, R11, R11 ++ MOVV R12, (R6)(R4) ++ OR R9, R11, R8 ++ ADDV $8, R6 ++ JMP loop ++done: ++ MOVV R8, c+72(FP) ++ RET + + // func addVW(z, x []Word, y Word) (c Word) + TEXT ·addVW(SB),NOSPLIT,$0 +-- +2.38.1 + diff --git a/0015-debug-Add-sw64-port.patch b/0015-debug-Add-sw64-port.patch new file mode 100644 index 0000000000000000000000000000000000000000..a977d4dc864f9e94ca6dfe8b731242b304aa1f05 --- /dev/null +++ b/0015-debug-Add-sw64-port.patch @@ -0,0 +1,214 @@ +diff --git a/src/debug/elf/elf.go b/src/debug/elf/elf.go +index e902f84665..04a0304bca 100644 +--- a/src/debug/elf/elf.go ++++ b/src/debug/elf/elf.go +@@ -391,6 +391,7 @@ const ( + EM_MIPS_RS4_BE Machine = 10 /* MIPS R4000 Big-Endian */ + EM_ALPHA_STD Machine = 41 /* Digital Alpha (standard value). */ + EM_ALPHA Machine = 0x9026 /* Alpha (written in the absence of an ABI) */ ++ EM_SW64 Machine = 0x9916 + ) + + var machineStrings = []intName{ +@@ -583,6 +584,7 @@ var machineStrings = []intName{ + {10, "EM_MIPS_RS4_BE"}, + {41, "EM_ALPHA_STD"}, + {0x9026, "EM_ALPHA"}, ++ {0x9916, "EM_SW64"}, + } + + func (i Machine) String() string { return stringName(uint32(i), machineStrings, false) } +@@ -3001,6 +3003,113 @@ var rppc64Strings = []intName{ + func (i R_PPC64) String() string { return stringName(uint32(i), rppc64Strings, false) } + func (i R_PPC64) GoString() string { return stringName(uint32(i), rppc64Strings, true) } + ++// Relocation types for SW64. ++type R_SW64 int ++ ++const ( ++ R_SW64_NONE R_SW64 = 0 /* No reloc */ ++ R_SW64_REFLONG R_SW64 = 1 /* Direct 32 bit */ ++ R_SW64_REFQUAD R_SW64 = 2 /* Direct 64 bit */ ++ R_SW64_GPREL32 R_SW64 = 3 /* GP relative 32 bit */ ++ R_SW64_LITERAL R_SW64 = 4 /* GP relative 16 bit w/optimization */ ++ R_SW64_LITUSE R_SW64 = 5 /* Optimization hint for LITERAL */ ++ R_SW64_GPDISP R_SW64 = 6 /* Add displacement to GP */ ++ R_SW64_BRADDR R_SW64 = 7 /* PC+4 relative 23 bit shifted */ ++ R_SW64_HINT R_SW64 = 8 /* PC+4 relative 16 bit shifted */ ++ R_SW64_SREL16 R_SW64 = 9 /* PC relative 16 bit */ ++ R_SW64_SREL32 R_SW64 = 10 /* PC relative 32 bit */ ++ R_SW64_SREL64 R_SW64 = 11 /* PC relative 64 bit */ ++ R_SW64_OP_PUSH R_SW64 = 12 /* OP stack push */ /* Skip 12 - 16 on sw64; deprecated ECOFF relocs. Now copy 12 - 16 of ALPHA*/ ++ R_SW64_OP_STORE R_SW64 = 13 /* OP stack pop and store */ ++ R_SW64_OP_PSUB R_SW64 = 14 /* OP stack subtract */ ++ R_SW64_OP_PRSHIFT R_SW64 = 15 /* OP stack right shift */ ++ R_SW64_GPVALUE R_SW64 = 16 ++ R_SW64_GPRELHIGH R_SW64 = 17 /* GP relative 32 bit, high 16 bits */ ++ R_SW64_GPRELLOW R_SW64 = 18 /* GP relative 32 bit, low 16 bits */ ++ R_SW64_GPREL16 R_SW64 = 19 /* GP relative 16 bit */ ++ R_SW64_IMMED_GP_HI32 R_SW64 = 20 /* Skip 20 - 23 on sw64; deprecated ECOFF relocs. Now copy 20 - 23 of ALPHA*/ ++ R_SW64_IMMED_SCN_HI32 R_SW64 = 21 ++ R_SW64_IMMED_BR_HI32 R_SW64 = 22 ++ R_SW64_IMMED_LO32 R_SW64 = 23 ++ R_SW64_COPY R_SW64 = 24 /* Copy symbol at runtime */ ++ R_SW64_GLOB_DAT R_SW64 = 25 /* Create GOT entry */ ++ R_SW64_JMP_SLOT R_SW64 = 26 /* Create PLT entry */ ++ R_SW64_RELATIVE R_SW64 = 27 /* Adjust by program base */ ++ R_SW64_BRSGP R_SW64 = 28 /* Like BRADDR, but assert that the source and target object file share the same GP value, and adjust the target address for STO_SW64_STD_GPLOAD. */ ++ R_SW64_TLSGD R_SW64 = 29 /* 29 - 41 Thread-Local Storage. */ ++ R_SW64_TLSLDM R_SW64 = 30 ++ R_SW64_DTPMOD64 R_SW64 = 31 ++ R_SW64_GOTDTPREL R_SW64 = 32 ++ R_SW64_DTPREL64 R_SW64 = 33 ++ R_SW64_DTPRELHI R_SW64 = 34 ++ R_SW64_DTPRELLO R_SW64 = 35 ++ R_SW64_DTPREL16 R_SW64 = 36 ++ R_SW64_GOTTPREL R_SW64 = 37 ++ R_SW64_TPREL64 R_SW64 = 38 ++ R_SW64_TPRELHI R_SW64 = 39 ++ R_SW64_TPRELLO R_SW64 = 40 ++ R_SW64_TPREL16 R_SW64 = 41 ++ R_SW64_BR26ADDR R_SW64 = 42 ++ R_SW64_LITERAL_GOT R_SW64 = 43 ++ R_SW64_ADD_PCREL_HI_13 R_SW64 = 45 ++ R_SW64_ADD_PCREL_LO_13 R_SW64 = 46 ++ R_SW64_ADD_ABS_LO_16 R_SW64 = 47 ++ R_SW64_CALL26 R_SW64 = 48 ++) ++ ++var rsw64Strings = []intName{ ++ {0, "R_SW64_NONE"}, ++ {1, "R_SW64_REFLONG"}, ++ {2, "R_SW64_REFQUAD"}, ++ {3, "R_SW64_GPREL32"}, ++ {4, "R_SW64_LITERAL"}, ++ {5, "R_SW64_LITUSE"}, ++ {6, "R_SW64_GPDISP"}, ++ {7, "R_SW64_BRADDR"}, ++ {8, "R_SW64_HINT"}, ++ {9, "R_SW64_SREL16"}, ++ {10, "R_SW64_SREL32"}, ++ {11, "R_SW64_SREL64"}, ++ {12, "R_SW64_OP_PUSH"}, ++ {13, "R_SW64_OP_STORE"}, ++ {14, "R_SW64_OP_PSUB"}, ++ {15, "R_SW64_OP_PRSHIFT"}, ++ {16, "R_SW64_GPVALUE"}, ++ {17, "R_SW64_GPRELHIGH"}, ++ {18, "R_SW64_GPRELLOW"}, ++ {19, "R_SW64_GPREL16"}, ++ {20, "R_SW64_IMMED_GP_HI32"}, ++ {21, "R_SW64_IMMED_SCN_HI32"}, ++ {22, "R_SW64_IMMED_BR_HI32"}, ++ {23, "R_SW64_IMMED_LO32"}, ++ {24, "R_SW64_COPY"}, ++ {25, "R_SW64_GLOB_DAT"}, ++ {26, "R_SW64_JMP_SLOT"}, ++ {27, "R_SW64_RELATIVE"}, ++ {28, "R_SW64_BRSGP"}, ++ {29, "R_SW64_TLSGD"}, ++ {30, "R_SW64_TLSLDM"}, ++ {31, "R_SW64_DTPMOD64"}, ++ {32, "R_SW64_GOTDTPREL"}, ++ {33, "R_SW64_DTPREL64"}, ++ {34, "R_SW64_DTPRELHI"}, ++ {35, "R_SW64_DTPRELLO"}, ++ {36, "R_SW64_DTPREL16"}, ++ {37, "R_SW64_GOTTPREL"}, ++ {38, "R_SW64_TPREL64"}, ++ {39, "R_SW64_TPRELHI"}, ++ {40, "R_SW64_TPRELLO"}, ++ {41, "R_SW64_TPREL16"}, ++ {42, "R_SW64_BR26ADDR"}, ++ {43, "R_SW64_LITERAL_GOT"}, ++ {45, "R_SW64_ADD_PCREL_HI_13"}, ++ {46, "R_SW64_ADD_PCREL_LO_13"}, ++ {47, "R_SW64_ADD_ABS_LO_16"}, ++} ++ ++func (i R_SW64) String() string { return stringName(uint32(i), rsw64Strings, false) } ++func (i R_SW64) GoString() string { return stringName(uint32(i), rsw64Strings, true) } ++ + // Relocation types for RISC-V processors. + type R_RISCV int + +diff --git a/src/debug/elf/elf_test.go b/src/debug/elf/elf_test.go +index 0350d53050..81151a20f2 100644 +--- a/src/debug/elf/elf_test.go ++++ b/src/debug/elf/elf_test.go +@@ -32,6 +32,7 @@ var nameTests = []nameTest{ + {STV_HIDDEN, "STV_HIDDEN"}, + {R_X86_64_PC32, "R_X86_64_PC32"}, + {R_ALPHA_OP_PUSH, "R_ALPHA_OP_PUSH"}, ++ {R_SW64_OP_PUSH, "R_SW64_OP_PUSH"}, + {R_ARM_THM_ABS5, "R_ARM_THM_ABS5"}, + {R_386_GOT32, "R_386_GOT32"}, + {R_PPC_GOT16_HI, "R_PPC_GOT16_HI"}, +diff --git a/src/debug/elf/file.go b/src/debug/elf/file.go +index 89bd70b5b2..a08a6d6e3b 100644 +--- a/src/debug/elf/file.go ++++ b/src/debug/elf/file.go +@@ -779,6 +779,8 @@ func (f *File) applyRelocations(dst []byte, rels []byte) error { + return f.applyRelocationss390x(dst, rels) + case f.Class == ELFCLASS64 && f.Machine == EM_SPARCV9: + return f.applyRelocationsSPARC64(dst, rels) ++ case f.Class == ELFCLASS64 && f.Machine == EM_SW64: ++ return f.applyRelocationsSW64(dst, rels) + default: + return errors.New("applyRelocations: not implemented") + } +@@ -1332,6 +1334,54 @@ func (f *File) applyRelocationsSPARC64(dst []byte, rels []byte) error { + return nil + } + ++func (f *File) applyRelocationsSW64(dst []byte, rels []byte) error { ++ // 24 is the size of Rela64. ++ if len(rels)%24 != 0 { ++ return errors.New("length of relocation section is not a multiple of 24") ++ } ++ ++ symbols, _, err := f.getSymbols(SHT_SYMTAB) ++ if err != nil { ++ return err ++ } ++ ++ b := bytes.NewReader(rels) ++ var rela Rela64 ++ ++ for b.Len() > 0 { ++ binary.Read(b, f.ByteOrder, &rela) ++ symNo := rela.Info >> 32 ++ t := R_SW64(rela.Info & 0xffff) ++ ++ if symNo == 0 || symNo > uint64(len(symbols)) { ++ continue ++ } ++ ++ sym := &symbols[symNo-1] ++ if !canApplyRelocation(sym) { ++ // We don't handle non-section relocations for now. ++ continue ++ } ++ switch t { ++ case R_SW64_REFQUAD: ++ if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 { ++ continue ++ } ++ val64 := sym.Value + uint64(rela.Addend) ++ f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64) ++ case R_SW64_REFLONG: ++ if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 { ++ continue ++ } ++ val32 := uint32(sym.Value) + uint32(rela.Addend) ++ f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32) ++ } ++ } ++ ++ return nil ++} ++ ++ + func (f *File) DWARF() (*dwarf.Data, error) { + dwarfSuffix := func(s *Section) string { + switch { diff --git a/0015-math-big-optimize-subVW-function-for-loong64.patch b/0015-math-big-optimize-subVW-function-for-loong64.patch new file mode 100644 index 0000000000000000000000000000000000000000..82c8a1c43ae0fc4c6ba1edd1e62c907c855baf55 --- /dev/null +++ b/0015-math-big-optimize-subVW-function-for-loong64.patch @@ -0,0 +1,82 @@ +From b8516483f552400ef8708645b8a10bed5f666dba Mon Sep 17 00:00:00 2001 +From: Huang Qiqi +Date: Tue, 11 Jun 2024 20:33:50 +0800 +Subject: [PATCH 15/44] math/big: optimize subVW function for loong64 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Benchmark results on Loongson 3C5000 (which is an LA464 implementation): + +goos: linux +goarch: loong64 +pkg: math/big +cpu: Loongson-3C5000 @ 2200.00MHz + │ test/old_3c5000_subvw.log │ test/new_3c5000_subvw.log │ + │ sec/op │ sec/op vs base │ +SubVW/1 8.564n ± 0% 5.915n ± 0% -30.93% (p=0.000 n=20) +SubVW/2 11.675n ± 0% 6.825n ± 0% -41.54% (p=0.000 n=20) +SubVW/3 13.410n ± 0% 7.969n ± 0% -40.57% (p=0.000 n=20) +SubVW/4 15.300n ± 0% 9.740n ± 0% -36.34% (p=0.000 n=20) +SubVW/5 17.34n ± 1% 10.66n ± 0% -38.55% (p=0.000 n=20) +SubVW/10 26.55n ± 0% 15.21n ± 0% -42.70% (p=0.000 n=20) +SubVW/100 199.2n ± 0% 102.5n ± 0% -48.52% (p=0.000 n=20) +SubVW/1000 1866.5n ± 1% 924.6n ± 0% -50.46% (p=0.000 n=20) +SubVW/10000 17.67µ ± 2% 12.04µ ± 2% -31.83% (p=0.000 n=20) +SubVW/100000 186.4µ ± 0% 132.0µ ± 0% -29.17% (p=0.000 n=20) +SubVWext/1 8.616n ± 0% 5.949n ± 0% -30.95% (p=0.000 n=20) +SubVWext/2 11.410n ± 0% 7.008n ± 1% -38.58% (p=0.000 n=20) +SubVWext/3 13.255n ± 1% 8.073n ± 0% -39.09% (p=0.000 n=20) +SubVWext/4 15.095n ± 0% 9.893n ± 0% -34.47% (p=0.000 n=20) +SubVWext/5 16.87n ± 0% 10.86n ± 0% -35.63% (p=0.000 n=20) +SubVWext/10 26.00n ± 0% 15.54n ± 0% -40.22% (p=0.000 n=20) +SubVWext/100 196.0n ± 0% 104.3n ± 1% -46.76% (p=0.000 n=20) +SubVWext/1000 1847.0n ± 0% 923.7n ± 0% -49.99% (p=0.000 n=20) +SubVWext/10000 17.30µ ± 1% 11.71µ ± 1% -32.31% (p=0.000 n=20) +SubVWext/100000 187.5µ ± 0% 131.6µ ± 0% -29.82% (p=0.000 n=20) +geomean 159.7n 97.79n -38.79% + +Change-Id: I21a6903e79b02cb22282e80c9bfe2ae9f1a87589 +--- + src/math/big/arith_loong64.s | 24 +++++++++++++++++++++++- + 1 file changed, 23 insertions(+), 1 deletion(-) + +diff --git a/src/math/big/arith_loong64.s b/src/math/big/arith_loong64.s +index 8016c25207..02d8262129 100644 +--- a/src/math/big/arith_loong64.s ++++ b/src/math/big/arith_loong64.s +@@ -94,8 +94,30 @@ done: + MOVV R10, c+56(FP) + RET + ++// func subVW(z, x []Word, y Word) (c Word) + TEXT ·subVW(SB),NOSPLIT,$0 +- JMP ·subVW_g(SB) ++ // input: ++ // R4: z ++ // R5: z_len ++ // R7: x ++ // R10: y ++ MOVV z+0(FP), R4 ++ MOVV z_len+8(FP), R5 ++ MOVV x+24(FP), R7 ++ MOVV y+48(FP), R10 ++ MOVV $0, R6 ++ SLLV $3, R5 ++loop: ++ BEQ R5, R6, done ++ MOVV (R6)(R7), R8 ++ SUBV R10, R8, R11 // x1 - c = z1, if z1 > x1 then overflow ++ SGTU R11, R8, R10 ++ MOVV R11, (R6)(R4) ++ ADDV $8, R6 ++ JMP loop ++done: ++ MOVV R10, c+56(FP) ++ RET + + TEXT ·shlVU(SB),NOSPLIT,$0 + JMP ·shlVU_g(SB) +-- +2.38.1 + diff --git a/0016-encoding-os-sw64-add-var-NativeEndian.patch b/0016-encoding-os-sw64-add-var-NativeEndian.patch new file mode 100644 index 0000000000000000000000000000000000000000..2d4198ee27af9de9e573fbc0681cdf3f451a661f --- /dev/null +++ b/0016-encoding-os-sw64-add-var-NativeEndian.patch @@ -0,0 +1,13 @@ +diff --git a/src/encoding/binary/native_endian_little.go b/src/encoding/binary/native_endian_little.go +index 38d3e9b695..d1ca072198 100644 +--- a/src/encoding/binary/native_endian_little.go ++++ b/src/encoding/binary/native_endian_little.go +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build 386 || amd64 || amd64p32 || alpha || arm || arm64 || loong64 || mipsle || mips64le || mips64p32le || nios2 || ppc64le || riscv || riscv64 || sh || wasm ++//go:build 386 || amd64 || amd64p32 || alpha || arm || arm64 || loong64 || mipsle || mips64le || mips64p32le || nios2 || ppc64le || riscv || riscv64 || sh || wasm || sw64 + + package binary + diff --git a/0016-math-big-optimize-shlVU-function-for-loong64.patch b/0016-math-big-optimize-shlVU-function-for-loong64.patch new file mode 100644 index 0000000000000000000000000000000000000000..a7fb046e70251547d0934928b6f9000eb7ac700a --- /dev/null +++ b/0016-math-big-optimize-shlVU-function-for-loong64.patch @@ -0,0 +1,92 @@ +From 3d520765bbff022132512b918379fe1a5e788f2e Mon Sep 17 00:00:00 2001 +From: Huang Qiqi +Date: Thu, 13 Jun 2024 11:36:30 +0800 +Subject: [PATCH 16/44] math/big: optimize shlVU function for loong64 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Benchmark results on Loongson 3A5000 (which is an LA464 implementation): + +goos: linux +goarch: loong64 +pkg: math/big +cpu: Loongson-3A5000-HV @ 2500.00MHz + │ old_3a5000_shlvu.log │ new_3a5000_shlvu_1st.log │ + │ sec/op │ sec/op vs base │ +NonZeroShifts/1/shlVU 7.606n ± 0% 5.304n ± 0% -30.27% (p=0.000 n=20) +NonZeroShifts/2/shlVU 9.608n ± 0% 6.164n ± 0% -35.85% (p=0.000 n=20) +NonZeroShifts/3/shlVU 11.610n ± 0% 6.984n ± 0% -39.84% (p=0.000 n=20) +NonZeroShifts/4/shlVU 12.210n ± 0% 8.869n ± 0% -27.36% (p=0.000 n=20) +NonZeroShifts/5/shlVU 14.11n ± 0% 10.41n ± 0% -26.22% (p=0.000 n=20) +NonZeroShifts/10/shlVU 22.02n ± 0% 14.77n ± 0% -32.92% (p=0.000 n=20) +NonZeroShifts/100/shlVU 161.30n ± 0% 91.15n ± 0% -43.49% (p=0.000 n=20) +NonZeroShifts/1000/shlVU 1514.0n ± 0% 811.7n ± 0% -46.39% (p=0.000 n=20) +NonZeroShifts/10000/shlVU 21.53µ ± 0% 10.54µ ± 0% -51.04% (p=0.000 n=20) +NonZeroShifts/100000/shlVU 208.1µ ± 0% 113.0µ ± 0% -45.69% (p=0.000 n=20) +geomean 142.8n 87.87n -38.46% + +Change-Id: I8e13eb0af27ac3d6846e559cdb61d2b544b05353 +--- + src/math/big/arith_loong64.s | 44 +++++++++++++++++++++++++++++++++++- + 1 file changed, 43 insertions(+), 1 deletion(-) + +diff --git a/src/math/big/arith_loong64.s b/src/math/big/arith_loong64.s +index 02d8262129..1820988d3f 100644 +--- a/src/math/big/arith_loong64.s ++++ b/src/math/big/arith_loong64.s +@@ -119,8 +119,50 @@ done: + MOVV R10, c+56(FP) + RET + ++// func shlVU(z, x []Word, s uint) (c Word) + TEXT ·shlVU(SB),NOSPLIT,$0 +- JMP ·shlVU_g(SB) ++ // input: ++ // R4: z ++ // R5: z_len ++ // R7: x ++ // R10: s ++ MOVV z_len+8(FP), R5 ++ MOVV s+48(FP), R10 ++ MOVV z+0(FP), R4 ++ MOVV x+24(FP), R7 ++ BEQ R5, len0 ++ SLLV $3, R5 ++ BEQ R10, copy ++ MOVV $64, R9 ++ ADDV $-8, R7 // &x[-1] ++ SUB R10, R9 // ŝ = 64 - s ++ MOVV (R5)(R7), R6 ++ SRLV R9, R6, R8 // c = x[len(z)-1] >> ŝ ++loop: ++ ADDV $-8, R5 ++ BEQ R5, done ++ SLLV R10, R6, R12 ++ MOVV (R5)(R7), R6 ++ SRLV R9, R6, R11 ++ OR R11, R12 ++ MOVV R12, (R5)(R4) // z[i] = x[i]<>ŝ ++ JMP loop ++done: ++ SLLV R10, R6 ++ MOVV R8, c+56(FP) ++ MOVV R6, 0(R4) // z[0] = x[0] << s ++ RET ++copy: ++ BEQ R7, R4, len0 ++copyloop: ++ ADDV $-8, R5 ++ BLT R5, R0, len0 ++ MOVV (R5)(R7), R9 ++ MOVV R9, (R5)(R4) ++ JMP copyloop ++len0: ++ MOVV R0, c+56(FP) ++ RET + + TEXT ·shrVU(SB),NOSPLIT,$0 + JMP ·shrVU_g(SB) +-- +2.38.1 + diff --git a/0017-math-big-optimize-shrVU-function-for-loong64.patch b/0017-math-big-optimize-shrVU-function-for-loong64.patch new file mode 100644 index 0000000000000000000000000000000000000000..504501900a094f24b89d68fa1e33f51664a5575e --- /dev/null +++ b/0017-math-big-optimize-shrVU-function-for-loong64.patch @@ -0,0 +1,92 @@ +From 14d44d92f1d59c42e85bd89797a3730f48699dc6 Mon Sep 17 00:00:00 2001 +From: Huang Qiqi +Date: Tue, 18 Jun 2024 02:00:38 +0000 +Subject: [PATCH 17/44] math/big: optimize shrVU function for loong64 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Benchmark results on Loongson 3A5000 (which is an LA464 implementation): + +goos: linux +goarch: loong64 +pkg: math/big +cpu: Loongson-3A5000-HV @ 2500.00MHz + │ test/old_3a5000_shrvu.log │ test/new_3a5000_shrvu.log │ + │ sec/op │ sec/op vs base │ +NonZeroShifts/1/shrVU 7.968n ± 0% 5.210n ± 0% -34.62% (p=0.000 n=20) +NonZeroShifts/2/shrVU 9.608n ± 0% 6.178n ± 0% -35.70% (p=0.000 n=20) +NonZeroShifts/3/shrVU 11.400n ± 0% 7.419n ± 0% -34.92% (p=0.000 n=20) +NonZeroShifts/4/shrVU 13.350n ± 0% 9.159n ± 0% -31.39% (p=0.000 n=20) +NonZeroShifts/5/shrVU 15.93n ± 0% 10.58n ± 0% -33.58% (p=0.000 n=20) +NonZeroShifts/10/shrVU 24.42n ± 0% 15.70n ± 0% -35.71% (p=0.000 n=20) +NonZeroShifts/100/shrVU 190.60n ± 0% 90.87n ± 0% -52.32% (p=0.000 n=20) +NonZeroShifts/1000/shrVU 1782.0n ± 0% 811.5n ± 0% -54.46% (p=0.000 n=20) +NonZeroShifts/10000/shrVU 21.54µ ± 0% 12.55µ ± 0% -41.76% (p=0.000 n=20) +NonZeroShifts/100000/shrVU 224.1µ ± 0% 126.2µ ± 0% -43.71% (p=0.000 n=20) +geomean 153.9n 91.78n -40.35% + +Change-Id: I86f1f3ac44d60ad8dc2e77bdb9b541f55eb18e74 +--- + src/math/big/arith_loong64.s | 45 +++++++++++++++++++++++++++++++++++- + 1 file changed, 44 insertions(+), 1 deletion(-) + +diff --git a/src/math/big/arith_loong64.s b/src/math/big/arith_loong64.s +index 1820988d3f..bdaaf14821 100644 +--- a/src/math/big/arith_loong64.s ++++ b/src/math/big/arith_loong64.s +@@ -165,7 +165,50 @@ len0: + RET + + TEXT ·shrVU(SB),NOSPLIT,$0 +- JMP ·shrVU_g(SB) ++ // input: ++ // R4: z ++ // R5: z_len ++ // R7: x ++ // R10: s ++ MOVV z_len+8(FP), R5 ++ MOVV s+48(FP), R10 ++ MOVV z+0(FP), R4 ++ MOVV x+24(FP), R7 ++ BEQ R5, len0 ++ SLLV $3, R5 ++ BEQ R10, copy ++ MOVV 0(R7), R6 ++ MOVV $64, R9 ++ MOVV $8, R8 ++ SUB R10, R9 // ŝ = 64 - s ++ ADDV $-8, R4 // &z[-1] ++ SLLV R9, R6, R13 // c = x[0] << ŝ ++loop: ++ BEQ R5, R8, done ++ SRLV R10, R6, R12 ++ MOVV (R8)(R7), R6 ++ SLLV R9, R6, R11 ++ OR R11, R12 ++ MOVV R12, (R8)(R4) // z[i-1] = x[i-1]>>s | x[i]<<ŝ ++ ADDV $8, R8 ++ JMP loop ++done: ++ SRLV R10, R6 ++ MOVV R13, c+56(FP) ++ MOVV R6, (R8)(R4) // z[len(z)-1] = x[len(z)-1] >> s ++ RET ++copy: ++ MOVV $0, R8 ++ BEQ R7, R4, len0 ++copyloop: ++ BEQ R5, R8, len0 ++ MOVV (R8)(R7), R9 ++ MOVV R9, (R8)(R4) ++ ADDV $8, R8 ++ JMP copyloop ++len0: ++ MOVV R0, c+56(FP) ++ RET + + TEXT ·mulAddVWW(SB),NOSPLIT,$0 + JMP ·mulAddVWW_g(SB) +-- +2.38.1 + diff --git a/0018-math-big-optimize-mulAddVWW-function-for-loong64.patch b/0018-math-big-optimize-mulAddVWW-function-for-loong64.patch new file mode 100644 index 0000000000000000000000000000000000000000..0ad375fa32d09ecea23d0d692da2b3adc95add16 --- /dev/null +++ b/0018-math-big-optimize-mulAddVWW-function-for-loong64.patch @@ -0,0 +1,77 @@ +From b956f69c885cd7fdf5305fd4047fd939000c9745 Mon Sep 17 00:00:00 2001 +From: Huang Qiqi +Date: Wed, 19 Jun 2024 06:31:00 +0000 +Subject: [PATCH 18/44] math/big: optimize mulAddVWW function for loong64 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Benchmark results on Loongson 3A5000 (which is an LA464 implementation): + +goos: linux +goarch: loong64 +pkg: math/big +cpu: Loongson-3A5000-HV @ 2500.00MHz + │ test/old_3a5000_muladdvww.log │ test/new_3a5000_muladdvww.log │ + │ sec/op │ sec/op vs base │ +MulAddVWW/1 7.606n ± 0% 6.987n ± 0% -8.14% (p=0.000 n=20) +MulAddVWW/2 9.207n ± 0% 8.567n ± 0% -6.95% (p=0.000 n=20) +MulAddVWW/3 10.810n ± 0% 9.223n ± 0% -14.68% (p=0.000 n=20) +MulAddVWW/4 13.01n ± 0% 12.41n ± 0% -4.61% (p=0.000 n=20) +MulAddVWW/5 15.79n ± 0% 12.99n ± 0% -17.73% (p=0.000 n=20) +MulAddVWW/10 25.62n ± 0% 20.02n ± 0% -21.86% (p=0.000 n=20) +MulAddVWW/100 217.0n ± 0% 170.9n ± 0% -21.24% (p=0.000 n=20) +MulAddVWW/1000 2.064µ ± 0% 1.612µ ± 0% -21.90% (p=0.000 n=20) +MulAddVWW/10000 24.50µ ± 0% 16.74µ ± 0% -31.66% (p=0.000 n=20) +MulAddVWW/100000 239.1µ ± 0% 171.1µ ± 0% -28.45% (p=0.000 n=20) +geomean 159.2n 130.3n -18.18% + +Change-Id: I063434bc382f4f1234f879172ab671a3d6f2eb80 +--- + src/math/big/arith_loong64.s | 29 ++++++++++++++++++++++++++++- + 1 file changed, 28 insertions(+), 1 deletion(-) + +diff --git a/src/math/big/arith_loong64.s b/src/math/big/arith_loong64.s +index bdaaf14821..fe7c971120 100644 +--- a/src/math/big/arith_loong64.s ++++ b/src/math/big/arith_loong64.s +@@ -210,8 +210,35 @@ len0: + MOVV R0, c+56(FP) + RET + ++// func mulAddVWW(z, x []Word, y, r Word) (c Word) + TEXT ·mulAddVWW(SB),NOSPLIT,$0 +- JMP ·mulAddVWW_g(SB) ++ // input: ++ // R4: z ++ // R5: z_len ++ // R7: x ++ // R10: y ++ // R11: r ++ MOVV z+0(FP), R4 ++ MOVV z_len+8(FP), R5 ++ MOVV x+24(FP), R7 ++ MOVV y+48(FP), R10 ++ MOVV r+56(FP), R11 ++ SLLV $3, R5 ++ MOVV $0, R6 ++loop: ++ BEQ R5, R6, done ++ MOVV (R6)(R7), R8 ++ MULV R8, R10, R9 ++ MULHVU R8, R10, R12 ++ ADDV R9, R11, R8 ++ SGTU R9, R8, R11 // if (c' = lo + c) < lo then overflow ++ MOVV R8, (R6)(R4) ++ ADDV R12, R11 ++ ADDV $8, R6 ++ JMP loop ++done: ++ MOVV R11, c+64(FP) ++ RET + + TEXT ·addMulVVW(SB),NOSPLIT,$0 + JMP ·addMulVVW_g(SB) +-- +2.38.1 + diff --git a/0019-math-big-optimize-addMulVVW-function-for-loong64.patch b/0019-math-big-optimize-addMulVVW-function-for-loong64.patch new file mode 100644 index 0000000000000000000000000000000000000000..965a89c81ebc046ba70e60c87a94fc970c1005c4 --- /dev/null +++ b/0019-math-big-optimize-addMulVVW-function-for-loong64.patch @@ -0,0 +1,77 @@ +From e7a6135d5c0fc4685ad18a82e770acf9f226b08e Mon Sep 17 00:00:00 2001 +From: Huang Qiqi +Date: Wed, 19 Jun 2024 08:05:24 +0000 +Subject: [PATCH 19/44] math/big: optimize addMulVVW function for loong64 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Benchmark results on Loongson 3A5000 (which is an LA464 implementation): + +goos: linux +goarch: loong64 +pkg: math/big +cpu: Loongson-3A5000-HV @ 2500.00MHz + │ test/old_3a5000_addmulvvw.log │ test/new_3a5000_addmulvvw.log │ + │ sec/op │ sec/op vs base │ +AddMulVVW/1 9.208n ± 0% 5.777n ± 0% -37.26% (p=0.000 n=20) +AddMulVVW/2 11.950n ± 0% 7.763n ± 0% -35.04% (p=0.000 n=20) +AddMulVVW/3 14.01n ± 0% 10.41n ± 0% -25.70% (p=0.000 n=20) +AddMulVVW/4 16.01n ± 0% 13.21n ± 0% -17.49% (p=0.000 n=20) +AddMulVVW/5 18.01n ± 0% 14.12n ± 0% -21.57% (p=0.000 n=20) +AddMulVVW/10 29.60n ± 0% 23.35n ± 0% -21.11% (p=0.000 n=20) +AddMulVVW/100 273.4n ± 0% 173.8n ± 0% -36.43% (p=0.000 n=20) +AddMulVVW/1000 2.516µ ± 0% 1.615µ ± 0% -35.81% (p=0.000 n=20) +AddMulVVW/10000 30.31µ ± 0% 21.54µ ± 0% -28.93% (p=0.000 n=20) +AddMulVVW/100000 322.5µ ± 0% 234.1µ ± 0% -27.41% (p=0.000 n=20) +geomean 197.1n 139.9n -29.00% + +Change-Id: Ib7e95b50f7af893abee72ec26948a65115455692 +--- + src/math/big/arith_loong64.s | 32 +++++++++++++++++++++++++++++++- + 1 file changed, 31 insertions(+), 1 deletion(-) + +diff --git a/src/math/big/arith_loong64.s b/src/math/big/arith_loong64.s +index fe7c971120..012af94f5c 100644 +--- a/src/math/big/arith_loong64.s ++++ b/src/math/big/arith_loong64.s +@@ -240,5 +240,35 @@ done: + MOVV R11, c+64(FP) + RET + ++// func addMulVVW(z, x []Word, y Word) (c Word) + TEXT ·addMulVVW(SB),NOSPLIT,$0 +- JMP ·addMulVVW_g(SB) ++ // input: ++ // R4: z ++ // R5: z_len ++ // R7: x ++ // R10: y ++ MOVV z_len+8(FP), R5 ++ MOVV x+24(FP), R7 ++ MOVV z+0(FP), R4 ++ MOVV y+48(FP), R10 ++ MOVV $0, R6 ++ SLLV $3, R5 ++ MOVV $0, R11 ++loop: ++ BEQ R5, R6, done ++ MOVV (R6)(R7), R8 ++ MOVV (R6)(R4), R9 ++ MULV R8, R10, R12 ++ MULHVU R8, R10, R13 ++ ADDV R12, R9, R8 ++ SGTU R12, R8, R9 ++ ADDV R13, R9 ++ ADDV R8, R11, R12 ++ SGTU R8, R12, R11 ++ MOVV R12, (R6)(R4) ++ ADDV $8, R6 ++ ADDV R9, R11 ++ JMP loop ++done: ++ MOVV R11, c+56(FP) ++ RET +-- +2.38.1 + diff --git a/0020-cmd-compile-fold-constant-shift-with-extension-on-lo.patch b/0020-cmd-compile-fold-constant-shift-with-extension-on-lo.patch new file mode 100644 index 0000000000000000000000000000000000000000..48553defe786efdc60d7eafbccac34ccc458148f --- /dev/null +++ b/0020-cmd-compile-fold-constant-shift-with-extension-on-lo.patch @@ -0,0 +1,376 @@ +From f10d1a3db9650a738d0254a58aadb62ec89eaca9 Mon Sep 17 00:00:00 2001 +From: Xiaolin Zhao +Date: Tue, 24 Sep 2024 16:59:06 +0800 +Subject: [PATCH 20/44] cmd/compile: fold constant shift with extension on + loong64 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +goos: linux +goarch: loong64 +pkg: test/bench/go1 +cpu: Loongson-3A6000 @ 2500.00MHz + │ bench.old │ bench.new │ + │ sec/op │ sec/op vs base │ +BinaryTree17 7.775 ± 1% 7.747 ± 1% ~ (p=0.713 n=15) +Fannkuch11 2.645 ± 0% 2.646 ± 0% +0.05% (p=0.002 n=15) +FmtFprintfEmpty 35.87n ± 0% 35.85n ± 0% -0.06% (p=0.000 n=15) +FmtFprintfString 59.50n ± 0% 59.17n ± 0% -0.55% (p=0.000 n=15) +FmtFprintfInt 62.03n ± 0% 62.38n ± 0% +0.56% (p=0.000 n=15) +FmtFprintfIntInt 97.73n ± 0% 96.51n ± 0% -1.25% (p=0.000 n=15) +FmtFprintfPrefixedInt 116.6n ± 0% 118.8n ± 0% +1.89% (p=0.000 n=15) +FmtFprintfFloat 204.1n ± 0% 200.3n ± 0% -1.86% (p=0.000 n=15) +FmtManyArgs 455.1n ± 0% 464.8n ± 0% +2.13% (p=0.000 n=15) +GobDecode 7.127m ± 1% 7.063m ± 1% -0.89% (p=0.033 n=15) +GobEncode 8.061m ± 1% 8.069m ± 5% ~ (p=0.870 n=15) +Gzip 279.8m ± 0% 271.4m ± 0% -3.00% (p=0.000 n=15) +Gunzip 32.63m ± 0% 31.68m ± 0% -2.93% (p=0.000 n=15) +HTTPClientServer 53.39µ ± 0% 53.12µ ± 0% -0.51% (p=0.000 n=15) +JSONEncode 9.323m ± 0% 8.990m ± 1% -3.57% (p=0.000 n=15) +JSONDecode 46.65m ± 1% 46.58m ± 0% ~ (p=0.050 n=15) +Mandelbrot200 4.600m ± 0% 4.603m ± 0% +0.06% (p=0.000 n=15) +GoParse 4.651m ± 0% 4.765m ± 1% +2.45% (p=0.000 n=15) +RegexpMatchEasy0_32 59.64n ± 0% 58.26n ± 0% -2.31% (p=0.000 n=15) +RegexpMatchEasy0_1K 457.3n ± 0% 458.0n ± 0% +0.15% (p=0.002 n=15) +RegexpMatchEasy1_32 59.24n ± 0% 60.12n ± 0% +1.49% (p=0.000 n=15) +RegexpMatchEasy1_1K 556.6n ± 0% 556.9n ± 0% +0.05% (p=0.002 n=15) +RegexpMatchMedium_32 801.5n ± 0% 799.5n ± 0% -0.25% (p=0.000 n=15) +RegexpMatchMedium_1K 27.25µ ± 0% 27.21µ ± 0% -0.15% (p=0.001 n=15) +RegexpMatchHard_32 1.382µ ± 0% 1.412µ ± 0% +2.17% (p=0.000 n=15) +RegexpMatchHard_1K 40.84µ ± 0% 40.91µ ± 0% +0.18% (p=0.000 n=15) +Revcomp 474.5m ± 0% 473.9m ± 0% ~ (p=0.081 n=15) +Template 76.85m ± 1% 74.71m ± 1% -2.79% (p=0.000 n=15) +TimeParse 271.1n ± 0% 269.1n ± 0% -0.74% (p=0.000 n=15) +TimeFormat 289.5n ± 0% 287.5n ± 0% -0.69% (p=0.000 n=15) +geomean 51.59µ 51.40µ -0.38% + +Change-Id: I721e930c30b3d1cb88a79306ec51990505d850f1 +--- + .../internal/ssa/_gen/LOONG64latelower.rules | 19 ++ + src/cmd/compile/internal/ssa/config.go | 2 + + .../internal/ssa/rewriteLOONG64latelower.go | 246 ++++++++++++++++++ + test/codegen/shift.go | 3 + + 4 files changed, 270 insertions(+) + create mode 100644 src/cmd/compile/internal/ssa/_gen/LOONG64latelower.rules + create mode 100644 src/cmd/compile/internal/ssa/rewriteLOONG64latelower.go + +diff --git a/src/cmd/compile/internal/ssa/_gen/LOONG64latelower.rules b/src/cmd/compile/internal/ssa/_gen/LOONG64latelower.rules +new file mode 100644 +index 0000000000..1158f84422 +--- /dev/null ++++ b/src/cmd/compile/internal/ssa/_gen/LOONG64latelower.rules +@@ -0,0 +1,19 @@ ++// Copyright 2024 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. ++ ++// Fold constant shift with extension. ++(SRAVconst (MOVBreg x) [c]) && c < 8 => (SRAVconst (SLLVconst x [56]) [56+c]) ++(SRAVconst (MOVHreg x) [c]) && c < 16 => (SRAVconst (SLLVconst x [48]) [48+c]) ++(SRAVconst (MOVWreg x) [c]) && c < 32 => (SRAVconst (SLLVconst x [32]) [32+c]) ++(SRLVconst (MOVBUreg x) [c]) && c < 8 => (SRLVconst (SLLVconst x [56]) [56+c]) ++(SRLVconst (MOVHUreg x) [c]) && c < 16 => (SRLVconst (SLLVconst x [48]) [48+c]) ++(SRLVconst (MOVWUreg x) [c]) && c < 32 => (SRLVconst (SLLVconst x [32]) [32+c]) ++(SLLVconst (MOVBUreg x) [c]) && c <= 56 => (SRLVconst (SLLVconst x [56]) [56-c]) ++(SLLVconst (MOVHUreg x) [c]) && c <= 48 => (SRLVconst (SLLVconst x [48]) [48-c]) ++(SLLVconst (MOVWUreg x) [c]) && c <= 32 => (SRLVconst (SLLVconst x [32]) [32-c]) ++ ++// Shift by zero. ++(SRAVconst x [0]) => x ++(SRLVconst x [0]) => x ++(SLLVconst x [0]) => x +diff --git a/src/cmd/compile/internal/ssa/config.go b/src/cmd/compile/internal/ssa/config.go +index d674cca009..9c4f60f613 100644 +--- a/src/cmd/compile/internal/ssa/config.go ++++ b/src/cmd/compile/internal/ssa/config.go +@@ -280,6 +280,8 @@ func NewConfig(arch string, types Types, ctxt *obj.Link, optimize, softfloat boo + c.RegSize = 8 + c.lowerBlock = rewriteBlockLOONG64 + c.lowerValue = rewriteValueLOONG64 ++ c.lateLowerBlock = rewriteBlockLOONG64latelower ++ c.lateLowerValue = rewriteValueLOONG64latelower + c.registers = registersLOONG64[:] + c.gpRegMask = gpRegMaskLOONG64 + c.fpRegMask = fpRegMaskLOONG64 +diff --git a/src/cmd/compile/internal/ssa/rewriteLOONG64latelower.go b/src/cmd/compile/internal/ssa/rewriteLOONG64latelower.go +new file mode 100644 +index 0000000000..f092b0a1ef +--- /dev/null ++++ b/src/cmd/compile/internal/ssa/rewriteLOONG64latelower.go +@@ -0,0 +1,246 @@ ++// Code generated from _gen/LOONG64latelower.rules using 'go generate'; DO NOT EDIT. ++ ++package ssa ++ ++func rewriteValueLOONG64latelower(v *Value) bool { ++ switch v.Op { ++ case OpLOONG64SLLVconst: ++ return rewriteValueLOONG64latelower_OpLOONG64SLLVconst(v) ++ case OpLOONG64SRAVconst: ++ return rewriteValueLOONG64latelower_OpLOONG64SRAVconst(v) ++ case OpLOONG64SRLVconst: ++ return rewriteValueLOONG64latelower_OpLOONG64SRLVconst(v) ++ } ++ return false ++} ++func rewriteValueLOONG64latelower_OpLOONG64SLLVconst(v *Value) bool { ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (SLLVconst (MOVBUreg x) [c]) ++ // cond: c <= 56 ++ // result: (SRLVconst (SLLVconst x [56]) [56-c]) ++ for { ++ c := auxIntToInt64(v.AuxInt) ++ if v_0.Op != OpLOONG64MOVBUreg { ++ break ++ } ++ x := v_0.Args[0] ++ if !(c <= 56) { ++ break ++ } ++ v.reset(OpLOONG64SRLVconst) ++ v.AuxInt = int64ToAuxInt(56 - c) ++ v0 := b.NewValue0(v.Pos, OpLOONG64SLLVconst, typ.UInt64) ++ v0.AuxInt = int64ToAuxInt(56) ++ v0.AddArg(x) ++ v.AddArg(v0) ++ return true ++ } ++ // match: (SLLVconst (MOVHUreg x) [c]) ++ // cond: c <= 48 ++ // result: (SRLVconst (SLLVconst x [48]) [48-c]) ++ for { ++ c := auxIntToInt64(v.AuxInt) ++ if v_0.Op != OpLOONG64MOVHUreg { ++ break ++ } ++ x := v_0.Args[0] ++ if !(c <= 48) { ++ break ++ } ++ v.reset(OpLOONG64SRLVconst) ++ v.AuxInt = int64ToAuxInt(48 - c) ++ v0 := b.NewValue0(v.Pos, OpLOONG64SLLVconst, typ.UInt64) ++ v0.AuxInt = int64ToAuxInt(48) ++ v0.AddArg(x) ++ v.AddArg(v0) ++ return true ++ } ++ // match: (SLLVconst (MOVWUreg x) [c]) ++ // cond: c <= 32 ++ // result: (SRLVconst (SLLVconst x [32]) [32-c]) ++ for { ++ c := auxIntToInt64(v.AuxInt) ++ if v_0.Op != OpLOONG64MOVWUreg { ++ break ++ } ++ x := v_0.Args[0] ++ if !(c <= 32) { ++ break ++ } ++ v.reset(OpLOONG64SRLVconst) ++ v.AuxInt = int64ToAuxInt(32 - c) ++ v0 := b.NewValue0(v.Pos, OpLOONG64SLLVconst, typ.UInt64) ++ v0.AuxInt = int64ToAuxInt(32) ++ v0.AddArg(x) ++ v.AddArg(v0) ++ return true ++ } ++ // match: (SLLVconst x [0]) ++ // result: x ++ for { ++ if auxIntToInt64(v.AuxInt) != 0 { ++ break ++ } ++ x := v_0 ++ v.copyOf(x) ++ return true ++ } ++ return false ++} ++func rewriteValueLOONG64latelower_OpLOONG64SRAVconst(v *Value) bool { ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (SRAVconst (MOVBreg x) [c]) ++ // cond: c < 8 ++ // result: (SRAVconst (SLLVconst x [56]) [56+c]) ++ for { ++ c := auxIntToInt64(v.AuxInt) ++ if v_0.Op != OpLOONG64MOVBreg { ++ break ++ } ++ x := v_0.Args[0] ++ if !(c < 8) { ++ break ++ } ++ v.reset(OpLOONG64SRAVconst) ++ v.AuxInt = int64ToAuxInt(56 + c) ++ v0 := b.NewValue0(v.Pos, OpLOONG64SLLVconst, typ.Int64) ++ v0.AuxInt = int64ToAuxInt(56) ++ v0.AddArg(x) ++ v.AddArg(v0) ++ return true ++ } ++ // match: (SRAVconst (MOVHreg x) [c]) ++ // cond: c < 16 ++ // result: (SRAVconst (SLLVconst x [48]) [48+c]) ++ for { ++ c := auxIntToInt64(v.AuxInt) ++ if v_0.Op != OpLOONG64MOVHreg { ++ break ++ } ++ x := v_0.Args[0] ++ if !(c < 16) { ++ break ++ } ++ v.reset(OpLOONG64SRAVconst) ++ v.AuxInt = int64ToAuxInt(48 + c) ++ v0 := b.NewValue0(v.Pos, OpLOONG64SLLVconst, typ.Int64) ++ v0.AuxInt = int64ToAuxInt(48) ++ v0.AddArg(x) ++ v.AddArg(v0) ++ return true ++ } ++ // match: (SRAVconst (MOVWreg x) [c]) ++ // cond: c < 32 ++ // result: (SRAVconst (SLLVconst x [32]) [32+c]) ++ for { ++ c := auxIntToInt64(v.AuxInt) ++ if v_0.Op != OpLOONG64MOVWreg { ++ break ++ } ++ x := v_0.Args[0] ++ if !(c < 32) { ++ break ++ } ++ v.reset(OpLOONG64SRAVconst) ++ v.AuxInt = int64ToAuxInt(32 + c) ++ v0 := b.NewValue0(v.Pos, OpLOONG64SLLVconst, typ.Int64) ++ v0.AuxInt = int64ToAuxInt(32) ++ v0.AddArg(x) ++ v.AddArg(v0) ++ return true ++ } ++ // match: (SRAVconst x [0]) ++ // result: x ++ for { ++ if auxIntToInt64(v.AuxInt) != 0 { ++ break ++ } ++ x := v_0 ++ v.copyOf(x) ++ return true ++ } ++ return false ++} ++func rewriteValueLOONG64latelower_OpLOONG64SRLVconst(v *Value) bool { ++ v_0 := v.Args[0] ++ b := v.Block ++ typ := &b.Func.Config.Types ++ // match: (SRLVconst (MOVBUreg x) [c]) ++ // cond: c < 8 ++ // result: (SRLVconst (SLLVconst x [56]) [56+c]) ++ for { ++ c := auxIntToInt64(v.AuxInt) ++ if v_0.Op != OpLOONG64MOVBUreg { ++ break ++ } ++ x := v_0.Args[0] ++ if !(c < 8) { ++ break ++ } ++ v.reset(OpLOONG64SRLVconst) ++ v.AuxInt = int64ToAuxInt(56 + c) ++ v0 := b.NewValue0(v.Pos, OpLOONG64SLLVconst, typ.UInt64) ++ v0.AuxInt = int64ToAuxInt(56) ++ v0.AddArg(x) ++ v.AddArg(v0) ++ return true ++ } ++ // match: (SRLVconst (MOVHUreg x) [c]) ++ // cond: c < 16 ++ // result: (SRLVconst (SLLVconst x [48]) [48+c]) ++ for { ++ c := auxIntToInt64(v.AuxInt) ++ if v_0.Op != OpLOONG64MOVHUreg { ++ break ++ } ++ x := v_0.Args[0] ++ if !(c < 16) { ++ break ++ } ++ v.reset(OpLOONG64SRLVconst) ++ v.AuxInt = int64ToAuxInt(48 + c) ++ v0 := b.NewValue0(v.Pos, OpLOONG64SLLVconst, typ.UInt64) ++ v0.AuxInt = int64ToAuxInt(48) ++ v0.AddArg(x) ++ v.AddArg(v0) ++ return true ++ } ++ // match: (SRLVconst (MOVWUreg x) [c]) ++ // cond: c < 32 ++ // result: (SRLVconst (SLLVconst x [32]) [32+c]) ++ for { ++ c := auxIntToInt64(v.AuxInt) ++ if v_0.Op != OpLOONG64MOVWUreg { ++ break ++ } ++ x := v_0.Args[0] ++ if !(c < 32) { ++ break ++ } ++ v.reset(OpLOONG64SRLVconst) ++ v.AuxInt = int64ToAuxInt(32 + c) ++ v0 := b.NewValue0(v.Pos, OpLOONG64SLLVconst, typ.UInt64) ++ v0.AuxInt = int64ToAuxInt(32) ++ v0.AddArg(x) ++ v.AddArg(v0) ++ return true ++ } ++ // match: (SRLVconst x [0]) ++ // result: x ++ for { ++ if auxIntToInt64(v.AuxInt) != 0 { ++ break ++ } ++ x := v_0 ++ v.copyOf(x) ++ return true ++ } ++ return false ++} ++func rewriteBlockLOONG64latelower(b *Block) bool { ++ return false ++} +diff --git a/test/codegen/shift.go b/test/codegen/shift.go +index 2d8cf86857..ad69d69aa5 100644 +--- a/test/codegen/shift.go ++++ b/test/codegen/shift.go +@@ -61,18 +61,21 @@ func rshConst64x64Overflow8(v int8) int64 { + func lshConst32x64(v int32) int32 { + // ppc64x:"SLW" + // riscv64:"SLLI",-"AND",-"SLTIU", -"MOVW" ++ // loong64:"SLLV" + return v << uint64(29) + } + + func rshConst32Ux64(v uint32) uint32 { + // ppc64x:"SRW" + // riscv64:"SRLIW",-"AND",-"SLTIU", -"MOVW" ++ // loong64:"SLLV","SRLV",-"MOVWU" + return v >> uint64(29) + } + + func rshConst32x64(v int32) int32 { + // ppc64x:"SRAW" + // riscv64:"SRAIW",-"OR",-"SLTIU", -"MOVW" ++ // loong64:"SLLV","SRAV",-"MOVW" + return v >> uint64(29) + } + +-- +2.38.1 + diff --git a/0021-test-codegen-fix-the-matching-instructions-inside-pl.patch b/0021-test-codegen-fix-the-matching-instructions-inside-pl.patch new file mode 100644 index 0000000000000000000000000000000000000000..f9e0b7be338df01040c2c024600d5efd4d90c443 --- /dev/null +++ b/0021-test-codegen-fix-the-matching-instructions-inside-pl.patch @@ -0,0 +1,31 @@ +From 53fc992fd2ba2f64eb436c5cf210e31e70282fc0 Mon Sep 17 00:00:00 2001 +From: Xiaolin Zhao +Date: Tue, 8 Oct 2024 16:23:56 +0800 +Subject: [PATCH 21/44] test/codegen: fix the matching instructions inside + plain comments for func rshConst32Ux64 on loong64 + +after add rules for (x << lc) >> rc in commit "cmd/compile: add patterns +for bitfield opcodes on loong64", the generated assembly from func +rshConst32Ux64 matches BSTRPICKV, not SLLV and SRLV. + +Change-Id: I4348716156abc3410134495edb977a88727139f8 +--- + test/codegen/shift.go | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/test/codegen/shift.go b/test/codegen/shift.go +index ad69d69aa5..6112a989b9 100644 +--- a/test/codegen/shift.go ++++ b/test/codegen/shift.go +@@ -68,7 +68,7 @@ func lshConst32x64(v int32) int32 { + func rshConst32Ux64(v uint32) uint32 { + // ppc64x:"SRW" + // riscv64:"SRLIW",-"AND",-"SLTIU", -"MOVW" +- // loong64:"SLLV","SRLV",-"MOVWU" ++ // loong64:"BSTRPICKV",-"SLLV",-"SRLV",-"MOVWU" + return v >> uint64(29) + } + +-- +2.38.1 + diff --git a/0022-cmd-compile-optimize-shifts-of-int32-and-uint32-on-l.patch b/0022-cmd-compile-optimize-shifts-of-int32-and-uint32-on-l.patch new file mode 100644 index 0000000000000000000000000000000000000000..c119f2e94194934fc073159898e1795f4b99b70a --- /dev/null +++ b/0022-cmd-compile-optimize-shifts-of-int32-and-uint32-on-l.patch @@ -0,0 +1,1064 @@ +From 2ab1123adf4a080d91ef549b76572bf4b22f907f Mon Sep 17 00:00:00 2001 +From: Xiaolin Zhao +Date: Thu, 24 Oct 2024 17:41:01 +0800 +Subject: [PATCH 22/44] cmd/compile: optimize shifts of int32 and uint32 on + loong64 + +Change-Id: I6b8d110cfed8d55e2b753259a45f55e09b8f759d +--- + src/cmd/compile/internal/loong64/ssa.go | 6 + + .../compile/internal/ssa/_gen/LOONG64.rules | 39 +- + .../compile/internal/ssa/_gen/LOONG64Ops.go | 6 + + src/cmd/compile/internal/ssa/opGen.go | 90 ++++ + .../compile/internal/ssa/rewriteLOONG64.go | 431 +++++++++++++----- + test/codegen/shift.go | 20 +- + 6 files changed, 462 insertions(+), 130 deletions(-) + +diff --git a/src/cmd/compile/internal/loong64/ssa.go b/src/cmd/compile/internal/loong64/ssa.go +index 0ba9efa1d3..bd761c407e 100644 +--- a/src/cmd/compile/internal/loong64/ssa.go ++++ b/src/cmd/compile/internal/loong64/ssa.go +@@ -165,8 +165,11 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) { + ssa.OpLOONG64OR, + ssa.OpLOONG64XOR, + ssa.OpLOONG64NOR, ++ ssa.OpLOONG64SLL, + ssa.OpLOONG64SLLV, ++ ssa.OpLOONG64SRL, + ssa.OpLOONG64SRLV, ++ ssa.OpLOONG64SRA, + ssa.OpLOONG64SRAV, + ssa.OpLOONG64ROTR, + ssa.OpLOONG64ROTRV, +@@ -274,8 +277,11 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) { + ssa.OpLOONG64ORconst, + ssa.OpLOONG64XORconst, + ssa.OpLOONG64NORconst, ++ ssa.OpLOONG64SLLconst, + ssa.OpLOONG64SLLVconst, ++ ssa.OpLOONG64SRLconst, + ssa.OpLOONG64SRLVconst, ++ ssa.OpLOONG64SRAconst, + ssa.OpLOONG64SRAVconst, + ssa.OpLOONG64ROTRconst, + ssa.OpLOONG64ROTRVconst, +diff --git a/src/cmd/compile/internal/ssa/_gen/LOONG64.rules b/src/cmd/compile/internal/ssa/_gen/LOONG64.rules +index 00a0a84f33..014cd6fb05 100644 +--- a/src/cmd/compile/internal/ssa/_gen/LOONG64.rules ++++ b/src/cmd/compile/internal/ssa/_gen/LOONG64.rules +@@ -62,10 +62,10 @@ + (Lsh64x16 x y) => (MASKEQZ (SLLV x (ZeroExt16to64 y)) (SGTU (MOVVconst [64]) (ZeroExt16to64 y))) + (Lsh64x8 x y) => (MASKEQZ (SLLV x (ZeroExt8to64 y)) (SGTU (MOVVconst [64]) (ZeroExt8to64 y))) + +-(Lsh32x64 x y) => (MASKEQZ (SLLV x y) (SGTU (MOVVconst [64]) y)) +-(Lsh32x32 x y) => (MASKEQZ (SLLV x (ZeroExt32to64 y)) (SGTU (MOVVconst [64]) (ZeroExt32to64 y))) +-(Lsh32x16 x y) => (MASKEQZ (SLLV x (ZeroExt16to64 y)) (SGTU (MOVVconst [64]) (ZeroExt16to64 y))) +-(Lsh32x8 x y) => (MASKEQZ (SLLV x (ZeroExt8to64 y)) (SGTU (MOVVconst [64]) (ZeroExt8to64 y))) ++(Lsh32x64 x y) => (MASKEQZ (SLL x y) (SGTU (MOVVconst [32]) y)) ++(Lsh32x32 x y) => (MASKEQZ (SLL x (ZeroExt32to64 y)) (SGTU (MOVVconst [32]) (ZeroExt32to64 y))) ++(Lsh32x16 x y) => (MASKEQZ (SLL x (ZeroExt16to64 y)) (SGTU (MOVVconst [32]) (ZeroExt16to64 y))) ++(Lsh32x8 x y) => (MASKEQZ (SLL x (ZeroExt8to64 y)) (SGTU (MOVVconst [32]) (ZeroExt8to64 y))) + + (Lsh16x64 x y) => (MASKEQZ (SLLV x y) (SGTU (MOVVconst [64]) y)) + (Lsh16x32 x y) => (MASKEQZ (SLLV x (ZeroExt32to64 y)) (SGTU (MOVVconst [64]) (ZeroExt32to64 y))) +@@ -82,10 +82,10 @@ + (Rsh64Ux16 x y) => (MASKEQZ (SRLV x (ZeroExt16to64 y)) (SGTU (MOVVconst [64]) (ZeroExt16to64 y))) + (Rsh64Ux8 x y) => (MASKEQZ (SRLV x (ZeroExt8to64 y)) (SGTU (MOVVconst [64]) (ZeroExt8to64 y))) + +-(Rsh32Ux64 x y) => (MASKEQZ (SRLV (ZeroExt32to64 x) y) (SGTU (MOVVconst [64]) y)) +-(Rsh32Ux32 x y) => (MASKEQZ (SRLV (ZeroExt32to64 x) (ZeroExt32to64 y)) (SGTU (MOVVconst [64]) (ZeroExt32to64 y))) +-(Rsh32Ux16 x y) => (MASKEQZ (SRLV (ZeroExt32to64 x) (ZeroExt16to64 y)) (SGTU (MOVVconst [64]) (ZeroExt16to64 y))) +-(Rsh32Ux8 x y) => (MASKEQZ (SRLV (ZeroExt32to64 x) (ZeroExt8to64 y)) (SGTU (MOVVconst [64]) (ZeroExt8to64 y))) ++(Rsh32Ux64 x y) => (MASKEQZ (SRL x y) (SGTU (MOVVconst [32]) y)) ++(Rsh32Ux32 x y) => (MASKEQZ (SRL x (ZeroExt32to64 y)) (SGTU (MOVVconst [32]) (ZeroExt32to64 y))) ++(Rsh32Ux16 x y) => (MASKEQZ (SRL x (ZeroExt16to64 y)) (SGTU (MOVVconst [32]) (ZeroExt16to64 y))) ++(Rsh32Ux8 x y) => (MASKEQZ (SRL x (ZeroExt8to64 y)) (SGTU (MOVVconst [32]) (ZeroExt8to64 y))) + + (Rsh16Ux64 x y) => (MASKEQZ (SRLV (ZeroExt16to64 x) y) (SGTU (MOVVconst [64]) y)) + (Rsh16Ux32 x y) => (MASKEQZ (SRLV (ZeroExt16to64 x) (ZeroExt32to64 y)) (SGTU (MOVVconst [64]) (ZeroExt32to64 y))) +@@ -102,10 +102,10 @@ + (Rsh64x16 x y) => (SRAV x (OR (NEGV (SGTU (ZeroExt16to64 y) (MOVVconst [63]))) (ZeroExt16to64 y))) + (Rsh64x8 x y) => (SRAV x (OR (NEGV (SGTU (ZeroExt8to64 y) (MOVVconst [63]))) (ZeroExt8to64 y))) + +-(Rsh32x64 x y) => (SRAV (SignExt32to64 x) (OR (NEGV (SGTU y (MOVVconst [63]))) y)) +-(Rsh32x32 x y) => (SRAV (SignExt32to64 x) (OR (NEGV (SGTU (ZeroExt32to64 y) (MOVVconst [63]))) (ZeroExt32to64 y))) +-(Rsh32x16 x y) => (SRAV (SignExt32to64 x) (OR (NEGV (SGTU (ZeroExt16to64 y) (MOVVconst [63]))) (ZeroExt16to64 y))) +-(Rsh32x8 x y) => (SRAV (SignExt32to64 x) (OR (NEGV (SGTU (ZeroExt8to64 y) (MOVVconst [63]))) (ZeroExt8to64 y))) ++(Rsh32x64 x y) => (SRA x (OR (NEGV (SGTU y (MOVVconst [31]))) y)) ++(Rsh32x32 x y) => (SRA x (OR (NEGV (SGTU (ZeroExt32to64 y) (MOVVconst [31]))) (ZeroExt32to64 y))) ++(Rsh32x16 x y) => (SRA x (OR (NEGV (SGTU (ZeroExt16to64 y) (MOVVconst [31]))) (ZeroExt16to64 y))) ++(Rsh32x8 x y) => (SRA x (OR (NEGV (SGTU (ZeroExt8to64 y) (MOVVconst [31]))) (ZeroExt8to64 y))) + + (Rsh16x64 x y) => (SRAV (SignExt16to64 x) (OR (NEGV (SGTU y (MOVVconst [63]))) y)) + (Rsh16x32 x y) => (SRAV (SignExt16to64 x) (OR (NEGV (SGTU (ZeroExt32to64 y) (MOVVconst [63]))) (ZeroExt32to64 y))) +@@ -683,15 +683,30 @@ + (XOR x (MOVVconst [c])) && is32Bit(c) => (XORconst [c] x) + (NOR x (MOVVconst [c])) && is32Bit(c) => (NORconst [c] x) + ++(SLL _ (MOVVconst [c])) && uint64(c)>=32 => (MOVVconst [0]) + (SLLV _ (MOVVconst [c])) && uint64(c)>=64 => (MOVVconst [0]) ++(SRL _ (MOVVconst [c])) && uint64(c)>=32 => (MOVVconst [0]) + (SRLV _ (MOVVconst [c])) && uint64(c)>=64 => (MOVVconst [0]) ++(SRA x (MOVVconst [c])) && uint64(c)>=32 => (SRAconst x [31]) + (SRAV x (MOVVconst [c])) && uint64(c)>=64 => (SRAVconst x [63]) ++(SLL x (MOVVconst [c])) && uint64(c) >=0 && uint64(c) <= 31 => (SLLconst x [c]) + (SLLV x (MOVVconst [c])) => (SLLVconst x [c]) ++(SRL x (MOVVconst [c])) && uint64(c) >=0 && uint64(c) <= 31 => (SRLconst x [c]) + (SRLV x (MOVVconst [c])) => (SRLVconst x [c]) ++(SRA x (MOVVconst [c])) && uint64(c) >=0 && uint64(c) <= 31 => (SRAconst x [c]) + (SRAV x (MOVVconst [c])) => (SRAVconst x [c]) + (ROTR x (MOVVconst [c])) => (ROTRconst x [c&31]) + (ROTRV x (MOVVconst [c])) => (ROTRVconst x [c&63]) + ++// Avoid unnecessary zero and sign extension when right shifting. ++(SRLVconst [rc] (MOVWUreg y)) && rc >= 0 && rc <= 31 => (SRLconst [int64(rc)] y) ++(SRAVconst [rc] (MOVWreg y)) && rc >= 0 && rc <= 31 => (SRAconst [int64(rc)] y) ++ ++// Replace right shifts that exceed size of signed type. ++(SRAVconst [rc] (MOVBreg y)) && rc >= 8 => (SRAVconst [63] (SLLVconst [56] y)) ++(SRAVconst [rc] (MOVHreg y)) && rc >= 16 => (SRAVconst [63] (SLLVconst [48] y)) ++(SRAVconst [rc] (MOVWreg y)) && rc >= 32 => (SRAconst [31] y) ++ + // If the shift amount is larger than the datasize(32, 16, 8), we can optimize to constant 0. + (MOVWUreg (SLLVconst [lc] x)) && lc >= 32 => (MOVVconst [0]) + (MOVHUreg (SLLVconst [lc] x)) && lc >= 16 => (MOVVconst [0]) +diff --git a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go +index 8f17158b64..4b3f1fd689 100644 +--- a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go ++++ b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go +@@ -240,11 +240,17 @@ func init() { + {name: "FCOPYSGD", argLength: 2, reg: fp21, asm: "FCOPYSGD"}, // float64 + + // shifts ++ {name: "SLL", argLength: 2, reg: gp21, asm: "SLL"}, // arg0 << arg1, shift amount is mod 32 + {name: "SLLV", argLength: 2, reg: gp21, asm: "SLLV"}, // arg0 << arg1, shift amount is mod 64 ++ {name: "SLLconst", argLength: 1, reg: gp11, asm: "SLL", aux: "Int64"}, // arg0 << auxInt + {name: "SLLVconst", argLength: 1, reg: gp11, asm: "SLLV", aux: "Int64"}, // arg0 << auxInt ++ {name: "SRL", argLength: 2, reg: gp21, asm: "SRL"}, // arg0 >> arg1, unsigned, shift amount is mod 32 + {name: "SRLV", argLength: 2, reg: gp21, asm: "SRLV"}, // arg0 >> arg1, unsigned, shift amount is mod 64 ++ {name: "SRLconst", argLength: 1, reg: gp11, asm: "SRL", aux: "Int64"}, // arg0 >> auxInt, unsigned + {name: "SRLVconst", argLength: 1, reg: gp11, asm: "SRLV", aux: "Int64"}, // arg0 >> auxInt, unsigned ++ {name: "SRA", argLength: 2, reg: gp21, asm: "SRA"}, // arg0 >> arg1, signed, shift amount is mod 32 + {name: "SRAV", argLength: 2, reg: gp21, asm: "SRAV"}, // arg0 >> arg1, signed, shift amount is mod 64 ++ {name: "SRAconst", argLength: 1, reg: gp11, asm: "SRA", aux: "Int64"}, // arg0 >> auxInt, signed + {name: "SRAVconst", argLength: 1, reg: gp11, asm: "SRAV", aux: "Int64"}, // arg0 >> auxInt, signed + {name: "ROTR", argLength: 2, reg: gp21, asm: "ROTR"}, // arg0 right rotate by (arg1 mod 32) bits + {name: "ROTRV", argLength: 2, reg: gp21, asm: "ROTRV"}, // arg0 right rotate by (arg1 mod 64) bits +diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go +index df1ddfa69e..643d012ca1 100644 +--- a/src/cmd/compile/internal/ssa/opGen.go ++++ b/src/cmd/compile/internal/ssa/opGen.go +@@ -1824,11 +1824,17 @@ const ( + OpLOONG64MASKEQZ + OpLOONG64MASKNEZ + OpLOONG64FCOPYSGD ++ OpLOONG64SLL + OpLOONG64SLLV ++ OpLOONG64SLLconst + OpLOONG64SLLVconst ++ OpLOONG64SRL + OpLOONG64SRLV ++ OpLOONG64SRLconst + OpLOONG64SRLVconst ++ OpLOONG64SRA + OpLOONG64SRAV ++ OpLOONG64SRAconst + OpLOONG64SRAVconst + OpLOONG64ROTR + OpLOONG64ROTRV +@@ -24541,6 +24547,20 @@ var opcodeTable = [...]opInfo{ + }, + }, + }, ++ { ++ name: "SLL", ++ argLen: 2, ++ asm: loong64.ASLL, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ }, ++ outputs: []outputInfo{ ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 ++ }, ++ }, ++ }, + { + name: "SLLV", + argLen: 2, +@@ -24555,6 +24575,20 @@ var opcodeTable = [...]opInfo{ + }, + }, + }, ++ { ++ name: "SLLconst", ++ auxType: auxInt64, ++ argLen: 1, ++ asm: loong64.ASLL, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ }, ++ outputs: []outputInfo{ ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 ++ }, ++ }, ++ }, + { + name: "SLLVconst", + auxType: auxInt64, +@@ -24569,6 +24603,20 @@ var opcodeTable = [...]opInfo{ + }, + }, + }, ++ { ++ name: "SRL", ++ argLen: 2, ++ asm: loong64.ASRL, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ }, ++ outputs: []outputInfo{ ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 ++ }, ++ }, ++ }, + { + name: "SRLV", + argLen: 2, +@@ -24583,6 +24631,20 @@ var opcodeTable = [...]opInfo{ + }, + }, + }, ++ { ++ name: "SRLconst", ++ auxType: auxInt64, ++ argLen: 1, ++ asm: loong64.ASRL, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ }, ++ outputs: []outputInfo{ ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 ++ }, ++ }, ++ }, + { + name: "SRLVconst", + auxType: auxInt64, +@@ -24597,6 +24659,20 @@ var opcodeTable = [...]opInfo{ + }, + }, + }, ++ { ++ name: "SRA", ++ argLen: 2, ++ asm: loong64.ASRA, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ {1, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ }, ++ outputs: []outputInfo{ ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 ++ }, ++ }, ++ }, + { + name: "SRAV", + argLen: 2, +@@ -24611,6 +24687,20 @@ var opcodeTable = [...]opInfo{ + }, + }, + }, ++ { ++ name: "SRAconst", ++ auxType: auxInt64, ++ argLen: 1, ++ asm: loong64.ASRA, ++ reg: regInfo{ ++ inputs: []inputInfo{ ++ {0, 1073741816}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 g R23 R24 R25 R26 R27 R28 R29 R31 ++ }, ++ outputs: []outputInfo{ ++ {0, 1071644664}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R23 R24 R25 R26 R27 R28 R29 R31 ++ }, ++ }, ++ }, + { + name: "SRAVconst", + auxType: auxInt64, +diff --git a/src/cmd/compile/internal/ssa/rewriteLOONG64.go b/src/cmd/compile/internal/ssa/rewriteLOONG64.go +index ab39040de1..93bf95eb51 100644 +--- a/src/cmd/compile/internal/ssa/rewriteLOONG64.go ++++ b/src/cmd/compile/internal/ssa/rewriteLOONG64.go +@@ -440,14 +440,20 @@ func rewriteValueLOONG64(v *Value) bool { + return rewriteValueLOONG64_OpLOONG64SGTUconst(v) + case OpLOONG64SGTconst: + return rewriteValueLOONG64_OpLOONG64SGTconst(v) ++ case OpLOONG64SLL: ++ return rewriteValueLOONG64_OpLOONG64SLL(v) + case OpLOONG64SLLV: + return rewriteValueLOONG64_OpLOONG64SLLV(v) + case OpLOONG64SLLVconst: + return rewriteValueLOONG64_OpLOONG64SLLVconst(v) ++ case OpLOONG64SRA: ++ return rewriteValueLOONG64_OpLOONG64SRA(v) + case OpLOONG64SRAV: + return rewriteValueLOONG64_OpLOONG64SRAV(v) + case OpLOONG64SRAVconst: + return rewriteValueLOONG64_OpLOONG64SRAVconst(v) ++ case OpLOONG64SRL: ++ return rewriteValueLOONG64_OpLOONG64SRL(v) + case OpLOONG64SRLV: + return rewriteValueLOONG64_OpLOONG64SRLV(v) + case OpLOONG64SRLVconst: +@@ -5953,6 +5959,43 @@ func rewriteValueLOONG64_OpLOONG64SGTconst(v *Value) bool { + } + return false + } ++func rewriteValueLOONG64_OpLOONG64SLL(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ // match: (SLL _ (MOVVconst [c])) ++ // cond: uint64(c)>=32 ++ // result: (MOVVconst [0]) ++ for { ++ if v_1.Op != OpLOONG64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(uint64(c) >= 32) { ++ break ++ } ++ v.reset(OpLOONG64MOVVconst) ++ v.AuxInt = int64ToAuxInt(0) ++ return true ++ } ++ // match: (SLL x (MOVVconst [c])) ++ // cond: uint64(c) >=0 && uint64(c) <= 31 ++ // result: (SLLconst x [c]) ++ for { ++ x := v_0 ++ if v_1.Op != OpLOONG64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(uint64(c) >= 0 && uint64(c) <= 31) { ++ break ++ } ++ v.reset(OpLOONG64SLLconst) ++ v.AuxInt = int64ToAuxInt(c) ++ v.AddArg(x) ++ return true ++ } ++ return false ++} + func rewriteValueLOONG64_OpLOONG64SLLV(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] +@@ -6002,6 +6045,45 @@ func rewriteValueLOONG64_OpLOONG64SLLVconst(v *Value) bool { + } + return false + } ++func rewriteValueLOONG64_OpLOONG64SRA(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ // match: (SRA x (MOVVconst [c])) ++ // cond: uint64(c)>=32 ++ // result: (SRAconst x [31]) ++ for { ++ x := v_0 ++ if v_1.Op != OpLOONG64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(uint64(c) >= 32) { ++ break ++ } ++ v.reset(OpLOONG64SRAconst) ++ v.AuxInt = int64ToAuxInt(31) ++ v.AddArg(x) ++ return true ++ } ++ // match: (SRA x (MOVVconst [c])) ++ // cond: uint64(c) >=0 && uint64(c) <= 31 ++ // result: (SRAconst x [c]) ++ for { ++ x := v_0 ++ if v_1.Op != OpLOONG64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(uint64(c) >= 0 && uint64(c) <= 31) { ++ break ++ } ++ v.reset(OpLOONG64SRAconst) ++ v.AuxInt = int64ToAuxInt(c) ++ v.AddArg(x) ++ return true ++ } ++ return false ++} + func rewriteValueLOONG64_OpLOONG64SRAV(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] +@@ -6039,6 +6121,85 @@ func rewriteValueLOONG64_OpLOONG64SRAV(v *Value) bool { + } + func rewriteValueLOONG64_OpLOONG64SRAVconst(v *Value) bool { + v_0 := v.Args[0] ++ b := v.Block ++ // match: (SRAVconst [rc] (MOVWreg y)) ++ // cond: rc >= 0 && rc <= 31 ++ // result: (SRAconst [int64(rc)] y) ++ for { ++ t := v.Type ++ rc := auxIntToInt64(v.AuxInt) ++ if v_0.Op != OpLOONG64MOVWreg { ++ break ++ } ++ y := v_0.Args[0] ++ if !(rc >= 0 && rc <= 31) { ++ break ++ } ++ v.reset(OpLOONG64SRAconst) ++ v.Type = t ++ v.AuxInt = int64ToAuxInt(int64(rc)) ++ v.AddArg(y) ++ return true ++ } ++ // match: (SRAVconst [rc] (MOVBreg y)) ++ // cond: rc >= 8 ++ // result: (SRAVconst [63] (SLLVconst [56] y)) ++ for { ++ t := v.Type ++ rc := auxIntToInt64(v.AuxInt) ++ if v_0.Op != OpLOONG64MOVBreg { ++ break ++ } ++ y := v_0.Args[0] ++ if !(rc >= 8) { ++ break ++ } ++ v.reset(OpLOONG64SRAVconst) ++ v.AuxInt = int64ToAuxInt(63) ++ v0 := b.NewValue0(v.Pos, OpLOONG64SLLVconst, t) ++ v0.AuxInt = int64ToAuxInt(56) ++ v0.AddArg(y) ++ v.AddArg(v0) ++ return true ++ } ++ // match: (SRAVconst [rc] (MOVHreg y)) ++ // cond: rc >= 16 ++ // result: (SRAVconst [63] (SLLVconst [48] y)) ++ for { ++ t := v.Type ++ rc := auxIntToInt64(v.AuxInt) ++ if v_0.Op != OpLOONG64MOVHreg { ++ break ++ } ++ y := v_0.Args[0] ++ if !(rc >= 16) { ++ break ++ } ++ v.reset(OpLOONG64SRAVconst) ++ v.AuxInt = int64ToAuxInt(63) ++ v0 := b.NewValue0(v.Pos, OpLOONG64SLLVconst, t) ++ v0.AuxInt = int64ToAuxInt(48) ++ v0.AddArg(y) ++ v.AddArg(v0) ++ return true ++ } ++ // match: (SRAVconst [rc] (MOVWreg y)) ++ // cond: rc >= 32 ++ // result: (SRAconst [31] y) ++ for { ++ rc := auxIntToInt64(v.AuxInt) ++ if v_0.Op != OpLOONG64MOVWreg { ++ break ++ } ++ y := v_0.Args[0] ++ if !(rc >= 32) { ++ break ++ } ++ v.reset(OpLOONG64SRAconst) ++ v.AuxInt = int64ToAuxInt(31) ++ v.AddArg(y) ++ return true ++ } + // match: (SRAVconst [c] (MOVVconst [d])) + // result: (MOVVconst [d>>uint64(c)]) + for { +@@ -6053,6 +6214,43 @@ func rewriteValueLOONG64_OpLOONG64SRAVconst(v *Value) bool { + } + return false + } ++func rewriteValueLOONG64_OpLOONG64SRL(v *Value) bool { ++ v_1 := v.Args[1] ++ v_0 := v.Args[0] ++ // match: (SRL _ (MOVVconst [c])) ++ // cond: uint64(c)>=32 ++ // result: (MOVVconst [0]) ++ for { ++ if v_1.Op != OpLOONG64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(uint64(c) >= 32) { ++ break ++ } ++ v.reset(OpLOONG64MOVVconst) ++ v.AuxInt = int64ToAuxInt(0) ++ return true ++ } ++ // match: (SRL x (MOVVconst [c])) ++ // cond: uint64(c) >=0 && uint64(c) <= 31 ++ // result: (SRLconst x [c]) ++ for { ++ x := v_0 ++ if v_1.Op != OpLOONG64MOVVconst { ++ break ++ } ++ c := auxIntToInt64(v_1.AuxInt) ++ if !(uint64(c) >= 0 && uint64(c) <= 31) { ++ break ++ } ++ v.reset(OpLOONG64SRLconst) ++ v.AuxInt = int64ToAuxInt(c) ++ v.AddArg(x) ++ return true ++ } ++ return false ++} + func rewriteValueLOONG64_OpLOONG64SRLV(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] +@@ -6157,6 +6355,25 @@ func rewriteValueLOONG64_OpLOONG64SRLVconst(v *Value) bool { + v.AddArg(x) + return true + } ++ // match: (SRLVconst [rc] (MOVWUreg y)) ++ // cond: rc >= 0 && rc <= 31 ++ // result: (SRLconst [int64(rc)] y) ++ for { ++ t := v.Type ++ rc := auxIntToInt64(v.AuxInt) ++ if v_0.Op != OpLOONG64MOVWUreg { ++ break ++ } ++ y := v_0.Args[0] ++ if !(rc >= 0 && rc <= 31) { ++ break ++ } ++ v.reset(OpLOONG64SRLconst) ++ v.Type = t ++ v.AuxInt = int64ToAuxInt(int64(rc)) ++ v.AddArg(y) ++ return true ++ } + // match: (SRLVconst [rc] (MOVWUreg x)) + // cond: rc >= 32 + // result: (MOVVconst [0]) +@@ -7262,19 +7479,19 @@ func rewriteValueLOONG64_OpLsh32x16(v *Value) bool { + b := v.Block + typ := &b.Func.Config.Types + // match: (Lsh32x16 x y) +- // result: (MASKEQZ (SLLV x (ZeroExt16to64 y)) (SGTU (MOVVconst [64]) (ZeroExt16to64 y))) ++ // result: (MASKEQZ (SLL x (ZeroExt16to64 y)) (SGTU (MOVVconst [32]) (ZeroExt16to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 + v.reset(OpLOONG64MASKEQZ) +- v0 := b.NewValue0(v.Pos, OpLOONG64SLLV, t) ++ v0 := b.NewValue0(v.Pos, OpLOONG64SLL, t) + v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) + v1.AddArg(y) + v0.AddArg2(x, v1) + v2 := b.NewValue0(v.Pos, OpLOONG64SGTU, typ.Bool) + v3 := b.NewValue0(v.Pos, OpLOONG64MOVVconst, typ.UInt64) +- v3.AuxInt = int64ToAuxInt(64) ++ v3.AuxInt = int64ToAuxInt(32) + v2.AddArg2(v3, v1) + v.AddArg2(v0, v2) + return true +@@ -7286,19 +7503,19 @@ func rewriteValueLOONG64_OpLsh32x32(v *Value) bool { + b := v.Block + typ := &b.Func.Config.Types + // match: (Lsh32x32 x y) +- // result: (MASKEQZ (SLLV x (ZeroExt32to64 y)) (SGTU (MOVVconst [64]) (ZeroExt32to64 y))) ++ // result: (MASKEQZ (SLL x (ZeroExt32to64 y)) (SGTU (MOVVconst [32]) (ZeroExt32to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 + v.reset(OpLOONG64MASKEQZ) +- v0 := b.NewValue0(v.Pos, OpLOONG64SLLV, t) ++ v0 := b.NewValue0(v.Pos, OpLOONG64SLL, t) + v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) + v1.AddArg(y) + v0.AddArg2(x, v1) + v2 := b.NewValue0(v.Pos, OpLOONG64SGTU, typ.Bool) + v3 := b.NewValue0(v.Pos, OpLOONG64MOVVconst, typ.UInt64) +- v3.AuxInt = int64ToAuxInt(64) ++ v3.AuxInt = int64ToAuxInt(32) + v2.AddArg2(v3, v1) + v.AddArg2(v0, v2) + return true +@@ -7310,17 +7527,17 @@ func rewriteValueLOONG64_OpLsh32x64(v *Value) bool { + b := v.Block + typ := &b.Func.Config.Types + // match: (Lsh32x64 x y) +- // result: (MASKEQZ (SLLV x y) (SGTU (MOVVconst [64]) y)) ++ // result: (MASKEQZ (SLL x y) (SGTU (MOVVconst [32]) y)) + for { + t := v.Type + x := v_0 + y := v_1 + v.reset(OpLOONG64MASKEQZ) +- v0 := b.NewValue0(v.Pos, OpLOONG64SLLV, t) ++ v0 := b.NewValue0(v.Pos, OpLOONG64SLL, t) + v0.AddArg2(x, y) + v1 := b.NewValue0(v.Pos, OpLOONG64SGTU, typ.Bool) + v2 := b.NewValue0(v.Pos, OpLOONG64MOVVconst, typ.UInt64) +- v2.AuxInt = int64ToAuxInt(64) ++ v2.AuxInt = int64ToAuxInt(32) + v1.AddArg2(v2, y) + v.AddArg2(v0, v1) + return true +@@ -7332,19 +7549,19 @@ func rewriteValueLOONG64_OpLsh32x8(v *Value) bool { + b := v.Block + typ := &b.Func.Config.Types + // match: (Lsh32x8 x y) +- // result: (MASKEQZ (SLLV x (ZeroExt8to64 y)) (SGTU (MOVVconst [64]) (ZeroExt8to64 y))) ++ // result: (MASKEQZ (SLL x (ZeroExt8to64 y)) (SGTU (MOVVconst [32]) (ZeroExt8to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 + v.reset(OpLOONG64MASKEQZ) +- v0 := b.NewValue0(v.Pos, OpLOONG64SLLV, t) ++ v0 := b.NewValue0(v.Pos, OpLOONG64SLL, t) + v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) + v1.AddArg(y) + v0.AddArg2(x, v1) + v2 := b.NewValue0(v.Pos, OpLOONG64SGTU, typ.Bool) + v3 := b.NewValue0(v.Pos, OpLOONG64MOVVconst, typ.UInt64) +- v3.AuxInt = int64ToAuxInt(64) ++ v3.AuxInt = int64ToAuxInt(32) + v2.AddArg2(v3, v1) + v.AddArg2(v0, v2) + return true +@@ -8694,23 +8911,21 @@ func rewriteValueLOONG64_OpRsh32Ux16(v *Value) bool { + b := v.Block + typ := &b.Func.Config.Types + // match: (Rsh32Ux16 x y) +- // result: (MASKEQZ (SRLV (ZeroExt32to64 x) (ZeroExt16to64 y)) (SGTU (MOVVconst [64]) (ZeroExt16to64 y))) ++ // result: (MASKEQZ (SRL x (ZeroExt16to64 y)) (SGTU (MOVVconst [32]) (ZeroExt16to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 + v.reset(OpLOONG64MASKEQZ) +- v0 := b.NewValue0(v.Pos, OpLOONG64SRLV, t) +- v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) +- v1.AddArg(x) +- v2 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) +- v2.AddArg(y) +- v0.AddArg2(v1, v2) +- v3 := b.NewValue0(v.Pos, OpLOONG64SGTU, typ.Bool) +- v4 := b.NewValue0(v.Pos, OpLOONG64MOVVconst, typ.UInt64) +- v4.AuxInt = int64ToAuxInt(64) +- v3.AddArg2(v4, v2) +- v.AddArg2(v0, v3) ++ v0 := b.NewValue0(v.Pos, OpLOONG64SRL, t) ++ v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) ++ v1.AddArg(y) ++ v0.AddArg2(x, v1) ++ v2 := b.NewValue0(v.Pos, OpLOONG64SGTU, typ.Bool) ++ v3 := b.NewValue0(v.Pos, OpLOONG64MOVVconst, typ.UInt64) ++ v3.AuxInt = int64ToAuxInt(32) ++ v2.AddArg2(v3, v1) ++ v.AddArg2(v0, v2) + return true + } + } +@@ -8720,23 +8935,21 @@ func rewriteValueLOONG64_OpRsh32Ux32(v *Value) bool { + b := v.Block + typ := &b.Func.Config.Types + // match: (Rsh32Ux32 x y) +- // result: (MASKEQZ (SRLV (ZeroExt32to64 x) (ZeroExt32to64 y)) (SGTU (MOVVconst [64]) (ZeroExt32to64 y))) ++ // result: (MASKEQZ (SRL x (ZeroExt32to64 y)) (SGTU (MOVVconst [32]) (ZeroExt32to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 + v.reset(OpLOONG64MASKEQZ) +- v0 := b.NewValue0(v.Pos, OpLOONG64SRLV, t) ++ v0 := b.NewValue0(v.Pos, OpLOONG64SRL, t) + v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) +- v1.AddArg(x) +- v2 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) +- v2.AddArg(y) +- v0.AddArg2(v1, v2) +- v3 := b.NewValue0(v.Pos, OpLOONG64SGTU, typ.Bool) +- v4 := b.NewValue0(v.Pos, OpLOONG64MOVVconst, typ.UInt64) +- v4.AuxInt = int64ToAuxInt(64) +- v3.AddArg2(v4, v2) +- v.AddArg2(v0, v3) ++ v1.AddArg(y) ++ v0.AddArg2(x, v1) ++ v2 := b.NewValue0(v.Pos, OpLOONG64SGTU, typ.Bool) ++ v3 := b.NewValue0(v.Pos, OpLOONG64MOVVconst, typ.UInt64) ++ v3.AuxInt = int64ToAuxInt(32) ++ v2.AddArg2(v3, v1) ++ v.AddArg2(v0, v2) + return true + } + } +@@ -8746,21 +8959,19 @@ func rewriteValueLOONG64_OpRsh32Ux64(v *Value) bool { + b := v.Block + typ := &b.Func.Config.Types + // match: (Rsh32Ux64 x y) +- // result: (MASKEQZ (SRLV (ZeroExt32to64 x) y) (SGTU (MOVVconst [64]) y)) ++ // result: (MASKEQZ (SRL x y) (SGTU (MOVVconst [32]) y)) + for { + t := v.Type + x := v_0 + y := v_1 + v.reset(OpLOONG64MASKEQZ) +- v0 := b.NewValue0(v.Pos, OpLOONG64SRLV, t) +- v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) +- v1.AddArg(x) +- v0.AddArg2(v1, y) +- v2 := b.NewValue0(v.Pos, OpLOONG64SGTU, typ.Bool) +- v3 := b.NewValue0(v.Pos, OpLOONG64MOVVconst, typ.UInt64) +- v3.AuxInt = int64ToAuxInt(64) +- v2.AddArg2(v3, y) +- v.AddArg2(v0, v2) ++ v0 := b.NewValue0(v.Pos, OpLOONG64SRL, t) ++ v0.AddArg2(x, y) ++ v1 := b.NewValue0(v.Pos, OpLOONG64SGTU, typ.Bool) ++ v2 := b.NewValue0(v.Pos, OpLOONG64MOVVconst, typ.UInt64) ++ v2.AuxInt = int64ToAuxInt(32) ++ v1.AddArg2(v2, y) ++ v.AddArg2(v0, v1) + return true + } + } +@@ -8770,23 +8981,21 @@ func rewriteValueLOONG64_OpRsh32Ux8(v *Value) bool { + b := v.Block + typ := &b.Func.Config.Types + // match: (Rsh32Ux8 x y) +- // result: (MASKEQZ (SRLV (ZeroExt32to64 x) (ZeroExt8to64 y)) (SGTU (MOVVconst [64]) (ZeroExt8to64 y))) ++ // result: (MASKEQZ (SRL x (ZeroExt8to64 y)) (SGTU (MOVVconst [32]) (ZeroExt8to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 + v.reset(OpLOONG64MASKEQZ) +- v0 := b.NewValue0(v.Pos, OpLOONG64SRLV, t) +- v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) +- v1.AddArg(x) +- v2 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) +- v2.AddArg(y) +- v0.AddArg2(v1, v2) +- v3 := b.NewValue0(v.Pos, OpLOONG64SGTU, typ.Bool) +- v4 := b.NewValue0(v.Pos, OpLOONG64MOVVconst, typ.UInt64) +- v4.AuxInt = int64ToAuxInt(64) +- v3.AddArg2(v4, v2) +- v.AddArg2(v0, v3) ++ v0 := b.NewValue0(v.Pos, OpLOONG64SRL, t) ++ v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) ++ v1.AddArg(y) ++ v0.AddArg2(x, v1) ++ v2 := b.NewValue0(v.Pos, OpLOONG64SGTU, typ.Bool) ++ v3 := b.NewValue0(v.Pos, OpLOONG64MOVVconst, typ.UInt64) ++ v3.AuxInt = int64ToAuxInt(32) ++ v2.AddArg2(v3, v1) ++ v.AddArg2(v0, v2) + return true + } + } +@@ -8796,25 +9005,23 @@ func rewriteValueLOONG64_OpRsh32x16(v *Value) bool { + b := v.Block + typ := &b.Func.Config.Types + // match: (Rsh32x16 x y) +- // result: (SRAV (SignExt32to64 x) (OR (NEGV (SGTU (ZeroExt16to64 y) (MOVVconst [63]))) (ZeroExt16to64 y))) ++ // result: (SRA x (OR (NEGV (SGTU (ZeroExt16to64 y) (MOVVconst [31]))) (ZeroExt16to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 +- v.reset(OpLOONG64SRAV) +- v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) +- v0.AddArg(x) +- v1 := b.NewValue0(v.Pos, OpLOONG64OR, t) +- v2 := b.NewValue0(v.Pos, OpLOONG64NEGV, t) +- v3 := b.NewValue0(v.Pos, OpLOONG64SGTU, typ.Bool) +- v4 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) +- v4.AddArg(y) +- v5 := b.NewValue0(v.Pos, OpLOONG64MOVVconst, typ.UInt64) +- v5.AuxInt = int64ToAuxInt(63) +- v3.AddArg2(v4, v5) +- v2.AddArg(v3) +- v1.AddArg2(v2, v4) +- v.AddArg2(v0, v1) ++ v.reset(OpLOONG64SRA) ++ v0 := b.NewValue0(v.Pos, OpLOONG64OR, t) ++ v1 := b.NewValue0(v.Pos, OpLOONG64NEGV, t) ++ v2 := b.NewValue0(v.Pos, OpLOONG64SGTU, typ.Bool) ++ v3 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) ++ v3.AddArg(y) ++ v4 := b.NewValue0(v.Pos, OpLOONG64MOVVconst, typ.UInt64) ++ v4.AuxInt = int64ToAuxInt(31) ++ v2.AddArg2(v3, v4) ++ v1.AddArg(v2) ++ v0.AddArg2(v1, v3) ++ v.AddArg2(x, v0) + return true + } + } +@@ -8824,25 +9031,23 @@ func rewriteValueLOONG64_OpRsh32x32(v *Value) bool { + b := v.Block + typ := &b.Func.Config.Types + // match: (Rsh32x32 x y) +- // result: (SRAV (SignExt32to64 x) (OR (NEGV (SGTU (ZeroExt32to64 y) (MOVVconst [63]))) (ZeroExt32to64 y))) ++ // result: (SRA x (OR (NEGV (SGTU (ZeroExt32to64 y) (MOVVconst [31]))) (ZeroExt32to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 +- v.reset(OpLOONG64SRAV) +- v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) +- v0.AddArg(x) +- v1 := b.NewValue0(v.Pos, OpLOONG64OR, t) +- v2 := b.NewValue0(v.Pos, OpLOONG64NEGV, t) +- v3 := b.NewValue0(v.Pos, OpLOONG64SGTU, typ.Bool) +- v4 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) +- v4.AddArg(y) +- v5 := b.NewValue0(v.Pos, OpLOONG64MOVVconst, typ.UInt64) +- v5.AuxInt = int64ToAuxInt(63) +- v3.AddArg2(v4, v5) +- v2.AddArg(v3) +- v1.AddArg2(v2, v4) +- v.AddArg2(v0, v1) ++ v.reset(OpLOONG64SRA) ++ v0 := b.NewValue0(v.Pos, OpLOONG64OR, t) ++ v1 := b.NewValue0(v.Pos, OpLOONG64NEGV, t) ++ v2 := b.NewValue0(v.Pos, OpLOONG64SGTU, typ.Bool) ++ v3 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) ++ v3.AddArg(y) ++ v4 := b.NewValue0(v.Pos, OpLOONG64MOVVconst, typ.UInt64) ++ v4.AuxInt = int64ToAuxInt(31) ++ v2.AddArg2(v3, v4) ++ v1.AddArg(v2) ++ v0.AddArg2(v1, v3) ++ v.AddArg2(x, v0) + return true + } + } +@@ -8852,23 +9057,21 @@ func rewriteValueLOONG64_OpRsh32x64(v *Value) bool { + b := v.Block + typ := &b.Func.Config.Types + // match: (Rsh32x64 x y) +- // result: (SRAV (SignExt32to64 x) (OR (NEGV (SGTU y (MOVVconst [63]))) y)) ++ // result: (SRA x (OR (NEGV (SGTU y (MOVVconst [31]))) y)) + for { + t := v.Type + x := v_0 + y := v_1 +- v.reset(OpLOONG64SRAV) +- v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) +- v0.AddArg(x) +- v1 := b.NewValue0(v.Pos, OpLOONG64OR, t) +- v2 := b.NewValue0(v.Pos, OpLOONG64NEGV, t) +- v3 := b.NewValue0(v.Pos, OpLOONG64SGTU, typ.Bool) +- v4 := b.NewValue0(v.Pos, OpLOONG64MOVVconst, typ.UInt64) +- v4.AuxInt = int64ToAuxInt(63) +- v3.AddArg2(y, v4) +- v2.AddArg(v3) +- v1.AddArg2(v2, y) +- v.AddArg2(v0, v1) ++ v.reset(OpLOONG64SRA) ++ v0 := b.NewValue0(v.Pos, OpLOONG64OR, t) ++ v1 := b.NewValue0(v.Pos, OpLOONG64NEGV, t) ++ v2 := b.NewValue0(v.Pos, OpLOONG64SGTU, typ.Bool) ++ v3 := b.NewValue0(v.Pos, OpLOONG64MOVVconst, typ.UInt64) ++ v3.AuxInt = int64ToAuxInt(31) ++ v2.AddArg2(y, v3) ++ v1.AddArg(v2) ++ v0.AddArg2(v1, y) ++ v.AddArg2(x, v0) + return true + } + } +@@ -8878,25 +9081,23 @@ func rewriteValueLOONG64_OpRsh32x8(v *Value) bool { + b := v.Block + typ := &b.Func.Config.Types + // match: (Rsh32x8 x y) +- // result: (SRAV (SignExt32to64 x) (OR (NEGV (SGTU (ZeroExt8to64 y) (MOVVconst [63]))) (ZeroExt8to64 y))) ++ // result: (SRA x (OR (NEGV (SGTU (ZeroExt8to64 y) (MOVVconst [31]))) (ZeroExt8to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 +- v.reset(OpLOONG64SRAV) +- v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64) +- v0.AddArg(x) +- v1 := b.NewValue0(v.Pos, OpLOONG64OR, t) +- v2 := b.NewValue0(v.Pos, OpLOONG64NEGV, t) +- v3 := b.NewValue0(v.Pos, OpLOONG64SGTU, typ.Bool) +- v4 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) +- v4.AddArg(y) +- v5 := b.NewValue0(v.Pos, OpLOONG64MOVVconst, typ.UInt64) +- v5.AuxInt = int64ToAuxInt(63) +- v3.AddArg2(v4, v5) +- v2.AddArg(v3) +- v1.AddArg2(v2, v4) +- v.AddArg2(v0, v1) ++ v.reset(OpLOONG64SRA) ++ v0 := b.NewValue0(v.Pos, OpLOONG64OR, t) ++ v1 := b.NewValue0(v.Pos, OpLOONG64NEGV, t) ++ v2 := b.NewValue0(v.Pos, OpLOONG64SGTU, typ.Bool) ++ v3 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) ++ v3.AddArg(y) ++ v4 := b.NewValue0(v.Pos, OpLOONG64MOVVconst, typ.UInt64) ++ v4.AuxInt = int64ToAuxInt(31) ++ v2.AddArg2(v3, v4) ++ v1.AddArg(v2) ++ v0.AddArg2(v1, v3) ++ v.AddArg2(x, v0) + return true + } + } +diff --git a/test/codegen/shift.go b/test/codegen/shift.go +index 6112a989b9..3c669edcb2 100644 +--- a/test/codegen/shift.go ++++ b/test/codegen/shift.go +@@ -11,87 +11,99 @@ package codegen + // ------------------ // + + func lshConst64x64(v int64) int64 { ++ // loong64:"SLLV" + // ppc64x:"SLD" + // riscv64:"SLLI",-"AND",-"SLTIU" + return v << uint64(33) + } + + func rshConst64Ux64(v uint64) uint64 { ++ // loong64:"SRLV" + // ppc64x:"SRD" + // riscv64:"SRLI\t",-"AND",-"SLTIU" + return v >> uint64(33) + } + + func rshConst64Ux64Overflow32(v uint32) uint64 { ++ // loong64:"MOVV\t\\$0,",-"SRL\t" + // riscv64:"MOV\t\\$0,",-"SRL" + return uint64(v) >> 32 + } + + func rshConst64Ux64Overflow16(v uint16) uint64 { ++ // loong64:"MOVV\t\\$0,",-"SRLV" + // riscv64:"MOV\t\\$0,",-"SRL" + return uint64(v) >> 16 + } + + func rshConst64Ux64Overflow8(v uint8) uint64 { ++ // loong64:"MOVV\t\\$0,",-"SRLV" + // riscv64:"MOV\t\\$0,",-"SRL" + return uint64(v) >> 8 + } + + func rshConst64x64(v int64) int64 { ++ // loong64:"SRAV" + // ppc64x:"SRAD" + // riscv64:"SRAI\t",-"OR",-"SLTIU" + return v >> uint64(33) + } + + func rshConst64x64Overflow32(v int32) int64 { ++ // loong64:"SRA\t\\$31" + // riscv64:"SRAIW",-"SLLI",-"SRAI\t" + return int64(v) >> 32 + } + + func rshConst64x64Overflow16(v int16) int64 { ++ // loong64:"SLLV\t\\$48","SRAV\t\\$63" + // riscv64:"SLLI","SRAI",-"SRAIW" + return int64(v) >> 16 + } + + func rshConst64x64Overflow8(v int8) int64 { ++ // loong64:"SLLV\t\\$56","SRAV\t\\$63" + // riscv64:"SLLI","SRAI",-"SRAIW" + return int64(v) >> 8 + } + + func lshConst32x64(v int32) int32 { ++ // loong64:"SLL\t" + // ppc64x:"SLW" + // riscv64:"SLLI",-"AND",-"SLTIU", -"MOVW" +- // loong64:"SLLV" + return v << uint64(29) + } + + func rshConst32Ux64(v uint32) uint32 { ++ // loong64:"SRL\t" + // ppc64x:"SRW" + // riscv64:"SRLIW",-"AND",-"SLTIU", -"MOVW" +- // loong64:"BSTRPICKV",-"SLLV",-"SRLV",-"MOVWU" + return v >> uint64(29) + } + + func rshConst32x64(v int32) int32 { ++ // loong64:"SRA\t" + // ppc64x:"SRAW" + // riscv64:"SRAIW",-"OR",-"SLTIU", -"MOVW" +- // loong64:"SLLV","SRAV",-"MOVW" + return v >> uint64(29) + } + + func lshConst64x32(v int64) int64 { ++ // loong64:"SLLV" + // ppc64x:"SLD" + // riscv64:"SLLI",-"AND",-"SLTIU" + return v << uint32(33) + } + + func rshConst64Ux32(v uint64) uint64 { ++ // loong64:"SRLV" + // ppc64x:"SRD" + // riscv64:"SRLI\t",-"AND",-"SLTIU" + return v >> uint32(33) + } + + func rshConst64x32(v int64) int64 { ++ // loong64:"SRAV" + // ppc64x:"SRAD" + // riscv64:"SRAI\t",-"OR",-"SLTIU" + return v >> uint32(33) +@@ -253,6 +265,7 @@ func rshGuarded64U(v uint64, s uint) uint64 { + // s390x:-"RISBGZ",-"AND",-"LOCGR" + // wasm:-"Select",-".*LtU" + // arm64:"LSR",-"CSEL" ++ // loong64:"SRLV" + return v >> s + } + panic("shift too large") +@@ -264,6 +277,7 @@ func rshGuarded64(v int64, s uint) int64 { + // s390x:-"RISBGZ",-"AND",-"LOCGR" + // wasm:-"Select",-".*LtU" + // arm64:"ASR",-"CSEL" ++ // loong64:"SRAV" + return v >> s + } + panic("shift too large") +-- +2.38.1 + diff --git a/0023-cmd-compile-simplify-bounded-shift-on-loong64.patch b/0023-cmd-compile-simplify-bounded-shift-on-loong64.patch new file mode 100644 index 0000000000000000000000000000000000000000..c4ba508b2422f8ec4217d0e36810d86d60d1d763 --- /dev/null +++ b/0023-cmd-compile-simplify-bounded-shift-on-loong64.patch @@ -0,0 +1,2206 @@ +From 03f91ceb084274b0840d7c2cf7a7cb83a7fb2ed0 Mon Sep 17 00:00:00 2001 +From: Xiaolin Zhao +Date: Fri, 15 Nov 2024 17:28:07 +0800 +Subject: [PATCH 23/44] cmd/compile: simplify bounded shift on loong64 + +Use the shiftIsBounded function to generate more efficient shift instructions. +Also optimize shift ops when the shift value is v&63 and v&31. + +Change-Id: I12548101a7cea6bca7f5fef2b12c4b8af8a20bb3 +--- + .../compile/internal/ssa/_gen/LOONG64.rules | 146 +-- + .../compile/internal/ssa/rewriteLOONG64.go | 968 ++++++++++++++++++ + test/codegen/shift.go | 16 + + 3 files changed, 1071 insertions(+), 59 deletions(-) + +diff --git a/src/cmd/compile/internal/ssa/_gen/LOONG64.rules b/src/cmd/compile/internal/ssa/_gen/LOONG64.rules +index 014cd6fb05..9d0435f434 100644 +--- a/src/cmd/compile/internal/ssa/_gen/LOONG64.rules ++++ b/src/cmd/compile/internal/ssa/_gen/LOONG64.rules +@@ -57,65 +57,84 @@ + // shifts + // hardware instruction uses only the low 6 bits of the shift + // we compare to 64 to ensure Go semantics for large shifts +-(Lsh64x64 x y) => (MASKEQZ (SLLV x y) (SGTU (MOVVconst [64]) y)) +-(Lsh64x32 x y) => (MASKEQZ (SLLV x (ZeroExt32to64 y)) (SGTU (MOVVconst [64]) (ZeroExt32to64 y))) +-(Lsh64x16 x y) => (MASKEQZ (SLLV x (ZeroExt16to64 y)) (SGTU (MOVVconst [64]) (ZeroExt16to64 y))) +-(Lsh64x8 x y) => (MASKEQZ (SLLV x (ZeroExt8to64 y)) (SGTU (MOVVconst [64]) (ZeroExt8to64 y))) +- +-(Lsh32x64 x y) => (MASKEQZ (SLL x y) (SGTU (MOVVconst [32]) y)) +-(Lsh32x32 x y) => (MASKEQZ (SLL x (ZeroExt32to64 y)) (SGTU (MOVVconst [32]) (ZeroExt32to64 y))) +-(Lsh32x16 x y) => (MASKEQZ (SLL x (ZeroExt16to64 y)) (SGTU (MOVVconst [32]) (ZeroExt16to64 y))) +-(Lsh32x8 x y) => (MASKEQZ (SLL x (ZeroExt8to64 y)) (SGTU (MOVVconst [32]) (ZeroExt8to64 y))) +- +-(Lsh16x64 x y) => (MASKEQZ (SLLV x y) (SGTU (MOVVconst [64]) y)) +-(Lsh16x32 x y) => (MASKEQZ (SLLV x (ZeroExt32to64 y)) (SGTU (MOVVconst [64]) (ZeroExt32to64 y))) +-(Lsh16x16 x y) => (MASKEQZ (SLLV x (ZeroExt16to64 y)) (SGTU (MOVVconst [64]) (ZeroExt16to64 y))) +-(Lsh16x8 x y) => (MASKEQZ (SLLV x (ZeroExt8to64 y)) (SGTU (MOVVconst [64]) (ZeroExt8to64 y))) +- +-(Lsh8x64 x y) => (MASKEQZ (SLLV x y) (SGTU (MOVVconst [64]) y)) +-(Lsh8x32 x y) => (MASKEQZ (SLLV x (ZeroExt32to64 y)) (SGTU (MOVVconst [64]) (ZeroExt32to64 y))) +-(Lsh8x16 x y) => (MASKEQZ (SLLV x (ZeroExt16to64 y)) (SGTU (MOVVconst [64]) (ZeroExt16to64 y))) +-(Lsh8x8 x y) => (MASKEQZ (SLLV x (ZeroExt8to64 y)) (SGTU (MOVVconst [64]) (ZeroExt8to64 y))) +- +-(Rsh64Ux64 x y) => (MASKEQZ (SRLV x y) (SGTU (MOVVconst [64]) y)) +-(Rsh64Ux32 x y) => (MASKEQZ (SRLV x (ZeroExt32to64 y)) (SGTU (MOVVconst [64]) (ZeroExt32to64 y))) +-(Rsh64Ux16 x y) => (MASKEQZ (SRLV x (ZeroExt16to64 y)) (SGTU (MOVVconst [64]) (ZeroExt16to64 y))) +-(Rsh64Ux8 x y) => (MASKEQZ (SRLV x (ZeroExt8to64 y)) (SGTU (MOVVconst [64]) (ZeroExt8to64 y))) +- +-(Rsh32Ux64 x y) => (MASKEQZ (SRL x y) (SGTU (MOVVconst [32]) y)) +-(Rsh32Ux32 x y) => (MASKEQZ (SRL x (ZeroExt32to64 y)) (SGTU (MOVVconst [32]) (ZeroExt32to64 y))) +-(Rsh32Ux16 x y) => (MASKEQZ (SRL x (ZeroExt16to64 y)) (SGTU (MOVVconst [32]) (ZeroExt16to64 y))) +-(Rsh32Ux8 x y) => (MASKEQZ (SRL x (ZeroExt8to64 y)) (SGTU (MOVVconst [32]) (ZeroExt8to64 y))) +- +-(Rsh16Ux64 x y) => (MASKEQZ (SRLV (ZeroExt16to64 x) y) (SGTU (MOVVconst [64]) y)) +-(Rsh16Ux32 x y) => (MASKEQZ (SRLV (ZeroExt16to64 x) (ZeroExt32to64 y)) (SGTU (MOVVconst [64]) (ZeroExt32to64 y))) +-(Rsh16Ux16 x y) => (MASKEQZ (SRLV (ZeroExt16to64 x) (ZeroExt16to64 y)) (SGTU (MOVVconst [64]) (ZeroExt16to64 y))) +-(Rsh16Ux8 x y) => (MASKEQZ (SRLV (ZeroExt16to64 x) (ZeroExt8to64 y)) (SGTU (MOVVconst [64]) (ZeroExt8to64 y))) +- +-(Rsh8Ux64 x y) => (MASKEQZ (SRLV (ZeroExt8to64 x) y) (SGTU (MOVVconst [64]) y)) +-(Rsh8Ux32 x y) => (MASKEQZ (SRLV (ZeroExt8to64 x) (ZeroExt32to64 y)) (SGTU (MOVVconst [64]) (ZeroExt32to64 y))) +-(Rsh8Ux16 x y) => (MASKEQZ (SRLV (ZeroExt8to64 x) (ZeroExt16to64 y)) (SGTU (MOVVconst [64]) (ZeroExt16to64 y))) +-(Rsh8Ux8 x y) => (MASKEQZ (SRLV (ZeroExt8to64 x) (ZeroExt8to64 y)) (SGTU (MOVVconst [64]) (ZeroExt8to64 y))) +- +-(Rsh64x64 x y) => (SRAV x (OR (NEGV (SGTU y (MOVVconst [63]))) y)) +-(Rsh64x32 x y) => (SRAV x (OR (NEGV (SGTU (ZeroExt32to64 y) (MOVVconst [63]))) (ZeroExt32to64 y))) +-(Rsh64x16 x y) => (SRAV x (OR (NEGV (SGTU (ZeroExt16to64 y) (MOVVconst [63]))) (ZeroExt16to64 y))) +-(Rsh64x8 x y) => (SRAV x (OR (NEGV (SGTU (ZeroExt8to64 y) (MOVVconst [63]))) (ZeroExt8to64 y))) +- +-(Rsh32x64 x y) => (SRA x (OR (NEGV (SGTU y (MOVVconst [31]))) y)) +-(Rsh32x32 x y) => (SRA x (OR (NEGV (SGTU (ZeroExt32to64 y) (MOVVconst [31]))) (ZeroExt32to64 y))) +-(Rsh32x16 x y) => (SRA x (OR (NEGV (SGTU (ZeroExt16to64 y) (MOVVconst [31]))) (ZeroExt16to64 y))) +-(Rsh32x8 x y) => (SRA x (OR (NEGV (SGTU (ZeroExt8to64 y) (MOVVconst [31]))) (ZeroExt8to64 y))) +- +-(Rsh16x64 x y) => (SRAV (SignExt16to64 x) (OR (NEGV (SGTU y (MOVVconst [63]))) y)) +-(Rsh16x32 x y) => (SRAV (SignExt16to64 x) (OR (NEGV (SGTU (ZeroExt32to64 y) (MOVVconst [63]))) (ZeroExt32to64 y))) +-(Rsh16x16 x y) => (SRAV (SignExt16to64 x) (OR (NEGV (SGTU (ZeroExt16to64 y) (MOVVconst [63]))) (ZeroExt16to64 y))) +-(Rsh16x8 x y) => (SRAV (SignExt16to64 x) (OR (NEGV (SGTU (ZeroExt8to64 y) (MOVVconst [63]))) (ZeroExt8to64 y))) +- +-(Rsh8x64 x y) => (SRAV (SignExt8to64 x) (OR (NEGV (SGTU y (MOVVconst [63]))) y)) +-(Rsh8x32 x y) => (SRAV (SignExt8to64 x) (OR (NEGV (SGTU (ZeroExt32to64 y) (MOVVconst [63]))) (ZeroExt32to64 y))) +-(Rsh8x16 x y) => (SRAV (SignExt8to64 x) (OR (NEGV (SGTU (ZeroExt16to64 y) (MOVVconst [63]))) (ZeroExt16to64 y))) +-(Rsh8x8 x y) => (SRAV (SignExt8to64 x) (OR (NEGV (SGTU (ZeroExt8to64 y) (MOVVconst [63]))) (ZeroExt8to64 y))) ++ ++// left shift ++(Lsh64x(64|32|16|8) x y) && shiftIsBounded(v) => (SLLV x y) ++(Lsh32x(64|32|16|8) x y) && shiftIsBounded(v) => (SLL x y) ++(Lsh16x(64|32|16|8) x y) && shiftIsBounded(v) => (SLLV x y) ++(Lsh8x(64|32|16|8) x y) && shiftIsBounded(v) => (SLLV x y) ++ ++(Lsh64x64 x y) && !shiftIsBounded(v) => (MASKEQZ (SLLV x y) (SGTU (MOVVconst [64]) y)) ++(Lsh64x32 x y) && !shiftIsBounded(v) => (MASKEQZ (SLLV x (ZeroExt32to64 y)) (SGTU (MOVVconst [64]) (ZeroExt32to64 y))) ++(Lsh64x16 x y) && !shiftIsBounded(v) => (MASKEQZ (SLLV x (ZeroExt16to64 y)) (SGTU (MOVVconst [64]) (ZeroExt16to64 y))) ++(Lsh64x8 x y) && !shiftIsBounded(v) => (MASKEQZ (SLLV x (ZeroExt8to64 y)) (SGTU (MOVVconst [64]) (ZeroExt8to64 y))) ++ ++(Lsh32x64 x y) && !shiftIsBounded(v) => (MASKEQZ (SLL x y) (SGTU (MOVVconst [32]) y)) ++(Lsh32x32 x y) && !shiftIsBounded(v) => (MASKEQZ (SLL x (ZeroExt32to64 y)) (SGTU (MOVVconst [32]) (ZeroExt32to64 y))) ++(Lsh32x16 x y) && !shiftIsBounded(v) => (MASKEQZ (SLL x (ZeroExt16to64 y)) (SGTU (MOVVconst [32]) (ZeroExt16to64 y))) ++(Lsh32x8 x y) && !shiftIsBounded(v) => (MASKEQZ (SLL x (ZeroExt8to64 y)) (SGTU (MOVVconst [32]) (ZeroExt8to64 y))) ++ ++(Lsh16x64 x y) && !shiftIsBounded(v) => (MASKEQZ (SLLV x y) (SGTU (MOVVconst [64]) y)) ++(Lsh16x32 x y) && !shiftIsBounded(v) => (MASKEQZ (SLLV x (ZeroExt32to64 y)) (SGTU (MOVVconst [64]) (ZeroExt32to64 y))) ++(Lsh16x16 x y) && !shiftIsBounded(v) => (MASKEQZ (SLLV x (ZeroExt16to64 y)) (SGTU (MOVVconst [64]) (ZeroExt16to64 y))) ++(Lsh16x8 x y) && !shiftIsBounded(v) => (MASKEQZ (SLLV x (ZeroExt8to64 y)) (SGTU (MOVVconst [64]) (ZeroExt8to64 y))) ++ ++(Lsh8x64 x y) && !shiftIsBounded(v) => (MASKEQZ (SLLV x y) (SGTU (MOVVconst [64]) y)) ++(Lsh8x32 x y) && !shiftIsBounded(v) => (MASKEQZ (SLLV x (ZeroExt32to64 y)) (SGTU (MOVVconst [64]) (ZeroExt32to64 y))) ++(Lsh8x16 x y) && !shiftIsBounded(v) => (MASKEQZ (SLLV x (ZeroExt16to64 y)) (SGTU (MOVVconst [64]) (ZeroExt16to64 y))) ++(Lsh8x8 x y) && !shiftIsBounded(v) => (MASKEQZ (SLLV x (ZeroExt8to64 y)) (SGTU (MOVVconst [64]) (ZeroExt8to64 y))) ++ ++// unsigned right shift ++(Rsh64Ux(64|32|16|8) x y) && shiftIsBounded(v) => (SRLV x y) ++(Rsh32Ux(64|32|16|8) x y) && shiftIsBounded(v) => (SRL x y) ++(Rsh16Ux(64|32|16|8) x y) && shiftIsBounded(v) => (SRLV (ZeroExt16to64 x) y) ++(Rsh8Ux(64|32|16|8) x y) && shiftIsBounded(v) => (SRLV (ZeroExt8to64 x) y) ++ ++(Rsh64Ux64 x y) && !shiftIsBounded(v) => (MASKEQZ (SRLV x y) (SGTU (MOVVconst [64]) y)) ++(Rsh64Ux32 x y) && !shiftIsBounded(v) => (MASKEQZ (SRLV x (ZeroExt32to64 y)) (SGTU (MOVVconst [64]) (ZeroExt32to64 y))) ++(Rsh64Ux16 x y) && !shiftIsBounded(v) => (MASKEQZ (SRLV x (ZeroExt16to64 y)) (SGTU (MOVVconst [64]) (ZeroExt16to64 y))) ++(Rsh64Ux8 x y) && !shiftIsBounded(v) => (MASKEQZ (SRLV x (ZeroExt8to64 y)) (SGTU (MOVVconst [64]) (ZeroExt8to64 y))) ++ ++(Rsh32Ux64 x y) && !shiftIsBounded(v) => (MASKEQZ (SRL x y) (SGTU (MOVVconst [32]) y)) ++(Rsh32Ux32 x y) && !shiftIsBounded(v) => (MASKEQZ (SRL x (ZeroExt32to64 y)) (SGTU (MOVVconst [32]) (ZeroExt32to64 y))) ++(Rsh32Ux16 x y) && !shiftIsBounded(v) => (MASKEQZ (SRL x (ZeroExt16to64 y)) (SGTU (MOVVconst [32]) (ZeroExt16to64 y))) ++(Rsh32Ux8 x y) && !shiftIsBounded(v) => (MASKEQZ (SRL x (ZeroExt8to64 y)) (SGTU (MOVVconst [32]) (ZeroExt8to64 y))) ++ ++(Rsh16Ux64 x y) && !shiftIsBounded(v) => (MASKEQZ (SRLV (ZeroExt16to64 x) y) (SGTU (MOVVconst [64]) y)) ++(Rsh16Ux32 x y) && !shiftIsBounded(v) => (MASKEQZ (SRLV (ZeroExt16to64 x) (ZeroExt32to64 y)) (SGTU (MOVVconst [64]) (ZeroExt32to64 y))) ++(Rsh16Ux16 x y) && !shiftIsBounded(v) => (MASKEQZ (SRLV (ZeroExt16to64 x) (ZeroExt16to64 y)) (SGTU (MOVVconst [64]) (ZeroExt16to64 y))) ++(Rsh16Ux8 x y) && !shiftIsBounded(v) => (MASKEQZ (SRLV (ZeroExt16to64 x) (ZeroExt8to64 y)) (SGTU (MOVVconst [64]) (ZeroExt8to64 y))) ++ ++(Rsh8Ux64 x y) && !shiftIsBounded(v) => (MASKEQZ (SRLV (ZeroExt8to64 x) y) (SGTU (MOVVconst [64]) y)) ++(Rsh8Ux32 x y) && !shiftIsBounded(v) => (MASKEQZ (SRLV (ZeroExt8to64 x) (ZeroExt32to64 y)) (SGTU (MOVVconst [64]) (ZeroExt32to64 y))) ++(Rsh8Ux16 x y) && !shiftIsBounded(v) => (MASKEQZ (SRLV (ZeroExt8to64 x) (ZeroExt16to64 y)) (SGTU (MOVVconst [64]) (ZeroExt16to64 y))) ++(Rsh8Ux8 x y) && !shiftIsBounded(v) => (MASKEQZ (SRLV (ZeroExt8to64 x) (ZeroExt8to64 y)) (SGTU (MOVVconst [64]) (ZeroExt8to64 y))) ++ ++// signed right shift ++(Rsh64x(64|32|16|8) x y) && shiftIsBounded(v) => (SRAV x y) ++(Rsh32x(64|32|16|8) x y) && shiftIsBounded(v) => (SRA x y) ++(Rsh16x(64|32|16|8) x y) && shiftIsBounded(v) => (SRAV (SignExt16to64 x) y) ++(Rsh8x(64|32|16|8) x y) && shiftIsBounded(v) => (SRAV (SignExt8to64 x) y) ++ ++(Rsh64x64 x y) && !shiftIsBounded(v) => (SRAV x (OR (NEGV (SGTU y (MOVVconst [63]))) y)) ++(Rsh64x32 x y) && !shiftIsBounded(v) => (SRAV x (OR (NEGV (SGTU (ZeroExt32to64 y) (MOVVconst [63]))) (ZeroExt32to64 y))) ++(Rsh64x16 x y) && !shiftIsBounded(v) => (SRAV x (OR (NEGV (SGTU (ZeroExt16to64 y) (MOVVconst [63]))) (ZeroExt16to64 y))) ++(Rsh64x8 x y) && !shiftIsBounded(v) => (SRAV x (OR (NEGV (SGTU (ZeroExt8to64 y) (MOVVconst [63]))) (ZeroExt8to64 y))) ++ ++(Rsh32x64 x y) && !shiftIsBounded(v) => (SRA x (OR (NEGV (SGTU y (MOVVconst [31]))) y)) ++(Rsh32x32 x y) && !shiftIsBounded(v) => (SRA x (OR (NEGV (SGTU (ZeroExt32to64 y) (MOVVconst [31]))) (ZeroExt32to64 y))) ++(Rsh32x16 x y) && !shiftIsBounded(v) => (SRA x (OR (NEGV (SGTU (ZeroExt16to64 y) (MOVVconst [31]))) (ZeroExt16to64 y))) ++(Rsh32x8 x y) && !shiftIsBounded(v) => (SRA x (OR (NEGV (SGTU (ZeroExt8to64 y) (MOVVconst [31]))) (ZeroExt8to64 y))) ++ ++(Rsh16x64 x y) && !shiftIsBounded(v) => (SRAV (SignExt16to64 x) (OR (NEGV (SGTU y (MOVVconst [63]))) y)) ++(Rsh16x32 x y) && !shiftIsBounded(v) => (SRAV (SignExt16to64 x) (OR (NEGV (SGTU (ZeroExt32to64 y) (MOVVconst [63]))) (ZeroExt32to64 y))) ++(Rsh16x16 x y) && !shiftIsBounded(v) => (SRAV (SignExt16to64 x) (OR (NEGV (SGTU (ZeroExt16to64 y) (MOVVconst [63]))) (ZeroExt16to64 y))) ++(Rsh16x8 x y) && !shiftIsBounded(v) => (SRAV (SignExt16to64 x) (OR (NEGV (SGTU (ZeroExt8to64 y) (MOVVconst [63]))) (ZeroExt8to64 y))) ++ ++(Rsh8x64 x y) && !shiftIsBounded(v) => (SRAV (SignExt8to64 x) (OR (NEGV (SGTU y (MOVVconst [63]))) y)) ++(Rsh8x32 x y) && !shiftIsBounded(v) => (SRAV (SignExt8to64 x) (OR (NEGV (SGTU (ZeroExt32to64 y) (MOVVconst [63]))) (ZeroExt32to64 y))) ++(Rsh8x16 x y) && !shiftIsBounded(v) => (SRAV (SignExt8to64 x) (OR (NEGV (SGTU (ZeroExt16to64 y) (MOVVconst [63]))) (ZeroExt16to64 y))) ++(Rsh8x8 x y) && !shiftIsBounded(v) => (SRAV (SignExt8to64 x) (OR (NEGV (SGTU (ZeroExt8to64 y) (MOVVconst [63]))) (ZeroExt8to64 y))) + + // bitfield ops + +@@ -698,6 +717,15 @@ + (ROTR x (MOVVconst [c])) => (ROTRconst x [c&31]) + (ROTRV x (MOVVconst [c])) => (ROTRVconst x [c&63]) + ++// SLLV/SRLV/SRAV only considers the bottom 6 bits of y, similarly SLL/SRL/SRA only considers the ++// bottom 5 bits of y. ++(SLL x (ANDconst [31] y)) => (SLL x y) ++(SRL x (ANDconst [31] y)) => (SRL x y) ++(SRA x (ANDconst [31] y)) => (SRA x y) ++(SLLV x (ANDconst [63] y)) => (SLLV x y) ++(SRLV x (ANDconst [63] y)) => (SRLV x y) ++(SRAV x (ANDconst [63] y)) => (SRAV x y) ++ + // Avoid unnecessary zero and sign extension when right shifting. + (SRLVconst [rc] (MOVWUreg y)) && rc >= 0 && rc <= 31 => (SRLconst [int64(rc)] y) + (SRAVconst [rc] (MOVWreg y)) && rc >= 0 && rc <= 31 => (SRAconst [int64(rc)] y) +diff --git a/src/cmd/compile/internal/ssa/rewriteLOONG64.go b/src/cmd/compile/internal/ssa/rewriteLOONG64.go +index 93bf95eb51..9efdca9c9c 100644 +--- a/src/cmd/compile/internal/ssa/rewriteLOONG64.go ++++ b/src/cmd/compile/internal/ssa/rewriteLOONG64.go +@@ -5994,6 +5994,18 @@ func rewriteValueLOONG64_OpLOONG64SLL(v *Value) bool { + v.AddArg(x) + return true + } ++ // match: (SLL x (ANDconst [31] y)) ++ // result: (SLL x y) ++ for { ++ x := v_0 ++ if v_1.Op != OpLOONG64ANDconst || auxIntToInt64(v_1.AuxInt) != 31 { ++ break ++ } ++ y := v_1.Args[0] ++ v.reset(OpLOONG64SLL) ++ v.AddArg2(x, y) ++ return true ++ } + return false + } + func rewriteValueLOONG64_OpLOONG64SLLV(v *Value) bool { +@@ -6027,6 +6039,18 @@ func rewriteValueLOONG64_OpLOONG64SLLV(v *Value) bool { + v.AddArg(x) + return true + } ++ // match: (SLLV x (ANDconst [63] y)) ++ // result: (SLLV x y) ++ for { ++ x := v_0 ++ if v_1.Op != OpLOONG64ANDconst || auxIntToInt64(v_1.AuxInt) != 63 { ++ break ++ } ++ y := v_1.Args[0] ++ v.reset(OpLOONG64SLLV) ++ v.AddArg2(x, y) ++ return true ++ } + return false + } + func rewriteValueLOONG64_OpLOONG64SLLVconst(v *Value) bool { +@@ -6082,6 +6106,18 @@ func rewriteValueLOONG64_OpLOONG64SRA(v *Value) bool { + v.AddArg(x) + return true + } ++ // match: (SRA x (ANDconst [31] y)) ++ // result: (SRA x y) ++ for { ++ x := v_0 ++ if v_1.Op != OpLOONG64ANDconst || auxIntToInt64(v_1.AuxInt) != 31 { ++ break ++ } ++ y := v_1.Args[0] ++ v.reset(OpLOONG64SRA) ++ v.AddArg2(x, y) ++ return true ++ } + return false + } + func rewriteValueLOONG64_OpLOONG64SRAV(v *Value) bool { +@@ -6117,6 +6153,18 @@ func rewriteValueLOONG64_OpLOONG64SRAV(v *Value) bool { + v.AddArg(x) + return true + } ++ // match: (SRAV x (ANDconst [63] y)) ++ // result: (SRAV x y) ++ for { ++ x := v_0 ++ if v_1.Op != OpLOONG64ANDconst || auxIntToInt64(v_1.AuxInt) != 63 { ++ break ++ } ++ y := v_1.Args[0] ++ v.reset(OpLOONG64SRAV) ++ v.AddArg2(x, y) ++ return true ++ } + return false + } + func rewriteValueLOONG64_OpLOONG64SRAVconst(v *Value) bool { +@@ -6249,6 +6297,18 @@ func rewriteValueLOONG64_OpLOONG64SRL(v *Value) bool { + v.AddArg(x) + return true + } ++ // match: (SRL x (ANDconst [31] y)) ++ // result: (SRL x y) ++ for { ++ x := v_0 ++ if v_1.Op != OpLOONG64ANDconst || auxIntToInt64(v_1.AuxInt) != 31 { ++ break ++ } ++ y := v_1.Args[0] ++ v.reset(OpLOONG64SRL) ++ v.AddArg2(x, y) ++ return true ++ } + return false + } + func rewriteValueLOONG64_OpLOONG64SRLV(v *Value) bool { +@@ -6282,6 +6342,18 @@ func rewriteValueLOONG64_OpLOONG64SRLV(v *Value) bool { + v.AddArg(x) + return true + } ++ // match: (SRLV x (ANDconst [63] y)) ++ // result: (SRLV x y) ++ for { ++ x := v_0 ++ if v_1.Op != OpLOONG64ANDconst || auxIntToInt64(v_1.AuxInt) != 63 { ++ break ++ } ++ y := v_1.Args[0] ++ v.reset(OpLOONG64SRLV) ++ v.AddArg2(x, y) ++ return true ++ } + return false + } + func rewriteValueLOONG64_OpLOONG64SRLVconst(v *Value) bool { +@@ -7384,12 +7456,29 @@ func rewriteValueLOONG64_OpLsh16x16(v *Value) bool { + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Lsh16x16 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SLLV x y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SLLV) ++ v.AddArg2(x, y) ++ return true ++ } + // match: (Lsh16x16 x y) ++ // cond: !shiftIsBounded(v) + // result: (MASKEQZ (SLLV x (ZeroExt16to64 y)) (SGTU (MOVVconst [64]) (ZeroExt16to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64MASKEQZ) + v0 := b.NewValue0(v.Pos, OpLOONG64SLLV, t) + v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) +@@ -7402,18 +7491,36 @@ func rewriteValueLOONG64_OpLsh16x16(v *Value) bool { + v.AddArg2(v0, v2) + return true + } ++ return false + } + func rewriteValueLOONG64_OpLsh16x32(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Lsh16x32 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SLLV x y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SLLV) ++ v.AddArg2(x, y) ++ return true ++ } + // match: (Lsh16x32 x y) ++ // cond: !shiftIsBounded(v) + // result: (MASKEQZ (SLLV x (ZeroExt32to64 y)) (SGTU (MOVVconst [64]) (ZeroExt32to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64MASKEQZ) + v0 := b.NewValue0(v.Pos, OpLOONG64SLLV, t) + v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) +@@ -7426,18 +7533,36 @@ func rewriteValueLOONG64_OpLsh16x32(v *Value) bool { + v.AddArg2(v0, v2) + return true + } ++ return false + } + func rewriteValueLOONG64_OpLsh16x64(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Lsh16x64 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SLLV x y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SLLV) ++ v.AddArg2(x, y) ++ return true ++ } + // match: (Lsh16x64 x y) ++ // cond: !shiftIsBounded(v) + // result: (MASKEQZ (SLLV x y) (SGTU (MOVVconst [64]) y)) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64MASKEQZ) + v0 := b.NewValue0(v.Pos, OpLOONG64SLLV, t) + v0.AddArg2(x, y) +@@ -7448,18 +7573,36 @@ func rewriteValueLOONG64_OpLsh16x64(v *Value) bool { + v.AddArg2(v0, v1) + return true + } ++ return false + } + func rewriteValueLOONG64_OpLsh16x8(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Lsh16x8 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SLLV x y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SLLV) ++ v.AddArg2(x, y) ++ return true ++ } + // match: (Lsh16x8 x y) ++ // cond: !shiftIsBounded(v) + // result: (MASKEQZ (SLLV x (ZeroExt8to64 y)) (SGTU (MOVVconst [64]) (ZeroExt8to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64MASKEQZ) + v0 := b.NewValue0(v.Pos, OpLOONG64SLLV, t) + v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) +@@ -7472,18 +7615,36 @@ func rewriteValueLOONG64_OpLsh16x8(v *Value) bool { + v.AddArg2(v0, v2) + return true + } ++ return false + } + func rewriteValueLOONG64_OpLsh32x16(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Lsh32x16 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SLL x y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SLL) ++ v.AddArg2(x, y) ++ return true ++ } + // match: (Lsh32x16 x y) ++ // cond: !shiftIsBounded(v) + // result: (MASKEQZ (SLL x (ZeroExt16to64 y)) (SGTU (MOVVconst [32]) (ZeroExt16to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64MASKEQZ) + v0 := b.NewValue0(v.Pos, OpLOONG64SLL, t) + v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) +@@ -7496,18 +7657,36 @@ func rewriteValueLOONG64_OpLsh32x16(v *Value) bool { + v.AddArg2(v0, v2) + return true + } ++ return false + } + func rewriteValueLOONG64_OpLsh32x32(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Lsh32x32 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SLL x y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SLL) ++ v.AddArg2(x, y) ++ return true ++ } + // match: (Lsh32x32 x y) ++ // cond: !shiftIsBounded(v) + // result: (MASKEQZ (SLL x (ZeroExt32to64 y)) (SGTU (MOVVconst [32]) (ZeroExt32to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64MASKEQZ) + v0 := b.NewValue0(v.Pos, OpLOONG64SLL, t) + v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) +@@ -7520,18 +7699,36 @@ func rewriteValueLOONG64_OpLsh32x32(v *Value) bool { + v.AddArg2(v0, v2) + return true + } ++ return false + } + func rewriteValueLOONG64_OpLsh32x64(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Lsh32x64 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SLL x y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SLL) ++ v.AddArg2(x, y) ++ return true ++ } + // match: (Lsh32x64 x y) ++ // cond: !shiftIsBounded(v) + // result: (MASKEQZ (SLL x y) (SGTU (MOVVconst [32]) y)) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64MASKEQZ) + v0 := b.NewValue0(v.Pos, OpLOONG64SLL, t) + v0.AddArg2(x, y) +@@ -7542,18 +7739,36 @@ func rewriteValueLOONG64_OpLsh32x64(v *Value) bool { + v.AddArg2(v0, v1) + return true + } ++ return false + } + func rewriteValueLOONG64_OpLsh32x8(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Lsh32x8 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SLL x y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SLL) ++ v.AddArg2(x, y) ++ return true ++ } + // match: (Lsh32x8 x y) ++ // cond: !shiftIsBounded(v) + // result: (MASKEQZ (SLL x (ZeroExt8to64 y)) (SGTU (MOVVconst [32]) (ZeroExt8to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64MASKEQZ) + v0 := b.NewValue0(v.Pos, OpLOONG64SLL, t) + v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) +@@ -7566,18 +7781,36 @@ func rewriteValueLOONG64_OpLsh32x8(v *Value) bool { + v.AddArg2(v0, v2) + return true + } ++ return false + } + func rewriteValueLOONG64_OpLsh64x16(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Lsh64x16 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SLLV x y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SLLV) ++ v.AddArg2(x, y) ++ return true ++ } + // match: (Lsh64x16 x y) ++ // cond: !shiftIsBounded(v) + // result: (MASKEQZ (SLLV x (ZeroExt16to64 y)) (SGTU (MOVVconst [64]) (ZeroExt16to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64MASKEQZ) + v0 := b.NewValue0(v.Pos, OpLOONG64SLLV, t) + v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) +@@ -7590,18 +7823,36 @@ func rewriteValueLOONG64_OpLsh64x16(v *Value) bool { + v.AddArg2(v0, v2) + return true + } ++ return false + } + func rewriteValueLOONG64_OpLsh64x32(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Lsh64x32 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SLLV x y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SLLV) ++ v.AddArg2(x, y) ++ return true ++ } + // match: (Lsh64x32 x y) ++ // cond: !shiftIsBounded(v) + // result: (MASKEQZ (SLLV x (ZeroExt32to64 y)) (SGTU (MOVVconst [64]) (ZeroExt32to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64MASKEQZ) + v0 := b.NewValue0(v.Pos, OpLOONG64SLLV, t) + v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) +@@ -7614,18 +7865,36 @@ func rewriteValueLOONG64_OpLsh64x32(v *Value) bool { + v.AddArg2(v0, v2) + return true + } ++ return false + } + func rewriteValueLOONG64_OpLsh64x64(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Lsh64x64 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SLLV x y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SLLV) ++ v.AddArg2(x, y) ++ return true ++ } + // match: (Lsh64x64 x y) ++ // cond: !shiftIsBounded(v) + // result: (MASKEQZ (SLLV x y) (SGTU (MOVVconst [64]) y)) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64MASKEQZ) + v0 := b.NewValue0(v.Pos, OpLOONG64SLLV, t) + v0.AddArg2(x, y) +@@ -7636,18 +7905,36 @@ func rewriteValueLOONG64_OpLsh64x64(v *Value) bool { + v.AddArg2(v0, v1) + return true + } ++ return false + } + func rewriteValueLOONG64_OpLsh64x8(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Lsh64x8 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SLLV x y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SLLV) ++ v.AddArg2(x, y) ++ return true ++ } + // match: (Lsh64x8 x y) ++ // cond: !shiftIsBounded(v) + // result: (MASKEQZ (SLLV x (ZeroExt8to64 y)) (SGTU (MOVVconst [64]) (ZeroExt8to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64MASKEQZ) + v0 := b.NewValue0(v.Pos, OpLOONG64SLLV, t) + v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) +@@ -7660,18 +7947,36 @@ func rewriteValueLOONG64_OpLsh64x8(v *Value) bool { + v.AddArg2(v0, v2) + return true + } ++ return false + } + func rewriteValueLOONG64_OpLsh8x16(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Lsh8x16 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SLLV x y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SLLV) ++ v.AddArg2(x, y) ++ return true ++ } + // match: (Lsh8x16 x y) ++ // cond: !shiftIsBounded(v) + // result: (MASKEQZ (SLLV x (ZeroExt16to64 y)) (SGTU (MOVVconst [64]) (ZeroExt16to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64MASKEQZ) + v0 := b.NewValue0(v.Pos, OpLOONG64SLLV, t) + v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) +@@ -7684,18 +7989,36 @@ func rewriteValueLOONG64_OpLsh8x16(v *Value) bool { + v.AddArg2(v0, v2) + return true + } ++ return false + } + func rewriteValueLOONG64_OpLsh8x32(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Lsh8x32 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SLLV x y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SLLV) ++ v.AddArg2(x, y) ++ return true ++ } + // match: (Lsh8x32 x y) ++ // cond: !shiftIsBounded(v) + // result: (MASKEQZ (SLLV x (ZeroExt32to64 y)) (SGTU (MOVVconst [64]) (ZeroExt32to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64MASKEQZ) + v0 := b.NewValue0(v.Pos, OpLOONG64SLLV, t) + v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) +@@ -7708,18 +8031,36 @@ func rewriteValueLOONG64_OpLsh8x32(v *Value) bool { + v.AddArg2(v0, v2) + return true + } ++ return false + } + func rewriteValueLOONG64_OpLsh8x64(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Lsh8x64 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SLLV x y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SLLV) ++ v.AddArg2(x, y) ++ return true ++ } + // match: (Lsh8x64 x y) ++ // cond: !shiftIsBounded(v) + // result: (MASKEQZ (SLLV x y) (SGTU (MOVVconst [64]) y)) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64MASKEQZ) + v0 := b.NewValue0(v.Pos, OpLOONG64SLLV, t) + v0.AddArg2(x, y) +@@ -7730,18 +8071,36 @@ func rewriteValueLOONG64_OpLsh8x64(v *Value) bool { + v.AddArg2(v0, v1) + return true + } ++ return false + } + func rewriteValueLOONG64_OpLsh8x8(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Lsh8x8 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SLLV x y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SLLV) ++ v.AddArg2(x, y) ++ return true ++ } + // match: (Lsh8x8 x y) ++ // cond: !shiftIsBounded(v) + // result: (MASKEQZ (SLLV x (ZeroExt8to64 y)) (SGTU (MOVVconst [64]) (ZeroExt8to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64MASKEQZ) + v0 := b.NewValue0(v.Pos, OpLOONG64SLLV, t) + v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) +@@ -7754,6 +8113,7 @@ func rewriteValueLOONG64_OpLsh8x8(v *Value) bool { + v.AddArg2(v0, v2) + return true + } ++ return false + } + func rewriteValueLOONG64_OpMod16(v *Value) bool { + v_1 := v.Args[1] +@@ -8698,12 +9058,31 @@ func rewriteValueLOONG64_OpRsh16Ux16(v *Value) bool { + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Rsh16Ux16 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SRLV (ZeroExt16to64 x) y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SRLV) ++ v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) ++ v0.AddArg(x) ++ v.AddArg2(v0, y) ++ return true ++ } + // match: (Rsh16Ux16 x y) ++ // cond: !shiftIsBounded(v) + // result: (MASKEQZ (SRLV (ZeroExt16to64 x) (ZeroExt16to64 y)) (SGTU (MOVVconst [64]) (ZeroExt16to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64MASKEQZ) + v0 := b.NewValue0(v.Pos, OpLOONG64SRLV, t) + v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) +@@ -8718,18 +9097,38 @@ func rewriteValueLOONG64_OpRsh16Ux16(v *Value) bool { + v.AddArg2(v0, v3) + return true + } ++ return false + } + func rewriteValueLOONG64_OpRsh16Ux32(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Rsh16Ux32 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SRLV (ZeroExt16to64 x) y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SRLV) ++ v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) ++ v0.AddArg(x) ++ v.AddArg2(v0, y) ++ return true ++ } + // match: (Rsh16Ux32 x y) ++ // cond: !shiftIsBounded(v) + // result: (MASKEQZ (SRLV (ZeroExt16to64 x) (ZeroExt32to64 y)) (SGTU (MOVVconst [64]) (ZeroExt32to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64MASKEQZ) + v0 := b.NewValue0(v.Pos, OpLOONG64SRLV, t) + v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) +@@ -8744,18 +9143,38 @@ func rewriteValueLOONG64_OpRsh16Ux32(v *Value) bool { + v.AddArg2(v0, v3) + return true + } ++ return false + } + func rewriteValueLOONG64_OpRsh16Ux64(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Rsh16Ux64 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SRLV (ZeroExt16to64 x) y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SRLV) ++ v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) ++ v0.AddArg(x) ++ v.AddArg2(v0, y) ++ return true ++ } + // match: (Rsh16Ux64 x y) ++ // cond: !shiftIsBounded(v) + // result: (MASKEQZ (SRLV (ZeroExt16to64 x) y) (SGTU (MOVVconst [64]) y)) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64MASKEQZ) + v0 := b.NewValue0(v.Pos, OpLOONG64SRLV, t) + v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) +@@ -8768,18 +9187,38 @@ func rewriteValueLOONG64_OpRsh16Ux64(v *Value) bool { + v.AddArg2(v0, v2) + return true + } ++ return false + } + func rewriteValueLOONG64_OpRsh16Ux8(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Rsh16Ux8 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SRLV (ZeroExt16to64 x) y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SRLV) ++ v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) ++ v0.AddArg(x) ++ v.AddArg2(v0, y) ++ return true ++ } + // match: (Rsh16Ux8 x y) ++ // cond: !shiftIsBounded(v) + // result: (MASKEQZ (SRLV (ZeroExt16to64 x) (ZeroExt8to64 y)) (SGTU (MOVVconst [64]) (ZeroExt8to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64MASKEQZ) + v0 := b.NewValue0(v.Pos, OpLOONG64SRLV, t) + v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) +@@ -8794,18 +9233,38 @@ func rewriteValueLOONG64_OpRsh16Ux8(v *Value) bool { + v.AddArg2(v0, v3) + return true + } ++ return false + } + func rewriteValueLOONG64_OpRsh16x16(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Rsh16x16 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SRAV (SignExt16to64 x) y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SRAV) ++ v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) ++ v0.AddArg(x) ++ v.AddArg2(v0, y) ++ return true ++ } + // match: (Rsh16x16 x y) ++ // cond: !shiftIsBounded(v) + // result: (SRAV (SignExt16to64 x) (OR (NEGV (SGTU (ZeroExt16to64 y) (MOVVconst [63]))) (ZeroExt16to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64SRAV) + v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) + v0.AddArg(x) +@@ -8822,18 +9281,38 @@ func rewriteValueLOONG64_OpRsh16x16(v *Value) bool { + v.AddArg2(v0, v1) + return true + } ++ return false + } + func rewriteValueLOONG64_OpRsh16x32(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Rsh16x32 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SRAV (SignExt16to64 x) y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SRAV) ++ v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) ++ v0.AddArg(x) ++ v.AddArg2(v0, y) ++ return true ++ } + // match: (Rsh16x32 x y) ++ // cond: !shiftIsBounded(v) + // result: (SRAV (SignExt16to64 x) (OR (NEGV (SGTU (ZeroExt32to64 y) (MOVVconst [63]))) (ZeroExt32to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64SRAV) + v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) + v0.AddArg(x) +@@ -8850,18 +9329,38 @@ func rewriteValueLOONG64_OpRsh16x32(v *Value) bool { + v.AddArg2(v0, v1) + return true + } ++ return false + } + func rewriteValueLOONG64_OpRsh16x64(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Rsh16x64 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SRAV (SignExt16to64 x) y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SRAV) ++ v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) ++ v0.AddArg(x) ++ v.AddArg2(v0, y) ++ return true ++ } + // match: (Rsh16x64 x y) ++ // cond: !shiftIsBounded(v) + // result: (SRAV (SignExt16to64 x) (OR (NEGV (SGTU y (MOVVconst [63]))) y)) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64SRAV) + v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) + v0.AddArg(x) +@@ -8876,18 +9375,38 @@ func rewriteValueLOONG64_OpRsh16x64(v *Value) bool { + v.AddArg2(v0, v1) + return true + } ++ return false + } + func rewriteValueLOONG64_OpRsh16x8(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Rsh16x8 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SRAV (SignExt16to64 x) y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SRAV) ++ v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) ++ v0.AddArg(x) ++ v.AddArg2(v0, y) ++ return true ++ } + // match: (Rsh16x8 x y) ++ // cond: !shiftIsBounded(v) + // result: (SRAV (SignExt16to64 x) (OR (NEGV (SGTU (ZeroExt8to64 y) (MOVVconst [63]))) (ZeroExt8to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64SRAV) + v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64) + v0.AddArg(x) +@@ -8904,18 +9423,36 @@ func rewriteValueLOONG64_OpRsh16x8(v *Value) bool { + v.AddArg2(v0, v1) + return true + } ++ return false + } + func rewriteValueLOONG64_OpRsh32Ux16(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Rsh32Ux16 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SRL x y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SRL) ++ v.AddArg2(x, y) ++ return true ++ } + // match: (Rsh32Ux16 x y) ++ // cond: !shiftIsBounded(v) + // result: (MASKEQZ (SRL x (ZeroExt16to64 y)) (SGTU (MOVVconst [32]) (ZeroExt16to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64MASKEQZ) + v0 := b.NewValue0(v.Pos, OpLOONG64SRL, t) + v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) +@@ -8928,18 +9465,36 @@ func rewriteValueLOONG64_OpRsh32Ux16(v *Value) bool { + v.AddArg2(v0, v2) + return true + } ++ return false + } + func rewriteValueLOONG64_OpRsh32Ux32(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Rsh32Ux32 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SRL x y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SRL) ++ v.AddArg2(x, y) ++ return true ++ } + // match: (Rsh32Ux32 x y) ++ // cond: !shiftIsBounded(v) + // result: (MASKEQZ (SRL x (ZeroExt32to64 y)) (SGTU (MOVVconst [32]) (ZeroExt32to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64MASKEQZ) + v0 := b.NewValue0(v.Pos, OpLOONG64SRL, t) + v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) +@@ -8952,18 +9507,36 @@ func rewriteValueLOONG64_OpRsh32Ux32(v *Value) bool { + v.AddArg2(v0, v2) + return true + } ++ return false + } + func rewriteValueLOONG64_OpRsh32Ux64(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Rsh32Ux64 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SRL x y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SRL) ++ v.AddArg2(x, y) ++ return true ++ } + // match: (Rsh32Ux64 x y) ++ // cond: !shiftIsBounded(v) + // result: (MASKEQZ (SRL x y) (SGTU (MOVVconst [32]) y)) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64MASKEQZ) + v0 := b.NewValue0(v.Pos, OpLOONG64SRL, t) + v0.AddArg2(x, y) +@@ -8974,18 +9547,36 @@ func rewriteValueLOONG64_OpRsh32Ux64(v *Value) bool { + v.AddArg2(v0, v1) + return true + } ++ return false + } + func rewriteValueLOONG64_OpRsh32Ux8(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Rsh32Ux8 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SRL x y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SRL) ++ v.AddArg2(x, y) ++ return true ++ } + // match: (Rsh32Ux8 x y) ++ // cond: !shiftIsBounded(v) + // result: (MASKEQZ (SRL x (ZeroExt8to64 y)) (SGTU (MOVVconst [32]) (ZeroExt8to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64MASKEQZ) + v0 := b.NewValue0(v.Pos, OpLOONG64SRL, t) + v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) +@@ -8998,18 +9589,36 @@ func rewriteValueLOONG64_OpRsh32Ux8(v *Value) bool { + v.AddArg2(v0, v2) + return true + } ++ return false + } + func rewriteValueLOONG64_OpRsh32x16(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Rsh32x16 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SRA x y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SRA) ++ v.AddArg2(x, y) ++ return true ++ } + // match: (Rsh32x16 x y) ++ // cond: !shiftIsBounded(v) + // result: (SRA x (OR (NEGV (SGTU (ZeroExt16to64 y) (MOVVconst [31]))) (ZeroExt16to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64SRA) + v0 := b.NewValue0(v.Pos, OpLOONG64OR, t) + v1 := b.NewValue0(v.Pos, OpLOONG64NEGV, t) +@@ -9024,18 +9633,36 @@ func rewriteValueLOONG64_OpRsh32x16(v *Value) bool { + v.AddArg2(x, v0) + return true + } ++ return false + } + func rewriteValueLOONG64_OpRsh32x32(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Rsh32x32 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SRA x y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SRA) ++ v.AddArg2(x, y) ++ return true ++ } + // match: (Rsh32x32 x y) ++ // cond: !shiftIsBounded(v) + // result: (SRA x (OR (NEGV (SGTU (ZeroExt32to64 y) (MOVVconst [31]))) (ZeroExt32to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64SRA) + v0 := b.NewValue0(v.Pos, OpLOONG64OR, t) + v1 := b.NewValue0(v.Pos, OpLOONG64NEGV, t) +@@ -9050,18 +9677,36 @@ func rewriteValueLOONG64_OpRsh32x32(v *Value) bool { + v.AddArg2(x, v0) + return true + } ++ return false + } + func rewriteValueLOONG64_OpRsh32x64(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Rsh32x64 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SRA x y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SRA) ++ v.AddArg2(x, y) ++ return true ++ } + // match: (Rsh32x64 x y) ++ // cond: !shiftIsBounded(v) + // result: (SRA x (OR (NEGV (SGTU y (MOVVconst [31]))) y)) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64SRA) + v0 := b.NewValue0(v.Pos, OpLOONG64OR, t) + v1 := b.NewValue0(v.Pos, OpLOONG64NEGV, t) +@@ -9074,18 +9719,36 @@ func rewriteValueLOONG64_OpRsh32x64(v *Value) bool { + v.AddArg2(x, v0) + return true + } ++ return false + } + func rewriteValueLOONG64_OpRsh32x8(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Rsh32x8 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SRA x y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SRA) ++ v.AddArg2(x, y) ++ return true ++ } + // match: (Rsh32x8 x y) ++ // cond: !shiftIsBounded(v) + // result: (SRA x (OR (NEGV (SGTU (ZeroExt8to64 y) (MOVVconst [31]))) (ZeroExt8to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64SRA) + v0 := b.NewValue0(v.Pos, OpLOONG64OR, t) + v1 := b.NewValue0(v.Pos, OpLOONG64NEGV, t) +@@ -9100,18 +9763,36 @@ func rewriteValueLOONG64_OpRsh32x8(v *Value) bool { + v.AddArg2(x, v0) + return true + } ++ return false + } + func rewriteValueLOONG64_OpRsh64Ux16(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Rsh64Ux16 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SRLV x y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SRLV) ++ v.AddArg2(x, y) ++ return true ++ } + // match: (Rsh64Ux16 x y) ++ // cond: !shiftIsBounded(v) + // result: (MASKEQZ (SRLV x (ZeroExt16to64 y)) (SGTU (MOVVconst [64]) (ZeroExt16to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64MASKEQZ) + v0 := b.NewValue0(v.Pos, OpLOONG64SRLV, t) + v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64) +@@ -9124,18 +9805,36 @@ func rewriteValueLOONG64_OpRsh64Ux16(v *Value) bool { + v.AddArg2(v0, v2) + return true + } ++ return false + } + func rewriteValueLOONG64_OpRsh64Ux32(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Rsh64Ux32 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SRLV x y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SRLV) ++ v.AddArg2(x, y) ++ return true ++ } + // match: (Rsh64Ux32 x y) ++ // cond: !shiftIsBounded(v) + // result: (MASKEQZ (SRLV x (ZeroExt32to64 y)) (SGTU (MOVVconst [64]) (ZeroExt32to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64MASKEQZ) + v0 := b.NewValue0(v.Pos, OpLOONG64SRLV, t) + v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64) +@@ -9148,18 +9847,36 @@ func rewriteValueLOONG64_OpRsh64Ux32(v *Value) bool { + v.AddArg2(v0, v2) + return true + } ++ return false + } + func rewriteValueLOONG64_OpRsh64Ux64(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Rsh64Ux64 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SRLV x y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SRLV) ++ v.AddArg2(x, y) ++ return true ++ } + // match: (Rsh64Ux64 x y) ++ // cond: !shiftIsBounded(v) + // result: (MASKEQZ (SRLV x y) (SGTU (MOVVconst [64]) y)) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64MASKEQZ) + v0 := b.NewValue0(v.Pos, OpLOONG64SRLV, t) + v0.AddArg2(x, y) +@@ -9170,18 +9887,36 @@ func rewriteValueLOONG64_OpRsh64Ux64(v *Value) bool { + v.AddArg2(v0, v1) + return true + } ++ return false + } + func rewriteValueLOONG64_OpRsh64Ux8(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Rsh64Ux8 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SRLV x y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SRLV) ++ v.AddArg2(x, y) ++ return true ++ } + // match: (Rsh64Ux8 x y) ++ // cond: !shiftIsBounded(v) + // result: (MASKEQZ (SRLV x (ZeroExt8to64 y)) (SGTU (MOVVconst [64]) (ZeroExt8to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64MASKEQZ) + v0 := b.NewValue0(v.Pos, OpLOONG64SRLV, t) + v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) +@@ -9194,18 +9929,36 @@ func rewriteValueLOONG64_OpRsh64Ux8(v *Value) bool { + v.AddArg2(v0, v2) + return true + } ++ return false + } + func rewriteValueLOONG64_OpRsh64x16(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Rsh64x16 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SRAV x y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SRAV) ++ v.AddArg2(x, y) ++ return true ++ } + // match: (Rsh64x16 x y) ++ // cond: !shiftIsBounded(v) + // result: (SRAV x (OR (NEGV (SGTU (ZeroExt16to64 y) (MOVVconst [63]))) (ZeroExt16to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64SRAV) + v0 := b.NewValue0(v.Pos, OpLOONG64OR, t) + v1 := b.NewValue0(v.Pos, OpLOONG64NEGV, t) +@@ -9220,18 +9973,36 @@ func rewriteValueLOONG64_OpRsh64x16(v *Value) bool { + v.AddArg2(x, v0) + return true + } ++ return false + } + func rewriteValueLOONG64_OpRsh64x32(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Rsh64x32 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SRAV x y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SRAV) ++ v.AddArg2(x, y) ++ return true ++ } + // match: (Rsh64x32 x y) ++ // cond: !shiftIsBounded(v) + // result: (SRAV x (OR (NEGV (SGTU (ZeroExt32to64 y) (MOVVconst [63]))) (ZeroExt32to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64SRAV) + v0 := b.NewValue0(v.Pos, OpLOONG64OR, t) + v1 := b.NewValue0(v.Pos, OpLOONG64NEGV, t) +@@ -9246,18 +10017,36 @@ func rewriteValueLOONG64_OpRsh64x32(v *Value) bool { + v.AddArg2(x, v0) + return true + } ++ return false + } + func rewriteValueLOONG64_OpRsh64x64(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Rsh64x64 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SRAV x y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SRAV) ++ v.AddArg2(x, y) ++ return true ++ } + // match: (Rsh64x64 x y) ++ // cond: !shiftIsBounded(v) + // result: (SRAV x (OR (NEGV (SGTU y (MOVVconst [63]))) y)) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64SRAV) + v0 := b.NewValue0(v.Pos, OpLOONG64OR, t) + v1 := b.NewValue0(v.Pos, OpLOONG64NEGV, t) +@@ -9270,18 +10059,36 @@ func rewriteValueLOONG64_OpRsh64x64(v *Value) bool { + v.AddArg2(x, v0) + return true + } ++ return false + } + func rewriteValueLOONG64_OpRsh64x8(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Rsh64x8 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SRAV x y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SRAV) ++ v.AddArg2(x, y) ++ return true ++ } + // match: (Rsh64x8 x y) ++ // cond: !shiftIsBounded(v) + // result: (SRAV x (OR (NEGV (SGTU (ZeroExt8to64 y) (MOVVconst [63]))) (ZeroExt8to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64SRAV) + v0 := b.NewValue0(v.Pos, OpLOONG64OR, t) + v1 := b.NewValue0(v.Pos, OpLOONG64NEGV, t) +@@ -9296,18 +10103,38 @@ func rewriteValueLOONG64_OpRsh64x8(v *Value) bool { + v.AddArg2(x, v0) + return true + } ++ return false + } + func rewriteValueLOONG64_OpRsh8Ux16(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Rsh8Ux16 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SRLV (ZeroExt8to64 x) y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SRLV) ++ v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) ++ v0.AddArg(x) ++ v.AddArg2(v0, y) ++ return true ++ } + // match: (Rsh8Ux16 x y) ++ // cond: !shiftIsBounded(v) + // result: (MASKEQZ (SRLV (ZeroExt8to64 x) (ZeroExt16to64 y)) (SGTU (MOVVconst [64]) (ZeroExt16to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64MASKEQZ) + v0 := b.NewValue0(v.Pos, OpLOONG64SRLV, t) + v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) +@@ -9322,18 +10149,38 @@ func rewriteValueLOONG64_OpRsh8Ux16(v *Value) bool { + v.AddArg2(v0, v3) + return true + } ++ return false + } + func rewriteValueLOONG64_OpRsh8Ux32(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Rsh8Ux32 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SRLV (ZeroExt8to64 x) y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SRLV) ++ v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) ++ v0.AddArg(x) ++ v.AddArg2(v0, y) ++ return true ++ } + // match: (Rsh8Ux32 x y) ++ // cond: !shiftIsBounded(v) + // result: (MASKEQZ (SRLV (ZeroExt8to64 x) (ZeroExt32to64 y)) (SGTU (MOVVconst [64]) (ZeroExt32to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64MASKEQZ) + v0 := b.NewValue0(v.Pos, OpLOONG64SRLV, t) + v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) +@@ -9348,18 +10195,38 @@ func rewriteValueLOONG64_OpRsh8Ux32(v *Value) bool { + v.AddArg2(v0, v3) + return true + } ++ return false + } + func rewriteValueLOONG64_OpRsh8Ux64(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Rsh8Ux64 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SRLV (ZeroExt8to64 x) y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SRLV) ++ v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) ++ v0.AddArg(x) ++ v.AddArg2(v0, y) ++ return true ++ } + // match: (Rsh8Ux64 x y) ++ // cond: !shiftIsBounded(v) + // result: (MASKEQZ (SRLV (ZeroExt8to64 x) y) (SGTU (MOVVconst [64]) y)) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64MASKEQZ) + v0 := b.NewValue0(v.Pos, OpLOONG64SRLV, t) + v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) +@@ -9372,18 +10239,38 @@ func rewriteValueLOONG64_OpRsh8Ux64(v *Value) bool { + v.AddArg2(v0, v2) + return true + } ++ return false + } + func rewriteValueLOONG64_OpRsh8Ux8(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Rsh8Ux8 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SRLV (ZeroExt8to64 x) y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SRLV) ++ v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) ++ v0.AddArg(x) ++ v.AddArg2(v0, y) ++ return true ++ } + // match: (Rsh8Ux8 x y) ++ // cond: !shiftIsBounded(v) + // result: (MASKEQZ (SRLV (ZeroExt8to64 x) (ZeroExt8to64 y)) (SGTU (MOVVconst [64]) (ZeroExt8to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64MASKEQZ) + v0 := b.NewValue0(v.Pos, OpLOONG64SRLV, t) + v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64) +@@ -9398,18 +10285,38 @@ func rewriteValueLOONG64_OpRsh8Ux8(v *Value) bool { + v.AddArg2(v0, v3) + return true + } ++ return false + } + func rewriteValueLOONG64_OpRsh8x16(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Rsh8x16 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SRAV (SignExt8to64 x) y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SRAV) ++ v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) ++ v0.AddArg(x) ++ v.AddArg2(v0, y) ++ return true ++ } + // match: (Rsh8x16 x y) ++ // cond: !shiftIsBounded(v) + // result: (SRAV (SignExt8to64 x) (OR (NEGV (SGTU (ZeroExt16to64 y) (MOVVconst [63]))) (ZeroExt16to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64SRAV) + v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) + v0.AddArg(x) +@@ -9426,18 +10333,38 @@ func rewriteValueLOONG64_OpRsh8x16(v *Value) bool { + v.AddArg2(v0, v1) + return true + } ++ return false + } + func rewriteValueLOONG64_OpRsh8x32(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Rsh8x32 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SRAV (SignExt8to64 x) y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SRAV) ++ v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) ++ v0.AddArg(x) ++ v.AddArg2(v0, y) ++ return true ++ } + // match: (Rsh8x32 x y) ++ // cond: !shiftIsBounded(v) + // result: (SRAV (SignExt8to64 x) (OR (NEGV (SGTU (ZeroExt32to64 y) (MOVVconst [63]))) (ZeroExt32to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64SRAV) + v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) + v0.AddArg(x) +@@ -9454,18 +10381,38 @@ func rewriteValueLOONG64_OpRsh8x32(v *Value) bool { + v.AddArg2(v0, v1) + return true + } ++ return false + } + func rewriteValueLOONG64_OpRsh8x64(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Rsh8x64 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SRAV (SignExt8to64 x) y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SRAV) ++ v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) ++ v0.AddArg(x) ++ v.AddArg2(v0, y) ++ return true ++ } + // match: (Rsh8x64 x y) ++ // cond: !shiftIsBounded(v) + // result: (SRAV (SignExt8to64 x) (OR (NEGV (SGTU y (MOVVconst [63]))) y)) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64SRAV) + v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) + v0.AddArg(x) +@@ -9480,18 +10427,38 @@ func rewriteValueLOONG64_OpRsh8x64(v *Value) bool { + v.AddArg2(v0, v1) + return true + } ++ return false + } + func rewriteValueLOONG64_OpRsh8x8(v *Value) bool { + v_1 := v.Args[1] + v_0 := v.Args[0] + b := v.Block + typ := &b.Func.Config.Types ++ // match: (Rsh8x8 x y) ++ // cond: shiftIsBounded(v) ++ // result: (SRAV (SignExt8to64 x) y) ++ for { ++ x := v_0 ++ y := v_1 ++ if !(shiftIsBounded(v)) { ++ break ++ } ++ v.reset(OpLOONG64SRAV) ++ v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) ++ v0.AddArg(x) ++ v.AddArg2(v0, y) ++ return true ++ } + // match: (Rsh8x8 x y) ++ // cond: !shiftIsBounded(v) + // result: (SRAV (SignExt8to64 x) (OR (NEGV (SGTU (ZeroExt8to64 y) (MOVVconst [63]))) (ZeroExt8to64 y))) + for { + t := v.Type + x := v_0 + y := v_1 ++ if !(!shiftIsBounded(v)) { ++ break ++ } + v.reset(OpLOONG64SRAV) + v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64) + v0.AddArg(x) +@@ -9508,6 +10475,7 @@ func rewriteValueLOONG64_OpRsh8x8(v *Value) bool { + v.AddArg2(v0, v1) + return true + } ++ return false + } + func rewriteValueLOONG64_OpSelect0(v *Value) bool { + v_0 := v.Args[0] +diff --git a/test/codegen/shift.go b/test/codegen/shift.go +index 3c669edcb2..db4e6409a8 100644 +--- a/test/codegen/shift.go ++++ b/test/codegen/shift.go +@@ -115,6 +115,7 @@ func rshConst64x32(v int64) int64 { + + func lshMask64x64(v int64, s uint64) int64 { + // arm64:"LSL",-"AND" ++ // loong64:"SLLV",-"AND" + // ppc64x:"RLDICL",-"ORN",-"ISEL" + // riscv64:"SLL",-"AND\t",-"SLTIU" + // s390x:-"RISBGZ",-"AND",-"LOCGR" +@@ -123,6 +124,7 @@ func lshMask64x64(v int64, s uint64) int64 { + + func rshMask64Ux64(v uint64, s uint64) uint64 { + // arm64:"LSR",-"AND",-"CSEL" ++ // loong64:"SRLV",-"AND" + // ppc64x:"RLDICL",-"ORN",-"ISEL" + // riscv64:"SRL\t",-"AND\t",-"SLTIU" + // s390x:-"RISBGZ",-"AND",-"LOCGR" +@@ -131,6 +133,7 @@ func rshMask64Ux64(v uint64, s uint64) uint64 { + + func rshMask64x64(v int64, s uint64) int64 { + // arm64:"ASR",-"AND",-"CSEL" ++ // loong64:"SRAV",-"AND" + // ppc64x:"RLDICL",-"ORN",-"ISEL" + // riscv64:"SRA\t",-"OR",-"SLTIU" + // s390x:-"RISBGZ",-"AND",-"LOCGR" +@@ -139,14 +142,21 @@ func rshMask64x64(v int64, s uint64) int64 { + + func lshMask32x64(v int32, s uint64) int32 { + // arm64:"LSL",-"AND" ++ // loong64:"SLL\t","AND","SGTU","MASKEQZ" + // ppc64x:"ISEL",-"ORN" + // riscv64:"SLL",-"AND\t",-"SLTIU" + // s390x:-"RISBGZ",-"AND",-"LOCGR" + return v << (s & 63) + } + ++func lsh5Mask32x64(v int32, s uint64) int32 { ++ // loong64:"SLL\t",-"AND" ++ return v << (s & 31) ++} ++ + func rshMask32Ux64(v uint32, s uint64) uint32 { + // arm64:"LSR",-"AND" ++ // loong64:"SRL\t","AND","SGTU","MASKEQZ" + // ppc64x:"ISEL",-"ORN" + // riscv64:"SRLW","SLTIU","NEG","AND\t",-"SRL\t" + // s390x:-"RISBGZ",-"AND",-"LOCGR" +@@ -154,12 +164,14 @@ func rshMask32Ux64(v uint32, s uint64) uint32 { + } + + func rsh5Mask32Ux64(v uint32, s uint64) uint32 { ++ // loong64:"SRL\t",-"AND" + // riscv64:"SRLW",-"AND\t",-"SLTIU",-"SRL\t" + return v >> (s & 31) + } + + func rshMask32x64(v int32, s uint64) int32 { + // arm64:"ASR",-"AND" ++ // loong64:"SRA\t","AND","SGTU","SUBVU","OR" + // ppc64x:"ISEL",-"ORN" + // riscv64:"SRAW","OR","SLTIU" + // s390x:-"RISBGZ",-"AND",-"LOCGR" +@@ -167,12 +179,14 @@ func rshMask32x64(v int32, s uint64) int32 { + } + + func rsh5Mask32x64(v int32, s uint64) int32 { ++ // loong64:"SRA\t",-"AND" + // riscv64:"SRAW",-"OR",-"SLTIU" + return v >> (s & 31) + } + + func lshMask64x32(v int64, s uint32) int64 { + // arm64:"LSL",-"AND" ++ // loong64:"SLLV",-"AND" + // ppc64x:"RLDICL",-"ORN" + // riscv64:"SLL",-"AND\t",-"SLTIU" + // s390x:-"RISBGZ",-"AND",-"LOCGR" +@@ -181,6 +195,7 @@ func lshMask64x32(v int64, s uint32) int64 { + + func rshMask64Ux32(v uint64, s uint32) uint64 { + // arm64:"LSR",-"AND",-"CSEL" ++ // loong64:"SRLV",-"AND" + // ppc64x:"RLDICL",-"ORN" + // riscv64:"SRL\t",-"AND\t",-"SLTIU" + // s390x:-"RISBGZ",-"AND",-"LOCGR" +@@ -189,6 +204,7 @@ func rshMask64Ux32(v uint64, s uint32) uint64 { + + func rshMask64x32(v int64, s uint32) int64 { + // arm64:"ASR",-"AND",-"CSEL" ++ // loong64:"SRAV",-"AND" + // ppc64x:"RLDICL",-"ORN",-"ISEL" + // riscv64:"SRA\t",-"OR",-"SLTIU" + // s390x:-"RISBGZ",-"AND",-"LOCGR" +-- +2.38.1 + diff --git a/0024-runtime-use-ABIInternal-on-syscall-and-other-sys.stu.patch b/0024-runtime-use-ABIInternal-on-syscall-and-other-sys.stu.patch new file mode 100644 index 0000000000000000000000000000000000000000..bc81e40b22cf501e51b804355e9f185b57a9dd79 --- /dev/null +++ b/0024-runtime-use-ABIInternal-on-syscall-and-other-sys.stu.patch @@ -0,0 +1,505 @@ +From 7e54d3bbc1af00ca94819f9c1bbb61f822d37439 Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Tue, 26 Nov 2024 15:44:28 +0800 +Subject: [PATCH 24/44] runtime: use ABIInternal on syscall and other sys.stuff + for loong64 + +Change-Id: Ieeb3f2af02c55a9ad62a19d0085b0e082a182db4 +--- + src/runtime/sys_linux_loong64.s | 227 +++++++++++--------------------- + 1 file changed, 79 insertions(+), 148 deletions(-) + +diff --git a/src/runtime/sys_linux_loong64.s b/src/runtime/sys_linux_loong64.s +index 57cee99da7..b4e9930755 100644 +--- a/src/runtime/sys_linux_loong64.s ++++ b/src/runtime/sys_linux_loong64.s +@@ -47,8 +47,7 @@ + #define SYS_timer_delete 111 + + // func exit(code int32) +-TEXT runtime·exit(SB),NOSPLIT|NOFRAME,$0-4 +- MOVW code+0(FP), R4 ++TEXT runtime·exit(SB),NOSPLIT,$0 + MOVV $SYS_exit_group, R11 + SYSCALL + RET +@@ -67,48 +66,49 @@ TEXT runtime·exitThread(SB),NOSPLIT|NOFRAME,$0-8 + JMP 0(PC) + + // func open(name *byte, mode, perm int32) int32 +-TEXT runtime·open(SB),NOSPLIT|NOFRAME,$0-20 ++TEXT runtime·open(SB),NOSPLIT,$0 ++ // before: ++ // R4: name ++ // R5: mode ++ // R6: perm ++ ++ // after: ++ // R4: AT_FDCWD ++ // R5: name ++ // R6: mode ++ // R7: perm ++ ++ MOVW R6, R7 ++ MOVW R5, R6 ++ MOVV R4, R5 + MOVW $AT_FDCWD, R4 // AT_FDCWD, so this acts like open +- MOVV name+0(FP), R5 +- MOVW mode+8(FP), R6 +- MOVW perm+12(FP), R7 ++ + MOVV $SYS_openat, R11 + SYSCALL + MOVW $-4096, R5 + BGEU R5, R4, 2(PC) + MOVW $-1, R4 +- MOVW R4, ret+16(FP) + RET + + // func closefd(fd int32) int32 +-TEXT runtime·closefd(SB),NOSPLIT|NOFRAME,$0-12 +- MOVW fd+0(FP), R4 ++TEXT runtime·closefd(SB),NOSPLIT,$0 + MOVV $SYS_close, R11 + SYSCALL + MOVW $-4096, R5 + BGEU R5, R4, 2(PC) + MOVW $-1, R4 +- MOVW R4, ret+8(FP) + RET + + // func write1(fd uintptr, p unsafe.Pointer, n int32) int32 +-TEXT runtime·write1(SB),NOSPLIT|NOFRAME,$0-28 +- MOVV fd+0(FP), R4 +- MOVV p+8(FP), R5 +- MOVW n+16(FP), R6 ++TEXT runtime·write1(SB),NOSPLIT,$0 + MOVV $SYS_write, R11 + SYSCALL +- MOVW R4, ret+24(FP) + RET + + // func read(fd int32, p unsafe.Pointer, n int32) int32 +-TEXT runtime·read(SB),NOSPLIT|NOFRAME,$0-28 +- MOVW fd+0(FP), R4 +- MOVV p+8(FP), R5 +- MOVW n+16(FP), R6 ++TEXT runtime·read(SB),NOSPLIT,$0 + MOVV $SYS_read, R11 + SYSCALL +- MOVW R4, ret+24(FP) + RET + + // func pipe2(flags int32) (r, w int32, errno int32) +@@ -121,16 +121,15 @@ TEXT runtime·pipe2(SB),NOSPLIT|NOFRAME,$0-20 + RET + + // func usleep(usec uint32) +-TEXT runtime·usleep(SB),NOSPLIT,$16-4 +- MOVWU usec+0(FP), R7 ++TEXT runtime·usleep(SB),NOSPLIT,$16 + MOVV $1000, R6 +- MULVU R6, R7, R7 ++ MULVU R6, R4, R4 + MOVV $1000000000, R6 + +- DIVVU R6, R7, R5 // ts->tv_sec +- REMVU R6, R7, R4 // ts->tv_nsec ++ DIVVU R6, R4, R5 // ts->tv_sec ++ REMVU R6, R4, R8 // ts->tv_nsec + MOVV R5, 8(R3) +- MOVV R4, 16(R3) ++ MOVV R8, 16(R3) + + // nanosleep(&ts, 0) + ADDV $8, R3, R4 +@@ -140,14 +139,14 @@ TEXT runtime·usleep(SB),NOSPLIT,$16-4 + RET + + // func gettid() uint32 +-TEXT runtime·gettid(SB),NOSPLIT,$0-4 ++TEXT runtime·gettid(SB),NOSPLIT,$0 + MOVV $SYS_gettid, R11 + SYSCALL +- MOVW R4, ret+0(FP) + RET + + // func raise(sig uint32) +-TEXT runtime·raise(SB),NOSPLIT|NOFRAME,$0 ++TEXT runtime·raise(SB),NOSPLIT,$0 ++ MOVW R4, R24 // backup sig + MOVV $SYS_getpid, R11 + SYSCALL + MOVW R4, R23 +@@ -155,87 +154,66 @@ TEXT runtime·raise(SB),NOSPLIT|NOFRAME,$0 + SYSCALL + MOVW R4, R5 // arg 2 tid + MOVW R23, R4 // arg 1 pid +- MOVW sig+0(FP), R6 // arg 3 ++ MOVW R24, R6 // arg 3 + MOVV $SYS_tgkill, R11 + SYSCALL + RET + + // func raiseproc(sig uint32) +-TEXT runtime·raiseproc(SB),NOSPLIT|NOFRAME,$0 ++TEXT runtime·raiseproc(SB),NOSPLIT,$0 ++ MOVW R4, R24 // backup sig + MOVV $SYS_getpid, R11 + SYSCALL + //MOVW R4, R4 // arg 1 pid +- MOVW sig+0(FP), R5 // arg 2 ++ MOVW R24, R5 // arg 2 + MOVV $SYS_kill, R11 + SYSCALL + RET + + // func getpid() int +-TEXT ·getpid(SB),NOSPLIT|NOFRAME,$0-8 ++TEXT ·getpid(SB),NOSPLIT,$0 + MOVV $SYS_getpid, R11 + SYSCALL +- MOVV R4, ret+0(FP) + RET + + // func tgkill(tgid, tid, sig int) +-TEXT ·tgkill(SB),NOSPLIT|NOFRAME,$0-24 +- MOVV tgid+0(FP), R4 +- MOVV tid+8(FP), R5 +- MOVV sig+16(FP), R6 ++TEXT ·tgkill(SB),NOSPLIT,$0 + MOVV $SYS_tgkill, R11 + SYSCALL + RET + + // func setitimer(mode int32, new, old *itimerval) +-TEXT runtime·setitimer(SB),NOSPLIT|NOFRAME,$0-24 +- MOVW mode+0(FP), R4 +- MOVV new+8(FP), R5 +- MOVV old+16(FP), R6 ++TEXT runtime·setitimer(SB),NOSPLIT,$0 + MOVV $SYS_setitimer, R11 + SYSCALL + RET + + // func timer_create(clockid int32, sevp *sigevent, timerid *int32) int32 +-TEXT runtime·timer_create(SB),NOSPLIT,$0-28 +- MOVW clockid+0(FP), R4 +- MOVV sevp+8(FP), R5 +- MOVV timerid+16(FP), R6 ++TEXT runtime·timer_create(SB),NOSPLIT,$0 + MOVV $SYS_timer_create, R11 + SYSCALL +- MOVW R4, ret+24(FP) + RET + + // func timer_settime(timerid int32, flags int32, new, old *itimerspec) int32 +-TEXT runtime·timer_settime(SB),NOSPLIT,$0-28 +- MOVW timerid+0(FP), R4 +- MOVW flags+4(FP), R5 +- MOVV new+8(FP), R6 +- MOVV old+16(FP), R7 ++TEXT runtime·timer_settime(SB),NOSPLIT,$0 + MOVV $SYS_timer_settime, R11 + SYSCALL +- MOVW R4, ret+24(FP) + RET + + // func timer_delete(timerid int32) int32 +-TEXT runtime·timer_delete(SB),NOSPLIT,$0-12 +- MOVW timerid+0(FP), R4 ++TEXT runtime·timer_delete(SB),NOSPLIT,$0 + MOVV $SYS_timer_delete, R11 + SYSCALL +- MOVW R4, ret+8(FP) + RET + + // func mincore(addr unsafe.Pointer, n uintptr, dst *byte) int32 +-TEXT runtime·mincore(SB),NOSPLIT|NOFRAME,$0-28 +- MOVV addr+0(FP), R4 +- MOVV n+8(FP), R5 +- MOVV dst+16(FP), R6 ++TEXT runtime·mincore(SB),NOSPLIT,$0 + MOVV $SYS_mincore, R11 + SYSCALL +- MOVW R4, ret+24(FP) + RET + + // func walltime() (sec int64, nsec int32) +-TEXT runtime·walltime(SB),NOSPLIT,$24-12 ++TEXT runtime·walltime(SB),NOSPLIT,$24 + MOVV R3, R23 // R23 is unchanged by C code + MOVV R3, R25 + +@@ -291,7 +269,7 @@ nosaveg: + JAL (R20) + + finish: +- MOVV 0(R3), R7 // sec ++ MOVV 0(R3), R4 // sec + MOVV 8(R3), R5 // nsec + + MOVV R23, R3 // restore SP +@@ -304,9 +282,6 @@ finish: + MOVV R25, m_vdsoSP(R24) + MOVV 8(R3), R25 + MOVV R25, m_vdsoPC(R24) +- +- MOVV R7, sec+0(FP) +- MOVW R5, nsec+8(FP) + RET + + fallback: +@@ -315,7 +290,7 @@ fallback: + JMP finish + + // func nanotime1() int64 +-TEXT runtime·nanotime1(SB),NOSPLIT,$16-8 ++TEXT runtime·nanotime1(SB),NOSPLIT,$24 + MOVV R3, R23 // R23 is unchanged by C code + MOVV R3, R25 + +@@ -389,8 +364,7 @@ finish: + // return nsec in R7 + MOVV $1000000000, R4 + MULVU R4, R7, R7 +- ADDVU R5, R7 +- MOVV R7, ret+0(FP) ++ ADDVU R5, R7, R4 + RET + + fallback: +@@ -399,11 +373,7 @@ fallback: + JMP finish + + // func rtsigprocmask(how int32, new, old *sigset, size int32) +-TEXT runtime·rtsigprocmask(SB),NOSPLIT|NOFRAME,$0-28 +- MOVW how+0(FP), R4 +- MOVV new+8(FP), R5 +- MOVV old+16(FP), R6 +- MOVW size+24(FP), R7 ++TEXT runtime·rtsigprocmask(SB),NOSPLIT,$0 + MOVV $SYS_rt_sigprocmask, R11 + SYSCALL + MOVW $-4096, R5 +@@ -412,22 +382,21 @@ TEXT runtime·rtsigprocmask(SB),NOSPLIT|NOFRAME,$0-28 + RET + + // func rt_sigaction(sig uintptr, new, old *sigactiont, size uintptr) int32 +-TEXT runtime·rt_sigaction(SB),NOSPLIT|NOFRAME,$0-36 +- MOVV sig+0(FP), R4 +- MOVV new+8(FP), R5 +- MOVV old+16(FP), R6 +- MOVV size+24(FP), R7 ++TEXT runtime·rt_sigaction(SB),NOSPLIT,$0 + MOVV $SYS_rt_sigaction, R11 + SYSCALL +- MOVW R4, ret+32(FP) + RET + + // func sigfwd(fn uintptr, sig uint32, info *siginfo, ctx unsafe.Pointer) +-TEXT runtime·sigfwd(SB),NOSPLIT,$0-32 +- MOVW sig+8(FP), R4 +- MOVV info+16(FP), R5 +- MOVV ctx+24(FP), R6 +- MOVV fn+0(FP), R20 ++TEXT runtime·sigfwd(SB),NOSPLIT,$0 ++ // before: ++ // R4: fn, R5: sig, R6: info, R7: ctx ++ // after: ++ // R20: fn, R4: sig, R5: info, R6: ctx ++ MOVV R4, R20 ++ MOVV R5, R4 ++ MOVV R6, R5 ++ MOVV R7, R6 + JAL (R20) + RET + +@@ -460,48 +429,31 @@ TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0 + JMP runtime·sigtramp(SB) + + // func sysMmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) (p unsafe.Pointer, err int) +-TEXT runtime·sysMmap(SB),NOSPLIT|NOFRAME,$0 +- MOVV addr+0(FP), R4 +- MOVV n+8(FP), R5 +- MOVW prot+16(FP), R6 +- MOVW flags+20(FP), R7 +- MOVW fd+24(FP), R8 +- MOVW off+28(FP), R9 +- ++TEXT runtime·sysMmap(SB),NOSPLIT,$0 + MOVV $SYS_mmap, R11 + SYSCALL + MOVW $-4096, R5 + BGEU R5, R4, ok +- MOVV $0, p+32(FP) +- SUBVU R4, R0, R4 +- MOVV R4, err+40(FP) ++ SUBVU R4, R0, R5 ++ MOVV $0, R4 + RET + ok: +- MOVV R4, p+32(FP) +- MOVV $0, err+40(FP) ++ MOVV $0, R5 + RET + + // Call the function stored in _cgo_mmap using the GCC calling convention. + // This must be called on the system stack. + // func callCgoMmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) uintptr +-TEXT runtime·callCgoMmap(SB),NOSPLIT,$0 +- MOVV addr+0(FP), R4 +- MOVV n+8(FP), R5 +- MOVW prot+16(FP), R6 +- MOVW flags+20(FP), R7 +- MOVW fd+24(FP), R8 +- MOVW off+28(FP), R9 ++TEXT runtime·callCgoMmap(SB),NOSPLIT,$0 + MOVV _cgo_mmap(SB), R13 + SUBV $16, R3 // reserve 16 bytes for sp-8 where fp may be saved. + JAL (R13) + ADDV $16, R3 +- MOVV R4, ret+32(FP) ++ MOVV R4, R4 + RET + + // func sysMunmap(addr unsafe.Pointer, n uintptr) +-TEXT runtime·sysMunmap(SB),NOSPLIT|NOFRAME,$0 +- MOVV addr+0(FP), R4 +- MOVV n+8(FP), R5 ++TEXT runtime·sysMunmap(SB),NOSPLIT,$0 + MOVV $SYS_munmap, R11 + SYSCALL + MOVW $-4096, R5 +@@ -512,9 +464,7 @@ TEXT runtime·sysMunmap(SB),NOSPLIT|NOFRAME,$0 + // Call the function stored in _cgo_munmap using the GCC calling convention. + // This must be called on the system stack. + // func callCgoMunmap(addr unsafe.Pointer, n uintptr) +-TEXT runtime·callCgoMunmap(SB),NOSPLIT,$0 +- MOVV addr+0(FP), R4 +- MOVV n+8(FP), R5 ++TEXT runtime·callCgoMunmap(SB),NOSPLIT,$0 + MOVV _cgo_munmap(SB), R13 + SUBV $16, R3 // reserve 16 bytes for sp-8 where fp may be saved. + JAL (R13) +@@ -522,38 +472,24 @@ TEXT runtime·callCgoMunmap(SB),NOSPLIT,$0 + RET + + // func madvise(addr unsafe.Pointer, n uintptr, flags int32) +-TEXT runtime·madvise(SB),NOSPLIT|NOFRAME,$0 +- MOVV addr+0(FP), R4 +- MOVV n+8(FP), R5 +- MOVW flags+16(FP), R6 ++TEXT runtime·madvise(SB),NOSPLIT,$0 + MOVV $SYS_madvise, R11 + SYSCALL +- MOVW R4, ret+24(FP) + RET + + // func futex(addr unsafe.Pointer, op int32, val uint32, ts, addr2 unsafe.Pointer, val3 uint32) int32 +-TEXT runtime·futex(SB),NOSPLIT|NOFRAME,$0 +- MOVV addr+0(FP), R4 +- MOVW op+8(FP), R5 +- MOVW val+12(FP), R6 +- MOVV ts+16(FP), R7 +- MOVV addr2+24(FP), R8 +- MOVW val3+32(FP), R9 ++TEXT runtime·futex(SB),NOSPLIT,$0 + MOVV $SYS_futex, R11 + SYSCALL +- MOVW R4, ret+40(FP) + RET + + // int64 clone(int32 flags, void *stk, M *mp, G *gp, void (*fn)(void)); +-TEXT runtime·clone(SB),NOSPLIT|NOFRAME,$0 +- MOVW flags+0(FP), R4 +- MOVV stk+8(FP), R5 +- ++TEXT runtime·clone(SB),NOSPLIT,$0 + // Copy mp, gp, fn off parent stack for use by child. + // Careful: Linux system call clobbers ???. +- MOVV mp+16(FP), R23 +- MOVV gp+24(FP), R24 +- MOVV fn+32(FP), R25 ++ MOVV R6, R23 ++ MOVV R7, R24 ++ MOVV R8, R25 + + MOVV R23, -8(R5) + MOVV R24, -16(R5) +@@ -565,8 +501,7 @@ TEXT runtime·clone(SB),NOSPLIT|NOFRAME,$0 + SYSCALL + + // In parent, return. +- BEQ R4, 3(PC) +- MOVW R4, ret+40(FP) ++ BEQ R4, 2(PC) + RET + + // In child, on new stack. +@@ -606,9 +541,7 @@ nog: + JMP -3(PC) // keep exiting + + // func sigaltstack(new, old *stackt) +-TEXT runtime·sigaltstack(SB),NOSPLIT|NOFRAME,$0 +- MOVV new+0(FP), R4 +- MOVV old+8(FP), R5 ++TEXT runtime·sigaltstack(SB),NOSPLIT,$0 + MOVV $SYS_sigaltstack, R11 + SYSCALL + MOVW $-4096, R5 +@@ -617,42 +550,40 @@ TEXT runtime·sigaltstack(SB),NOSPLIT|NOFRAME,$0 + RET + + // func osyield() +-TEXT runtime·osyield(SB),NOSPLIT|NOFRAME,$0 ++TEXT runtime·osyield(SB),NOSPLIT,$0 + MOVV $SYS_sched_yield, R11 + SYSCALL + RET + + // func sched_getaffinity(pid, len uintptr, buf *uintptr) int32 +-TEXT runtime·sched_getaffinity(SB),NOSPLIT|NOFRAME,$0 +- MOVV pid+0(FP), R4 +- MOVV len+8(FP), R5 +- MOVV buf+16(FP), R6 ++TEXT runtime·sched_getaffinity(SB),NOSPLIT,$0 + MOVV $SYS_sched_getaffinity, R11 + SYSCALL +- MOVW R4, ret+24(FP) + RET + + // func sbrk0() uintptr +-TEXT runtime·sbrk0(SB),NOSPLIT|NOFRAME,$0-8 ++TEXT runtime·sbrk0(SB),NOSPLIT,$0 + // Implemented as brk(NULL). + MOVV $0, R4 + MOVV $SYS_brk, R11 + SYSCALL +- MOVV R4, ret+0(FP) + RET + ++// unimplemented, only needed for android; declared in stubs_linux.go + TEXT runtime·access(SB),$0-20 +- MOVV R0, 2(R0) // unimplemented, only needed for android; declared in stubs_linux.go ++ MOVV R0, 2(R0) + MOVW R0, ret+16(FP) // for vet + RET + ++// unimplemented, only needed for android; declared in stubs_linux.go + TEXT runtime·connect(SB),$0-28 +- MOVV R0, 2(R0) // unimplemented, only needed for android; declared in stubs_linux.go ++ MOVV R0, 2(R0) + MOVW R0, ret+24(FP) // for vet + RET + ++// unimplemented, only needed for android; declared in stubs_linux.go + TEXT runtime·socket(SB),$0-20 +- MOVV R0, 2(R0) // unimplemented, only needed for android; declared in stubs_linux.go ++ MOVV R0, 2(R0) + MOVW R0, ret+16(FP) // for vet + RET + +-- +2.38.1 + diff --git a/0025-runtime-use-correct-memory-barrier-in-exitThread-fun.patch b/0025-runtime-use-correct-memory-barrier-in-exitThread-fun.patch new file mode 100644 index 0000000000000000000000000000000000000000..0b81cb190f22ff450cd050c9bcc0f3cfc1827f41 --- /dev/null +++ b/0025-runtime-use-correct-memory-barrier-in-exitThread-fun.patch @@ -0,0 +1,34 @@ +From 5bb6b8ebb22faf46a01ff292c45a7dc72f2b5022 Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Tue, 26 Nov 2024 17:10:32 +0800 +Subject: [PATCH 25/44] runtime: use correct memory barrier in exitThread + function on loong64 + +In the runtime.exitThread function, a storeRelease barrier +is required instead of a full barrier. + +Change-Id: I614c6f74e8c9fd56c3badf3bf450b3314e3f377c +--- + src/runtime/sys_linux_loong64.s | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/src/runtime/sys_linux_loong64.s b/src/runtime/sys_linux_loong64.s +index b4e9930755..830eb9d099 100644 +--- a/src/runtime/sys_linux_loong64.s ++++ b/src/runtime/sys_linux_loong64.s +@@ -56,10 +56,8 @@ TEXT runtime·exit(SB),NOSPLIT,$0 + TEXT runtime·exitThread(SB),NOSPLIT|NOFRAME,$0-8 + MOVV wait+0(FP), R19 + // We're done using the stack. +- MOVW $0, R11 +- DBAR +- MOVW R11, (R19) +- DBAR ++ DBAR $0x12 // StoreRelease barrier ++ MOVW R0, (R19) + MOVW $0, R4 // exit code + MOVV $SYS_exit, R11 + SYSCALL +-- +2.38.1 + diff --git a/0026-cmd-internal-obj-loong64-add-V-XV-SEQI-V-XV-.-AND-OR.patch b/0026-cmd-internal-obj-loong64-add-V-XV-SEQI-V-XV-.-AND-OR.patch new file mode 100644 index 0000000000000000000000000000000000000000..d73cc6515c410c16cd99184bc242d0799d477852 --- /dev/null +++ b/0026-cmd-internal-obj-loong64-add-V-XV-SEQI-V-XV-.-AND-OR.patch @@ -0,0 +1,410 @@ +From 38ab8bc5eb69cb2746b32fd4a6ca7931adb7722b Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Fri, 29 Nov 2024 15:41:33 +0800 +Subject: [PATCH 26/44] cmd/internal/obj/loong64: add {V,XV}SEQI, + {V,XV}.{AND,OR,XOR,NOR} instructions support + +Go asm syntax: + VSEQB $1, V2, V3 + XVSEQB $2, X2, X3 + V{AND,OR,XOR,NOR}B $1, V2, V3 + XV{AND,OR,XOR,NOR}B $1, V2, V3 + V{AND,OR,XOR,NOR,ANDN,ORN}V V1, V2, V3 + XV{AND,OR,XOR,NOR,ANDN,ORN}V V1, V2, V3 + +Equivalent platform assembler syntax: + vseqi.b v3, v2, $1 + xvseqi.b x3, x2 ,$2 + v{and,or,xor,nor}.b v3, v2, $1 + xv{and,or,xor,nor}.b x3, x2, $1 + v{and,or,xor,nor,andn,orn}v v3, v2, v1 + xv{and,or,xor,nor,andn,orn}v x3, x2, x1 + +Change-Id: I56ae0db72c7f473755cbdc7f7171c1058a9def97 +--- + .../asm/internal/asm/testdata/loong64enc1.s | 38 ++++ + src/cmd/internal/obj/loong64/a.out.go | 21 +++ + src/cmd/internal/obj/loong64/anames.go | 20 ++ + src/cmd/internal/obj/loong64/asm.go | 173 ++++++++++++++++-- + 4 files changed, 238 insertions(+), 14 deletions(-) + +diff --git a/src/cmd/asm/internal/asm/testdata/loong64enc1.s b/src/cmd/asm/internal/asm/testdata/loong64enc1.s +index 3a3eb10a74..2418412a3a 100644 +--- a/src/cmd/asm/internal/asm/testdata/loong64enc1.s ++++ b/src/cmd/asm/internal/asm/testdata/loong64enc1.s +@@ -506,6 +506,16 @@ lable2: + XVSEQH X3, X2, X4 // 448c0074 + XVSEQW X3, X2, X4 // 440c0174 + XVSEQV X3, X2, X4 // 448c0174 ++ VSEQB $0, V2, V3 // 43008072 ++ VSEQH $1, V2, V3 // 43848072 ++ VSEQW $8, V2, V3 // 43208172 ++ VSEQV $15, V2, V3 // 43bc8172 ++ VSEQV $-15, V2, V3 // 43c48172 ++ XVSEQB $0, X2, X4 // 44008076 ++ XVSEQH $3, X2, X4 // 448c8076 ++ XVSEQW $12, X2, X4 // 44308176 ++ XVSEQV $15, X2, X4 // 44bc8176 ++ XVSEQV $-15, X2, X4 // 44c48176 + + // VPCNT{B,H,W,V}, XVPCNT{B,H,W,V} instruction + VPCNTB V1, V2 // 22209c72 +@@ -517,6 +527,34 @@ lable2: + XVPCNTW X3, X2 // 62289c76 + XVPCNTV X3, X2 // 622c9c76 + ++ // VANDV,VORV,VXORV,VNORV,VANDNV,VORNV ++ VANDV V1, V2, V3 // 43042671 ++ VORV V1, V2, V3 // 43842671 ++ VXORV V1, V2, V3 // 43042771 ++ VNORV V1, V2, V3 // 43842771 ++ VANDNV V1, V2, V3 // 43042871 ++ VORNV V1, V2, V3 // 43842871 ++ ++ // VANDB,VORB,VXORB,VNORB ++ VANDB $0, V2, V3 // 4300d073 ++ VORB $64, V2, V3 // 4300d573 ++ VXORB $128, V2, V3 // 4300da73 ++ VNORB $255, V2, V3 // 43fcdf73 ++ ++ // XVANDV,XVORV,XVXORV,XVNORV,XVANDNV,XVORNV ++ XVANDV X1, X2, X3 // 43042675 ++ XVORV X1, X2, X3 // 43842675 ++ XVXORV X1, X2, X3 // 43042775 ++ XVNORV X1, X2, X3 // 43842775 ++ XVANDNV X1, X2, X3 // 43042875 ++ XVORNV X1, X2, X3 // 43842875 ++ ++ // XVANDB,XVORB,XVXORB,XVNORB ++ XVANDB $0, X2, X3 // 4300d077 ++ XVORB $1, X2, X3 // 4304d477 ++ XVXORB $127, X2, X3 // 43fcd977 ++ XVNORB $255, X2, X3 // 43fcdf77 ++ + // MOVV C_DCON12_0, r + MOVV $0x7a90000000000000, R4 // MOVV $8831558869273542656, R4 // 04a41e03 + MOVV $0xea90000000000000, R4 // MOVV $-1544734672188080128, R4 // 04a43a03 +diff --git a/src/cmd/internal/obj/loong64/a.out.go b/src/cmd/internal/obj/loong64/a.out.go +index b2207c2523..bd3ce61826 100644 +--- a/src/cmd/internal/obj/loong64/a.out.go ++++ b/src/cmd/internal/obj/loong64/a.out.go +@@ -726,6 +726,27 @@ const ( + AXVMOVQ + + // LSX and LASX Bit-manipulation Instructions ++ AVANDB ++ AVORB ++ AVXORB ++ AVNORB ++ AXVANDB ++ AXVORB ++ AXVXORB ++ AXVNORB ++ AVANDV ++ AVORV ++ AVXORV ++ AVNORV ++ AVANDNV ++ AVORNV ++ AXVANDV ++ AXVORV ++ AXVXORV ++ AXVNORV ++ AXVANDNV ++ AXVORNV ++ + AVPCNTB + AVPCNTH + AVPCNTW +diff --git a/src/cmd/internal/obj/loong64/anames.go b/src/cmd/internal/obj/loong64/anames.go +index 3d2f329917..6c1537d123 100644 +--- a/src/cmd/internal/obj/loong64/anames.go ++++ b/src/cmd/internal/obj/loong64/anames.go +@@ -257,6 +257,26 @@ var Anames = []string{ + "FTINTRNEVD", + "VMOVQ", + "XVMOVQ", ++ "VANDB", ++ "VORB", ++ "VXORB", ++ "VNORB", ++ "XVANDB", ++ "XVORB", ++ "XVXORB", ++ "XVNORB", ++ "VANDV", ++ "VORV", ++ "VXORV", ++ "VNORV", ++ "VANDNV", ++ "VORNV", ++ "XVANDV", ++ "XVORV", ++ "XVXORV", ++ "XVNORV", ++ "XVANDNV", ++ "XVORNV", + "VPCNTB", + "VPCNTH", + "VPCNTW", +diff --git a/src/cmd/internal/obj/loong64/asm.go b/src/cmd/internal/obj/loong64/asm.go +index 5757c3c452..7247193c95 100644 +--- a/src/cmd/internal/obj/loong64/asm.go ++++ b/src/cmd/internal/obj/loong64/asm.go +@@ -51,6 +51,8 @@ const ( + // branchLoopHead marks loop entry. + // Used to insert padding for under-aligned loops. + branchLoopHead ++ immFiledSi5 // The encoding of the immediate field in the instruction is 5-bits ++ immFiledUi8 // The encoding of the immediate field in the instruction is 8-bits + ) + + var optab = []Optab{ +@@ -88,6 +90,17 @@ var optab = []Optab{ + {ACMPEQF, C_FREG, C_FREG, C_NONE, C_FCCREG, C_NONE, 2, 4, 0, 0}, + {AVSEQB, C_VREG, C_VREG, C_NONE, C_VREG, C_NONE, 2, 4, 0, 0}, + {AXVSEQB, C_XREG, C_XREG, C_NONE, C_XREG, C_NONE, 2, 4, 0, 0}, ++ {AVSEQB, C_SCON, C_VREG, C_NONE, C_VREG, C_NONE, 13, 4, 0, immFiledSi5}, ++ {AXVSEQB, C_SCON, C_XREG, C_NONE, C_XREG, C_NONE, 13, 4, 0, immFiledSi5}, ++ {AVSEQB, C_ADDCON, C_VREG, C_NONE, C_VREG, C_NONE, 13, 4, 0, immFiledSi5}, ++ {AXVSEQB, C_ADDCON, C_XREG, C_NONE, C_XREG, C_NONE, 13, 4, 0, immFiledSi5}, ++ ++ {AVANDV, C_VREG, C_VREG, C_NONE, C_VREG, C_NONE, 2, 4, 0, 0}, ++ {AXVANDV, C_XREG, C_XREG, C_NONE, C_XREG, C_NONE, 2, 4, 0, 0}, ++ {AVANDB, C_SCON, C_VREG, C_NONE, C_VREG, C_NONE, 14, 4, 0, immFiledUi8}, ++ {AXVANDB, C_SCON, C_XREG, C_NONE, C_XREG, C_NONE, 14, 4, 0, immFiledUi8}, ++ {AVANDB, C_ADDCON, C_VREG, C_NONE, C_VREG, C_NONE, 14, 4, 0, immFiledUi8}, ++ {AXVANDB, C_ADDCON, C_XREG, C_NONE, C_XREG, C_NONE, 14, 4, 0, immFiledUi8}, + + {ACLOW, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 9, 4, 0, 0}, + {AABSF, C_FREG, C_NONE, C_NONE, C_FREG, C_NONE, 9, 4, 0, 0}, +@@ -1499,6 +1512,7 @@ func buildop(ctxt *obj.Link) { + } + opset(i, r0) + } ++ + case AVSEQB: + opset(AVSEQH, r0) + opset(AVSEQW, r0) +@@ -1509,6 +1523,30 @@ func buildop(ctxt *obj.Link) { + opset(AXVSEQW, r0) + opset(AXVSEQV, r0) + ++ case AVANDB: ++ opset(AVORB, r0) ++ opset(AVXORB, r0) ++ opset(AVNORB, r0) ++ ++ case AXVANDB: ++ opset(AXVORB, r0) ++ opset(AXVXORB, r0) ++ opset(AXVNORB, r0) ++ ++ case AVANDV: ++ opset(AVORV, r0) ++ opset(AVXORV, r0) ++ opset(AVNORV, r0) ++ opset(AVANDNV, r0) ++ opset(AVORNV, r0) ++ ++ case AXVANDV: ++ opset(AXVORV, r0) ++ opset(AXVXORV, r0) ++ opset(AXVNORV, r0) ++ opset(AXVANDNV, r0) ++ opset(AXVORNV, r0) ++ + case AVPCNTB: + opset(AVPCNTH, r0) + opset(AVPCNTW, r0) +@@ -1551,6 +1589,14 @@ func OP_12IRR(op uint32, i uint32, r2 uint32, r3 uint32) uint32 { + return op | (i&0xFFF)<<10 | (r2&0x1F)<<5 | (r3&0x1F)<<0 + } + ++func OP_8IRR(op uint32, i uint32, r2 uint32, r3 uint32) uint32 { ++ return op | (i&0xFF)<<10 | (r2&0x1F)<<5 | (r3&0x1F)<<0 ++} ++ ++func OP_5IRR(op uint32, i uint32, r2 uint32, r3 uint32) uint32 { ++ return op | (i&0x1F)<<10 | (r2&0x1F)<<5 | (r3&0x1F)<<0 ++} ++ + func OP_IR(op uint32, i uint32, r2 uint32) uint32 { + return op | (i&0xFFFFF)<<5 | (r2&0x1F)<<0 // ui20, rd5 + } +@@ -1623,12 +1669,10 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) { + + case 4: // add $scon,[r1],r2 + v := c.regoff(&p.From) +- + r := int(p.Reg) + if r == 0 { + r = int(p.To.Reg) + } +- + o1 = OP_12IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.To.Reg)) + + case 5: // syscall +@@ -1738,6 +1782,36 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) { + c.ctxt.Diag("unexpected encoding\n%v", p) + } + ++ case 13: // add $si5,[r1],r2 ++ v := c.regoff(&p.From) ++ r := int(p.Reg) ++ if r == 0 { ++ r = int(p.To.Reg) ++ } ++ ++ switch o.flag { ++ case immFiledSi5: ++ c.checkimmFiled(p, v, 5, true) ++ o1 = OP_5IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.To.Reg)) ++ default: ++ c.ctxt.Diag("Invalid immediate value type\n%v", p) ++ } ++ ++ case 14: // add $ui8,[r1],r2 ++ v := c.regoff(&p.From) ++ r := int(p.Reg) ++ if r == 0 { ++ r = int(p.To.Reg) ++ } ++ ++ switch o.flag { ++ case immFiledUi8: ++ c.checkimmFiled(p, v, 8, false) ++ o1 = OP_8IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.To.Reg)) ++ default: ++ c.ctxt.Diag("Invalid immediate value type\n%v", p) ++ } ++ + case 15: // teq $c r,r + v := c.regoff(&p.From) + r := int(p.Reg) +@@ -1760,18 +1834,18 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) { + o2 = OP_15I(c.opi(ABREAK), uint32(v)) + + case 16: // sll $c,[r1],r2 +- v := c.regoff(&p.From) +- r := int(p.Reg) +- if r == 0 { +- r = int(p.To.Reg) +- } +- +- // instruction ending with V:6-digit immediate, others:5-digit immediate +- if v >= 32 && vshift(p.As) { +- o1 = OP_16IRR(c.opirr(p.As), uint32(v)&0x3f, uint32(r), uint32(p.To.Reg)) +- } else { +- o1 = OP_16IRR(c.opirr(p.As), uint32(v)&0x1f, uint32(r), uint32(p.To.Reg)) +- } ++ v := c.regoff(&p.From) ++ r := int(p.Reg) ++ if r == 0 { ++ r = int(p.To.Reg) ++ } ++ ++ // instruction ending with V:6-digit immediate, others:5-digit immediate ++ if v >= 32 && vshift(p.As) { ++ o1 = OP_16IRR(c.opirr(p.As), uint32(v)&0x3f, uint32(r), uint32(p.To.Reg)) ++ } else { ++ o1 = OP_16IRR(c.opirr(p.As), uint32(v)&0x1f, uint32(r), uint32(p.To.Reg)) ++ } + + case 17: // bstrpickw $msbw, r1, $lsbw, r2 + rd, rj := p.To.Reg, p.Reg +@@ -2348,6 +2422,21 @@ func (c *ctxt0) checkindex(p *obj.Prog, index uint32, mask uint32) { + } + } + ++// checkimmFiled checks whether the immediate value exceeds the valid encoding range ++func (c *ctxt0) checkimmFiled(p *obj.Prog, imm int32, bits uint8, isSigned bool) { ++ if isSigned { ++ bound := int32(1 << (bits - 1)) ++ if imm < -bound || imm > bound { ++ c.ctxt.Diag("signed immediate %v exceeds the %d-bit range: %v", imm, bits, p) ++ } ++ } else { ++ mask := uint32(0xffffffff) << bits ++ if uint32(imm) != (uint32(imm) & ^mask) { ++ c.ctxt.Diag("unsigned immediate %v exceeds the %d-bit range: %v", imm, bits, p) ++ } ++ } ++} ++ + func (c *ctxt0) vregoff(a *obj.Addr) int64 { + c.instoffset = 0 + c.aclass(a) +@@ -2588,6 +2677,30 @@ func (c *ctxt0) oprrr(a obj.As) uint32 { + return 0x0e003 << 15 // vseq.d + case AXVSEQV: + return 0x0e803 << 15 // xvseq.d ++ case AVANDV: ++ return 0x0E24C << 15 // vand.v ++ case AVORV: ++ return 0x0E24D << 15 // vor.v ++ case AVXORV: ++ return 0x0E24E << 15 // vxor.v ++ case AVNORV: ++ return 0x0E24F << 15 // vnor.v ++ case AVANDNV: ++ return 0x0E250 << 15 // vandn.v ++ case AVORNV: ++ return 0x0E251 << 15 // vorn.v ++ case AXVANDV: ++ return 0x0EA4C << 15 // xvand.v ++ case AXVORV: ++ return 0x0EA4D << 15 // xvor.v ++ case AXVXORV: ++ return 0x0EA4E << 15 // xvxor.v ++ case AXVNORV: ++ return 0x0EA4F << 15 // xvnor.v ++ case AXVANDNV: ++ return 0x0EA50 << 15 // xvandn.v ++ case AXVORNV: ++ return 0x0EA51 << 15 // xvorn.v + } + + if a < 0 { +@@ -2915,6 +3028,38 @@ func (c *ctxt0) opirr(a obj.As) uint32 { + return 0x021 << 24 + case ASCV: + return 0x023 << 24 ++ case AVANDB: ++ return 0x1CF4 << 18 // vandi.b ++ case AVORB: ++ return 0x1CF5 << 18 // vori.b ++ case AVXORB: ++ return 0x1CF6 << 18 // xori.b ++ case AVNORB: ++ return 0x1CF7 << 18 // xnori.b ++ case AXVANDB: ++ return 0x1DF4 << 18 // xvandi.b ++ case AXVORB: ++ return 0x1DF5 << 18 // xvori.b ++ case AXVXORB: ++ return 0x1DF6 << 18 // xvxori.b ++ case AXVNORB: ++ return 0x1DF7 << 18 // xvnor.b ++ case AVSEQB: ++ return 0x0E500 << 15 //vseqi.b ++ case AVSEQH: ++ return 0x0E501 << 15 // vseqi.h ++ case AVSEQW: ++ return 0x0E502 << 15 //vseqi.w ++ case AVSEQV: ++ return 0x0E503 << 15 //vseqi.d ++ case AXVSEQB: ++ return 0x0ED00 << 15 //xvseqi.b ++ case AXVSEQH: ++ return 0x0ED01 << 15 // xvseqi.h ++ case AXVSEQW: ++ return 0x0ED02 << 15 // xvseqi.w ++ case AXVSEQV: ++ return 0x0ED03 << 15 // xvseqi.d + } + + if a < 0 { +-- +2.38.1 + diff --git a/0027-cmd-internal-obj-loong64-add-V-XV-ADD-SUB-.-B-H-W-D-.patch b/0027-cmd-internal-obj-loong64-add-V-XV-ADD-SUB-.-B-H-W-D-.patch new file mode 100644 index 0000000000000000000000000000000000000000..2192272d7bb79100579ca52591c8b18158fec4a7 --- /dev/null +++ b/0027-cmd-internal-obj-loong64-add-V-XV-ADD-SUB-.-B-H-W-D-.patch @@ -0,0 +1,207 @@ +From f5bbb15710944ebcc7d2c808fe9087892a690bc4 Mon Sep 17 00:00:00 2001 +From: Xiaolin Zhao +Date: Wed, 11 Dec 2024 09:26:38 +0800 +Subject: [PATCH 27/44] cmd/internal/obj/loong64: add + {V,XV}{ADD/SUB}.{B,H,W,D,Q} instructions support + +Go asm syntax: + V{ADD/SUB}{B,H,W,V,Q} VK, VJ, VD + XV{ADD/SUB}{B,H,W,V,Q} XK, XJ, XD + +Equivalent platform assembler syntax: + v{add/sub}.{b,w,h,d,q} vd, vj, vk + xv{add/sub}.{b,w,h,d,q} xd, xj, xk + +Change-Id: Iadc28100c93d6d6c69e9641bfea78fa85d75bddf +--- + .../asm/internal/asm/testdata/loong64enc1.s | 22 +++++++ + src/cmd/internal/obj/loong64/a.out.go | 22 +++++++ + src/cmd/internal/obj/loong64/anames.go | 20 +++++++ + src/cmd/internal/obj/loong64/asm.go | 60 +++++++++++++++++++ + 4 files changed, 124 insertions(+) + +diff --git a/src/cmd/asm/internal/asm/testdata/loong64enc1.s b/src/cmd/asm/internal/asm/testdata/loong64enc1.s +index 2418412a3a..76faf2d3cb 100644 +--- a/src/cmd/asm/internal/asm/testdata/loong64enc1.s ++++ b/src/cmd/asm/internal/asm/testdata/loong64enc1.s +@@ -555,6 +555,28 @@ lable2: + XVXORB $127, X2, X3 // 43fcd977 + XVNORB $255, X2, X3 // 43fcdf77 + ++ // [X]VADD{B,H,W,V,Q}, [X]VSUB{B,H,W,V,Q} instructions ++ VADDB V1, V2, V3 // 43040a70 ++ VADDH V1, V2, V3 // 43840a70 ++ VADDW V1, V2, V3 // 43040b70 ++ VADDV V1, V2, V3 // 43840b70 ++ VADDQ V1, V2, V3 // 43042d71 ++ VSUBB V1, V2, V3 // 43040c70 ++ VSUBH V1, V2, V3 // 43840c70 ++ VSUBW V1, V2, V3 // 43040d70 ++ VSUBV V1, V2, V3 // 43840d70 ++ VSUBQ V1, V2, V3 // 43842d71 ++ XVADDB X3, X2, X1 // 410c0a74 ++ XVADDH X3, X2, X1 // 418c0a74 ++ XVADDW X3, X2, X1 // 410c0b74 ++ XVADDV X3, X2, X1 // 418c0b74 ++ XVADDQ X3, X2, X1 // 410c2d75 ++ XVSUBB X3, X2, X1 // 410c0c74 ++ XVSUBH X3, X2, X1 // 418c0c74 ++ XVSUBW X3, X2, X1 // 410c0d74 ++ XVSUBV X3, X2, X1 // 418c0d74 ++ XVSUBQ X3, X2, X1 // 418c2d75 ++ + // MOVV C_DCON12_0, r + MOVV $0x7a90000000000000, R4 // MOVV $8831558869273542656, R4 // 04a41e03 + MOVV $0xea90000000000000, R4 // MOVV $-1544734672188080128, R4 // 04a43a03 +diff --git a/src/cmd/internal/obj/loong64/a.out.go b/src/cmd/internal/obj/loong64/a.out.go +index bd3ce61826..3bef0da869 100644 +--- a/src/cmd/internal/obj/loong64/a.out.go ++++ b/src/cmd/internal/obj/loong64/a.out.go +@@ -725,6 +725,28 @@ const ( + AVMOVQ + AXVMOVQ + ++ // LSX and LASX arithmetic instructions ++ AVADDB ++ AVADDH ++ AVADDW ++ AVADDV ++ AVADDQ ++ AXVADDB ++ AXVADDH ++ AXVADDW ++ AXVADDV ++ AXVADDQ ++ AVSUBB ++ AVSUBH ++ AVSUBW ++ AVSUBV ++ AVSUBQ ++ AXVSUBB ++ AXVSUBH ++ AXVSUBW ++ AXVSUBV ++ AXVSUBQ ++ + // LSX and LASX Bit-manipulation Instructions + AVANDB + AVORB +diff --git a/src/cmd/internal/obj/loong64/anames.go b/src/cmd/internal/obj/loong64/anames.go +index 6c1537d123..194021219e 100644 +--- a/src/cmd/internal/obj/loong64/anames.go ++++ b/src/cmd/internal/obj/loong64/anames.go +@@ -257,6 +257,26 @@ var Anames = []string{ + "FTINTRNEVD", + "VMOVQ", + "XVMOVQ", ++ "VADDB", ++ "VADDH", ++ "VADDW", ++ "VADDV", ++ "VADDQ", ++ "XVADDB", ++ "XVADDH", ++ "XVADDW", ++ "XVADDV", ++ "XVADDQ", ++ "VSUBB", ++ "VSUBH", ++ "VSUBW", ++ "VSUBV", ++ "VSUBQ", ++ "XVSUBB", ++ "XVSUBH", ++ "XVSUBW", ++ "XVSUBV", ++ "XVSUBQ", + "VANDB", + "VORB", + "VXORB", +diff --git a/src/cmd/internal/obj/loong64/asm.go b/src/cmd/internal/obj/loong64/asm.go +index 7247193c95..7489b4dbf6 100644 +--- a/src/cmd/internal/obj/loong64/asm.go ++++ b/src/cmd/internal/obj/loong64/asm.go +@@ -1539,6 +1539,16 @@ func buildop(ctxt *obj.Link) { + opset(AVNORV, r0) + opset(AVANDNV, r0) + opset(AVORNV, r0) ++ opset(AVADDB, r0) ++ opset(AVADDH, r0) ++ opset(AVADDW, r0) ++ opset(AVADDV, r0) ++ opset(AVADDQ, r0) ++ opset(AVSUBB, r0) ++ opset(AVSUBH, r0) ++ opset(AVSUBW, r0) ++ opset(AVSUBV, r0) ++ opset(AVSUBQ, r0) + + case AXVANDV: + opset(AXVORV, r0) +@@ -1546,6 +1556,16 @@ func buildop(ctxt *obj.Link) { + opset(AXVNORV, r0) + opset(AXVANDNV, r0) + opset(AXVORNV, r0) ++ opset(AXVADDB, r0) ++ opset(AXVADDH, r0) ++ opset(AXVADDW, r0) ++ opset(AXVADDV, r0) ++ opset(AXVADDQ, r0) ++ opset(AXVSUBB, r0) ++ opset(AXVSUBH, r0) ++ opset(AXVSUBW, r0) ++ opset(AXVSUBV, r0) ++ opset(AXVSUBQ, r0) + + case AVPCNTB: + opset(AVPCNTH, r0) +@@ -2701,6 +2721,46 @@ func (c *ctxt0) oprrr(a obj.As) uint32 { + return 0x0EA50 << 15 // xvandn.v + case AXVORNV: + return 0x0EA51 << 15 // xvorn.v ++ case AVADDB: ++ return 0xE014 << 15 // vadd.b ++ case AVADDH: ++ return 0xE015 << 15 // vadd.h ++ case AVADDW: ++ return 0xE016 << 15 // vadd.w ++ case AVADDV: ++ return 0xE017 << 15 // vadd.d ++ case AVADDQ: ++ return 0xE25A << 15 // vadd.q ++ case AVSUBB: ++ return 0xE018 << 15 // vsub.b ++ case AVSUBH: ++ return 0xE019 << 15 // vsub.h ++ case AVSUBW: ++ return 0xE01A << 15 // vsub.w ++ case AVSUBV: ++ return 0xE01B << 15 // vsub.d ++ case AVSUBQ: ++ return 0xE25B << 15 // vsub.q ++ case AXVADDB: ++ return 0xE814 << 15 // xvadd.b ++ case AXVADDH: ++ return 0xE815 << 15 // xvadd.h ++ case AXVADDW: ++ return 0xE816 << 15 // xvadd.w ++ case AXVADDV: ++ return 0xE817 << 15 // xvadd.d ++ case AXVADDQ: ++ return 0xEA5A << 15 // xvadd.q ++ case AXVSUBB: ++ return 0xE818 << 15 // xvsub.b ++ case AXVSUBH: ++ return 0xE819 << 15 // xvsub.h ++ case AXVSUBW: ++ return 0xE81A << 15 // xvsub.w ++ case AXVSUBV: ++ return 0xE81B << 15 // xvsub.d ++ case AXVSUBQ: ++ return 0xEA5B << 15 // xvsub.q + } + + if a < 0 { +-- +2.38.1 + diff --git a/0028-cmd-internal-obj-loong64-add-V-XV-ILV-L-H-.-B-H-W-D-.patch b/0028-cmd-internal-obj-loong64-add-V-XV-ILV-L-H-.-B-H-W-D-.patch new file mode 100644 index 0000000000000000000000000000000000000000..316746628a9aa2ec11178b65fa685d12a159372e --- /dev/null +++ b/0028-cmd-internal-obj-loong64-add-V-XV-ILV-L-H-.-B-H-W-D-.patch @@ -0,0 +1,181 @@ +From db7ccba69b0c246434a610f3be2ab31c8406b163 Mon Sep 17 00:00:00 2001 +From: Xiaolin Zhao +Date: Wed, 11 Dec 2024 10:24:13 +0800 +Subject: [PATCH 28/44] cmd/internal/obj/loong64: add {V,XV}ILV{L/H}.{B/H/W/D} + instructions support + +Go asm syntax: + VILV{L/H}{B/H/W/V} VK, VJ, VD + XVILV{L/H}{B/H/W/V} XK, XJ, XD +Equivalent platform assembler syntax: + vilv{l/h}.{b/h/w/d} vd, vj, vk + xvilv{l/h}.{b/h/w/d} xd, xj, xk + +Change-Id: If1f146fd5e049281494026bf4c24d302bcad1373 +--- + .../asm/internal/asm/testdata/loong64enc1.s | 18 +++++++ + src/cmd/internal/obj/loong64/a.out.go | 18 +++++++ + src/cmd/internal/obj/loong64/anames.go | 16 +++++++ + src/cmd/internal/obj/loong64/asm.go | 48 +++++++++++++++++++ + 4 files changed, 100 insertions(+) + +diff --git a/src/cmd/asm/internal/asm/testdata/loong64enc1.s b/src/cmd/asm/internal/asm/testdata/loong64enc1.s +index 76faf2d3cb..419f257c4a 100644 +--- a/src/cmd/asm/internal/asm/testdata/loong64enc1.s ++++ b/src/cmd/asm/internal/asm/testdata/loong64enc1.s +@@ -577,6 +577,24 @@ lable2: + XVSUBV X3, X2, X1 // 418c0d74 + XVSUBQ X3, X2, X1 // 418c2d75 + ++ // [X]VILV{L/H}{B,H,W,V} instructions ++ VILVLB V1, V2, V3 // 43041a71 ++ VILVLH V1, V2, V3 // 43841a71 ++ VILVLW V1, V2, V3 // 43041b71 ++ VILVLV V1, V2, V3 // 43841b71 ++ VILVHB V1, V2, V3 // 43041c71 ++ VILVHH V1, V2, V3 // 43841c71 ++ VILVHW V1, V2, V3 // 43041d71 ++ VILVHV V1, V2, V3 // 43841d71 ++ XVILVLB X3, X2, X1 // 410c1a75 ++ XVILVLH X3, X2, X1 // 418c1a75 ++ XVILVLW X3, X2, X1 // 410c1b75 ++ XVILVLV X3, X2, X1 // 418c1b75 ++ XVILVHB X3, X2, X1 // 410c1c75 ++ XVILVHH X3, X2, X1 // 418c1c75 ++ XVILVHW X3, X2, X1 // 410c1d75 ++ XVILVHV X3, X2, X1 // 418c1d75 ++ + // MOVV C_DCON12_0, r + MOVV $0x7a90000000000000, R4 // MOVV $8831558869273542656, R4 // 04a41e03 + MOVV $0xea90000000000000, R4 // MOVV $-1544734672188080128, R4 // 04a43a03 +diff --git a/src/cmd/internal/obj/loong64/a.out.go b/src/cmd/internal/obj/loong64/a.out.go +index 3bef0da869..c7f4769395 100644 +--- a/src/cmd/internal/obj/loong64/a.out.go ++++ b/src/cmd/internal/obj/loong64/a.out.go +@@ -788,6 +788,24 @@ const ( + AVSEQV + AXVSEQV + ++ // LSX and LASX move and shuffle instructions ++ AVILVLB ++ AVILVLH ++ AVILVLW ++ AVILVLV ++ AVILVHB ++ AVILVHH ++ AVILVHW ++ AVILVHV ++ AXVILVLB ++ AXVILVLH ++ AXVILVLW ++ AXVILVLV ++ AXVILVHB ++ AXVILVHH ++ AXVILVHW ++ AXVILVHV ++ + ALAST + + // aliases +diff --git a/src/cmd/internal/obj/loong64/anames.go b/src/cmd/internal/obj/loong64/anames.go +index 194021219e..485940e19c 100644 +--- a/src/cmd/internal/obj/loong64/anames.go ++++ b/src/cmd/internal/obj/loong64/anames.go +@@ -313,5 +313,21 @@ var Anames = []string{ + "XVSEQW", + "VSEQV", + "XVSEQV", ++ "VILVLB", ++ "VILVLH", ++ "VILVLW", ++ "VILVLV", ++ "VILVHB", ++ "VILVHH", ++ "VILVHW", ++ "VILVHV", ++ "XVILVLB", ++ "XVILVLH", ++ "XVILVLW", ++ "XVILVLV", ++ "XVILVHB", ++ "XVILVHH", ++ "XVILVHW", ++ "XVILVHV", + "LAST", + } +diff --git a/src/cmd/internal/obj/loong64/asm.go b/src/cmd/internal/obj/loong64/asm.go +index 7489b4dbf6..9ef414a132 100644 +--- a/src/cmd/internal/obj/loong64/asm.go ++++ b/src/cmd/internal/obj/loong64/asm.go +@@ -1549,6 +1549,14 @@ func buildop(ctxt *obj.Link) { + opset(AVSUBW, r0) + opset(AVSUBV, r0) + opset(AVSUBQ, r0) ++ opset(AVILVLB, r0) ++ opset(AVILVLH, r0) ++ opset(AVILVLW, r0) ++ opset(AVILVLV, r0) ++ opset(AVILVHB, r0) ++ opset(AVILVHH, r0) ++ opset(AVILVHW, r0) ++ opset(AVILVHV, r0) + + case AXVANDV: + opset(AXVORV, r0) +@@ -1566,6 +1574,14 @@ func buildop(ctxt *obj.Link) { + opset(AXVSUBW, r0) + opset(AXVSUBV, r0) + opset(AXVSUBQ, r0) ++ opset(AXVILVLB, r0) ++ opset(AXVILVLH, r0) ++ opset(AXVILVLW, r0) ++ opset(AXVILVLV, r0) ++ opset(AXVILVHB, r0) ++ opset(AXVILVHH, r0) ++ opset(AXVILVHW, r0) ++ opset(AXVILVHV, r0) + + case AVPCNTB: + opset(AVPCNTH, r0) +@@ -2761,6 +2777,38 @@ func (c *ctxt0) oprrr(a obj.As) uint32 { + return 0xE81B << 15 // xvsub.d + case AXVSUBQ: + return 0xEA5B << 15 // xvsub.q ++ case AVILVLB: ++ return 0xE234 << 15 // vilvl.b ++ case AVILVLH: ++ return 0xE235 << 15 // vilvl.h ++ case AVILVLW: ++ return 0xE236 << 15 // vilvl.w ++ case AVILVLV: ++ return 0xE237 << 15 // vilvl.d ++ case AVILVHB: ++ return 0xE238 << 15 // vilvh.b ++ case AVILVHH: ++ return 0xE239 << 15 // vilvh.h ++ case AVILVHW: ++ return 0xE23A << 15 // vilvh.w ++ case AVILVHV: ++ return 0xE23B << 15 // vilvh.d ++ case AXVILVLB: ++ return 0xEA34 << 15 // xvilvl.b ++ case AXVILVLH: ++ return 0xEA35 << 15 // xvilvl.h ++ case AXVILVLW: ++ return 0xEA36 << 15 // xvilvl.w ++ case AXVILVLV: ++ return 0xEA37 << 15 // xvilvl.d ++ case AXVILVHB: ++ return 0xEA38 << 15 // xvilvh.b ++ case AXVILVHH: ++ return 0xEA39 << 15 // xvilvh.h ++ case AXVILVHW: ++ return 0xEA3A << 15 // xvilvh.w ++ case AXVILVHV: ++ return 0xEA3B << 15 // xvilvh.d + } + + if a < 0 { +-- +2.38.1 + diff --git a/0029-cmd-internal-obj-loong64-add-V-XV-SLL-SRL-SRA-ROTR-I.patch b/0029-cmd-internal-obj-loong64-add-V-XV-SLL-SRL-SRA-ROTR-I.patch new file mode 100644 index 0000000000000000000000000000000000000000..71ebec387f8fd8b8c24ca42ab3e6d936640ccb99 --- /dev/null +++ b/0029-cmd-internal-obj-loong64-add-V-XV-SLL-SRL-SRA-ROTR-I.patch @@ -0,0 +1,599 @@ +From d765027e47dec10f8869d04b0bf52661ac63f302 Mon Sep 17 00:00:00 2001 +From: Xiaolin Zhao +Date: Wed, 11 Dec 2024 14:19:04 +0800 +Subject: [PATCH 29/44] cmd/internal/obj/loong64: add + {V,XV}{SLL/SRL/SRA/ROTR}[I].{B/H/W/D} instructions support + +Go asm syntax: + V{SLL/SRL/SRA/ROTR}{B/H/W/V} $1, V2, V3 + XV{SLL/SRL/SRA/ROTR}{B/H/W/V} $1, X2, X3 + V{SLL/SRL/SRA/ROTR}{B/H/W/V} VK, VJ, VD + XV{SLL/SRL/SRA/ROTR}{B/H/W/V} XK, XJ, XD + +Equivalent platform assembler syntax: + v{sll/srl/sra/rotr}i.{b/h/w/d} v3, v2, $1 + xv{sll/srl/sra/rotr}i.{b/h/w/d} x3, x2, $1 + v{sll/srl/sra/rotr}.{b/h/w/d} vd, vj, vk + xv{sll/srl/sra/rotr}.{b/h/w/d} xd, xj, xk + +Change-Id: I8693e15f3778057e5a1e636d618c6f46acc5042b +--- + .../asm/internal/asm/testdata/loong64enc1.s | 130 +++++++++ + src/cmd/internal/obj/loong64/a.out.go | 33 +++ + src/cmd/internal/obj/loong64/anames.go | 32 ++ + src/cmd/internal/obj/loong64/asm.go | 274 +++++++++++++++++- + 4 files changed, 468 insertions(+), 1 deletion(-) + +diff --git a/src/cmd/asm/internal/asm/testdata/loong64enc1.s b/src/cmd/asm/internal/asm/testdata/loong64enc1.s +index 419f257c4a..79012784dc 100644 +--- a/src/cmd/asm/internal/asm/testdata/loong64enc1.s ++++ b/src/cmd/asm/internal/asm/testdata/loong64enc1.s +@@ -595,6 +595,136 @@ lable2: + XVILVHW X3, X2, X1 // 410c1d75 + XVILVHV X3, X2, X1 // 418c1d75 + ++ // [X]{VSLL/VSRL/VSRA/VROTR}{B,H,W,V} instructions ++ VSLLB V1, V2, V3 // 4304e870 ++ VSLLH V1, V2, V3 // 4384e870 ++ VSLLW V1, V2, V3 // 4304e970 ++ VSLLV V1, V2, V3 // 4384e970 ++ VSRLB V1, V2, V3 // 4304ea70 ++ VSRLH V1, V2, V3 // 4384ea70 ++ VSRLW V1, V2, V3 // 4304eb70 ++ VSRLV V1, V2, V3 // 4384eb70 ++ VSRAB V1, V2, V3 // 4304ec70 ++ VSRAH V1, V2, V3 // 4384ec70 ++ VSRAW V1, V2, V3 // 4304ed70 ++ VSRAV V1, V2, V3 // 4384ed70 ++ VROTRB V1, V2, V3 // 4304ee70 ++ VROTRH V1, V2, V3 // 4384ee70 ++ VROTRW V1, V2, V3 // 4304ef70 ++ VROTRV V1, V2, V3 // 4384ef70 ++ XVSLLB X3, X2, X1 // 410ce874 ++ XVSLLH X3, X2, X1 // 418ce874 ++ XVSLLW X3, X2, X1 // 410ce974 ++ XVSLLV X3, X2, X1 // 418ce974 ++ XVSRLB X3, X2, X1 // 410cea74 ++ XVSRLH X3, X2, X1 // 418cea74 ++ XVSRLW X3, X2, X1 // 410ceb74 ++ XVSRLV X3, X2, X1 // 418ceb74 ++ XVSRAB X3, X2, X1 // 410cec74 ++ XVSRAH X3, X2, X1 // 418cec74 ++ XVSRAW X3, X2, X1 // 410ced74 ++ XVSRAV X3, X2, X1 // 418ced74 ++ XVROTRB X3, X2, X1 // 410cee74 ++ XVROTRH X3, X2, X1 // 418cee74 ++ XVROTRW X3, X2, X1 // 410cef74 ++ XVROTRV X3, X2, X1 // 418cef74 ++ VSLLB $0, V1, V2 // 22202c73 ++ VSLLB $7, V1, V2 // 223c2c73 ++ VSLLB $5, V1 // 21342c73 ++ VSLLH $0, V1, V2 // 22402c73 ++ VSLLH $15, V1, V2 // 227c2c73 ++ VSLLH $10, V1 // 21682c73 ++ VSLLW $0, V1, V2 // 22802c73 ++ VSLLW $31, V1, V2 // 22fc2c73 ++ VSLLW $11, V1 // 21ac2c73 ++ VSLLV $0, V1, V2 // 22002d73 ++ VSLLV $63, V1, V2 // 22fc2d73 ++ VSLLV $30, V1 // 21782d73 ++ VSRLB $0, V1, V2 // 22203073 ++ VSRLB $7, V1, V2 // 223c3073 ++ VSRLB $4, V1 // 21303073 ++ VSRLH $0, V1, V2 // 22403073 ++ VSRLH $15, V1, V2 // 227c3073 ++ VSRLH $9, V1 // 21643073 ++ VSRLW $0, V1, V2 // 22803073 ++ VSRLW $31, V1, V2 // 22fc3073 ++ VSRLW $16, V1 // 21c03073 ++ VSRLV $0, V1, V2 // 22003173 ++ VSRLV $63, V1, V2 // 22fc3173 ++ VSRLV $40, V1 // 21a03173 ++ VSRAB $0, V1, V2 // 22203473 ++ VSRAB $7, V1, V2 // 223c3473 ++ VSRAB $6, V1 // 21383473 ++ VSRAH $0, V1, V2 // 22403473 ++ VSRAH $15, V1, V2 // 227c3473 ++ VSRAH $8, V1 // 21603473 ++ VSRAW $0, V1, V2 // 22803473 ++ VSRAW $31, V1, V2 // 22fc3473 ++ VSRAW $12, V1 // 21b03473 ++ VSRAV $0, V1, V2 // 22003573 ++ VSRAV $63, V1, V2 // 22fc3573 ++ VSRAV $50, V1 // 21c83573 ++ VROTRB $0, V1, V2 // 2220a072 ++ VROTRB $7, V1, V2 // 223ca072 ++ VROTRB $3, V1 // 212ca072 ++ VROTRH $0, V1, V2 // 2240a072 ++ VROTRH $15, V1, V2 // 227ca072 ++ VROTRH $5, V1 // 2154a072 ++ VROTRW $0, V1, V2 // 2280a072 ++ VROTRW $31, V1, V2 // 22fca072 ++ VROTRW $18, V1 // 21c8a072 ++ VROTRV $0, V1, V2 // 2200a172 ++ VROTRV $63, V1, V2 // 22fca172 ++ VROTRV $52, V1 // 21d0a172 ++ XVSLLB $0, X2, X1 // 41202c77 ++ XVSLLB $7, X2, X1 // 413c2c77 ++ XVSLLB $4, X2 // 42302c77 ++ XVSLLH $0, X2, X1 // 41402c77 ++ XVSLLH $15, X2, X1 // 417c2c77 ++ XVSLLH $8, X2 // 42602c77 ++ XVSLLW $0, X2, X1 // 41802c77 ++ XVSLLW $31, X2, X1 // 41fc2c77 ++ XVSLLW $13, X2 // 42b42c77 ++ XVSLLV $0, X2, X1 // 41002d77 ++ XVSLLV $63, X2, X1 // 41fc2d77 ++ XVSLLV $36, X2 // 42902d77 ++ XVSRLB $0, X2, X1 // 41203077 ++ XVSRLB $7, X2, X1 // 413c3077 ++ XVSRLB $5, X2 // 42343077 ++ XVSRLH $0, X2, X1 // 41403077 ++ XVSRLH $15, X2, X1 // 417c3077 ++ XVSRLH $9, X2 // 42643077 ++ XVSRLW $0, X2, X1 // 41803077 ++ XVSRLW $31, X2, X1 // 41fc3077 ++ XVSRLW $14, X2 // 42b83077 ++ XVSRLV $0, X2, X1 // 41003177 ++ XVSRLV $63, X2, X1 // 41fc3177 ++ XVSRLV $45, X2 // 42b43177 ++ XVSRAB $0, X2, X1 // 41203477 ++ XVSRAB $7, X2, X1 // 413c3477 ++ XVSRAB $6, X2 // 42383477 ++ XVSRAH $0, X2, X1 // 41403477 ++ XVSRAH $15, X2, X1 // 417c3477 ++ XVSRAH $10, X2 // 42683477 ++ XVSRAW $0, X2, X1 // 41803477 ++ XVSRAW $31, X2, X1 // 41fc3477 ++ XVSRAW $16, X2 // 42c03477 ++ XVSRAV $0, X2, X1 // 41003577 ++ XVSRAV $63, X2, X1 // 41fc3577 ++ XVSRAV $48, X2 // 42c03577 ++ XVROTRB $0, X2, X1 // 4120a076 ++ XVROTRB $7, X2, X1 // 413ca076 ++ XVROTRB $3, X2 // 422ca076 ++ XVROTRH $0, X2, X1 // 4140a076 ++ XVROTRH $15, X2, X1 // 417ca076 ++ XVROTRH $13, X2 // 4274a076 ++ XVROTRW $0, X2, X1 // 4180a076 ++ XVROTRW $31, X2, X1 // 41fca076 ++ XVROTRW $24, X2 // 42e0a076 ++ XVROTRV $0, X2, X1 // 4100a176 ++ XVROTRV $63, X2, X1 // 41fca176 ++ XVROTRV $52, X2 // 42d0a176 ++ + // MOVV C_DCON12_0, r + MOVV $0x7a90000000000000, R4 // MOVV $8831558869273542656, R4 // 04a41e03 + MOVV $0xea90000000000000, R4 // MOVV $-1544734672188080128, R4 // 04a43a03 +diff --git a/src/cmd/internal/obj/loong64/a.out.go b/src/cmd/internal/obj/loong64/a.out.go +index c7f4769395..3257d376b4 100644 +--- a/src/cmd/internal/obj/loong64/a.out.go ++++ b/src/cmd/internal/obj/loong64/a.out.go +@@ -769,6 +769,39 @@ const ( + AXVANDNV + AXVORNV + ++ AVSLLB ++ AVSLLH ++ AVSLLW ++ AVSLLV ++ AVSRLB ++ AVSRLH ++ AVSRLW ++ AVSRLV ++ AVSRAB ++ AVSRAH ++ AVSRAW ++ AVSRAV ++ AVROTRB ++ AVROTRH ++ AVROTRW ++ AVROTRV ++ AXVSLLB ++ AXVSLLH ++ AXVSLLW ++ AXVSLLV ++ AXVSRLB ++ AXVSRLH ++ AXVSRLW ++ AXVSRLV ++ AXVSRAB ++ AXVSRAH ++ AXVSRAW ++ AXVSRAV ++ AXVROTRB ++ AXVROTRH ++ AXVROTRW ++ AXVROTRV ++ + AVPCNTB + AVPCNTH + AVPCNTW +diff --git a/src/cmd/internal/obj/loong64/anames.go b/src/cmd/internal/obj/loong64/anames.go +index 485940e19c..776e272a0b 100644 +--- a/src/cmd/internal/obj/loong64/anames.go ++++ b/src/cmd/internal/obj/loong64/anames.go +@@ -297,6 +297,38 @@ var Anames = []string{ + "XVNORV", + "XVANDNV", + "XVORNV", ++ "VSLLB", ++ "VSLLH", ++ "VSLLW", ++ "VSLLV", ++ "VSRLB", ++ "VSRLH", ++ "VSRLW", ++ "VSRLV", ++ "VSRAB", ++ "VSRAH", ++ "VSRAW", ++ "VSRAV", ++ "VROTRB", ++ "VROTRH", ++ "VROTRW", ++ "VROTRV", ++ "XVSLLB", ++ "XVSLLH", ++ "XVSLLW", ++ "XVSLLV", ++ "XVSRLB", ++ "XVSRLH", ++ "XVSRLW", ++ "XVSRLV", ++ "XVSRAB", ++ "XVSRAH", ++ "XVSRAW", ++ "XVSRAV", ++ "XVROTRB", ++ "XVROTRH", ++ "XVROTRW", ++ "XVROTRV", + "VPCNTB", + "VPCNTH", + "VPCNTW", +diff --git a/src/cmd/internal/obj/loong64/asm.go b/src/cmd/internal/obj/loong64/asm.go +index 9ef414a132..25a40d736e 100644 +--- a/src/cmd/internal/obj/loong64/asm.go ++++ b/src/cmd/internal/obj/loong64/asm.go +@@ -52,6 +52,10 @@ const ( + // Used to insert padding for under-aligned loops. + branchLoopHead + immFiledSi5 // The encoding of the immediate field in the instruction is 5-bits ++ immFiledUi3 // The encoding of the immediate field in the instruction is 3-bits ++ immFiledUi4 // The encoding of the immediate field in the instruction is 4-bits ++ immFiledUi5 // The encoding of the immediate field in the instruction is 5-bits ++ immFiledUi6 // The encoding of the immediate field in the instruction is 6-bits + immFiledUi8 // The encoding of the immediate field in the instruction is 8-bits + ) + +@@ -102,6 +106,34 @@ var optab = []Optab{ + {AVANDB, C_ADDCON, C_VREG, C_NONE, C_VREG, C_NONE, 14, 4, 0, immFiledUi8}, + {AXVANDB, C_ADDCON, C_XREG, C_NONE, C_XREG, C_NONE, 14, 4, 0, immFiledUi8}, + ++ {AVSLLB, C_VREG, C_VREG, C_NONE, C_VREG, C_NONE, 2, 4, 0, 0}, ++ {AXVSLLB, C_XREG, C_XREG, C_NONE, C_XREG, C_NONE, 2, 4, 0, 0}, ++ {AVSLLB, C_SCON, C_VREG, C_NONE, C_VREG, C_NONE, 29, 4, 0, immFiledUi3}, ++ {AXVSLLB, C_SCON, C_XREG, C_NONE, C_XREG, C_NONE, 29, 4, 0, immFiledUi3}, ++ {AVSLLB, C_SCON, C_NONE, C_NONE, C_VREG, C_NONE, 29, 4, 0, immFiledUi3}, ++ {AXVSLLB, C_SCON, C_NONE, C_NONE, C_XREG, C_NONE, 29, 4, 0, immFiledUi3}, ++ ++ {AVSLLH, C_VREG, C_VREG, C_NONE, C_VREG, C_NONE, 2, 4, 0, 0}, ++ {AXVSLLH, C_XREG, C_XREG, C_NONE, C_XREG, C_NONE, 2, 4, 0, 0}, ++ {AVSLLH, C_SCON, C_VREG, C_NONE, C_VREG, C_NONE, 31, 4, 0, immFiledUi4}, ++ {AXVSLLH, C_SCON, C_XREG, C_NONE, C_XREG, C_NONE, 31, 4, 0, immFiledUi4}, ++ {AVSLLH, C_SCON, C_NONE, C_NONE, C_VREG, C_NONE, 31, 4, 0, immFiledUi4}, ++ {AXVSLLH, C_SCON, C_NONE, C_NONE, C_XREG, C_NONE, 31, 4, 0, immFiledUi4}, ++ ++ {AVSLLW, C_VREG, C_VREG, C_NONE, C_VREG, C_NONE, 2, 4, 0, 0}, ++ {AXVSLLW, C_XREG, C_XREG, C_NONE, C_XREG, C_NONE, 2, 4, 0, 0}, ++ {AVSLLW, C_SCON, C_VREG, C_NONE, C_VREG, C_NONE, 32, 4, 0, immFiledUi5}, ++ {AXVSLLW, C_SCON, C_XREG, C_NONE, C_XREG, C_NONE, 32, 4, 0, immFiledUi5}, ++ {AVSLLW, C_SCON, C_NONE, C_NONE, C_VREG, C_NONE, 32, 4, 0, immFiledUi5}, ++ {AXVSLLW, C_SCON, C_NONE, C_NONE, C_XREG, C_NONE, 32, 4, 0, immFiledUi5}, ++ ++ {AVSLLV, C_VREG, C_VREG, C_NONE, C_VREG, C_NONE, 2, 4, 0, 0}, ++ {AXVSLLV, C_XREG, C_XREG, C_NONE, C_XREG, C_NONE, 2, 4, 0, 0}, ++ {AVSLLV, C_SCON, C_VREG, C_NONE, C_VREG, C_NONE, 33, 4, 0, immFiledUi6}, ++ {AXVSLLV, C_SCON, C_XREG, C_NONE, C_XREG, C_NONE, 33, 4, 0, immFiledUi6}, ++ {AVSLLV, C_SCON, C_NONE, C_NONE, C_VREG, C_NONE, 33, 4, 0, immFiledUi6}, ++ {AXVSLLV, C_SCON, C_NONE, C_NONE, C_XREG, C_NONE, 33, 4, 0, immFiledUi6}, ++ + {ACLOW, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 9, 4, 0, 0}, + {AABSF, C_FREG, C_NONE, C_NONE, C_FREG, C_NONE, 9, 4, 0, 0}, + {AMOVVF, C_FREG, C_NONE, C_NONE, C_FREG, C_NONE, 9, 4, 0, 0}, +@@ -1521,7 +1553,7 @@ func buildop(ctxt *obj.Link) { + case AXVSEQB: + opset(AXVSEQH, r0) + opset(AXVSEQW, r0) +- opset(AXVSEQV, r0) ++ opset(AXVSEQV, r0) + + case AVANDB: + opset(AVORB, r0) +@@ -1583,6 +1615,46 @@ func buildop(ctxt *obj.Link) { + opset(AXVILVHW, r0) + opset(AXVILVHV, r0) + ++ case AVSLLB: ++ opset(AVSRLB, r0) ++ opset(AVSRAB, r0) ++ opset(AVROTRB, r0) ++ ++ case AXVSLLB: ++ opset(AXVSRLB, r0) ++ opset(AXVSRAB, r0) ++ opset(AXVROTRB, r0) ++ ++ case AVSLLH: ++ opset(AVSRLH, r0) ++ opset(AVSRAH, r0) ++ opset(AVROTRH, r0) ++ ++ case AXVSLLH: ++ opset(AXVSRLH, r0) ++ opset(AXVSRAH, r0) ++ opset(AXVROTRH, r0) ++ ++ case AVSLLW: ++ opset(AVSRLW, r0) ++ opset(AVSRAW, r0) ++ opset(AVROTRW, r0) ++ ++ case AXVSLLW: ++ opset(AXVSRLW, r0) ++ opset(AXVSRAW, r0) ++ opset(AXVROTRW, r0) ++ ++ case AVSLLV: ++ opset(AVSRLV, r0) ++ opset(AVSRAV, r0) ++ opset(AVROTRV, r0) ++ ++ case AXVSLLV: ++ opset(AXVSRLV, r0) ++ opset(AXVSRAV, r0) ++ opset(AXVROTRV, r0) ++ + case AVPCNTB: + opset(AVPCNTH, r0) + opset(AVPCNTW, r0) +@@ -1629,10 +1701,22 @@ func OP_8IRR(op uint32, i uint32, r2 uint32, r3 uint32) uint32 { + return op | (i&0xFF)<<10 | (r2&0x1F)<<5 | (r3&0x1F)<<0 + } + ++func OP_6IRR(op uint32, i uint32, r2 uint32, r3 uint32) uint32 { ++ return op | (i&0x3F)<<10 | (r2&0x1F)<<5 | (r3&0x1F)<<0 ++} ++ + func OP_5IRR(op uint32, i uint32, r2 uint32, r3 uint32) uint32 { + return op | (i&0x1F)<<10 | (r2&0x1F)<<5 | (r3&0x1F)<<0 + } + ++func OP_4IRR(op uint32, i uint32, r2 uint32, r3 uint32) uint32 { ++ return op | (i&0xF)<<10 | (r2&0x1F)<<5 | (r3&0x1F)<<0 ++} ++ ++func OP_3IRR(op uint32, i uint32, r2 uint32, r3 uint32) uint32 { ++ return op | (i&0x7)<<10 | (r2&0x1F)<<5 | (r3&0x1F)<<0 ++} ++ + func OP_IR(op uint32, i uint32, r2 uint32) uint32 { + return op | (i&0xFFFFF)<<5 | (r2&0x1F)<<0 // ui20, rd5 + } +@@ -1994,10 +2078,70 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) { + o1 = OP_12IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.From.Reg)) + } + ++ case 29: // add $ui3,[r1],r2 ++ v := c.regoff(&p.From) ++ r := int(p.Reg) ++ if r == 0 { ++ r = int(p.To.Reg) ++ } ++ ++ switch o.flag { ++ case immFiledUi3: ++ c.checkimmFiled(p, v, 3, false) ++ o1 = OP_3IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.To.Reg)) ++ default: ++ c.ctxt.Diag("Invalid immediate value type\n%v", p) ++ } ++ + case 30: // mov gr/fr/fcc/fcsr, fr/fcc/fcsr/gr + a := c.specialFpMovInst(p.As, oclass(&p.From), oclass(&p.To)) + o1 = OP_RR(a, uint32(p.From.Reg), uint32(p.To.Reg)) + ++ case 31: // add $ui4,[r1],r2 ++ v := c.regoff(&p.From) ++ r := int(p.Reg) ++ if r == 0 { ++ r = int(p.To.Reg) ++ } ++ ++ switch o.flag { ++ case immFiledUi4: ++ c.checkimmFiled(p, v, 4, false) ++ o1 = OP_4IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.To.Reg)) ++ default: ++ c.ctxt.Diag("Invalid immediate value type\n%v", p) ++ } ++ ++ case 32: // add $ui5,[r1],r2 ++ v := c.regoff(&p.From) ++ r := int(p.Reg) ++ if r == 0 { ++ r = int(p.To.Reg) ++ } ++ ++ switch o.flag { ++ case immFiledUi5: ++ c.checkimmFiled(p, v, 5, false) ++ o1 = OP_5IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.To.Reg)) ++ default: ++ c.ctxt.Diag("Invalid immediate value type\n%v", p) ++ } ++ ++ case 33: // add $ui6,[r1],r2 ++ v := c.regoff(&p.From) ++ r := int(p.Reg) ++ if r == 0 { ++ r = int(p.To.Reg) ++ } ++ ++ switch o.flag { ++ case immFiledUi6: ++ c.checkimmFiled(p, v, 6, false) ++ o1 = OP_6IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.To.Reg)) ++ default: ++ c.ctxt.Diag("Invalid immediate value type\n%v", p) ++ } ++ + case 34: // mov $con,fr + v := c.regoff(&p.From) + a := AADDU +@@ -2809,6 +2953,70 @@ func (c *ctxt0) oprrr(a obj.As) uint32 { + return 0xEA3A << 15 // xvilvh.w + case AXVILVHV: + return 0xEA3B << 15 // xvilvh.d ++ case AVSLLB: ++ return 0xE1D0 << 15 // vsll.b ++ case AVSLLH: ++ return 0xE1D1 << 15 // vsll.h ++ case AVSLLW: ++ return 0xE1D2 << 15 // vsll.w ++ case AVSLLV: ++ return 0xE1D3 << 15 // vsll.d ++ case AVSRLB: ++ return 0xE1D4 << 15 // vsrl.b ++ case AVSRLH: ++ return 0xE1D5 << 15 // vsrl.h ++ case AVSRLW: ++ return 0xE1D6 << 15 // vsrl.w ++ case AVSRLV: ++ return 0xE1D7 << 15 // vsrl.d ++ case AVSRAB: ++ return 0xE1D8 << 15 // vsra.b ++ case AVSRAH: ++ return 0xE1D9 << 15 // vsra.h ++ case AVSRAW: ++ return 0xE1DA << 15 // vsra.w ++ case AVSRAV: ++ return 0xE1DB << 15 // vsra.d ++ case AVROTRB: ++ return 0xE1DC << 15 // vrotr.b ++ case AVROTRH: ++ return 0xE1DD << 15 // vrotr.h ++ case AVROTRW: ++ return 0xE1DE << 15 // vrotr.w ++ case AVROTRV: ++ return 0xE1DF << 15 // vrotr.d ++ case AXVSLLB: ++ return 0xE9D0 << 15 // xvsll.b ++ case AXVSLLH: ++ return 0xE9D1 << 15 // xvsll.h ++ case AXVSLLW: ++ return 0xE9D2 << 15 // xvsll.w ++ case AXVSLLV: ++ return 0xE9D3 << 15 // xvsll.d ++ case AXVSRLB: ++ return 0xE9D4 << 15 // xvsrl.b ++ case AXVSRLH: ++ return 0xE9D5 << 15 // xvsrl.h ++ case AXVSRLW: ++ return 0xE9D6 << 15 // xvsrl.w ++ case AXVSRLV: ++ return 0xE9D7 << 15 // xvsrl.d ++ case AXVSRAB: ++ return 0xE9D8 << 15 // xvsra.b ++ case AXVSRAH: ++ return 0xE9D9 << 15 // xvsra.h ++ case AXVSRAW: ++ return 0xE9DA << 15 // xvsra.w ++ case AXVSRAV: ++ return 0xE9DB << 15 // xvsra.d ++ case AXVROTRB: ++ return 0xE9DC << 15 // xvrotr.b ++ case AXVROTRH: ++ return 0xE9DD << 15 // xvrotr.h ++ case AXVROTRW: ++ return 0xE9DE << 15 // xvrotr.w ++ case AXVROTRV: ++ return 0xE9DF << 15 // xvrotr.d + } + + if a < 0 { +@@ -3168,6 +3376,70 @@ func (c *ctxt0) opirr(a obj.As) uint32 { + return 0x0ED02 << 15 // xvseqi.w + case AXVSEQV: + return 0x0ED03 << 15 // xvseqi.d ++ case AVROTRB: ++ return 0x1CA8<<18 | 0x1<<13 // vrotri.b ++ case AVROTRH: ++ return 0x1CA8<<18 | 0x1<<14 // vrotri.h ++ case AVROTRW: ++ return 0x1CA8<<18 | 0x1<<15 // vrotri.w ++ case AVROTRV: ++ return 0x1CA8<<18 | 0x1<<16 // vrotri.d ++ case AXVROTRB: ++ return 0x1DA8<<18 | 0x1<<13 // xvrotri.b ++ case AXVROTRH: ++ return 0x1DA8<<18 | 0x1<<14 // xvrotri.h ++ case AXVROTRW: ++ return 0x1DA8<<18 | 0x1<<15 // xvrotri.w ++ case AXVROTRV: ++ return 0x1DA8<<18 | 0x1<<16 // xvrotri.d ++ case AVSLLB: ++ return 0x1CCB<<18 | 0x1<<13 // vslli.b ++ case AVSLLH: ++ return 0x1CCB<<18 | 0x1<<14 // vslli.h ++ case AVSLLW: ++ return 0x1CCB<<18 | 0x1<<15 // vslli.w ++ case AVSLLV: ++ return 0x1CCB<<18 | 0x1<<16 // vslli.d ++ case AVSRLB: ++ return 0x1CCC<<18 | 0x1<<13 // vsrli.b ++ case AVSRLH: ++ return 0x1CCC<<18 | 0x1<<14 // vsrli.h ++ case AVSRLW: ++ return 0x1CCC<<18 | 0x1<<15 // vsrli.w ++ case AVSRLV: ++ return 0x1CCC<<18 | 0x1<<16 // vsrli.d ++ case AVSRAB: ++ return 0x1CCD<<18 | 0x1<<13 // vsrai.b ++ case AVSRAH: ++ return 0x1CCD<<18 | 0x1<<14 // vsrai.h ++ case AVSRAW: ++ return 0x1CCD<<18 | 0x1<<15 // vsrai.w ++ case AVSRAV: ++ return 0x1CCD<<18 | 0x1<<16 // vsrai.d ++ case AXVSLLB: ++ return 0x1DCB<<18 | 0x1<<13 // xvslli.b ++ case AXVSLLH: ++ return 0x1DCB<<18 | 0x1<<14 // xvslli.h ++ case AXVSLLW: ++ return 0x1DCB<<18 | 0x1<<15 // xvslli.w ++ case AXVSLLV: ++ return 0x1DCB<<18 | 0x1<<16 // xvslli.d ++ case AXVSRLB: ++ return 0x1DCC<<18 | 0x1<<13 // xvsrli.b ++ case AXVSRLH: ++ return 0x1DCC<<18 | 0x1<<14 // xvsrli.h ++ case AXVSRLW: ++ return 0x1DCC<<18 | 0x1<<15 // xvsrli.w ++ case AXVSRLV: ++ return 0x1DCC<<18 | 0x1<<16 // xvsrli.d ++ case AXVSRAB: ++ return 0x1DCD<<18 | 0x1<<13 // xvsrai.b ++ case AXVSRAH: ++ return 0x1DCD<<18 | 0x1<<14 // xvsrai.h ++ case AXVSRAW: ++ return 0x1DCD<<18 | 0x1<<15 // xvsrai.w ++ case AXVSRAV: ++ return 0x1DCD<<18 | 0x1<<16 // xvsrai.d + } + + if a < 0 { +-- +2.38.1 + diff --git a/0030-cmd-internal-obj-loong64-add-V-XV-FSQRT-FRECIP-FRSQR.patch b/0030-cmd-internal-obj-loong64-add-V-XV-FSQRT-FRECIP-FRSQR.patch new file mode 100644 index 0000000000000000000000000000000000000000..ba201937d9220018abcfc3a9c8eb7ef92b211b0b --- /dev/null +++ b/0030-cmd-internal-obj-loong64-add-V-XV-FSQRT-FRECIP-FRSQR.patch @@ -0,0 +1,166 @@ +From 344852ff0ccb2b948dc77e0934f246cc5ddf9506 Mon Sep 17 00:00:00 2001 +From: Xiaolin Zhao +Date: Wed, 11 Dec 2024 16:49:08 +0800 +Subject: [PATCH 30/44] cmd/internal/obj/loong64: add + {V,XV}{FSQRT/FRECIP/FRSQRT}.{S/D} instructions support + +Go asm syntax: + V{FSQRT/FRECIP/FRSQRT}{F/D} VJ, VD + XV{FSQRT/FRECIP/FRSQRT}{F/D} XJ, XD + +Equivalent platform assembler syntax: + v{fsqrt/frecip/frsqrt}.{s/d} vd, vj + xv{fsqrt/frecip/frsqrt}.{s/d} xd, xj + +Change-Id: Ied0b959e703d2199939c9ac0608eb3408ea249fa +--- + .../asm/internal/asm/testdata/loong64enc1.s | 14 +++++++ + src/cmd/internal/obj/loong64/a.out.go | 14 +++++++ + src/cmd/internal/obj/loong64/anames.go | 12 ++++++ + src/cmd/internal/obj/loong64/asm.go | 38 ++++++++++++++++++- + 4 files changed, 77 insertions(+), 1 deletion(-) + +diff --git a/src/cmd/asm/internal/asm/testdata/loong64enc1.s b/src/cmd/asm/internal/asm/testdata/loong64enc1.s +index 79012784dc..e2e8a6de6c 100644 +--- a/src/cmd/asm/internal/asm/testdata/loong64enc1.s ++++ b/src/cmd/asm/internal/asm/testdata/loong64enc1.s +@@ -725,6 +725,20 @@ lable2: + XVROTRV $63, X2, X1 // 41fca176 + XVROTRV $52, X2 // 42d0a176 + ++ // [X]VF{SQRT/RECIP/RSQRT}{F/D} instructions ++ VFSQRTF V1, V2 // 22e49c72 ++ VFSQRTD V1, V2 // 22e89c72 ++ VFRECIPF V1, V2 // 22f49c72 ++ VFRECIPD V1, V2 // 22f89c72 ++ VFRSQRTF V1, V2 // 22049d72 ++ VFRSQRTD V1, V2 // 22089d72 ++ XVFSQRTF X2, X1 // 41e49c76 ++ XVFSQRTD X2, X1 // 41e89c76 ++ XVFRECIPF X2, X1 // 41f49c76 ++ XVFRECIPD X2, X1 // 41f89c76 ++ XVFRSQRTF X2, X1 // 41049d76 ++ XVFRSQRTD X2, X1 // 41089d76 ++ + // MOVV C_DCON12_0, r + MOVV $0x7a90000000000000, R4 // MOVV $8831558869273542656, R4 // 04a41e03 + MOVV $0xea90000000000000, R4 // MOVV $-1544734672188080128, R4 // 04a43a03 +diff --git a/src/cmd/internal/obj/loong64/a.out.go b/src/cmd/internal/obj/loong64/a.out.go +index 3257d376b4..bd2b1e8300 100644 +--- a/src/cmd/internal/obj/loong64/a.out.go ++++ b/src/cmd/internal/obj/loong64/a.out.go +@@ -811,6 +811,20 @@ const ( + AXVPCNTW + AXVPCNTV + ++ // LSX and LASX floating point instructions ++ AVFSQRTF ++ AVFSQRTD ++ AVFRECIPF ++ AVFRECIPD ++ AVFRSQRTF ++ AVFRSQRTD ++ AXVFSQRTF ++ AXVFSQRTD ++ AXVFRECIPF ++ AXVFRECIPD ++ AXVFRSQRTF ++ AXVFRSQRTD ++ + // LSX and LASX integer comparison instruction + AVSEQB + AXVSEQB +diff --git a/src/cmd/internal/obj/loong64/anames.go b/src/cmd/internal/obj/loong64/anames.go +index 776e272a0b..7dbe9b92e6 100644 +--- a/src/cmd/internal/obj/loong64/anames.go ++++ b/src/cmd/internal/obj/loong64/anames.go +@@ -337,6 +337,18 @@ var Anames = []string{ + "XVPCNTH", + "XVPCNTW", + "XVPCNTV", ++ "VFSQRTF", ++ "VFSQRTD", ++ "VFRECIPF", ++ "VFRECIPD", ++ "VFRSQRTF", ++ "VFRSQRTD", ++ "XVFSQRTF", ++ "XVFSQRTD", ++ "XVFRECIPF", ++ "XVFRECIPD", ++ "XVFRSQRTF", ++ "XVFRSQRTD", + "VSEQB", + "XVSEQB", + "VSEQH", +diff --git a/src/cmd/internal/obj/loong64/asm.go b/src/cmd/internal/obj/loong64/asm.go +index 25a40d736e..af38bef3aa 100644 +--- a/src/cmd/internal/obj/loong64/asm.go ++++ b/src/cmd/internal/obj/loong64/asm.go +@@ -1553,7 +1553,7 @@ func buildop(ctxt *obj.Link) { + case AXVSEQB: + opset(AXVSEQH, r0) + opset(AXVSEQW, r0) +- opset(AXVSEQV, r0) ++ opset(AXVSEQV, r0) + + case AVANDB: + opset(AVORB, r0) +@@ -1659,11 +1659,23 @@ func buildop(ctxt *obj.Link) { + opset(AVPCNTH, r0) + opset(AVPCNTW, r0) + opset(AVPCNTV, r0) ++ opset(AVFSQRTF, r0) ++ opset(AVFSQRTD, r0) ++ opset(AVFRECIPF, r0) ++ opset(AVFRECIPD, r0) ++ opset(AVFRSQRTF, r0) ++ opset(AVFRSQRTD, r0) + + case AXVPCNTB: + opset(AXVPCNTH, r0) + opset(AXVPCNTW, r0) + opset(AXVPCNTV, r0) ++ opset(AXVFSQRTF, r0) ++ opset(AXVFSQRTD, r0) ++ opset(AXVFRECIPF, r0) ++ opset(AXVFRECIPD, r0) ++ opset(AXVFRSQRTF, r0) ++ opset(AXVFRSQRTD, r0) + } + } + } +@@ -3193,6 +3205,30 @@ func (c *ctxt0) oprr(a obj.As) uint32 { + return 0x1da70a << 10 // xvpcnt.w + case AXVPCNTV: + return 0x1da70b << 10 // xvpcnt.v ++ case AVFSQRTF: ++ return 0x1ca739 << 10 // vfsqrt.s ++ case AVFSQRTD: ++ return 0x1ca73a << 10 // vfsqrt.d ++ case AVFRECIPF: ++ return 0x1ca73d << 10 // vfrecip.s ++ case AVFRECIPD: ++ return 0x1ca73e << 10 // vfrecip.d ++ case AVFRSQRTF: ++ return 0x1ca741 << 10 // vfrsqrt.s ++ case AVFRSQRTD: ++ return 0x1ca742 << 10 // vfrsqrt.d ++ case AXVFSQRTF: ++ return 0x1da739 << 10 // xvfsqrt.s ++ case AXVFSQRTD: ++ return 0x1da73a << 10 // xvfsqrt.d ++ case AXVFRECIPF: ++ return 0x1da73d << 10 // xvfrecip.s ++ case AXVFRECIPD: ++ return 0x1da73e << 10 // xvfrecip.d ++ case AXVFRSQRTF: ++ return 0x1da741 << 10 // xvfrsqrt.s ++ case AXVFRSQRTD: ++ return 0x1da742 << 10 // xvfrsqrt.d + } + + c.ctxt.Diag("bad rr opcode %v", a) +-- +2.38.1 + diff --git a/0031-cmd-internal-obj-loong64-add-V-XV-NEG-B-H-W-V-instru.patch b/0031-cmd-internal-obj-loong64-add-V-XV-NEG-B-H-W-V-instru.patch new file mode 100644 index 0000000000000000000000000000000000000000..40e749c6f39030fd62a0f682dc3cc8486c1577e6 --- /dev/null +++ b/0031-cmd-internal-obj-loong64-add-V-XV-NEG-B-H-W-V-instru.patch @@ -0,0 +1,135 @@ +From 6849aaa3deb1fec44bb7625a70ecc2a19f86a389 Mon Sep 17 00:00:00 2001 +From: Xiaolin Zhao +Date: Wed, 11 Dec 2024 17:19:04 +0800 +Subject: [PATCH 31/44] cmd/internal/obj/loong64: add {V,XV}NEG{B/H/W/V} + instructions support + +Go asm syntax: + VNEG{B/H/W/V} VJ, VD + XVNEG{B/H/W/V} XJ, XD + +Equivalent platform assembler syntax: + vneg.{b/h/w/d} vd, vj + xvneg.{b/h/w/d} xd, xj + +Change-Id: Ib2df46b5386149efb44fe12e2485c01826339a5d +--- + .../asm/internal/asm/testdata/loong64enc1.s | 10 ++++++++ + src/cmd/internal/obj/loong64/a.out.go | 10 ++++++++ + src/cmd/internal/obj/loong64/anames.go | 8 +++++++ + src/cmd/internal/obj/loong64/asm.go | 24 +++++++++++++++++++ + 4 files changed, 52 insertions(+) + +diff --git a/src/cmd/asm/internal/asm/testdata/loong64enc1.s b/src/cmd/asm/internal/asm/testdata/loong64enc1.s +index e2e8a6de6c..9deb3cbafd 100644 +--- a/src/cmd/asm/internal/asm/testdata/loong64enc1.s ++++ b/src/cmd/asm/internal/asm/testdata/loong64enc1.s +@@ -739,6 +739,16 @@ lable2: + XVFRSQRTF X2, X1 // 41049d76 + XVFRSQRTD X2, X1 // 41089d76 + ++ // [X]VNEG{B/H/W/V} instructions ++ VNEGB V1, V2 // 22309c72 ++ VNEGH V1, V2 // 22349c72 ++ VNEGW V1, V2 // 22389c72 ++ VNEGV V1, V2 // 223c9c72 ++ XVNEGB X2, X1 // 41309c76 ++ XVNEGH X2, X1 // 41349c76 ++ XVNEGW X2, X1 // 41389c76 ++ XVNEGV X2, X1 // 413c9c76 ++ + // MOVV C_DCON12_0, r + MOVV $0x7a90000000000000, R4 // MOVV $8831558869273542656, R4 // 04a41e03 + MOVV $0xea90000000000000, R4 // MOVV $-1544734672188080128, R4 // 04a43a03 +diff --git a/src/cmd/internal/obj/loong64/a.out.go b/src/cmd/internal/obj/loong64/a.out.go +index bd2b1e8300..486dc9fa89 100644 +--- a/src/cmd/internal/obj/loong64/a.out.go ++++ b/src/cmd/internal/obj/loong64/a.out.go +@@ -747,6 +747,16 @@ const ( + AXVSUBV + AXVSUBQ + ++ // LSX and LASX integer neg instructions ++ AVNEGB ++ AVNEGH ++ AVNEGW ++ AVNEGV ++ AXVNEGB ++ AXVNEGH ++ AXVNEGW ++ AXVNEGV ++ + // LSX and LASX Bit-manipulation Instructions + AVANDB + AVORB +diff --git a/src/cmd/internal/obj/loong64/anames.go b/src/cmd/internal/obj/loong64/anames.go +index 7dbe9b92e6..d697b73e71 100644 +--- a/src/cmd/internal/obj/loong64/anames.go ++++ b/src/cmd/internal/obj/loong64/anames.go +@@ -277,6 +277,14 @@ var Anames = []string{ + "XVSUBW", + "XVSUBV", + "XVSUBQ", ++ "VNEGB", ++ "VNEGH", ++ "VNEGW", ++ "VNEGV", ++ "XVNEGB", ++ "XVNEGH", ++ "XVNEGW", ++ "XVNEGV", + "VANDB", + "VORB", + "VXORB", +diff --git a/src/cmd/internal/obj/loong64/asm.go b/src/cmd/internal/obj/loong64/asm.go +index af38bef3aa..e2c7afd82d 100644 +--- a/src/cmd/internal/obj/loong64/asm.go ++++ b/src/cmd/internal/obj/loong64/asm.go +@@ -1665,6 +1665,10 @@ func buildop(ctxt *obj.Link) { + opset(AVFRECIPD, r0) + opset(AVFRSQRTF, r0) + opset(AVFRSQRTD, r0) ++ opset(AVNEGB, r0) ++ opset(AVNEGH, r0) ++ opset(AVNEGW, r0) ++ opset(AVNEGV, r0) + + case AXVPCNTB: + opset(AXVPCNTH, r0) +@@ -1676,6 +1680,10 @@ func buildop(ctxt *obj.Link) { + opset(AXVFRECIPD, r0) + opset(AXVFRSQRTF, r0) + opset(AXVFRSQRTD, r0) ++ opset(AXVNEGB, r0) ++ opset(AXVNEGH, r0) ++ opset(AXVNEGW, r0) ++ opset(AXVNEGV, r0) + } + } + } +@@ -3229,6 +3237,22 @@ func (c *ctxt0) oprr(a obj.As) uint32 { + return 0x1da741 << 10 // xvfrsqrt.s + case AXVFRSQRTD: + return 0x1da742 << 10 // xvfrsqrt.d ++ case AVNEGB: ++ return 0x1ca70c << 10 // vneg.b ++ case AVNEGH: ++ return 0x1ca70d << 10 // vneg.h ++ case AVNEGW: ++ return 0x1ca70e << 10 // vneg.w ++ case AVNEGV: ++ return 0x1ca70f << 10 // vneg.d ++ case AXVNEGB: ++ return 0x1da70c << 10 // xvneg.b ++ case AXVNEGH: ++ return 0x1da70d << 10 // xvneg.h ++ case AXVNEGW: ++ return 0x1da70e << 10 // xvneg.w ++ case AXVNEGV: ++ return 0x1da70f << 10 // xvneg.d + } + + c.ctxt.Diag("bad rr opcode %v", a) +-- +2.38.1 + diff --git a/0032-cmd-internal-obj-loong64-add-V-XV-MUL-B-H-W-V-and-V-.patch b/0032-cmd-internal-obj-loong64-add-V-XV-MUL-B-H-W-V-and-V-.patch new file mode 100644 index 0000000000000000000000000000000000000000..67724ac532b420e34fd99dc4c3ea21173f284099 --- /dev/null +++ b/0032-cmd-internal-obj-loong64-add-V-XV-MUL-B-H-W-V-and-V-.patch @@ -0,0 +1,235 @@ +From 984f12cbb1763c855882b3c8e89727ad560b38c1 Mon Sep 17 00:00:00 2001 +From: Xiaolin Zhao +Date: Wed, 11 Dec 2024 17:46:09 +0800 +Subject: [PATCH 32/44] cmd/internal/obj/loong64: add {V,XV}MUL{B/H/W/V} and + {V,XV}MUH{B/H/W/V}[U] instructions support + +Go asm syntax: + VMUL{B/H/W/V} VK, VJ, VD + VMUH{B/H/W/V}[U] VK, VJ, VD + XVMUL{B/H/W/V} XK, XJ, XD + XVMUH{B/H/W/V}[U] XK, XJ, XD + +Equivalent platform assembler syntax: + vmul.{b/h/w/d} vd, vj, vk + vmuh.{b/h/w/d}[u] vd, vj, vk + xvmul.{b/h/w/d} xd, xj, xk + xvmuh.{b/h/w/d}[u] xd, xj, xk + +Change-Id: I8890f8a41100e4681a833c27067f0f76b593f731 +--- + .../asm/internal/asm/testdata/loong64enc1.s | 26 +++++++ + src/cmd/internal/obj/loong64/a.out.go | 26 +++++++ + src/cmd/internal/obj/loong64/anames.go | 24 +++++++ + src/cmd/internal/obj/loong64/asm.go | 72 +++++++++++++++++++ + 4 files changed, 148 insertions(+) + +diff --git a/src/cmd/asm/internal/asm/testdata/loong64enc1.s b/src/cmd/asm/internal/asm/testdata/loong64enc1.s +index 9deb3cbafd..c8b490234f 100644 +--- a/src/cmd/asm/internal/asm/testdata/loong64enc1.s ++++ b/src/cmd/asm/internal/asm/testdata/loong64enc1.s +@@ -749,6 +749,32 @@ lable2: + XVNEGW X2, X1 // 41389c76 + XVNEGV X2, X1 // 413c9c76 + ++ // [X]VMUL{B/H/W/V} and [X]VMUH{B/H/W/V}[U] instructions ++ VMULB V1, V2, V3 // 43048470 ++ VMULH V1, V2, V3 // 43848470 ++ VMULW V1, V2, V3 // 43048570 ++ VMULV V1, V2, V3 // 43848570 ++ VMUHB V1, V2, V3 // 43048670 ++ VMUHH V1, V2, V3 // 43848670 ++ VMUHW V1, V2, V3 // 43048770 ++ VMUHV V1, V2, V3 // 43848770 ++ VMUHBU V1, V2, V3 // 43048870 ++ VMUHHU V1, V2, V3 // 43848870 ++ VMUHWU V1, V2, V3 // 43048970 ++ VMUHVU V1, V2, V3 // 43848970 ++ XVMULB X3, X2, X1 // 410c8474 ++ XVMULH X3, X2, X1 // 418c8474 ++ XVMULW X3, X2, X1 // 410c8574 ++ XVMULV X3, X2, X1 // 418c8574 ++ XVMUHB X3, X2, X1 // 410c8674 ++ XVMUHH X3, X2, X1 // 418c8674 ++ XVMUHW X3, X2, X1 // 410c8774 ++ XVMUHV X3, X2, X1 // 418c8774 ++ XVMUHBU X3, X2, X1 // 410c8874 ++ XVMUHHU X3, X2, X1 // 418c8874 ++ XVMUHWU X3, X2, X1 // 410c8974 ++ XVMUHVU X3, X2, X1 // 418c8974 ++ + // MOVV C_DCON12_0, r + MOVV $0x7a90000000000000, R4 // MOVV $8831558869273542656, R4 // 04a41e03 + MOVV $0xea90000000000000, R4 // MOVV $-1544734672188080128, R4 // 04a43a03 +diff --git a/src/cmd/internal/obj/loong64/a.out.go b/src/cmd/internal/obj/loong64/a.out.go +index 486dc9fa89..95744e77a1 100644 +--- a/src/cmd/internal/obj/loong64/a.out.go ++++ b/src/cmd/internal/obj/loong64/a.out.go +@@ -757,6 +757,32 @@ const ( + AXVNEGW + AXVNEGV + ++ // LSX and LASX integer mul instructions ++ AVMULB ++ AVMULH ++ AVMULW ++ AVMULV ++ AVMUHB ++ AVMUHH ++ AVMUHW ++ AVMUHV ++ AVMUHBU ++ AVMUHHU ++ AVMUHWU ++ AVMUHVU ++ AXVMULB ++ AXVMULH ++ AXVMULW ++ AXVMULV ++ AXVMUHB ++ AXVMUHH ++ AXVMUHW ++ AXVMUHV ++ AXVMUHBU ++ AXVMUHHU ++ AXVMUHWU ++ AXVMUHVU ++ + // LSX and LASX Bit-manipulation Instructions + AVANDB + AVORB +diff --git a/src/cmd/internal/obj/loong64/anames.go b/src/cmd/internal/obj/loong64/anames.go +index d697b73e71..d0cd3a26fa 100644 +--- a/src/cmd/internal/obj/loong64/anames.go ++++ b/src/cmd/internal/obj/loong64/anames.go +@@ -285,6 +285,30 @@ var Anames = []string{ + "XVNEGH", + "XVNEGW", + "XVNEGV", ++ "VMULB", ++ "VMULH", ++ "VMULW", ++ "VMULV", ++ "VMUHB", ++ "VMUHH", ++ "VMUHW", ++ "VMUHV", ++ "VMUHBU", ++ "VMUHHU", ++ "VMUHWU", ++ "VMUHVU", ++ "XVMULB", ++ "XVMULH", ++ "XVMULW", ++ "XVMULV", ++ "XVMUHB", ++ "XVMUHH", ++ "XVMUHW", ++ "XVMUHV", ++ "XVMUHBU", ++ "XVMUHHU", ++ "XVMUHWU", ++ "XVMUHVU", + "VANDB", + "VORB", + "VXORB", +diff --git a/src/cmd/internal/obj/loong64/asm.go b/src/cmd/internal/obj/loong64/asm.go +index e2c7afd82d..7fb99f66e6 100644 +--- a/src/cmd/internal/obj/loong64/asm.go ++++ b/src/cmd/internal/obj/loong64/asm.go +@@ -1589,6 +1589,18 @@ func buildop(ctxt *obj.Link) { + opset(AVILVHH, r0) + opset(AVILVHW, r0) + opset(AVILVHV, r0) ++ opset(AVMULB, r0) ++ opset(AVMULH, r0) ++ opset(AVMULW, r0) ++ opset(AVMULV, r0) ++ opset(AVMUHB, r0) ++ opset(AVMUHH, r0) ++ opset(AVMUHW, r0) ++ opset(AVMUHV, r0) ++ opset(AVMUHBU, r0) ++ opset(AVMUHHU, r0) ++ opset(AVMUHWU, r0) ++ opset(AVMUHVU, r0) + + case AXVANDV: + opset(AXVORV, r0) +@@ -1614,6 +1626,18 @@ func buildop(ctxt *obj.Link) { + opset(AXVILVHH, r0) + opset(AXVILVHW, r0) + opset(AXVILVHV, r0) ++ opset(AXVMULB, r0) ++ opset(AXVMULH, r0) ++ opset(AXVMULW, r0) ++ opset(AXVMULV, r0) ++ opset(AXVMUHB, r0) ++ opset(AXVMUHH, r0) ++ opset(AXVMUHW, r0) ++ opset(AXVMUHV, r0) ++ opset(AXVMUHBU, r0) ++ opset(AXVMUHHU, r0) ++ opset(AXVMUHWU, r0) ++ opset(AXVMUHVU, r0) + + case AVSLLB: + opset(AVSRLB, r0) +@@ -3037,6 +3061,54 @@ func (c *ctxt0) oprrr(a obj.As) uint32 { + return 0xE9DE << 15 // xvrotr.w + case AXVROTRV: + return 0xE9DF << 15 // xvrotr.d ++ case AVMULB: ++ return 0xe108 << 15 // vmul.b ++ case AVMULH: ++ return 0xe109 << 15 // vmul.h ++ case AVMULW: ++ return 0xe10a << 15 // vmul.w ++ case AVMULV: ++ return 0xe10b << 15 // vmul.d ++ case AVMUHB: ++ return 0xe10c << 15 // vmuh.b ++ case AVMUHH: ++ return 0xe10d << 15 // vmuh.h ++ case AVMUHW: ++ return 0xe10e << 15 // vmuh.w ++ case AVMUHV: ++ return 0xe10f << 15 // vmuh.d ++ case AVMUHBU: ++ return 0xe110 << 15 // vmuh.bu ++ case AVMUHHU: ++ return 0xe111 << 15 // vmuh.hu ++ case AVMUHWU: ++ return 0xe112 << 15 // vmuh.wu ++ case AVMUHVU: ++ return 0xe113 << 15 // vmuh.du ++ case AXVMULB: ++ return 0xe908 << 15 // xvmul.b ++ case AXVMULH: ++ return 0xe909 << 15 // xvmul.h ++ case AXVMULW: ++ return 0xe90a << 15 // xvmul.w ++ case AXVMULV: ++ return 0xe90b << 15 // xvmul.d ++ case AXVMUHB: ++ return 0xe90c << 15 // xvmuh.b ++ case AXVMUHH: ++ return 0xe90d << 15 // xvmuh.h ++ case AXVMUHW: ++ return 0xe90e << 15 // xvmuh.w ++ case AXVMUHV: ++ return 0xe90f << 15 // xvmuh.d ++ case AXVMUHBU: ++ return 0xe910 << 15 // xvmuh.bu ++ case AXVMUHHU: ++ return 0xe911 << 15 // xvmuh.hu ++ case AXVMUHWU: ++ return 0xe912 << 15 // xvmuh.wu ++ case AXVMUHVU: ++ return 0xe913 << 15 // xvmuh.du + } + + if a < 0 { +-- +2.38.1 + diff --git a/0033-cmd-internal-obj-loong64-add-V-XV-DIV-B-H-W-V-U-and-.patch b/0033-cmd-internal-obj-loong64-add-V-XV-DIV-B-H-W-V-U-and-.patch new file mode 100644 index 0000000000000000000000000000000000000000..967f56d10b28d942f5868f28bd56209e5a7fbeb9 --- /dev/null +++ b/0033-cmd-internal-obj-loong64-add-V-XV-DIV-B-H-W-V-U-and-.patch @@ -0,0 +1,283 @@ +From 116a2261b3a110e6ff4f9608f447e6f07156d55f Mon Sep 17 00:00:00 2001 +From: Xiaolin Zhao +Date: Wed, 11 Dec 2024 18:08:16 +0800 +Subject: [PATCH 33/44] cmd/internal/obj/loong64: add {V,XV}DIV{B/H/W/V}[U] and + {V,XV}MOD{B/H/W/V}[U] instructions support + +Go asm syntax: + VDIV{B/H/W/V}[U] VK, VJ, VD + XVDIV{B/H/W/V}[U] XK, XJ, XD + VMOD{B/H/W/V}[U] VK, VJ, VD + XVMOD{B/H/W/V}[U] XK, XJ, XD + +Equivalent platform assembler syntax: + vdiv.{b/h/w/d}[u] vd, vj, vk + xvdiv.{b/h/w/d}[u] xd, xj, xk + vmod.{b/h/w/d}[u] vd, vj, vk + xvmod.{b/h/w/d}[u] xd, xj, xk + +Change-Id: I27e9bc8999e6525a27f0bf12b21cc896c5a2a69c +--- + .../asm/internal/asm/testdata/loong64enc1.s | 34 +++++++ + src/cmd/internal/obj/loong64/a.out.go | 34 +++++++ + src/cmd/internal/obj/loong64/anames.go | 32 +++++++ + src/cmd/internal/obj/loong64/asm.go | 96 +++++++++++++++++++ + 4 files changed, 196 insertions(+) + +diff --git a/src/cmd/asm/internal/asm/testdata/loong64enc1.s b/src/cmd/asm/internal/asm/testdata/loong64enc1.s +index c8b490234f..bbac6036cf 100644 +--- a/src/cmd/asm/internal/asm/testdata/loong64enc1.s ++++ b/src/cmd/asm/internal/asm/testdata/loong64enc1.s +@@ -775,6 +775,40 @@ lable2: + XVMUHWU X3, X2, X1 // 410c8974 + XVMUHVU X3, X2, X1 // 418c8974 + ++ // [X]VDIV{B/H/W/V}[U] and [X]VMOD{B/H/W/V}[U] instructions ++ VDIVB V1, V2, V3 // 4304e070 ++ VDIVH V1, V2, V3 // 4384e070 ++ VDIVW V1, V2, V3 // 4304e170 ++ VDIVV V1, V2, V3 // 4384e170 ++ VDIVBU V1, V2, V3 // 4304e470 ++ VDIVHU V1, V2, V3 // 4384e470 ++ VDIVWU V1, V2, V3 // 4304e570 ++ VDIVVU V1, V2, V3 // 4384e570 ++ VMODB V1, V2, V3 // 4304e270 ++ VMODH V1, V2, V3 // 4384e270 ++ VMODW V1, V2, V3 // 4304e370 ++ VMODV V1, V2, V3 // 4384e370 ++ VMODBU V1, V2, V3 // 4304e670 ++ VMODHU V1, V2, V3 // 4384e670 ++ VMODWU V1, V2, V3 // 4304e770 ++ VMODVU V1, V2, V3 // 4384e770 ++ XVDIVB X3, X2, X1 // 410ce074 ++ XVDIVH X3, X2, X1 // 418ce074 ++ XVDIVW X3, X2, X1 // 410ce174 ++ XVDIVV X3, X2, X1 // 418ce174 ++ XVDIVBU X3, X2, X1 // 410ce474 ++ XVDIVHU X3, X2, X1 // 418ce474 ++ XVDIVWU X3, X2, X1 // 410ce574 ++ XVDIVVU X3, X2, X1 // 418ce574 ++ XVMODB X3, X2, X1 // 410ce274 ++ XVMODH X3, X2, X1 // 418ce274 ++ XVMODW X3, X2, X1 // 410ce374 ++ XVMODV X3, X2, X1 // 418ce374 ++ XVMODBU X3, X2, X1 // 410ce674 ++ XVMODHU X3, X2, X1 // 418ce674 ++ XVMODWU X3, X2, X1 // 410ce774 ++ XVMODVU X3, X2, X1 // 418ce774 ++ + // MOVV C_DCON12_0, r + MOVV $0x7a90000000000000, R4 // MOVV $8831558869273542656, R4 // 04a41e03 + MOVV $0xea90000000000000, R4 // MOVV $-1544734672188080128, R4 // 04a43a03 +diff --git a/src/cmd/internal/obj/loong64/a.out.go b/src/cmd/internal/obj/loong64/a.out.go +index 95744e77a1..9164e9d59f 100644 +--- a/src/cmd/internal/obj/loong64/a.out.go ++++ b/src/cmd/internal/obj/loong64/a.out.go +@@ -783,6 +783,40 @@ const ( + AXVMUHWU + AXVMUHVU + ++ // LSX and LASX integer div and mod instructions ++ AVDIVB ++ AVDIVH ++ AVDIVW ++ AVDIVV ++ AVDIVBU ++ AVDIVHU ++ AVDIVWU ++ AVDIVVU ++ AVMODB ++ AVMODH ++ AVMODW ++ AVMODV ++ AVMODBU ++ AVMODHU ++ AVMODWU ++ AVMODVU ++ AXVDIVB ++ AXVDIVH ++ AXVDIVW ++ AXVDIVV ++ AXVDIVBU ++ AXVDIVHU ++ AXVDIVWU ++ AXVDIVVU ++ AXVMODB ++ AXVMODH ++ AXVMODW ++ AXVMODV ++ AXVMODBU ++ AXVMODHU ++ AXVMODWU ++ AXVMODVU ++ + // LSX and LASX Bit-manipulation Instructions + AVANDB + AVORB +diff --git a/src/cmd/internal/obj/loong64/anames.go b/src/cmd/internal/obj/loong64/anames.go +index d0cd3a26fa..15a264c8e2 100644 +--- a/src/cmd/internal/obj/loong64/anames.go ++++ b/src/cmd/internal/obj/loong64/anames.go +@@ -309,6 +309,38 @@ var Anames = []string{ + "XVMUHHU", + "XVMUHWU", + "XVMUHVU", ++ "VDIVB", ++ "VDIVH", ++ "VDIVW", ++ "VDIVV", ++ "VDIVBU", ++ "VDIVHU", ++ "VDIVWU", ++ "VDIVVU", ++ "VMODB", ++ "VMODH", ++ "VMODW", ++ "VMODV", ++ "VMODBU", ++ "VMODHU", ++ "VMODWU", ++ "VMODVU", ++ "XVDIVB", ++ "XVDIVH", ++ "XVDIVW", ++ "XVDIVV", ++ "XVDIVBU", ++ "XVDIVHU", ++ "XVDIVWU", ++ "XVDIVVU", ++ "XVMODB", ++ "XVMODH", ++ "XVMODW", ++ "XVMODV", ++ "XVMODBU", ++ "XVMODHU", ++ "XVMODWU", ++ "XVMODVU", + "VANDB", + "VORB", + "VXORB", +diff --git a/src/cmd/internal/obj/loong64/asm.go b/src/cmd/internal/obj/loong64/asm.go +index 7fb99f66e6..7a14137374 100644 +--- a/src/cmd/internal/obj/loong64/asm.go ++++ b/src/cmd/internal/obj/loong64/asm.go +@@ -1601,6 +1601,22 @@ func buildop(ctxt *obj.Link) { + opset(AVMUHHU, r0) + opset(AVMUHWU, r0) + opset(AVMUHVU, r0) ++ opset(AVDIVB, r0) ++ opset(AVDIVH, r0) ++ opset(AVDIVW, r0) ++ opset(AVDIVV, r0) ++ opset(AVMODB, r0) ++ opset(AVMODH, r0) ++ opset(AVMODW, r0) ++ opset(AVMODV, r0) ++ opset(AVDIVBU, r0) ++ opset(AVDIVHU, r0) ++ opset(AVDIVWU, r0) ++ opset(AVDIVVU, r0) ++ opset(AVMODBU, r0) ++ opset(AVMODHU, r0) ++ opset(AVMODWU, r0) ++ opset(AVMODVU, r0) + + case AXVANDV: + opset(AXVORV, r0) +@@ -1638,6 +1654,22 @@ func buildop(ctxt *obj.Link) { + opset(AXVMUHHU, r0) + opset(AXVMUHWU, r0) + opset(AXVMUHVU, r0) ++ opset(AXVDIVB, r0) ++ opset(AXVDIVH, r0) ++ opset(AXVDIVW, r0) ++ opset(AXVDIVV, r0) ++ opset(AXVMODB, r0) ++ opset(AXVMODH, r0) ++ opset(AXVMODW, r0) ++ opset(AXVMODV, r0) ++ opset(AXVDIVBU, r0) ++ opset(AXVDIVHU, r0) ++ opset(AXVDIVWU, r0) ++ opset(AXVDIVVU, r0) ++ opset(AXVMODBU, r0) ++ opset(AXVMODHU, r0) ++ opset(AXVMODWU, r0) ++ opset(AXVMODVU, r0) + + case AVSLLB: + opset(AVSRLB, r0) +@@ -3109,6 +3141,70 @@ func (c *ctxt0) oprrr(a obj.As) uint32 { + return 0xe912 << 15 // xvmuh.wu + case AXVMUHVU: + return 0xe913 << 15 // xvmuh.du ++ case AVDIVB: ++ return 0xe1c0 << 15 // vdiv.b ++ case AVDIVH: ++ return 0xe1c1 << 15 // vdiv.h ++ case AVDIVW: ++ return 0xe1c2 << 15 // vdiv.w ++ case AVDIVV: ++ return 0xe1c3 << 15 // vdiv.d ++ case AVMODB: ++ return 0xe1c4 << 15 // vmod.b ++ case AVMODH: ++ return 0xe1c5 << 15 // vmod.h ++ case AVMODW: ++ return 0xe1c6 << 15 // vmod.w ++ case AVMODV: ++ return 0xe1c7 << 15 // vmod.d ++ case AVDIVBU: ++ return 0xe1c8 << 15 // vdiv.bu ++ case AVDIVHU: ++ return 0xe1c9 << 15 // vdiv.hu ++ case AVDIVWU: ++ return 0xe1ca << 15 // vdiv.wu ++ case AVDIVVU: ++ return 0xe1cb << 15 // vdiv.du ++ case AVMODBU: ++ return 0xe1cc << 15 // vmod.bu ++ case AVMODHU: ++ return 0xe1cd << 15 // vmod.hu ++ case AVMODWU: ++ return 0xe1ce << 15 // vmod.wu ++ case AVMODVU: ++ return 0xe1cf << 15 // vmod.du ++ case AXVDIVB: ++ return 0xe9c0 << 15 // xvdiv.b ++ case AXVDIVH: ++ return 0xe9c1 << 15 // xvdiv.h ++ case AXVDIVW: ++ return 0xe9c2 << 15 // xvdiv.w ++ case AXVDIVV: ++ return 0xe9c3 << 15 // xvdiv.d ++ case AXVMODB: ++ return 0xe9c4 << 15 // xvmod.b ++ case AXVMODH: ++ return 0xe9c5 << 15 // xvmod.h ++ case AXVMODW: ++ return 0xe9c6 << 15 // xvmod.w ++ case AXVMODV: ++ return 0xe9c7 << 15 // xvmod.d ++ case AXVDIVBU: ++ return 0xe9c8 << 15 // xvdiv.bu ++ case AXVDIVHU: ++ return 0xe9c9 << 15 // xvdiv.hu ++ case AXVDIVWU: ++ return 0xe9ca << 15 // xvdiv.wu ++ case AXVDIVVU: ++ return 0xe9cb << 15 // xvdiv.du ++ case AXVMODBU: ++ return 0xe9cc << 15 // xvmod.bu ++ case AXVMODHU: ++ return 0xe9cd << 15 // xvmod.hu ++ case AXVMODWU: ++ return 0xe9ce << 15 // xvmod.wu ++ case AXVMODVU: ++ return 0xe9cf << 15 // xvmod.du + } + + if a < 0 { +-- +2.38.1 + diff --git a/0034-cmd-internal-obj-loong64-add-V-XV-BITCLR-BITSET-BITR.patch b/0034-cmd-internal-obj-loong64-add-V-XV-BITCLR-BITSET-BITR.patch new file mode 100644 index 0000000000000000000000000000000000000000..2a2d4b13d8efbdfe73ea616c881cc4dc7968ad49 --- /dev/null +++ b/0034-cmd-internal-obj-loong64-add-V-XV-BITCLR-BITSET-BITR.patch @@ -0,0 +1,341 @@ +From 054df785d79675c02f6bd2ad3ace9f1ce5874e84 Mon Sep 17 00:00:00 2001 +From: Xiaolin Zhao +Date: Thu, 12 Dec 2024 10:54:00 +0800 +Subject: [PATCH 34/44] cmd/internal/obj/loong64: add + {V,XV}{BITCLR/BITSET/BITREV}[I].{B/H/W/D} instructions support + +Go asm syntax: + V{BITCLR/BITSET/BITREV}{B/H/W/V} $1, V2, V3 + XV{BITCLR/BITSET/BITREV}{B/H/W/V} $1, X2, X3 + V{BITCLR/BITSET/BITREV}{B/H/W/V} VK, VJ, VD + XV{BITCLR/BITSET/BITREV}{B/H/W/V} XK, XJ, XD + +Equivalent platform assembler syntax: + v{bitclr/bitset/bitrev}i.{b/h/w/d} v3, v2, $1 + xv{bitclr/bitset/bitrev}i.{b/h/w/d} x3, x2, $1 + v{bitclr/bitset/bitrev}.{b/h/w/d} vd, vj, vk + xv{bitclr/bitset/bitrev}.{b/h/w/d} xd, xj, xk + +Change-Id: Id44e6cb7c22d650bb6b4d9f6faee5dcda4edb24e +--- + .../asm/internal/asm/testdata/loong64enc1.s | 50 ++++++++ + src/cmd/internal/obj/loong64/a.out.go | 25 ++++ + src/cmd/internal/obj/loong64/anames.go | 24 ++++ + src/cmd/internal/obj/loong64/asm.go | 120 ++++++++++++++++++ + 4 files changed, 219 insertions(+) + +diff --git a/src/cmd/asm/internal/asm/testdata/loong64enc1.s b/src/cmd/asm/internal/asm/testdata/loong64enc1.s +index bbac6036cf..19070c89ef 100644 +--- a/src/cmd/asm/internal/asm/testdata/loong64enc1.s ++++ b/src/cmd/asm/internal/asm/testdata/loong64enc1.s +@@ -809,6 +809,56 @@ lable2: + XVMODWU X3, X2, X1 // 410ce774 + XVMODVU X3, X2, X1 // 418ce774 + ++ // [X]{VBITCLR/VBITSET/VBITREV}{B,H,W,V} instructions ++ VBITCLRB V1, V2, V3 // 43040c71 ++ VBITCLRH V1, V2, V3 // 43840c71 ++ VBITCLRW V1, V2, V3 // 43040d71 ++ VBITCLRV V1, V2, V3 // 43840d71 ++ VBITSETB V1, V2, V3 // 43040e71 ++ VBITSETH V1, V2, V3 // 43840e71 ++ VBITSETW V1, V2, V3 // 43040f71 ++ VBITSETV V1, V2, V3 // 43840f71 ++ VBITREVB V1, V2, V3 // 43041071 ++ VBITREVH V1, V2, V3 // 43841071 ++ VBITREVW V1, V2, V3 // 43041171 ++ VBITREVV V1, V2, V3 // 43841171 ++ XVBITCLRB X3, X2, X1 // 410c0c75 ++ XVBITCLRH X3, X2, X1 // 418c0c75 ++ XVBITCLRW X3, X2, X1 // 410c0d75 ++ XVBITCLRV X3, X2, X1 // 418c0d75 ++ XVBITSETB X3, X2, X1 // 410c0e75 ++ XVBITSETH X3, X2, X1 // 418c0e75 ++ XVBITSETW X3, X2, X1 // 410c0f75 ++ XVBITSETV X3, X2, X1 // 418c0f75 ++ XVBITREVB X3, X2, X1 // 410c1075 ++ XVBITREVH X3, X2, X1 // 418c1075 ++ XVBITREVW X3, X2, X1 // 410c1175 ++ XVBITREVV X3, X2, X1 // 418c1175 ++ VBITCLRB $7, V2, V3 // 433c1073 ++ VBITCLRH $15, V2, V3 // 437c1073 ++ VBITCLRW $31, V2, V3 // 43fc1073 ++ VBITCLRV $63, V2, V3 // 43fc1173 ++ VBITSETB $7, V2, V3 // 433c1473 ++ VBITSETH $15, V2, V3 // 437c1473 ++ VBITSETW $31, V2, V3 // 43fc1473 ++ VBITSETV $63, V2, V3 // 43fc1573 ++ VBITREVB $7, V2, V3 // 433c1873 ++ VBITREVH $15, V2, V3 // 437c1873 ++ VBITREVW $31, V2, V3 // 43fc1873 ++ VBITREVV $63, V2, V3 // 43fc1973 ++ XVBITCLRB $7, X2, X1 // 413c1077 ++ XVBITCLRH $15, X2, X1 // 417c1077 ++ XVBITCLRW $31, X2, X1 // 41fc1077 ++ XVBITCLRV $63, X2, X1 // 41fc1177 ++ XVBITSETB $7, X2, X1 // 413c1477 ++ XVBITSETH $15, X2, X1 // 417c1477 ++ XVBITSETW $31, X2, X1 // 41fc1477 ++ XVBITSETV $63, X2, X1 // 41fc1577 ++ XVBITREVB $7, X2, X1 // 413c1877 ++ XVBITREVH $15, X2, X1 // 417c1877 ++ XVBITREVW $31, X2, X1 // 41fc1877 ++ XVBITREVV $63, X2, X1 // 41fc1977 ++ + // MOVV C_DCON12_0, r + MOVV $0x7a90000000000000, R4 // MOVV $8831558869273542656, R4 // 04a41e03 + MOVV $0xea90000000000000, R4 // MOVV $-1544734672188080128, R4 // 04a43a03 +diff --git a/src/cmd/internal/obj/loong64/a.out.go b/src/cmd/internal/obj/loong64/a.out.go +index 9164e9d59f..1fadbc648a 100644 +--- a/src/cmd/internal/obj/loong64/a.out.go ++++ b/src/cmd/internal/obj/loong64/a.out.go +@@ -881,6 +881,31 @@ const ( + AXVPCNTW + AXVPCNTV + ++ AVBITCLRB ++ AVBITCLRH ++ AVBITCLRW ++ AVBITCLRV ++ AVBITSETB ++ AVBITSETH ++ AVBITSETW ++ AVBITSETV ++ AVBITREVB ++ AVBITREVH ++ AVBITREVW ++ AVBITREVV ++ AXVBITCLRB ++ AXVBITCLRH ++ AXVBITCLRW ++ AXVBITCLRV ++ AXVBITSETB ++ AXVBITSETH ++ AXVBITSETW ++ AXVBITSETV ++ AXVBITREVB ++ AXVBITREVH ++ AXVBITREVW ++ AXVBITREVV ++ + // LSX and LASX floating point instructions + AVFSQRTF + AVFSQRTD +diff --git a/src/cmd/internal/obj/loong64/anames.go b/src/cmd/internal/obj/loong64/anames.go +index 15a264c8e2..aee0da0a6e 100644 +--- a/src/cmd/internal/obj/loong64/anames.go ++++ b/src/cmd/internal/obj/loong64/anames.go +@@ -401,6 +401,30 @@ var Anames = []string{ + "XVPCNTH", + "XVPCNTW", + "XVPCNTV", ++ "VBITCLRB", ++ "VBITCLRH", ++ "VBITCLRW", ++ "VBITCLRV", ++ "VBITSETB", ++ "VBITSETH", ++ "VBITSETW", ++ "VBITSETV", ++ "VBITREVB", ++ "VBITREVH", ++ "VBITREVW", ++ "VBITREVV", ++ "XVBITCLRB", ++ "XVBITCLRH", ++ "XVBITCLRW", ++ "XVBITCLRV", ++ "XVBITSETB", ++ "XVBITSETH", ++ "XVBITSETW", ++ "XVBITSETV", ++ "XVBITREVB", ++ "XVBITREVH", ++ "XVBITREVW", ++ "XVBITREVV", + "VFSQRTF", + "VFSQRTD", + "VFRECIPF", +diff --git a/src/cmd/internal/obj/loong64/asm.go b/src/cmd/internal/obj/loong64/asm.go +index 7a14137374..657d32ae81 100644 +--- a/src/cmd/internal/obj/loong64/asm.go ++++ b/src/cmd/internal/obj/loong64/asm.go +@@ -1675,41 +1675,65 @@ func buildop(ctxt *obj.Link) { + opset(AVSRLB, r0) + opset(AVSRAB, r0) + opset(AVROTRB, r0) ++ opset(AVBITCLRB, r0) ++ opset(AVBITSETB, r0) ++ opset(AVBITREVB, r0) + + case AXVSLLB: + opset(AXVSRLB, r0) + opset(AXVSRAB, r0) + opset(AXVROTRB, r0) ++ opset(AXVBITCLRB, r0) ++ opset(AXVBITSETB, r0) ++ opset(AXVBITREVB, r0) + + case AVSLLH: + opset(AVSRLH, r0) + opset(AVSRAH, r0) + opset(AVROTRH, r0) ++ opset(AVBITCLRH, r0) ++ opset(AVBITSETH, r0) ++ opset(AVBITREVH, r0) + + case AXVSLLH: + opset(AXVSRLH, r0) + opset(AXVSRAH, r0) + opset(AXVROTRH, r0) ++ opset(AXVBITCLRH, r0) ++ opset(AXVBITSETH, r0) ++ opset(AXVBITREVH, r0) + + case AVSLLW: + opset(AVSRLW, r0) + opset(AVSRAW, r0) + opset(AVROTRW, r0) ++ opset(AVBITCLRW, r0) ++ opset(AVBITSETW, r0) ++ opset(AVBITREVW, r0) + + case AXVSLLW: + opset(AXVSRLW, r0) + opset(AXVSRAW, r0) + opset(AXVROTRW, r0) ++ opset(AXVBITCLRW, r0) ++ opset(AXVBITSETW, r0) ++ opset(AXVBITREVW, r0) + + case AVSLLV: + opset(AVSRLV, r0) + opset(AVSRAV, r0) + opset(AVROTRV, r0) ++ opset(AVBITCLRV, r0) ++ opset(AVBITSETV, r0) ++ opset(AVBITREVV, r0) + + case AXVSLLV: + opset(AXVSRLV, r0) + opset(AXVSRAV, r0) + opset(AXVROTRV, r0) ++ opset(AXVBITCLRV, r0) ++ opset(AXVBITSETV, r0) ++ opset(AXVBITREVV, r0) + + case AVPCNTB: + opset(AVPCNTH, r0) +@@ -3205,6 +3229,54 @@ func (c *ctxt0) oprrr(a obj.As) uint32 { + return 0xe9ce << 15 // xvmod.wu + case AXVMODVU: + return 0xe9cf << 15 // xvmod.du ++ case AVBITCLRB: ++ return 0xe218 << 15 // vbitclr.b ++ case AVBITCLRH: ++ return 0xe219 << 15 // vbitclr.h ++ case AVBITCLRW: ++ return 0xe21a << 15 // vbitclr.w ++ case AVBITCLRV: ++ return 0xe21b << 15 // vbitclr.d ++ case AVBITSETB: ++ return 0xe21c << 15 // vbitset.b ++ case AVBITSETH: ++ return 0xe21d << 15 // vbitset.h ++ case AVBITSETW: ++ return 0xe21e << 15 // vbitset.w ++ case AVBITSETV: ++ return 0xe21f << 15 // vbitset.d ++ case AVBITREVB: ++ return 0xe220 << 15 // vbitrev.b ++ case AVBITREVH: ++ return 0xe221 << 15 // vbitrev.h ++ case AVBITREVW: ++ return 0xe222 << 15 // vbitrev.w ++ case AVBITREVV: ++ return 0xe223 << 15 // vbitrev.d ++ case AXVBITCLRB: ++ return 0xea18 << 15 // xvbitclr.b ++ case AXVBITCLRH: ++ return 0xea19 << 15 // xvbitclr.h ++ case AXVBITCLRW: ++ return 0xea1a << 15 // xvbitclr.w ++ case AXVBITCLRV: ++ return 0xea1b << 15 // xvbitclr.d ++ case AXVBITSETB: ++ return 0xea1c << 15 // xvbitset.b ++ case AXVBITSETH: ++ return 0xea1d << 15 // xvbitset.h ++ case AXVBITSETW: ++ return 0xea1e << 15 // xvbitset.w ++ case AXVBITSETV: ++ return 0xea1f << 15 // xvbitset.d ++ case AXVBITREVB: ++ return 0xea20 << 15 // xvbitrev.b ++ case AXVBITREVH: ++ return 0xea21 << 15 // xvbitrev.h ++ case AXVBITREVW: ++ return 0xea22 << 15 // xvbitrev.w ++ case AXVBITREVV: ++ return 0xea23 << 15 // xvbitrev.d + } + + if a < 0 { +@@ -3668,6 +3740,54 @@ func (c *ctxt0) opirr(a obj.As) uint32 { + return 0x1DCD<<18 | 0x1<<15 // xvsrai.w + case AXVSRAV: + return 0x1DCD<<18 | 0x1<<16 // xvsrai.d ++ case AVBITCLRB: ++ return 0x1CC4<<18 | 0x1<<13 // vbitclri.b ++ case AVBITCLRH: ++ return 0x1CC4<<18 | 0x1<<14 // vbitclri.h ++ case AVBITCLRW: ++ return 0x1CC4<<18 | 0x1<<15 // vbitclri.w ++ case AVBITCLRV: ++ return 0x1CC4<<18 | 0x1<<16 // vbitclri.d ++ case AVBITSETB: ++ return 0x1CC5<<18 | 0x1<<13 // vbitseti.b ++ case AVBITSETH: ++ return 0x1CC5<<18 | 0x1<<14 // vbitseti.h ++ case AVBITSETW: ++ return 0x1CC5<<18 | 0x1<<15 // vbitseti.w ++ case AVBITSETV: ++ return 0x1CC5<<18 | 0x1<<16 // vbitseti.d ++ case AVBITREVB: ++ return 0x1CC6<<18 | 0x1<<13 // vbitrevi.b ++ case AVBITREVH: ++ return 0x1CC6<<18 | 0x1<<14 // vbitrevi.h ++ case AVBITREVW: ++ return 0x1CC6<<18 | 0x1<<15 // vbitrevi.w ++ case AVBITREVV: ++ return 0x1CC6<<18 | 0x1<<16 // vbitrevi.d ++ case AXVBITCLRB: ++ return 0x1DC4<<18 | 0x1<<13 // xvbitclri.b ++ case AXVBITCLRH: ++ return 0x1DC4<<18 | 0x1<<14 // xvbitclri.h ++ case AXVBITCLRW: ++ return 0x1DC4<<18 | 0x1<<15 // xvbitclri.w ++ case AXVBITCLRV: ++ return 0x1DC4<<18 | 0x1<<16 // xvbitclri.d ++ case AXVBITSETB: ++ return 0x1DC5<<18 | 0x1<<13 // xvbitseti.b ++ case AXVBITSETH: ++ return 0x1DC5<<18 | 0x1<<14 // xvbitseti.h ++ case AXVBITSETW: ++ return 0x1DC5<<18 | 0x1<<15 // xvbitseti.w ++ case AXVBITSETV: ++ return 0x1DC5<<18 | 0x1<<16 // xvbitseti.d ++ case AXVBITREVB: ++ return 0x1DC6<<18 | 0x1<<13 // xvbitrevi.b ++ case AXVBITREVH: ++ return 0x1DC6<<18 | 0x1<<14 // xvbitrevi.h ++ case AXVBITREVW: ++ return 0x1DC6<<18 | 0x1<<15 // xvbitrevi.w ++ case AXVBITREVV: ++ return 0x1DC6<<18 | 0x1<<16 // xvbitrevi.d + } + + if a < 0 { +-- +2.38.1 + diff --git a/0035-crypto-chacha20-add-loong64-SIMD-implementation.patch b/0035-crypto-chacha20-add-loong64-SIMD-implementation.patch new file mode 100644 index 0000000000000000000000000000000000000000..2c8eb2b11612f20bef6bf8f08996bedaa193b3b8 --- /dev/null +++ b/0035-crypto-chacha20-add-loong64-SIMD-implementation.patch @@ -0,0 +1,490 @@ +From d6bdc012b1c105a007d0fb5d7d1642f1a5653b1d Mon Sep 17 00:00:00 2001 +From: Xiaolin Zhao +Date: Fri, 13 Dec 2024 17:09:31 +0800 +Subject: [PATCH 35/44] crypto/chacha20: add loong64 SIMD implementation +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The performance of chacha20 has been greatly improved. + +goos: linux +goarch: loong64 +pkg: golang.org/x/crypto/chacha20 +cpu: Loongson-3A6000 @ 2500.00MHz + | bench.old | bench.new | + | sec/op | sec/op vs base | +ChaCha20/64 171.9n ± 0% 159.3n ± 0% -7.33% (p=0.000 n=20) +ChaCha20/256 592.2n ± 0% 142.8n ± 0% -75.89% (p=0.000 n=20) +ChaCha20/10x25 981.5n ± 0% 518.8n ± 0% -47.14% (p=0.000 n=20) +ChaCha20/4096 8.991µ ± 0% 1.732µ ± 0% -80.74% (p=0.000 n=20) +ChaCha20/100x40 10.651µ ± 0% 5.135µ ± 0% -51.79% (p=0.000 n=20) +ChaCha20/65536 143.43µ ± 0% 28.76µ ± 0% -79.95% (p=0.000 n=20) +ChaCha20/1000x65 146.17µ ± 0% 37.13µ ± 0% -74.60% (p=0.000 n=20) +geomean 5.721µ 1.962µ -65.70% + + | bench.old | bench.new | + | B/s | B/s vs base | +ChaCha20/64 355.1Mi ± 0% 383.1Mi ± 0% +7.89% (p=0.000 n=20) +ChaCha20/256 412.2Mi ± 0% 1710.2Mi ± 0% +314.86% (p=0.000 n=20) +ChaCha20/10x25 242.9Mi ± 0% 459.6Mi ± 0% +89.19% (p=0.000 n=20) +ChaCha20/4096 434.5Mi ± 0% 2255.8Mi ± 0% +419.22% (p=0.000 n=20) +ChaCha20/100x40 358.1Mi ± 0% 742.9Mi ± 0% +107.44% (p=0.000 n=20) +ChaCha20/65536 435.8Mi ± 0% 2173.2Mi ± 0% +398.72% (p=0.000 n=20) +ChaCha20/1000x65 424.1Mi ± 0% 1669.4Mi ± 0% +293.64% (p=0.000 n=20) +geomean 373.9Mi 1.065Gi +191.55% + +goos: linux +goarch: loong64 +pkg: golang.org/x/crypto/chacha20 +cpu: Loongson-3A5000 @ 2500.00MHz + | bench.old | bench.new | + | sec/op | sec/op vs base | +ChaCha20/64 234.5n ± 0% 295.8n ± 0% +26.14% (p=0.000 n=20) +ChaCha20/256 782.0n ± 0% 274.6n ± 0% -64.88% (p=0.000 n=20) +ChaCha20/10x25 1340.0n ± 0% 752.7n ± 0% -43.83% (p=0.000 n=20) +ChaCha20/4096 11.744µ ± 0% 3.455µ ± 0% -70.58% (p=0.000 n=20) +ChaCha20/100x40 14.151µ ± 0% 7.435µ ± 0% -47.46% (p=0.000 n=20) +ChaCha20/65536 188.05µ ± 0% 54.33µ ± 0% -71.11% (p=0.000 n=20) +ChaCha20/1000x65 191.44µ ± 0% 66.29µ ± 0% -65.37% (p=0.000 n=20) +geomean 7.604µ 3.436µ -54.81% + + | bench.old | bench.new | + | B/s | B/s vs base | +ChaCha20/64 260.3Mi ± 0% 206.3Mi ± 0% -20.73% (p=0.000 n=20) +ChaCha20/256 312.2Mi ± 0% 888.9Mi ± 0% +184.75% (p=0.000 n=20) +ChaCha20/10x25 177.9Mi ± 0% 316.8Mi ± 0% +78.08% (p=0.000 n=20) +ChaCha20/4096 332.6Mi ± 0% 1130.8Mi ± 0% +239.95% (p=0.000 n=20) +ChaCha20/100x40 269.6Mi ± 0% 513.1Mi ± 0% +90.34% (p=0.000 n=20) +ChaCha20/65536 332.4Mi ± 0% 1150.5Mi ± 0% +246.16% (p=0.000 n=20) +ChaCha20/1000x65 323.8Mi ± 0% 935.2Mi ± 0% +188.81% (p=0.000 n=20) +geomean 281.3Mi 622.6Mi +121.31% + +Change-Id: Iab4934d78b845e3b248bd5d0a9a62e4e9c516831 +--- + .../x/crypto/chacha20/chacha_loong64.go | 17 + + .../x/crypto/chacha20/chacha_loong64.s | 374 ++++++++++++++++++ + .../x/crypto/chacha20/chacha_noasm.go | 2 +- + 3 files changed, 392 insertions(+), 1 deletion(-) + create mode 100644 src/vendor/golang.org/x/crypto/chacha20/chacha_loong64.go + create mode 100644 src/vendor/golang.org/x/crypto/chacha20/chacha_loong64.s + +diff --git a/src/vendor/golang.org/x/crypto/chacha20/chacha_loong64.go b/src/vendor/golang.org/x/crypto/chacha20/chacha_loong64.go +new file mode 100644 +index 0000000000..d0f5d909fc +--- /dev/null ++++ b/src/vendor/golang.org/x/crypto/chacha20/chacha_loong64.go +@@ -0,0 +1,17 @@ ++// Copyright 2024 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 gc && !purego ++ ++package chacha20 ++ ++const bufSize = 256 ++ ++//go:noescape ++func xorKeyStreamVX(dst, src []byte, key *[8]uint32, nonce *[3]uint32, counter *uint32) ++ ++func (c *Cipher) xorKeyStreamBlocks(dst, src []byte) { ++ // add cpu.Loong64.HasLSX check TODO ++ xorKeyStreamVX(dst, src, &c.key, &c.nonce, &c.counter) ++} +diff --git a/src/vendor/golang.org/x/crypto/chacha20/chacha_loong64.s b/src/vendor/golang.org/x/crypto/chacha20/chacha_loong64.s +new file mode 100644 +index 0000000000..883c8d992a +--- /dev/null ++++ b/src/vendor/golang.org/x/crypto/chacha20/chacha_loong64.s +@@ -0,0 +1,374 @@ ++// Copyright 2024 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. ++ ++// derived from chacha_arm64.s ++ ++//go:build gc && !purego ++ ++#include "textflag.h" ++ ++DATA ·constants+0x00(SB)/4, $0x61707865 ++DATA ·constants+0x04(SB)/4, $0x3320646e ++DATA ·constants+0x08(SB)/4, $0x79622d32 ++DATA ·constants+0x0c(SB)/4, $0x6b206574 ++GLOBL ·constants(SB), NOPTR|RODATA, $32 ++ ++DATA ·incRotMatrix+0x00(SB)/4, $0x00000000 ++DATA ·incRotMatrix+0x04(SB)/4, $0x00000001 ++DATA ·incRotMatrix+0x08(SB)/4, $0x00000002 ++DATA ·incRotMatrix+0x0c(SB)/4, $0x00000003 ++GLOBL ·incRotMatrix(SB), NOPTR|RODATA, $32 ++ ++#define NUM_ROUNDS 10 ++ ++// func xorKeyStreamVX(dst, src []byte, key *[8]uint32, nonce *[3]uint32, counter *uint32) ++TEXT ·xorKeyStreamVX(SB), NOSPLIT, $0 ++ MOVV dst+0(FP), R4 ++ MOVV src+24(FP), R5 ++ MOVV src_len+32(FP), R6 ++ MOVV key+48(FP), R7 ++ MOVV nonce+56(FP), R8 ++ MOVV counter+64(FP), R9 ++ ++ MOVV $·constants(SB), R10 ++ MOVV $·incRotMatrix(SB), R11 ++ ++ MOVW (R9), R12 ++ ++loop: ++ MOVV $NUM_ROUNDS, R15 ++ // load 4-32bit data from incRotMatrix added to counter ++ VMOVQ (R11), V30 ++ ++ // load contants ++ // VLDREPL.W $0, R10, V0 ++ WORD $0x30200140 ++ // VLDREPL.W $1, R10, V1 ++ WORD $0x30200541 ++ // VLDREPL.W $2, R10, V2 ++ WORD $0x30200942 ++ // VLDREPL.W $3, R10, V3 ++ WORD $0x30200d43 ++ ++ // load keys ++ // VLDREPL.W $0, R7, V4 ++ WORD $0x302000e4 ++ // VLDREPL.W $1, R7, V5 ++ WORD $0x302004e5 ++ // VLDREPL.W $2, R7, V6 ++ WORD $0x302008e6 ++ // VLDREPL.W $3, R7, V7 ++ WORD $0x30200ce7 ++ // VLDREPL.W $4, R7, V8 ++ WORD $0x302010e8 ++ // VLDREPL.W $5, R7, V9 ++ WORD $0x302014e9 ++ // VLDREPL.W $6, R7, V10 ++ WORD $0x302018ea ++ // VLDREPL.W $7, R7, V11 ++ WORD $0x30201ceb ++ ++ // load counter + nonce ++ // VLDREPL.W $0, R9, V12 ++ WORD $0x3020012c ++ ++ // VLDREPL.W $0, R8, V13 ++ WORD $0x3020010d ++ // VLDREPL.W $1, R8, V14 ++ WORD $0x3020050e ++ // VLDREPL.W $2, R8, V15 ++ WORD $0x3020090f ++ ++ // update counter ++ VADDW V30, V12, V12 ++ ++chacha: ++ // V0..V3 += V4..V7 ++ // V12..V15 <<<= ((V12..V15 XOR V0..V3), 16) ++ VADDW V0, V4, V0 ++ VADDW V1, V5, V1 ++ VADDW V2, V6, V2 ++ VADDW V3, V7, V3 ++ VXORV V12, V0, V12 ++ VXORV V13, V1, V13 ++ VXORV V14, V2, V14 ++ VXORV V15, V3, V15 ++ VROTRW $16, V12, V12 ++ VROTRW $16, V13, V13 ++ VROTRW $16, V14, V14 ++ VROTRW $16, V15, V15 ++ ++ // V8..V11 += V12..V15 ++ // V4..V7 <<<= ((V4..V7 XOR V8..V11), 12) ++ VADDW V8, V12, V8 ++ VADDW V9, V13, V9 ++ VADDW V10, V14, V10 ++ VADDW V11, V15, V11 ++ VXORV V4, V8, V4 ++ VXORV V5, V9, V5 ++ VXORV V6, V10, V6 ++ VXORV V7, V11, V7 ++ VROTRW $20, V4, V4 ++ VROTRW $20, V5, V5 ++ VROTRW $20, V6, V6 ++ VROTRW $20, V7, V7 ++ ++ // V0..V3 += V4..V7 ++ // V12..V15 <<<= ((V12..V15 XOR V0..V3), 8) ++ VADDW V0, V4, V0 ++ VADDW V1, V5, V1 ++ VADDW V2, V6, V2 ++ VADDW V3, V7, V3 ++ VXORV V12, V0, V12 ++ VXORV V13, V1, V13 ++ VXORV V14, V2, V14 ++ VXORV V15, V3, V15 ++ VROTRW $24, V12, V12 ++ VROTRW $24, V13, V13 ++ VROTRW $24, V14, V14 ++ VROTRW $24, V15, V15 ++ ++ // V8..V11 += V12..V15 ++ // V4..V7 <<<= ((V4..V7 XOR V8..V11), 7) ++ VADDW V12, V8, V8 ++ VADDW V13, V9, V9 ++ VADDW V14, V10, V10 ++ VADDW V15, V11, V11 ++ VXORV V4, V8, V4 ++ VXORV V5, V9, V5 ++ VXORV V6, V10, V6 ++ VXORV V7, V11, V7 ++ VROTRW $25, V4, V4 ++ VROTRW $25, V5, V5 ++ VROTRW $25, V6, V6 ++ VROTRW $25, V7, V7 ++ ++ // V0..V3 += V5..V7, V4 ++ // V15,V12-V14 <<<= ((V15,V12-V14 XOR V0..V3), 16) ++ VADDW V0, V5, V0 ++ VADDW V1, V6, V1 ++ VADDW V2, V7, V2 ++ VADDW V3, V4, V3 ++ VXORV V15, V0, V15 ++ VXORV V12, V1, V12 ++ VXORV V13, V2, V13 ++ VXORV V14, V3, V14 ++ VROTRW $16, V15, V15 ++ VROTRW $16, V12, V12 ++ VROTRW $16, V13, V13 ++ VROTRW $16, V14, V14 ++ ++ // V10,V11,V8,V9 += V15,V12,V13,V14 ++ // V5,V6,V7,V4 <<<= ((V5,V6,V7,V4 XOR V10,V11,V8,V9), 12) ++ VADDW V10, V15, V10 ++ VADDW V11, V12, V11 ++ VADDW V8, V13, V8 ++ VADDW V9, V14, V9 ++ VXORV V5, V10, V5 ++ VXORV V6, V11, V6 ++ VXORV V7, V8, V7 ++ VXORV V4, V9, V4 ++ VROTRW $20, V5, V5 ++ VROTRW $20, V6, V6 ++ VROTRW $20, V7, V7 ++ VROTRW $20, V4, V4 ++ ++ // V0..V3 += V5..V7, V4 ++ // V15,V12-V14 <<<= ((V15,V12-V14 XOR V0..V3), 8) ++ VADDW V5, V0, V0 ++ VADDW V6, V1, V1 ++ VADDW V7, V2, V2 ++ VADDW V4, V3, V3 ++ VXORV V15, V0, V15 ++ VXORV V12, V1, V12 ++ VXORV V13, V2, V13 ++ VXORV V14, V3, V14 ++ VROTRW $24, V15, V15 ++ VROTRW $24, V12, V12 ++ VROTRW $24, V13, V13 ++ VROTRW $24, V14, V14 ++ ++ // V10,V11,V8,V9 += V15,V12,V13,V14 ++ // V5,V6,V7,V4 <<<= ((V5,V6,V7,V4 XOR V10,V11,V8,V9), 7) ++ VADDW V15, V10, V10 ++ VADDW V12, V11, V11 ++ VADDW V13, V8, V8 ++ VADDW V14, V9, V9 ++ VXORV V5, V10, V5 ++ VXORV V6, V11, V6 ++ VXORV V7, V8, V7 ++ VXORV V4, V9, V4 ++ VROTRW $25, V5, V5 ++ VROTRW $25, V6, V6 ++ VROTRW $25, V7, V7 ++ VROTRW $25, V4, V4 ++ ++ SUBV $1, R15 ++ BNE R15, R0, chacha ++ ++ // load origin contants ++ // VLDREPL.W $0, R10, V16 ++ WORD $0x30200150 ++ // VLDREPL.W $1, R10, V17 ++ WORD $0x30200551 ++ // VLDREPL.W $2, R10, V18 ++ WORD $0x30200952 ++ // VLDREPL.W $3, R10, V19 ++ WORD $0x30200d53 ++ ++ // load origin keys ++ // VLDREPL.W $0, R7, V20 ++ WORD $0x302000f4 ++ // VLDREPL.W $1, R7, V21 ++ WORD $0x302004f5 ++ // VLDREPL.W $2, R7, V22 ++ WORD $0x302008f6 ++ // VLDREPL.W $3, R7, V23 ++ WORD $0x30200cf7 ++ // VLDREPL.W $4, R7, V24 ++ WORD $0x302010f8 ++ // VLDREPL.W $5, R7, V25 ++ WORD $0x302014f9 ++ // VLDREPL.W $6, R7, V26 ++ WORD $0x302018fa ++ // VLDREPL.W $7, R7, V27 ++ WORD $0x30201cfb ++ ++ // add back the initial state to generate the key stream ++ VADDW V30, V12, V12 // update counter in advance to prevent V30 from being overwritten ++ VADDW V16, V0, V0 ++ VADDW V17, V1, V1 ++ VADDW V18, V2, V2 ++ VADDW V19, V3, V3 ++ ++ // load origin counter + nonce ++ // VLDREPL.W $0, R9, V28 ++ WORD $0x3020013c ++ // VLDREPL.W $0, R8, V29 ++ WORD $0x3020011d ++ // VLDREPL.W $1, R8, V30 ++ WORD $0x3020051e ++ // VLDREPL.W $2, R8, V31 ++ WORD $0x3020091f ++ ++ VADDW V20, V4, V4 ++ VADDW V21, V5, V5 ++ VADDW V22, V6, V6 ++ VADDW V23, V7, V7 ++ VADDW V24, V8, V8 ++ VADDW V25, V9, V9 ++ VADDW V26, V10, V10 ++ VADDW V27, V11, V11 ++ VADDW V28, V12, V12 ++ VADDW V29, V13, V13 ++ VADDW V30, V14, V14 ++ VADDW V31, V15, V15 ++ ++ // shuffle ++ VILVLW V0, V1, V16 ++ VILVHW V0, V1, V17 ++ VILVLW V2, V3, V18 ++ VILVHW V2, V3, V19 ++ VILVLW V4, V5 ,V20 ++ VILVHW V4, V5, V21 ++ VILVLW V6, V7, V22 ++ VILVHW V6, V7, V23 ++ VILVLW V8, V9, V24 ++ VILVHW V8, V9, V25 ++ VILVLW V10, V11, V26 ++ VILVHW V10, V11, V27 ++ VILVLW V12, V13, V28 ++ VILVHW V12, V13, V29 ++ VILVLW V14, V15, V30 ++ VILVHW V14, V15, V31 ++ VILVLV V16, V18, V0 ++ VILVHV V16, V18, V4 ++ VILVLV V17, V19, V8 ++ VILVHV V17, V19, V12 ++ ++ // load src data from R5 ++ VMOVQ 0(R5), V16 ++ VMOVQ 16(R5), V17 ++ VMOVQ 32(R5), V18 ++ VMOVQ 48(R5), V19 ++ ++ VILVLV V20, V22, V1 ++ VILVHV V20, V22, V5 ++ VILVLV V21, V23, V9 ++ VILVHV V21, V23, V13 ++ ++ VMOVQ 64(R5), V20 ++ VMOVQ 80(R5), V21 ++ VMOVQ 96(R5), V22 ++ VMOVQ 112(R5), V23 ++ ++ VILVLV V24, V26, V2 ++ VILVHV V24, V26, V6 ++ VILVLV V25, V27, V10 ++ VILVHV V25, V27, V14 ++ ++ VMOVQ 128(R5), V24 ++ VMOVQ 144(R5), V25 ++ VMOVQ 160(R5), V26 ++ VMOVQ 176(R5), V27 ++ ++ VILVLV V28, V30, V3 ++ VILVHV V28, V30, V7 ++ VILVLV V29, V31, V11 ++ VILVHV V29, V31, V15 ++ ++ VMOVQ 192(R5), V28 ++ VMOVQ 208(R5), V29 ++ VMOVQ 224(R5), V30 ++ VMOVQ 240(R5), V31 ++ ++ VXORV V0, V16, V16 ++ VXORV V1, V17, V17 ++ VXORV V2, V18, V18 ++ VXORV V3, V19, V19 ++ ++ VMOVQ V16, 0(R4) ++ VMOVQ V17, 16(R4) ++ VMOVQ V18, 32(R4) ++ VMOVQ V19, 48(R4) ++ ++ VXORV V4, V20, V20 ++ VXORV V5, V21, V21 ++ VXORV V6, V22, V22 ++ VXORV V7, V23, V23 ++ ++ VMOVQ V20, 64(R4) ++ VMOVQ V21, 80(R4) ++ VMOVQ V22, 96(R4) ++ VMOVQ V23, 112(R4) ++ ++ VXORV V8, V24, V24 ++ VXORV V9, V25, V25 ++ VXORV V10, V26, V26 ++ VXORV V11, V27, V27 ++ ++ VMOVQ V24, 128(R4) ++ VMOVQ V25, 144(R4) ++ VMOVQ V26, 160(R4) ++ VMOVQ V27, 176(R4) ++ ++ VXORV V12, V28, V28 ++ VXORV V13, V29, V29 ++ VXORV V14, V30, V30 ++ VXORV V15, V31, V31 ++ ++ VMOVQ V28, 192(R4) ++ VMOVQ V29, 208(R4) ++ VMOVQ V30, 224(R4) ++ VMOVQ V31, 240(R4) ++ ++ ADD $4, R12, R12 ++ MOVW R12, (R9) // update counter ++ ++ ADDV $256, R4, R4 ++ ADDV $256, R5, R5 ++ SUBV $256, R6, R6 ++ BNE R6, R0, loop ++ ++ RET +diff --git a/src/vendor/golang.org/x/crypto/chacha20/chacha_noasm.go b/src/vendor/golang.org/x/crypto/chacha20/chacha_noasm.go +index c709b72847..3853cc0e0b 100644 +--- a/src/vendor/golang.org/x/crypto/chacha20/chacha_noasm.go ++++ b/src/vendor/golang.org/x/crypto/chacha20/chacha_noasm.go +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build (!arm64 && !s390x && !ppc64 && !ppc64le) || !gc || purego ++//go:build (!arm64 && !loong64 && !s390x && !ppc64 && !ppc64le) || !gc || purego + + package chacha20 + +-- +2.38.1 + diff --git a/0036-internal-bytealg-optimize-Count-String-in-loong64.patch b/0036-internal-bytealg-optimize-Count-String-in-loong64.patch new file mode 100644 index 0000000000000000000000000000000000000000..3a513c22d1714506707ce1b4ebb7eeff0af434cd --- /dev/null +++ b/0036-internal-bytealg-optimize-Count-String-in-loong64.patch @@ -0,0 +1,268 @@ +From 1698704d825764d2cbdbbf2718c582cf45d66fb0 Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Tue, 10 Dec 2024 21:06:28 +0800 +Subject: [PATCH 36/44] internal/bytealg: optimize Count{,String} in loong64 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Benchmark on Loongson 3A6000 and 3A5000: + +goos: linux +goarch: loong64 +pkg: bytes +cpu: Loongson-3A6000 @ 2500.00MHz + | bench.old | bench.new | + | sec/op | sec/op vs base | +CountSingle/10 12.81n ± 0% 10.74n ± 0% -16.16% (p=0.000 n=10) +CountSingle/32 33.135n ± 0% 8.007n ± 0% -75.84% (p=0.000 n=10) +CountSingle/4K 4057.0n ± 0% 207.5n ± 0% -94.89% (p=0.000 n=10) +CountSingle/4M 4161.7µ ± 0% 217.1µ ± 0% -94.78% (p=0.000 n=10) +CountSingle/64M 68.722m ± 0% 3.717m ± 11% -94.59% (p=0.000 n=10) +geomean 13.76µ 1.705µ -87.61% + + | bench.old | bench.new | + | B/s | B/s vs base | +CountSingle/10 744.4Mi ± 0% 887.8Mi ± 0% +19.26% (p=0.000 n=10) +CountSingle/32 921.0Mi ± 0% 3811.5Mi ± 0% +313.84% (p=0.000 n=10) +CountSingle/4K 962.7Mi ± 0% 18825.3Mi ± 0% +1855.40% (p=0.000 n=10) +CountSingle/4M 961.2Mi ± 0% 18425.4Mi ± 0% +1817.02% (p=0.000 n=10) +CountSingle/64M 931.3Mi ± 0% 17216.0Mi ± 10% +1748.62% (p=0.000 n=10) +geomean 900.1Mi 7.092Gi +706.88% + +goos: linux +goarch: loong64 +pkg: bytes +cpu: Loongson-3A5000-HV @ 2500.00MHz + | bench.old | bench.new | + | sec/op | sec/op vs base | +CountSingle/10 14.03n ± 1% 14.82n ± 0% +5.67% (p=0.000 n=10) +CountSingle/32 36.23n ± 0% 11.61n ± 0% -67.95% (p=0.000 n=10) +CountSingle/4K 4367.0n ± 0% 323.5n ± 0% -92.59% (p=0.000 n=10) +CountSingle/4M 4538.6µ ± 0% 381.2µ ± 0% -91.60% (p=0.000 n=10) +CountSingle/64M 76.575m ± 22% 7.971m ± 0% -89.59% (p=0.000 n=10) +geomean 15.05µ 2.790µ -81.46% + + | bench.old | bench.new | + | B/s | B/s vs base | +CountSingle/10 680.0Mi ± 1% 643.7Mi ± 0% -5.34% (p=0.000 n=10) +CountSingle/32 842.2Mi ± 0% 2628.4Mi ± 0% +212.07% (p=0.000 n=10) +CountSingle/4K 894.5Mi ± 0% 12075.4Mi ± 0% +1249.95% (p=0.000 n=10) +CountSingle/4M 881.3Mi ± 0% 10492.9Mi ± 0% +1090.57% (p=0.000 n=10) +CountSingle/64M 835.8Mi ± 18% 8028.7Mi ± 0% +860.61% (p=0.000 n=10) +geomean 822.9Mi 4.334Gi +439.27% + +Change-Id: I0a45139965b3e5eb09ab22be75145302f88a1915 +--- + src/internal/bytealg/bytealg.go | 3 + + src/internal/bytealg/count_loong64.s | 110 ++++++++++++++++++-------- + src/internal/cpu/cpu.go | 1 + + src/internal/cpu/cpu_loong64.go | 1 + + src/internal/cpu/cpu_loong64_hwcap.go | 2 + + 5 files changed, 85 insertions(+), 32 deletions(-) + +diff --git a/src/internal/bytealg/bytealg.go b/src/internal/bytealg/bytealg.go +index 6b79a2e1fa..a5f71ce342 100644 +--- a/src/internal/bytealg/bytealg.go ++++ b/src/internal/bytealg/bytealg.go +@@ -18,6 +18,9 @@ const ( + offsetS390xHasVX = unsafe.Offsetof(cpu.S390X.HasVX) + + offsetPPC64HasPOWER9 = unsafe.Offsetof(cpu.PPC64.IsPOWER9) ++ ++ offsetLOONG64HasLSX = unsafe.Offsetof(cpu.Loong64.HasLSX) ++ offsetLOONG64HasLASX = unsafe.Offsetof(cpu.Loong64.HasLASX) + ) + + // MaxLen is the maximum length of the string to be searched for (argument b) in Index. +diff --git a/src/internal/bytealg/count_loong64.s b/src/internal/bytealg/count_loong64.s +index db8ba2cb24..5c9dfeb0eb 100644 +--- a/src/internal/bytealg/count_loong64.s ++++ b/src/internal/bytealg/count_loong64.s +@@ -25,17 +25,81 @@ TEXT ·CountString(SB),NOSPLIT,$0-32 + // R5 = s_len + // R6 = byte to count + TEXT countbody<>(SB),NOSPLIT,$0 +- MOVV R0, R7 // count +- ADDV R4, R5 // end ++ MOVV R0, R7 // count ++ ++ // short path to handle 0-byte case ++ BEQ R5, done ++ ++ // jump directly to tail length < 4 ++ MOVV $4, R8 ++ BLT R5, R8, tail ++ ++ // jump directly to genericCountBody if length < 16 ++ MOVV $16, R8 ++ BLT R5, R8, genericCountBody ++ ++ // jump directly to lsxCountBody if length < 64 ++ MOVV $64, R8 ++ BLT R5, R8, lsxCountBody ++lasxCountBody: ++ MOVBU internal∕cpu·Loong64+const_offsetLOONG64HasLASX(SB), R8 ++ BEQ R8, lsxCountBody ++ MOVV $32, R9 ++ XVMOVQ R6, X0.B32 ++ ++ PCALIGN $16 ++lasxLoop: ++ XVMOVQ (R4), X1 ++ XVSEQB X0, X1, X2 ++ XVANDB $1, X2, X2 ++ XVPCNTV X2, X3 ++ XVMOVQ X3.V[0], R8 ++ ADDV R8, R7 ++ XVMOVQ X3.V[1], R8 ++ ADDV R8, R7 ++ XVMOVQ X3.V[2], R8 ++ ADDV R8, R7 ++ XVMOVQ X3.V[3], R8 ++ ADDV R8, R7 ++ ADDV $-32, R5 ++ ADDV $32, R4 ++ BGE R5, R9, lasxLoop ++ ++lsxCountBody: ++ MOVBU internal∕cpu·Loong64+const_offsetLOONG64HasLSX(SB), R8 ++ BEQ R8, genericCountBody ++ // jump directly to genericCountBody if length < 16 ++ MOVV $16, R9 ++ BLT R5, R9, genericCountBody ++ VMOVQ R6, V0.B16 ++ ++ PCALIGN $16 ++lsxLoop: ++ VMOVQ (R4), V1 ++ VSEQB V0, V1, V2 ++ VANDB $1, V2, V2 ++ VPCNTV V2, V3 ++ VMOVQ V3.V[0], R8 ++ ADDV R8, R7 ++ VMOVQ V3.V[1], R8 ++ ADDV R8, R7 ++ ADDV $-16, R5 ++ ADDV $16, R4 ++ BGE R5, R9, lsxLoop ++ ++ // Work with genericCountBody shorter than 16 bytes ++genericCountBody: ++ MOVV $4, R9 + MOVV $1, R17 + +-loop: +- ADDV $8, R4, R9 ++ PCALIGN $16 ++genericLoop: + BLT R5, R9, tail +- MOVV (R4), R8 ++ ADDV $-4, R5 ++ MOVWU (R4)(R5), R8 + + AND $0xff, R8, R10 +- WORD $0xcf210b // bstrpick.w r11, r8, 15, 8 ++ BSTRPICKW $15, R8, $8, R11 + XOR R6, R10, R10 + XOR R6, R11, R11 + MASKNEZ R10, R17, R12 +@@ -43,8 +107,8 @@ loop: + ADDV R7, R12, R7 + ADDV R7, R13, R7 + +- WORD $0xd7410a // bstrpick.w r10, r8, 23, 16 +- WORD $0xdf610b // bstrpick.w r11, r8, 31, 24 ++ BSTRPICKW $23, R8, $16, R10 ++ BSTRPICKW $31, R8, $24, R11 + XOR R6, R10, R10 + XOR R6, R11, R11 + MASKNEZ R10, R17, R12 +@@ -52,35 +116,17 @@ loop: + ADDV R7, R12, R7 + ADDV R7, R13, R7 + +- WORD $0xe7810a // bstrpick.w r10, r8, 39, 32 +- WORD $0xefa10b // bstrpick.w r11, r8, 47, 40 +- XOR R6, R10, R10 +- XOR R6, R11, R11 +- MASKNEZ R10, R17, R12 +- MASKNEZ R11, R17, R13 +- ADDV R7, R12, R7 +- ADDV R7, R13, R7 +- +- WORD $0xf7c10a // bstrpick.w r10, r8, 55, 48 +- WORD $0xffe10b // bstrpick.w r11, r8, 63, 56 +- XOR R6, R10, R10 +- XOR R6, R11, R11 +- MASKNEZ R10, R17, R12 +- MASKNEZ R11, R17, R13 +- ADDV R7, R12, R7 +- ADDV R7, R13, R7 +- +- MOVV R9, R4 +- JMP loop ++ JMP genericLoop + ++ // Work with tail shorter than 4 bytes ++ PCALIGN $16 + tail: +- BEQ R4, R5, done +- MOVBU (R4), R8 +- ADDV $1, R4 ++ BEQ R5, done ++ ADDV $-1, R5 ++ MOVBU (R4)(R5), R8 + BNE R6, R8, tail + ADDV $1, R7 + JMP tail +- + done: + MOVV R7, R4 + RET +diff --git a/src/internal/cpu/cpu.go b/src/internal/cpu/cpu.go +index cd3db10523..2443b31fc8 100644 +--- a/src/internal/cpu/cpu.go ++++ b/src/internal/cpu/cpu.go +@@ -83,6 +83,7 @@ var ARM64 struct { + var Loong64 struct { + _ CacheLinePad + HasLSX bool // support 128-bit vector extension ++ HasLASX bool // support 256-bit vector extension + HasCRC32 bool // support CRC instruction + HasLAMCAS bool // support AMCAS[_DB].{B/H/W/D} + HasLAM_BH bool // support AM{SWAP/ADD}[_DB].{B/H} instruction +diff --git a/src/internal/cpu/cpu_loong64.go b/src/internal/cpu/cpu_loong64.go +index 92583d0bca..9a58ea251c 100644 +--- a/src/internal/cpu/cpu_loong64.go ++++ b/src/internal/cpu/cpu_loong64.go +@@ -27,6 +27,7 @@ func get_cpucfg(reg uint32) uint32 + func doinit() { + options = []option{ + {Name: "lsx", Feature: &Loong64.HasLSX}, ++ {Name: "lasx", Feature: &Loong64.HasLASX}, + {Name: "crc32", Feature: &Loong64.HasCRC32}, + {Name: "lamcas", Feature: &Loong64.HasLAMCAS}, + {Name: "lam_bh", Feature: &Loong64.HasLAM_BH}, +diff --git a/src/internal/cpu/cpu_loong64_hwcap.go b/src/internal/cpu/cpu_loong64_hwcap.go +index 58397adae8..6c6b8a81f2 100644 +--- a/src/internal/cpu/cpu_loong64_hwcap.go ++++ b/src/internal/cpu/cpu_loong64_hwcap.go +@@ -13,12 +13,14 @@ var HWCap uint + // HWCAP bits. These are exposed by the Linux kernel. + const ( + hwcap_LOONGARCH_LSX = 1 << 4 ++ hwcap_LOONGARCH_LASX = 1 << 5 + ) + + func hwcapInit() { + // TODO: Features that require kernel support like LSX and LASX can + // be detected here once needed in std library or by the compiler. + Loong64.HasLSX = hwcIsSet(HWCap, hwcap_LOONGARCH_LSX) ++ Loong64.HasLASX = hwcIsSet(HWCap, hwcap_LOONGARCH_LASX) + } + + func hwcIsSet(hwc uint, val uint) bool { +-- +2.38.1 + diff --git a/0037-cmd-internal-obj-cmd-asm-reclassify-32-bit-immediate.patch b/0037-cmd-internal-obj-cmd-asm-reclassify-32-bit-immediate.patch new file mode 100644 index 0000000000000000000000000000000000000000..ccad194868f90528439f26426f941baa445ffaca --- /dev/null +++ b/0037-cmd-internal-obj-cmd-asm-reclassify-32-bit-immediate.patch @@ -0,0 +1,690 @@ +From a713105842cd7b88dbb573980731062c218a8310 Mon Sep 17 00:00:00 2001 +From: limeidan +Date: Mon, 16 Dec 2024 16:31:37 +0800 +Subject: [PATCH 37/44] cmd/internal/obj, cmd/asm: reclassify 32-bit immediate + value + +Change-Id: If9fd257ca0837a8c8597889c4f5ed3d4edc602c1 +--- + .../asm/internal/asm/testdata/loong64enc1.s | 4 +- + .../asm/internal/asm/testdata/loong64enc2.s | 2 +- + src/cmd/internal/obj/loong64/a.out.go | 31 +- + src/cmd/internal/obj/loong64/asm.go | 376 +++++++----------- + src/cmd/internal/obj/loong64/cnames.go | 25 +- + 5 files changed, 186 insertions(+), 252 deletions(-) + +diff --git a/src/cmd/asm/internal/asm/testdata/loong64enc1.s b/src/cmd/asm/internal/asm/testdata/loong64enc1.s +index 19070c89ef..b40d86e596 100644 +--- a/src/cmd/asm/internal/asm/testdata/loong64enc1.s ++++ b/src/cmd/asm/internal/asm/testdata/loong64enc1.s +@@ -107,8 +107,8 @@ lable2: + MOVV $4(R4), R5 // 8510c002 + MOVW $-1, R4 // 04fcff02 + MOVV $-1, R4 // 04fcff02 +- MOVW $1, R4 // 0404c002 +- MOVV $1, R4 // 0404c002 ++ MOVW $1, R4 // 04048003 ++ MOVV $1, R4 // 04048003 + ADD $-1, R4, R5 // 85fcbf02 + ADD $-1, R4 // 84fcbf02 + ADDV $-1, R4, R5 // 85fcff02 +diff --git a/src/cmd/asm/internal/asm/testdata/loong64enc2.s b/src/cmd/asm/internal/asm/testdata/loong64enc2.s +index ee3bad74b1..91aed4e2c7 100644 +--- a/src/cmd/asm/internal/asm/testdata/loong64enc2.s ++++ b/src/cmd/asm/internal/asm/testdata/loong64enc2.s +@@ -12,7 +12,7 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0 + AND $-1, R4, R5 // 1efcbf0285f81400 + AND $-1, R4 // 1efcbf0284f81400 + MOVW $-1, F4 // 1efcbf02c4a71401 +- MOVW $1, F4 // 1e048002c4a71401 ++ MOVW $1, F4 // 1e048003c4a71401 + TEQ $4, R4, R5 // 8508005c04002a00 + TEQ $4, R4 // 0408005c04002a00 + TNE $4, R4, R5 // 8508005804002a00 +diff --git a/src/cmd/internal/obj/loong64/a.out.go b/src/cmd/internal/obj/loong64/a.out.go +index 1fadbc648a..f2d4c41d68 100644 +--- a/src/cmd/internal/obj/loong64/a.out.go ++++ b/src/cmd/internal/obj/loong64/a.out.go +@@ -325,19 +325,26 @@ const ( + C_XREG + C_ARNG // Vn. + C_ELEM // Vn.[index] ++ + C_ZCON +- C_SCON // 12 bit signed +- C_UCON // 32 bit signed, low 12 bits 0 +- +- // When the immediate value is SCON, it can choose either the ADDCON implementation +- // or the ANDCON implementation, using ADD0CON/AND0CON to distinguish them, so that +- // the program can choose the implementation with fewer instructions. +- C_ADD0CON +- C_AND0CON +- +- C_ADDCON // -0x800 <= v < 0 +- C_ANDCON // 0 < v <= 0xFFF +- C_LCON // other 32 ++ C_U1CON // 1 bit unsigned constant ++ C_U2CON // 2 bit unsigned constant ++ C_U3CON // 3 bit unsigned constant ++ C_U4CON // 4 bit unsigned constant ++ C_U5CON // 5 bit unsigned constant ++ C_U6CON // 6 bit unsigned constant ++ C_U7CON // 7 bit unsigned constant ++ C_U8CON // 8 bit unsigned constant ++ C_S5CON // 5 bit signed constant ++ C_US12CON // same as C_S12CON, increase the priority of C_S12CON in special cases. ++ C_UU12CON // same as C_U12CON, increase the priority of C_U12CON in special cases. ++ C_S12CON // 12 bit signed constant, -0x800 < v <= 0x7ff ++ C_U12CON // 12 bit unsigned constant, 0 < v <= 0xfff ++ C_12CON // 12 bit signed constant, or 12 bit unsigned constant ++ C_U15CON // 15 bit unsigned constant ++ C_15CON20_0 // 15 bit unsigned constant, low 12 bits 0 ++ C_32CON20_0 // 32 bit signed, low 12 bits 0 ++ C_32CON // other 32 bit signed + + // 64 bit signed, lo32 bits 0, hi20 bits are not 0, hi12 bits can + // be obtained by sign extension of the hi20 bits. +diff --git a/src/cmd/internal/obj/loong64/asm.go b/src/cmd/internal/obj/loong64/asm.go +index 657d32ae81..2480cf9382 100644 +--- a/src/cmd/internal/obj/loong64/asm.go ++++ b/src/cmd/internal/obj/loong64/asm.go +@@ -51,12 +51,6 @@ const ( + // branchLoopHead marks loop entry. + // Used to insert padding for under-aligned loops. + branchLoopHead +- immFiledSi5 // The encoding of the immediate field in the instruction is 5-bits +- immFiledUi3 // The encoding of the immediate field in the instruction is 3-bits +- immFiledUi4 // The encoding of the immediate field in the instruction is 4-bits +- immFiledUi5 // The encoding of the immediate field in the instruction is 5-bits +- immFiledUi6 // The encoding of the immediate field in the instruction is 6-bits +- immFiledUi8 // The encoding of the immediate field in the instruction is 8-bits + ) + + var optab = []Optab{ +@@ -94,45 +88,41 @@ var optab = []Optab{ + {ACMPEQF, C_FREG, C_FREG, C_NONE, C_FCCREG, C_NONE, 2, 4, 0, 0}, + {AVSEQB, C_VREG, C_VREG, C_NONE, C_VREG, C_NONE, 2, 4, 0, 0}, + {AXVSEQB, C_XREG, C_XREG, C_NONE, C_XREG, C_NONE, 2, 4, 0, 0}, +- {AVSEQB, C_SCON, C_VREG, C_NONE, C_VREG, C_NONE, 13, 4, 0, immFiledSi5}, +- {AXVSEQB, C_SCON, C_XREG, C_NONE, C_XREG, C_NONE, 13, 4, 0, immFiledSi5}, +- {AVSEQB, C_ADDCON, C_VREG, C_NONE, C_VREG, C_NONE, 13, 4, 0, immFiledSi5}, +- {AXVSEQB, C_ADDCON, C_XREG, C_NONE, C_XREG, C_NONE, 13, 4, 0, immFiledSi5}, ++ {AVSEQB, C_S5CON, C_VREG, C_NONE, C_VREG, C_NONE, 13, 4, 0, 0}, ++ {AXVSEQB, C_S5CON, C_XREG, C_NONE, C_XREG, C_NONE, 13, 4, 0, 0}, + + {AVANDV, C_VREG, C_VREG, C_NONE, C_VREG, C_NONE, 2, 4, 0, 0}, + {AXVANDV, C_XREG, C_XREG, C_NONE, C_XREG, C_NONE, 2, 4, 0, 0}, +- {AVANDB, C_SCON, C_VREG, C_NONE, C_VREG, C_NONE, 14, 4, 0, immFiledUi8}, +- {AXVANDB, C_SCON, C_XREG, C_NONE, C_XREG, C_NONE, 14, 4, 0, immFiledUi8}, +- {AVANDB, C_ADDCON, C_VREG, C_NONE, C_VREG, C_NONE, 14, 4, 0, immFiledUi8}, +- {AXVANDB, C_ADDCON, C_XREG, C_NONE, C_XREG, C_NONE, 14, 4, 0, immFiledUi8}, ++ {AVANDB, C_U8CON, C_VREG, C_NONE, C_VREG, C_NONE, 14, 4, 0, 0}, ++ {AXVANDB, C_U8CON, C_XREG, C_NONE, C_XREG, C_NONE, 14, 4, 0, 0}, + + {AVSLLB, C_VREG, C_VREG, C_NONE, C_VREG, C_NONE, 2, 4, 0, 0}, + {AXVSLLB, C_XREG, C_XREG, C_NONE, C_XREG, C_NONE, 2, 4, 0, 0}, +- {AVSLLB, C_SCON, C_VREG, C_NONE, C_VREG, C_NONE, 29, 4, 0, immFiledUi3}, +- {AXVSLLB, C_SCON, C_XREG, C_NONE, C_XREG, C_NONE, 29, 4, 0, immFiledUi3}, +- {AVSLLB, C_SCON, C_NONE, C_NONE, C_VREG, C_NONE, 29, 4, 0, immFiledUi3}, +- {AXVSLLB, C_SCON, C_NONE, C_NONE, C_XREG, C_NONE, 29, 4, 0, immFiledUi3}, ++ {AVSLLB, C_U3CON, C_VREG, C_NONE, C_VREG, C_NONE, 29, 4, 0, 0}, ++ {AXVSLLB, C_U3CON, C_XREG, C_NONE, C_XREG, C_NONE, 29, 4, 0, 0}, ++ {AVSLLB, C_U3CON, C_NONE, C_NONE, C_VREG, C_NONE, 29, 4, 0, 0}, ++ {AXVSLLB, C_U3CON, C_NONE, C_NONE, C_XREG, C_NONE, 29, 4, 0, 0}, + + {AVSLLH, C_VREG, C_VREG, C_NONE, C_VREG, C_NONE, 2, 4, 0, 0}, + {AXVSLLH, C_XREG, C_XREG, C_NONE, C_XREG, C_NONE, 2, 4, 0, 0}, +- {AVSLLH, C_SCON, C_VREG, C_NONE, C_VREG, C_NONE, 31, 4, 0, immFiledUi4}, +- {AXVSLLH, C_SCON, C_XREG, C_NONE, C_XREG, C_NONE, 31, 4, 0, immFiledUi4}, +- {AVSLLH, C_SCON, C_NONE, C_NONE, C_VREG, C_NONE, 31, 4, 0, immFiledUi4}, +- {AXVSLLH, C_SCON, C_NONE, C_NONE, C_XREG, C_NONE, 31, 4, 0, immFiledUi4}, ++ {AVSLLH, C_U4CON, C_VREG, C_NONE, C_VREG, C_NONE, 31, 4, 0, 0}, ++ {AXVSLLH, C_U4CON, C_XREG, C_NONE, C_XREG, C_NONE, 31, 4, 0, 0}, ++ {AVSLLH, C_U4CON, C_NONE, C_NONE, C_VREG, C_NONE, 31, 4, 0, 0}, ++ {AXVSLLH, C_U4CON, C_NONE, C_NONE, C_XREG, C_NONE, 31, 4, 0, 0}, + + {AVSLLW, C_VREG, C_VREG, C_NONE, C_VREG, C_NONE, 2, 4, 0, 0}, + {AXVSLLW, C_XREG, C_XREG, C_NONE, C_XREG, C_NONE, 2, 4, 0, 0}, +- {AVSLLW, C_SCON, C_VREG, C_NONE, C_VREG, C_NONE, 32, 4, 0, immFiledUi5}, +- {AXVSLLW, C_SCON, C_XREG, C_NONE, C_XREG, C_NONE, 32, 4, 0, immFiledUi5}, +- {AVSLLW, C_SCON, C_NONE, C_NONE, C_VREG, C_NONE, 32, 4, 0, immFiledUi5}, +- {AXVSLLW, C_SCON, C_NONE, C_NONE, C_XREG, C_NONE, 32, 4, 0, immFiledUi5}, ++ {AVSLLW, C_U5CON, C_VREG, C_NONE, C_VREG, C_NONE, 32, 4, 0, 0}, ++ {AXVSLLW, C_U5CON, C_XREG, C_NONE, C_XREG, C_NONE, 32, 4, 0, 0}, ++ {AVSLLW, C_U5CON, C_NONE, C_NONE, C_VREG, C_NONE, 32, 4, 0, 0}, ++ {AXVSLLW, C_U5CON, C_NONE, C_NONE, C_XREG, C_NONE, 32, 4, 0, 0}, + + {AVSLLV, C_VREG, C_VREG, C_NONE, C_VREG, C_NONE, 2, 4, 0, 0}, + {AXVSLLV, C_XREG, C_XREG, C_NONE, C_XREG, C_NONE, 2, 4, 0, 0}, +- {AVSLLV, C_SCON, C_VREG, C_NONE, C_VREG, C_NONE, 33, 4, 0, immFiledUi6}, +- {AXVSLLV, C_SCON, C_XREG, C_NONE, C_XREG, C_NONE, 33, 4, 0, immFiledUi6}, +- {AVSLLV, C_SCON, C_NONE, C_NONE, C_VREG, C_NONE, 33, 4, 0, immFiledUi6}, +- {AXVSLLV, C_SCON, C_NONE, C_NONE, C_XREG, C_NONE, 33, 4, 0, immFiledUi6}, ++ {AVSLLV, C_U6CON, C_VREG, C_NONE, C_VREG, C_NONE, 33, 4, 0, 0}, ++ {AXVSLLV, C_U6CON, C_XREG, C_NONE, C_XREG, C_NONE, 33, 4, 0, 0}, ++ {AVSLLV, C_U6CON, C_NONE, C_NONE, C_VREG, C_NONE, 33, 4, 0, 0}, ++ {AXVSLLV, C_U6CON, C_NONE, C_NONE, C_XREG, C_NONE, 33, 4, 0, 0}, + + {ACLOW, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 9, 4, 0, 0}, + {AABSF, C_FREG, C_NONE, C_NONE, C_FREG, C_NONE, 9, 4, 0, 0}, +@@ -229,48 +219,46 @@ var optab = []Optab{ + + {AMOVW, C_LACON, C_NONE, C_NONE, C_REG, C_NONE, 26, 12, REGSP, 0}, + {AMOVV, C_LACON, C_NONE, C_NONE, C_REG, C_NONE, 26, 12, REGSP, 0}, +- {AMOVW, C_ADDCON, C_NONE, C_NONE, C_REG, C_NONE, 3, 4, REGZERO, 0}, +- {AMOVV, C_ADDCON, C_NONE, C_NONE, C_REG, C_NONE, 3, 4, REGZERO, 0}, +- {AMOVW, C_ANDCON, C_NONE, C_NONE, C_REG, C_NONE, 3, 4, REGZERO, 0}, +- {AMOVV, C_ANDCON, C_NONE, C_NONE, C_REG, C_NONE, 3, 4, REGZERO, 0}, +- +- {AMOVW, C_UCON, C_NONE, C_NONE, C_REG, C_NONE, 24, 4, 0, 0}, +- {AMOVV, C_UCON, C_NONE, C_NONE, C_REG, C_NONE, 24, 4, 0, 0}, +- {AMOVW, C_LCON, C_NONE, C_NONE, C_REG, C_NONE, 19, 8, 0, NOTUSETMP}, +- {AMOVV, C_LCON, C_NONE, C_NONE, C_REG, C_NONE, 19, 8, 0, NOTUSETMP}, ++ {AMOVW, C_12CON, C_NONE, C_NONE, C_REG, C_NONE, 3, 4, REGZERO, 0}, ++ {AMOVV, C_12CON, C_NONE, C_NONE, C_REG, C_NONE, 3, 4, REGZERO, 0}, ++ ++ {AMOVW, C_32CON20_0, C_NONE, C_NONE, C_REG, C_NONE, 24, 4, 0, 0}, ++ {AMOVV, C_32CON20_0, C_NONE, C_NONE, C_REG, C_NONE, 24, 4, 0, 0}, ++ {AMOVW, C_32CON, C_NONE, C_NONE, C_REG, C_NONE, 19, 8, 0, NOTUSETMP}, ++ {AMOVV, C_32CON, C_NONE, C_NONE, C_REG, C_NONE, 19, 8, 0, NOTUSETMP}, + {AMOVV, C_DCON12_0, C_NONE, C_NONE, C_REG, C_NONE, 67, 4, 0, NOTUSETMP}, + {AMOVV, C_DCON12_20S, C_NONE, C_NONE, C_REG, C_NONE, 68, 8, 0, NOTUSETMP}, + {AMOVV, C_DCON32_12S, C_NONE, C_NONE, C_REG, C_NONE, 69, 12, 0, NOTUSETMP}, + {AMOVV, C_DCON, C_NONE, C_NONE, C_REG, C_NONE, 59, 16, 0, NOTUSETMP}, + +- {AADD, C_ADD0CON, C_REG, C_NONE, C_REG, C_NONE, 4, 4, 0, 0}, +- {AADD, C_ADD0CON, C_NONE, C_NONE, C_REG, C_NONE, 4, 4, 0, 0}, +- {AADD, C_ANDCON, C_REG, C_NONE, C_REG, C_NONE, 10, 8, 0, 0}, +- {AADD, C_ANDCON, C_NONE, C_NONE, C_REG, C_NONE, 10, 8, 0, 0}, +- +- {AADDV, C_ADD0CON, C_REG, C_NONE, C_REG, C_NONE, 4, 4, 0, 0}, +- {AADDV, C_ADD0CON, C_NONE, C_NONE, C_REG, C_NONE, 4, 4, 0, 0}, +- {AADDV, C_ANDCON, C_REG, C_NONE, C_REG, C_NONE, 10, 8, 0, 0}, +- {AADDV, C_ANDCON, C_NONE, C_NONE, C_REG, C_NONE, 10, 8, 0, 0}, +- +- {AAND, C_AND0CON, C_REG, C_NONE, C_REG, C_NONE, 4, 4, 0, 0}, +- {AAND, C_AND0CON, C_NONE, C_NONE, C_REG, C_NONE, 4, 4, 0, 0}, +- {AAND, C_ADDCON, C_REG, C_NONE, C_REG, C_NONE, 10, 8, 0, 0}, +- {AAND, C_ADDCON, C_NONE, C_NONE, C_REG, C_NONE, 10, 8, 0, 0}, +- +- {AADD, C_UCON, C_REG, C_NONE, C_REG, C_NONE, 25, 8, 0, 0}, +- {AADD, C_UCON, C_NONE, C_NONE, C_REG, C_NONE, 25, 8, 0, 0}, +- {AADDV, C_UCON, C_REG, C_NONE, C_REG, C_NONE, 25, 8, 0, 0}, +- {AADDV, C_UCON, C_NONE, C_NONE, C_REG, C_NONE, 25, 8, 0, 0}, +- {AAND, C_UCON, C_REG, C_NONE, C_REG, C_NONE, 25, 8, 0, 0}, +- {AAND, C_UCON, C_NONE, C_NONE, C_REG, C_NONE, 25, 8, 0, 0}, +- +- {AADD, C_LCON, C_NONE, C_NONE, C_REG, C_NONE, 23, 12, 0, 0}, +- {AADDV, C_LCON, C_NONE, C_NONE, C_REG, C_NONE, 23, 12, 0, 0}, +- {AAND, C_LCON, C_NONE, C_NONE, C_REG, C_NONE, 23, 12, 0, 0}, +- {AADD, C_LCON, C_REG, C_NONE, C_REG, C_NONE, 23, 12, 0, 0}, +- {AADDV, C_LCON, C_REG, C_NONE, C_REG, C_NONE, 23, 12, 0, 0}, +- {AAND, C_LCON, C_REG, C_NONE, C_REG, C_NONE, 23, 12, 0, 0}, ++ {AADD, C_US12CON, C_REG, C_NONE, C_REG, C_NONE, 4, 4, 0, 0}, ++ {AADD, C_US12CON, C_NONE, C_NONE, C_REG, C_NONE, 4, 4, 0, 0}, ++ {AADD, C_U12CON, C_REG, C_NONE, C_REG, C_NONE, 10, 8, 0, 0}, ++ {AADD, C_U12CON, C_NONE, C_NONE, C_REG, C_NONE, 10, 8, 0, 0}, ++ ++ {AADDV, C_US12CON, C_REG, C_NONE, C_REG, C_NONE, 4, 4, 0, 0}, ++ {AADDV, C_US12CON, C_NONE, C_NONE, C_REG, C_NONE, 4, 4, 0, 0}, ++ {AADDV, C_U12CON, C_REG, C_NONE, C_REG, C_NONE, 10, 8, 0, 0}, ++ {AADDV, C_U12CON, C_NONE, C_NONE, C_REG, C_NONE, 10, 8, 0, 0}, ++ ++ {AAND, C_UU12CON, C_REG, C_NONE, C_REG, C_NONE, 4, 4, 0, 0}, ++ {AAND, C_UU12CON, C_NONE, C_NONE, C_REG, C_NONE, 4, 4, 0, 0}, ++ {AAND, C_S12CON, C_REG, C_NONE, C_REG, C_NONE, 10, 8, 0, 0}, ++ {AAND, C_S12CON, C_NONE, C_NONE, C_REG, C_NONE, 10, 8, 0, 0}, ++ ++ {AADD, C_32CON20_0, C_REG, C_NONE, C_REG, C_NONE, 25, 8, 0, 0}, ++ {AADD, C_32CON20_0, C_NONE, C_NONE, C_REG, C_NONE, 25, 8, 0, 0}, ++ {AADDV, C_32CON20_0, C_REG, C_NONE, C_REG, C_NONE, 25, 8, 0, 0}, ++ {AADDV, C_32CON20_0, C_NONE, C_NONE, C_REG, C_NONE, 25, 8, 0, 0}, ++ {AAND, C_32CON20_0, C_REG, C_NONE, C_REG, C_NONE, 25, 8, 0, 0}, ++ {AAND, C_32CON20_0, C_NONE, C_NONE, C_REG, C_NONE, 25, 8, 0, 0}, ++ ++ {AADD, C_32CON, C_NONE, C_NONE, C_REG, C_NONE, 23, 12, 0, 0}, ++ {AADDV, C_32CON, C_NONE, C_NONE, C_REG, C_NONE, 23, 12, 0, 0}, ++ {AAND, C_32CON, C_NONE, C_NONE, C_REG, C_NONE, 23, 12, 0, 0}, ++ {AADD, C_32CON, C_REG, C_NONE, C_REG, C_NONE, 23, 12, 0, 0}, ++ {AADDV, C_32CON, C_REG, C_NONE, C_REG, C_NONE, 23, 12, 0, 0}, ++ {AAND, C_32CON, C_REG, C_NONE, C_REG, C_NONE, 23, 12, 0, 0}, + + {AADDV, C_DCON, C_NONE, C_NONE, C_REG, C_NONE, 60, 20, 0, 0}, + {AADDV, C_DCON, C_REG, C_NONE, C_REG, C_NONE, 60, 20, 0, 0}, +@@ -289,18 +277,18 @@ var optab = []Optab{ + {AAND, C_DCON32_12S, C_NONE, C_NONE, C_REG, C_NONE, 72, 16, 0, 0}, + {AAND, C_DCON32_12S, C_REG, C_NONE, C_REG, C_NONE, 72, 16, 0, 0}, + +- {ASLL, C_SCON, C_REG, C_NONE, C_REG, C_NONE, 16, 4, 0, 0}, +- {ASLL, C_SCON, C_NONE, C_NONE, C_REG, C_NONE, 16, 4, 0, 0}, ++ {ASLL, C_U5CON, C_REG, C_NONE, C_REG, C_NONE, 16, 4, 0, 0}, ++ {ASLL, C_U5CON, C_NONE, C_NONE, C_REG, C_NONE, 16, 4, 0, 0}, + +- {ASLLV, C_SCON, C_REG, C_NONE, C_REG, C_NONE, 16, 4, 0, 0}, +- {ASLLV, C_SCON, C_NONE, C_NONE, C_REG, C_NONE, 16, 4, 0, 0}, ++ {ASLLV, C_U6CON, C_REG, C_NONE, C_REG, C_NONE, 16, 4, 0, 0}, ++ {ASLLV, C_U6CON, C_NONE, C_NONE, C_REG, C_NONE, 16, 4, 0, 0}, + +- {ABSTRPICKW, C_SCON, C_REG, C_SCON, C_REG, C_NONE, 17, 4, 0, 0}, +- {ABSTRPICKW, C_SCON, C_REG, C_ZCON, C_REG, C_NONE, 17, 4, 0, 0}, ++ {ABSTRPICKW, C_U6CON, C_REG, C_U6CON, C_REG, C_NONE, 17, 4, 0, 0}, ++ {ABSTRPICKW, C_U6CON, C_REG, C_ZCON, C_REG, C_NONE, 17, 4, 0, 0}, + {ABSTRPICKW, C_ZCON, C_REG, C_ZCON, C_REG, C_NONE, 17, 4, 0, 0}, + + {ASYSCALL, C_NONE, C_NONE, C_NONE, C_NONE, C_NONE, 5, 4, 0, 0}, +- {ASYSCALL, C_ANDCON, C_NONE, C_NONE, C_NONE, C_NONE, 5, 4, 0, 0}, ++ {ASYSCALL, C_U15CON, C_NONE, C_NONE, C_NONE, C_NONE, 5, 4, 0, 0}, + + {ABEQ, C_REG, C_REG, C_NONE, C_BRAN, C_NONE, 6, 4, 0, 0}, + {ABEQ, C_REG, C_NONE, C_NONE, C_BRAN, C_NONE, 6, 4, 0, 0}, +@@ -348,8 +336,7 @@ var optab = []Optab{ + {AMOVV, C_FREG, C_NONE, C_NONE, C_FCCREG, C_NONE, 30, 4, 0, 0}, + {AMOVV, C_FCCREG, C_NONE, C_NONE, C_FREG, C_NONE, 30, 4, 0, 0}, + +- {AMOVW, C_ADDCON, C_NONE, C_NONE, C_FREG, C_NONE, 34, 8, 0, 0}, +- {AMOVW, C_ANDCON, C_NONE, C_NONE, C_FREG, C_NONE, 34, 8, 0, 0}, ++ {AMOVW, C_12CON, C_NONE, C_NONE, C_FREG, C_NONE, 34, 8, 0, 0}, + + {AMOVB, C_REG, C_NONE, C_NONE, C_TLS_IE, C_NONE, 56, 16, 0, 0}, + {AMOVW, C_REG, C_NONE, C_NONE, C_TLS_IE, C_NONE, 56, 16, 0, 0}, +@@ -363,13 +350,13 @@ var optab = []Optab{ + {AMOVBU, C_TLS_IE, C_NONE, C_NONE, C_REG, C_NONE, 57, 16, 0, 0}, + {AMOVWU, C_TLS_IE, C_NONE, C_NONE, C_REG, C_NONE, 57, 16, 0, 0}, + +- {AWORD, C_LCON, C_NONE, C_NONE, C_NONE, C_NONE, 38, 4, 0, 0}, ++ {AWORD, C_32CON, C_NONE, C_NONE, C_NONE, C_NONE, 38, 4, 0, 0}, + {AWORD, C_DCON, C_NONE, C_NONE, C_NONE, C_NONE, 61, 4, 0, 0}, + + {AMOVV, C_GOTADDR, C_NONE, C_NONE, C_REG, C_NONE, 65, 8, 0, 0}, + +- {ATEQ, C_SCON, C_REG, C_NONE, C_REG, C_NONE, 15, 8, 0, 0}, +- {ATEQ, C_SCON, C_NONE, C_NONE, C_REG, C_NONE, 15, 8, 0, 0}, ++ {ATEQ, C_US12CON, C_REG, C_NONE, C_REG, C_NONE, 15, 8, 0, 0}, ++ {ATEQ, C_US12CON, C_NONE, C_NONE, C_REG, C_NONE, 15, 8, 0, 0}, + + {ARDTIMELW, C_NONE, C_NONE, C_NONE, C_REG, C_REG, 62, 4, 0, 0}, + {AAMSWAPW, C_REG, C_NONE, C_NONE, C_ZOREG, C_REG, 66, 4, 0, 0}, +@@ -409,12 +396,12 @@ var optab = []Optab{ + + {AVMOVQ, C_ELEM, C_NONE, C_NONE, C_ARNG, C_NONE, 45, 4, 0, 0}, + +- {obj.APCALIGN, C_SCON, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0}, +- {obj.APCDATA, C_LCON, C_NONE, C_NONE, C_LCON, C_NONE, 0, 0, 0, 0}, ++ {obj.APCALIGN, C_U12CON, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0}, ++ {obj.APCDATA, C_32CON, C_NONE, C_NONE, C_32CON, C_NONE, 0, 0, 0, 0}, + {obj.APCDATA, C_DCON, C_NONE, C_NONE, C_DCON, C_NONE, 0, 0, 0, 0}, +- {obj.AFUNCDATA, C_SCON, C_NONE, C_NONE, C_ADDR, C_NONE, 0, 0, 0, 0}, ++ {obj.AFUNCDATA, C_U12CON, C_NONE, C_NONE, C_ADDR, C_NONE, 0, 0, 0, 0}, + {obj.ANOP, C_NONE, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0}, +- {obj.ANOP, C_LCON, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0}, // nop variants, see #40689 ++ {obj.ANOP, C_32CON, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0}, // nop variants, see #40689 + {obj.ANOP, C_DCON, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0}, // nop variants, see #40689 + {obj.ANOP, C_REG, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0}, + {obj.ANOP, C_FREG, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0}, +@@ -857,34 +844,35 @@ func (c *ctxt0) aclass(a *obj.Addr) int { + } + + if c.instoffset >= 0 { +- if c.instoffset == 0 { +- return C_ZCON +- } +- if c.instoffset <= 0x7ff { +- return C_SCON +- } +- if c.instoffset <= 0xfff { +- return C_ANDCON +- } +- if c.instoffset&0xfff == 0 && isuint32(uint64(c.instoffset)) { // && ((instoffset & (1<<31)) == 0) +- return C_UCON ++ sbits := bits.Len64(uint64(c.instoffset)) ++ switch { ++ case sbits <=8: ++ return C_ZCON + sbits ++ case sbits <= 12: ++ if c.instoffset <= 0x7ff { ++ return C_US12CON ++ } ++ return C_U12CON ++ case sbits <= 15: ++ if c.instoffset & 0xfff == 0 { ++ return C_15CON20_0 ++ } ++ return C_U15CON + } +- if isint32(c.instoffset) || isuint32(uint64(c.instoffset)) { +- return C_LCON ++ } else { ++ sbits := bits.Len64(uint64(^c.instoffset)) ++ switch { ++ case sbits < 5: ++ return C_S5CON ++ case sbits < 12: ++ return C_S12CON + } +- return C_LCON + } + +- if c.instoffset >= -0x800 { +- return C_ADDCON ++ if c.instoffset&0xfff == 0 { ++ return C_32CON20_0 + } +- if c.instoffset&0xfff == 0 && isint32(c.instoffset) { +- return C_UCON +- } +- if isint32(c.instoffset) { +- return C_LCON +- } +- return C_LCON ++ return C_32CON + + case obj.TYPE_BRANCH: + return C_BRAN +@@ -1130,10 +1118,11 @@ func (c *ctxt0) oplook(p *obj.Prog) *Optab { + + ops := oprange[p.As&obj.AMask] + c1 := &xcmp[a1] ++ c3 := &xcmp[a3] + c4 := &xcmp[a4] + for i := range ops { + op := &ops[i] +- if (int(op.reg) == a2) && int(op.from3) == a3 && c1[op.from1] && c4[op.to1] && (int(op.to2) == a5) { ++ if (int(op.reg) == a2) && c3[op.from3] && c1[op.from1] && c4[op.to1] && (int(op.to2) == a5) { + p.Optab = uint16(cap(optab) - cap(ops) + i + 1) + return op + } +@@ -1151,21 +1140,41 @@ func cmp(a int, b int) bool { + } + switch a { + case C_DCON: +- if b == C_LCON || b == C_DCON32_0 || +- b == C_DCON12_0 || b == C_DCON20S_0 || +- b == C_DCON12_20S || b == C_DCON12_12S || +- b == C_DCON20S_20 || b == C_DCON32_20 || +- b == C_DCON20S_12S || b == C_DCON32_12S || +- b == C_DCON12_32S || b == C_DCON20S_32 || +- b == C_DCON12_12U || b == C_DCON20S_12U || +- b == C_DCON32_12U { +- return true +- } +- fallthrough +- case C_LCON: +- if b == C_ZCON || b == C_SCON || b == C_UCON || b == C_ADDCON || b == C_ANDCON { +- return true +- } ++ return cmp(C_32CON, b) || cmp(C_DCON12_20S, b) || cmp(C_DCON32_12S, b) || b == C_DCON12_0 ++ case C_32CON: ++ return cmp(C_32CON20_0, b) || cmp(C_U15CON, b) || cmp(C_S12CON, b) ++ case C_32CON20_0: ++ return b == C_15CON20_0 || b == C_ZCON ++ case C_U15CON: ++ return cmp(C_U12CON, b) || b == C_15CON20_0 ++ case C_12CON: ++ return cmp(C_U12CON, b) || cmp(C_S12CON, b) ++ case C_UU12CON: ++ return cmp(C_U12CON, b) ++ case C_U12CON: ++ return cmp(C_U8CON, b) || b == C_US12CON ++ case C_U8CON: ++ return cmp(C_U7CON, b) ++ case C_U7CON: ++ return cmp(C_U6CON, b) ++ case C_U6CON: ++ return cmp(C_U5CON, b) ++ case C_U5CON: ++ return cmp(C_U4CON, b) ++ case C_U4CON: ++ return cmp(C_U3CON, b) ++ case C_U3CON: ++ return cmp(C_U2CON, b) ++ case C_U2CON: ++ return cmp(C_U1CON, b) ++ case C_U1CON: ++ return cmp(C_ZCON, b) ++ case C_US12CON: ++ return cmp(C_S12CON, b) ++ case C_S12CON: ++ return cmp(C_S5CON, b) || cmp(C_U8CON, b) || b == C_US12CON ++ case C_S5CON: ++ return cmp(C_ZCON, b) || cmp(C_U4CON, b) + + case C_DCON12_0: + +@@ -1183,62 +1192,20 @@ func cmp(a int, b int) bool { + return true + } + +- case C_ADD0CON: +- if b == C_ADDCON { +- return true +- } +- fallthrough +- +- case C_ADDCON: +- if b == C_ZCON || b == C_SCON { +- return true +- } +- +- case C_AND0CON: +- if b == C_ANDCON { +- return true +- } +- fallthrough +- +- case C_ANDCON: +- if b == C_ZCON || b == C_SCON { +- return true +- } +- +- case C_UCON: +- if b == C_ZCON { +- return true +- } +- +- case C_SCON: +- if b == C_ZCON { +- return true +- } +- + case C_LACON: +- if b == C_SACON { +- return true +- } ++ return b == C_SACON + + case C_LAUTO: +- if b == C_SAUTO { +- return true +- } ++ return b == C_SAUTO + + case C_REG: +- if b == C_ZCON { +- return true +- } ++ return b == C_ZCON + + case C_LOREG: +- if b == C_ZOREG || b == C_SOREG { +- return true +- } ++ return b == C_ZOREG || b == C_SOREG + + case C_SOREG: +- if b == C_ZOREG { +- return true +- } ++ return b == C_ZOREG + } + + return false +@@ -1881,7 +1848,7 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) { + r = int(o.param) + } + a := add +- if o.from1 == C_ANDCON { ++ if o.from1 == C_12CON && v > 0 { + a = AOR + } + +@@ -2008,15 +1975,9 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) { + if r == 0 { + r = int(p.To.Reg) + } +- +- switch o.flag { +- case immFiledSi5: +- c.checkimmFiled(p, v, 5, true) +- o1 = OP_5IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.To.Reg)) +- default: +- c.ctxt.Diag("Invalid immediate value type\n%v", p) +- } +- ++ ++ o1 = OP_5IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.To.Reg)) ++ + case 14: // add $ui8,[r1],r2 + v := c.regoff(&p.From) + r := int(p.Reg) +@@ -2024,13 +1985,7 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) { + r = int(p.To.Reg) + } + +- switch o.flag { +- case immFiledUi8: +- c.checkimmFiled(p, v, 8, false) +- o1 = OP_8IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.To.Reg)) +- default: +- c.ctxt.Diag("Invalid immediate value type\n%v", p) +- } ++ o1 = OP_8IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.To.Reg)) + + case 15: // teq $c r,r + v := c.regoff(&p.From) +@@ -2185,13 +2140,7 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) { + r = int(p.To.Reg) + } + +- switch o.flag { +- case immFiledUi3: +- c.checkimmFiled(p, v, 3, false) +- o1 = OP_3IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.To.Reg)) +- default: +- c.ctxt.Diag("Invalid immediate value type\n%v", p) +- } ++ o1 = OP_3IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.To.Reg)) + + case 30: // mov gr/fr/fcc/fcsr, fr/fcc/fcsr/gr + a := c.specialFpMovInst(p.As, oclass(&p.From), oclass(&p.To)) +@@ -2204,13 +2153,7 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) { + r = int(p.To.Reg) + } + +- switch o.flag { +- case immFiledUi4: +- c.checkimmFiled(p, v, 4, false) +- o1 = OP_4IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.To.Reg)) +- default: +- c.ctxt.Diag("Invalid immediate value type\n%v", p) +- } ++ o1 = OP_4IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.To.Reg)) + + case 32: // add $ui5,[r1],r2 + v := c.regoff(&p.From) +@@ -2219,13 +2162,7 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) { + r = int(p.To.Reg) + } + +- switch o.flag { +- case immFiledUi5: +- c.checkimmFiled(p, v, 5, false) +- o1 = OP_5IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.To.Reg)) +- default: +- c.ctxt.Diag("Invalid immediate value type\n%v", p) +- } ++ o1 = OP_5IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.To.Reg)) + + case 33: // add $ui6,[r1],r2 + v := c.regoff(&p.From) +@@ -2234,18 +2171,12 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) { + r = int(p.To.Reg) + } + +- switch o.flag { +- case immFiledUi6: +- c.checkimmFiled(p, v, 6, false) +- o1 = OP_6IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.To.Reg)) +- default: +- c.ctxt.Diag("Invalid immediate value type\n%v", p) +- } ++ o1 = OP_6IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.To.Reg)) + + case 34: // mov $con,fr + v := c.regoff(&p.From) + a := AADDU +- if o.from1 == C_ANDCON { ++ if v > 0 { + a = AOR + } + a2 := c.specialFpMovInst(p.As, C_REG, oclass(&p.To)) +@@ -2702,21 +2633,6 @@ func (c *ctxt0) checkindex(p *obj.Prog, index uint32, mask uint32) { + } + } + +-// checkimmFiled checks whether the immediate value exceeds the valid encoding range +-func (c *ctxt0) checkimmFiled(p *obj.Prog, imm int32, bits uint8, isSigned bool) { +- if isSigned { +- bound := int32(1 << (bits - 1)) +- if imm < -bound || imm > bound { +- c.ctxt.Diag("signed immediate %v exceeds the %d-bit range: %v", imm, bits, p) +- } +- } else { +- mask := uint32(0xffffffff) << bits +- if uint32(imm) != (uint32(imm) & ^mask) { +- c.ctxt.Diag("unsigned immediate %v exceeds the %d-bit range: %v", imm, bits, p) +- } +- } +-} +- + func (c *ctxt0) vregoff(a *obj.Addr) int64 { + c.instoffset = 0 + c.aclass(a) +diff --git a/src/cmd/internal/obj/loong64/cnames.go b/src/cmd/internal/obj/loong64/cnames.go +index a2f04a22ee..1d38f1ee36 100644 +--- a/src/cmd/internal/obj/loong64/cnames.go ++++ b/src/cmd/internal/obj/loong64/cnames.go +@@ -14,13 +14,24 @@ var cnames0 = []string{ + "ARNG", + "ELEM", + "ZCON", +- "SCON", +- "UCON", +- "ADD0CON", +- "AND0CON", +- "ADDCON", +- "ANDCON", +- "LCON", ++ "U1CON", ++ "U2CON", ++ "U3CON", ++ "U4CON", ++ "U5CON", ++ "U6CON", ++ "U7CON", ++ "U8CON", ++ "S5CON", ++ "US12CON", ++ "UU12CON", ++ "S12CON", ++ "U12CON", ++ "12CON", ++ "U15CON", ++ "15CON20_0", ++ "32CON20_0", ++ "32CON", + "DCON20S_0", + "DCON12_0", + "DCON32_0", +-- +2.38.1 + diff --git a/0038-crypto-internal-poly1305-implement-function-update-i.patch b/0038-crypto-internal-poly1305-implement-function-update-i.patch new file mode 100644 index 0000000000000000000000000000000000000000..e18caf23e121c1bd51c48e07b0a441cfffe140d6 --- /dev/null +++ b/0038-crypto-internal-poly1305-implement-function-update-i.patch @@ -0,0 +1,298 @@ +From 9e01e315f3ea08fc01854bf8beb2cdeb9ff6dddc Mon Sep 17 00:00:00 2001 +From: Xiaolin Zhao +Date: Thu, 19 Dec 2024 15:38:48 +0800 +Subject: [PATCH 38/44] crypto/internal/poly1305: implement function update in + assembly on loong64 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +There is some improvement in performance on Loongson 3A5000 and 3A6000. + +goos: linux +goarch: loong64 +pkg: golang.org/x/crypto/internal/poly1305 +cpu: Loongson-3A5000 @ 2500.00MHz + | bench.old | bench.new | + | sec/op | sec/op vs base | +64 122.8n ± 0% 101.2n ± 0% -17.59% (p=0.000 n=10) +1K 1152.0n ± 0% 779.4n ± 0% -32.34% (p=0.000 n=10) +2M 2.356m ± 0% 1.556m ± 0% -33.94% (p=0.000 n=10) +64Unaligned 122.7n ± 0% 102.5n ± 0% -16.46% (p=0.000 n=10) +1KUnaligned 1152.0n ± 0% 802.4n ± 0% -30.35% (p=0.000 n=10) +2MUnaligned 2.336m ± 0% 1.582m ± 0% -32.26% (p=0.000 n=10) +Write64 77.92n ± 0% 57.45n ± 0% -26.27% (p=0.000 n=10) +Write1K 1106.0n ± 0% 736.2n ± 0% -33.44% (p=0.000 n=10) +Write2M 2.356m ± 0% 1.562m ± 0% -33.69% (p=0.000 n=10) +Write64Unaligned 77.87n ± 0% 59.71n ± 0% -23.33% (p=0.000 n=10) +Write1KUnaligned 1106.0n ± 0% 749.5n ± 0% -32.23% (p=0.000 n=10) +Write2MUnaligned 2.335m ± 0% 1.580m ± 0% -32.34% (p=0.000 n=10) +geomean 6.373µ 4.530µ -28.93% + + | bench.old | bench.new | + | B/s | B/s vs base | +64 497.1Mi ± 0% 603.3Mi ± 0% +21.37% (p=0.000 n=10) +1K 847.6Mi ± 0% 1252.9Mi ± 0% +47.82% (p=0.000 n=10) +2M 849.0Mi ± 0% 1285.3Mi ± 0% +51.39% (p=0.000 n=10) +64Unaligned 497.4Mi ± 0% 595.5Mi ± 0% +19.73% (p=0.000 n=10) +1KUnaligned 847.6Mi ± 0% 1217.1Mi ± 0% +43.59% (p=0.000 n=10) +2MUnaligned 856.3Mi ± 0% 1264.0Mi ± 0% +47.61% (p=0.000 n=10) +Write64 783.3Mi ± 0% 1062.4Mi ± 0% +35.64% (p=0.000 n=10) +Write1K 882.8Mi ± 0% 1326.5Mi ± 0% +50.25% (p=0.000 n=10) +Write2M 849.0Mi ± 0% 1280.3Mi ± 0% +50.80% (p=0.000 n=10) +Write64Unaligned 783.8Mi ± 0% 1022.3Mi ± 0% +30.43% (p=0.000 n=10) +Write1KUnaligned 882.8Mi ± 0% 1303.0Mi ± 0% +47.59% (p=0.000 n=10) +Write2MUnaligned 856.5Mi ± 0% 1266.0Mi ± 0% +47.81% (p=0.000 n=10) +geomean 772.2Mi 1.061Gi +40.72% + +goos: linux +goarch: loong64 +pkg: golang.org/x/crypto/internal/poly1305 +cpu: Loongson-3A6000 @ 2500.00MHz + | bench.old | bench.new | + | sec/op | sec/op vs base | +64 92.06n ± 0% 77.56n ± 0% -15.75% (p=0.000 n=10) +1K 998.4n ± 0% 683.0n ± 0% -31.59% (p=0.000 n=10) +2M 1.978m ± 0% 1.323m ± 0% -33.11% (p=0.000 n=10) +64Unaligned 92.06n ± 0% 77.56n ± 0% -15.75% (p=0.000 n=10) +1KUnaligned 998.4n ± 0% 683.0n ± 0% -31.59% (p=0.000 n=10) +2MUnaligned 1.979m ± 0% 1.369m ± 0% -30.82% (p=0.000 n=10) +Write64 65.25n ± 0% 50.39n ± 0% -22.77% (p=0.000 n=10) +Write1K 970.7n ± 0% 656.8n ± 0% -32.34% (p=0.000 n=10) +Write2M 1.966m ± 0% 1.323m ± 0% -32.73% (p=0.000 n=10) +Write64Unaligned 65.24n ± 0% 50.37n ± 0% -22.79% (p=0.000 n=10) +Write1KUnaligned 970.8n ± 0% 656.8n ± 0% -32.34% (p=0.000 n=10) +Write2MUnaligned 1.966m ± 0% 1.368m ± 0% -30.42% (p=0.000 n=10) +geomean 5.319µ 3.834µ -27.93% + + | bench.old | bench.new | + | B/s | B/s vs base | +64 663.0Mi ± 0% 786.9Mi ± 0% +18.69% (p=0.000 n=10) +1K 978.1Mi ± 0% 1429.8Mi ± 0% +46.18% (p=0.000 n=10) +2M 1011.0Mi ± 0% 1511.4Mi ± 0% +49.50% (p=0.000 n=10) +64Unaligned 663.0Mi ± 0% 786.9Mi ± 0% +18.69% (p=0.000 n=10) +1KUnaligned 978.1Mi ± 0% 1429.8Mi ± 0% +46.18% (p=0.000 n=10) +2MUnaligned 1010.6Mi ± 0% 1460.9Mi ± 0% +44.56% (p=0.000 n=10) +Write64 935.4Mi ± 0% 1211.3Mi ± 0% +29.49% (p=0.000 n=10) +Write1K 1006.0Mi ± 0% 1486.9Mi ± 0% +47.81% (p=0.000 n=10) +Write2M 1017.3Mi ± 0% 1512.1Mi ± 0% +48.64% (p=0.000 n=10) +Write64Unaligned 935.5Mi ± 0% 1211.7Mi ± 0% +29.53% (p=0.000 n=10) +Write1KUnaligned 1005.9Mi ± 0% 1486.9Mi ± 0% +47.81% (p=0.000 n=10) +Write2MUnaligned 1017.1Mi ± 0% 1461.8Mi ± 0% +43.71% (p=0.000 n=10) +geomean 925.3Mi 1.254Gi +38.75% + +Change-Id: Iec990384a7be9a89a019c2b3b546d9fc59a2d58e +--- + .../x/crypto/internal/poly1305/mac_noasm.go | 2 +- + .../x/crypto/internal/poly1305/sum_loong64.go | 47 +++++++ + .../x/crypto/internal/poly1305/sum_loong64.s | 131 ++++++++++++++++++ + 3 files changed, 179 insertions(+), 1 deletion(-) + create mode 100644 src/vendor/golang.org/x/crypto/internal/poly1305/sum_loong64.go + create mode 100644 src/vendor/golang.org/x/crypto/internal/poly1305/sum_loong64.s + +diff --git a/src/vendor/golang.org/x/crypto/internal/poly1305/mac_noasm.go b/src/vendor/golang.org/x/crypto/internal/poly1305/mac_noasm.go +index bd896bdc76..8d99551fee 100644 +--- a/src/vendor/golang.org/x/crypto/internal/poly1305/mac_noasm.go ++++ b/src/vendor/golang.org/x/crypto/internal/poly1305/mac_noasm.go +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build (!amd64 && !ppc64le && !ppc64 && !s390x) || !gc || purego ++//go:build (!amd64 && !loong64 && !ppc64le && !ppc64 && !s390x) || !gc || purego + + package poly1305 + +diff --git a/src/vendor/golang.org/x/crypto/internal/poly1305/sum_loong64.go b/src/vendor/golang.org/x/crypto/internal/poly1305/sum_loong64.go +new file mode 100644 +index 0000000000..d4dc8f91ec +--- /dev/null ++++ b/src/vendor/golang.org/x/crypto/internal/poly1305/sum_loong64.go +@@ -0,0 +1,47 @@ ++// Copyright 2024 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 gc && !purego ++ ++package poly1305 ++ ++//go:noescape ++func update(state *macState, msg []byte) ++ ++// mac is a wrapper for macGeneric that redirects calls that would have gone to ++// updateGeneric to update. ++// ++// Its Write and Sum methods are otherwise identical to the macGeneric ones, but ++// using function pointers would carry a major performance cost. ++type mac struct{ macGeneric } ++ ++func (h *mac) Write(p []byte) (int, error) { ++ nn := len(p) ++ if h.offset > 0 { ++ n := copy(h.buffer[h.offset:], p) ++ if h.offset+n < TagSize { ++ h.offset += n ++ return nn, nil ++ } ++ p = p[n:] ++ h.offset = 0 ++ update(&h.macState, h.buffer[:]) ++ } ++ if n := len(p) - (len(p) % TagSize); n > 0 { ++ update(&h.macState, p[:n]) ++ p = p[n:] ++ } ++ if len(p) > 0 { ++ h.offset += copy(h.buffer[h.offset:], p) ++ } ++ return nn, nil ++} ++ ++func (h *mac) Sum(out *[16]byte) { ++ state := h.macState ++ if h.offset > 0 { ++ update(&state, h.buffer[:h.offset]) ++ } ++ finalize(out, &state.h, &state.s) ++} +diff --git a/src/vendor/golang.org/x/crypto/internal/poly1305/sum_loong64.s b/src/vendor/golang.org/x/crypto/internal/poly1305/sum_loong64.s +new file mode 100644 +index 0000000000..baf0c95333 +--- /dev/null ++++ b/src/vendor/golang.org/x/crypto/internal/poly1305/sum_loong64.s +@@ -0,0 +1,131 @@ ++// Copyright 2024 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 gc && !purego ++ ++// func update(state *macState, msg []byte) ++TEXT ·update(SB), $0-32 ++ MOVV state+0(FP), R4 ++ MOVV msg_base+8(FP), R5 ++ MOVV msg_len+16(FP), R6 ++ MOVV $16, R7 ++ MOVV (R4), R8 // h0 ++ MOVV 8(R4), R9 // h1 ++ MOVV 16(R4), R10 // h2 ++ MOVV 24(R4), R11 // r0 ++ MOVV 32(R4), R12 // r1 ++ ++ BLT R6, R7, bytes_between_0_and_15 ++ ++loop: ++ MOVV (R5), R14 // msg[0:8] ++ MOVV 8(R5), R16 // msg[8:16] ++ ADDV R14, R8, R8 // h0 ++ ADDV R9, R16, R27 ++ SGTU R14, R8, R24 // h0.carry ++ SGTU R9, R27, R28 ++ ADDV R27, R24, R9 // h1 ++ SGTU R27, R9, R24 ++ OR R24, R28, R24 // h1.carry ++ ADDV $1, R24, R24 ++ ADDV R10, R24, R10 // h2 ++ ++ ADDV $16, R5, R5 // msg = msg[16:] ++ ++multiply: ++ MULV R8, R11, R13 // h0r0.lo ++ MULHVU R8, R11, R16 // h0r0.hi ++ MOVV R13, R14 ++ MOVV R16, R15 ++ MULV R9, R11, R13 // h1r0.lo ++ MULHVU R9, R11, R16 // h1r0.hi ++ ADDV R13, R15, R15 ++ SGTU R13, R15, R24 ++ ADDV R24, R16, R16 ++ MULV R10, R11, R25 ++ ADDV R16, R25, R25 ++ MULV R8, R12, R13 // h0r1.lo ++ MULHVU R8, R12, R16 // h0r1.hi ++ ADDV R13, R15, R15 ++ SGTU R13, R15, R24 ++ ADDV R24, R16, R16 ++ MOVV R16, R8 ++ MULV R10, R12, R26 // h2r1 ++ MULV R9, R12, R13 // h1r1.lo ++ MULHVU R9, R12, R16 // h1r1.hi ++ ADDV R13, R25, R25 ++ ADDV R16, R26, R27 ++ SGTU R13, R25, R24 ++ SGTU R16, R27, R28 ++ ADDV R27, R24, R26 ++ SGTU R27, R26, R24 ++ OR R24, R28, R24 ++ ADDV R8, R25, R25 ++ SGTU R8, R25, R24 ++ ADDV R24, R26, R26 ++ MOVV R14, R8 ++ MOVV R15, R9 ++ MOVV R25, R10 ++ MOVV R25, R14 ++ AND $3, R10, R10 ++ AND $-4, R14, R14 ++ ADDV R14, R8, R8 ++ ADDV R26, R9, R27 ++ SGTU R14, R8, R24 ++ SGTU R26, R27, R28 ++ ADDV R27, R24, R9 ++ SGTU R27, R9, R24 ++ OR R24, R28, R24 ++ ADDV R24, R10, R10 ++ SLLV $62, R26, R27 ++ SRLV $2, R25, R28 ++ SRLV $2, R26, R26 ++ OR R27, R28, R25 ++ ADDV R25, R8, R8 ++ ADDV R26, R9, R27 ++ SGTU R25, R8, R24 ++ SGTU R26, R27, R28 ++ ADDV R27, R24, R9 ++ SGTU R27, R9, R24 ++ OR R24, R28, R24 ++ ADDV R24, R10, R10 ++ ++ SUBV $16, R6, R6 ++ BGE R6, R7, loop ++ ++bytes_between_0_and_15: ++ BEQ R6, R0, done ++ MOVV $1, R14 ++ XOR R15, R15 ++ XOR R25, R25 ++ ADDV R6, R5, R5 ++ ++flush_buffer: ++ SRLV $56, R14, R24 ++ SLLV $8, R15, R28 ++ OR R24, R28, R15 ++ SLLV $8, R14, R14 ++ MOVBU -1(R5), R25 ++ XOR R25, R14, R14 ++ SUBV $1, R5, R5 ++ SUBV $1, R6, R6 ++ BNE R6, R0, flush_buffer ++ ++ ADDV R14, R8, R8 ++ SGTU R14, R8, R24 ++ ADDV R15, R9, R27 ++ SGTU R15, R27, R28 ++ ADDV R27, R24, R9 ++ SGTU R27, R9, R24 ++ OR R24, R28, R24 ++ ADDV R10, R24, R10 ++ ++ MOVV $16, R6 ++ JMP multiply ++ ++done: ++ MOVV R8, (R4) ++ MOVV R9, 8(R4) ++ MOVV R10, 16(R4) ++ RET +-- +2.38.1 + diff --git a/0039-runtime-optimize-the-implementation-of-memclrNoHeapP.patch b/0039-runtime-optimize-the-implementation-of-memclrNoHeapP.patch new file mode 100644 index 0000000000000000000000000000000000000000..289a1f5ac28f28b391aab13473136c3cdf82e036 --- /dev/null +++ b/0039-runtime-optimize-the-implementation-of-memclrNoHeapP.patch @@ -0,0 +1,374 @@ +From 0e94e34886a3632315e444c5fd0ba448239c500e Mon Sep 17 00:00:00 2001 +From: chenguoqi +Date: Tue, 31 Dec 2024 18:31:50 +0800 +Subject: [PATCH 39/44] runtime: optimize the implementation of + memclrNoHeapPointers on loong64 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +goos: linux +goarch: loong64 +pkg: runtime +cpu: Loongson-3A6000 @ 2500.00MHz + │ bench.old │ bench.new │ + │ sec/op │ sec/op vs base │ +Memclr/5 2.456n ± 0% 3.202n ± 0% +30.37% (p=0.000 n=10) +Memclr/16 2.806n ± 0% 2.810n ± 1% +0.14% (p=0.002 n=10) +Memclr/64 5.053n ± 1% 5.045n ± 1% ~ (p=0.591 n=10) +Memclr/256 10.240n ± 0% 6.027n ± 0% -41.14% (p=0.000 n=10) +Memclr/4096 107.00n ± 0% 30.46n ± 0% -71.53% (p=0.000 n=10) +Memclr/65536 1676.0n ± 0% 431.3n ± 0% -74.26% (p=0.000 n=10) +Memclr/1M 52.52µ ± 0% 32.81µ ± 0% -37.54% (p=0.000 n=10) +Memclr/4M 210.0µ ± 0% 131.3µ ± 0% -37.48% (p=0.000 n=10) +Memclr/8M 420.0µ ± 0% 262.8µ ± 1% -37.43% (p=0.000 n=10) +Memclr/16M 846.7µ ± 0% 528.8µ ± 0% -37.55% (p=0.000 n=10) +Memclr/64M 3.388m ± 0% 2.180m ± 1% -35.66% (p=0.000 n=10) +MemclrUnaligned/0_5 4.382n ± 0% 4.006n ± 0% -8.59% (p=0.000 n=10) +MemclrUnaligned/0_16 4.600n ± 0% 4.204n ± 0% -8.60% (p=0.000 n=10) +MemclrUnaligned/0_64 5.604n ± 0% 5.005n ± 0% -10.69% (p=0.000 n=10) +MemclrUnaligned/0_256 10.340n ± 0% 6.808n ± 0% -34.16% (p=0.000 n=10) +MemclrUnaligned/0_4096 107.10n ± 0% 33.81n ± 0% -68.43% (p=0.000 n=10) +MemclrUnaligned/0_65536 1701.0n ± 0% 441.6n ± 0% -74.04% (p=0.000 n=10) +MemclrUnaligned/1_5 4.386n ± 0% 4.004n ± 0% -8.71% (p=0.000 n=10) +MemclrUnaligned/1_16 4.597n ± 0% 4.203n ± 0% -8.56% (p=0.000 n=10) +MemclrUnaligned/1_64 7.204n ± 0% 7.106n ± 0% -1.36% (p=0.000 n=10) +MemclrUnaligned/1_256 12.580n ± 0% 9.796n ± 0% -22.13% (p=0.000 n=10) +MemclrUnaligned/1_4096 115.60n ± 0% 38.63n ± 0% -66.58% (p=0.000 n=10) +MemclrUnaligned/1_65536 1709.0n ± 0% 446.5n ± 0% -73.87% (p=0.000 n=10) +MemclrUnaligned/4_5 4.386n ± 0% 4.005n ± 0% -8.69% (p=0.000 n=10) +MemclrUnaligned/4_16 4.597n ± 0% 4.203n ± 0% -8.57% (p=0.000 n=10) +MemclrUnaligned/4_64 7.204n ± 0% 7.104n ± 0% -1.39% (p=0.000 n=10) +MemclrUnaligned/4_256 12.58n ± 0% 10.66n ± 0% -15.22% (p=0.000 n=10) +MemclrUnaligned/4_4096 114.30n ± 0% 39.99n ± 0% -65.01% (p=0.000 n=10) +MemclrUnaligned/4_65536 1709.0n ± 0% 449.8n ± 0% -73.68% (p=0.000 n=10) +MemclrUnaligned/7_5 4.381n ± 0% 4.002n ± 0% -8.64% (p=0.000 n=10) +MemclrUnaligned/7_16 4.597n ± 0% 4.202n ± 0% -8.59% (p=0.000 n=10) +MemclrUnaligned/7_64 7.204n ± 0% 7.104n ± 0% -1.39% (p=0.000 n=10) +MemclrUnaligned/7_256 12.58n ± 0% 10.60n ± 0% -15.74% (p=0.000 n=10) +MemclrUnaligned/7_4096 115.50n ± 0% 39.75n ± 0% -65.58% (p=0.000 n=10) +MemclrUnaligned/7_65536 1709.0n ± 0% 447.1n ± 0% -73.84% (p=0.000 n=10) +MemclrUnaligned/0_1M 52.52µ ± 0% 32.80µ ± 0% -37.56% (p=0.000 n=10) +MemclrUnaligned/0_4M 210.0µ ± 0% 131.2µ ± 0% -37.53% (p=0.000 n=10) +MemclrUnaligned/0_8M 419.9µ ± 0% 262.5µ ± 0% -37.48% (p=0.000 n=10) +MemclrUnaligned/0_16M 845.0µ ± 0% 528.1µ ± 0% -37.51% (p=0.000 n=10) +MemclrUnaligned/0_64M 3.406m ± 0% 2.165m ± 1% -36.44% (p=0.000 n=10) +MemclrUnaligned/1_1M 52.53µ ± 0% 32.80µ ± 0% -37.55% (p=0.000 n=10) +MemclrUnaligned/1_4M 210.2µ ± 0% 131.3µ ± 0% -37.55% (p=0.000 n=10) +MemclrUnaligned/1_8M 419.9µ ± 0% 262.4µ ± 0% -37.50% (p=0.000 n=10) +MemclrUnaligned/1_16M 844.2µ ± 0% 528.0µ ± 0% -37.46% (p=0.000 n=10) +MemclrUnaligned/1_64M 3.369m ± 0% 2.161m ± 5% -35.84% (p=0.000 n=10) +MemclrUnaligned/4_1M 52.53µ ± 0% 32.80µ ± 0% -37.55% (p=0.000 n=10) +MemclrUnaligned/4_4M 210.2µ ± 0% 131.2µ ± 0% -37.59% (p=0.000 n=10) +MemclrUnaligned/4_8M 419.9µ ± 0% 262.4µ ± 0% -37.52% (p=0.000 n=10) +MemclrUnaligned/4_16M 844.5µ ± 0% 527.9µ ± 0% -37.49% (p=0.000 n=10) +MemclrUnaligned/4_64M 3.366m ± 0% 2.173m ± 0% -35.46% (p=0.000 n=10) +MemclrUnaligned/7_1M 52.52µ ± 0% 32.80µ ± 0% -37.55% (p=0.000 n=10) +MemclrUnaligned/7_4M 210.2µ ± 0% 131.5µ ± 0% -37.45% (p=0.000 n=10) +MemclrUnaligned/7_8M 419.9µ ± 0% 262.6µ ± 0% -37.47% (p=0.000 n=10) +MemclrUnaligned/7_16M 844.4µ ± 0% 529.0µ ± 0% -37.36% (p=0.000 n=10) +MemclrUnaligned/7_64M 3.372m ± 1% 2.201m ± 0% -34.72% (p=0.000 n=10) +MemclrRange/1K_2K 2703.0n ± 0% 948.1n ± 0% -64.93% (p=0.000 n=10) +MemclrRange/2K_8K 8.826µ ± 0% 2.458µ ± 0% -72.15% (p=0.000 n=10) +MemclrRange/4K_16K 8.325µ ± 0% 2.210µ ± 0% -73.45% (p=0.000 n=10) +MemclrRange/160K_228K 83.40µ ± 0% 31.27µ ± 0% -62.50% (p=0.000 n=10) +MemclrKnownSize1 0.4003n ± 0% 0.4002n ± 0% -0.02% (p=0.027 n=10) +MemclrKnownSize2 0.4003n ± 0% 0.4002n ± 0% -0.02% (p=0.000 n=10) +MemclrKnownSize4 0.4003n ± 0% 0.4002n ± 0% -0.02% (p=0.000 n=10) +MemclrKnownSize8 0.4003n ± 0% 0.4002n ± 0% -0.02% (p=0.000 n=10) +MemclrKnownSize16 0.4213n ± 1% 0.8007n ± 0% +90.03% (p=0.000 n=10) +MemclrKnownSize32 2.001n ± 0% 1.602n ± 0% -19.94% (p=0.000 n=10) +MemclrKnownSize64 2.010n ± 0% 2.402n ± 0% +19.47% (p=0.000 n=10) +MemclrKnownSize112 3.202n ± 0% 2.803n ± 0% -12.46% (p=0.000 n=10) +MemclrKnownSize128 3.442n ± 0% 3.236n ± 0% -6.00% (p=0.000 n=10) +MemclrKnownSize192 5.204n ± 0% 5.205n ± 0% ~ (p=0.279 n=10) +MemclrKnownSize248 6.301n ± 0% 6.299n ± 0% -0.03% (p=0.000 n=10) +MemclrKnownSize256 6.707n ± 0% 6.704n ± 0% -0.04% (p=0.018 n=10) +MemclrKnownSize512 13.610n ± 0% 6.989n ± 0% -48.65% (p=0.000 n=10) +MemclrKnownSize1024 26.420n ± 0% 8.458n ± 0% -67.99% (p=0.000 n=10) +MemclrKnownSize4096 103.30n ± 0% 28.02n ± 0% -72.88% (p=0.000 n=10) +MemclrKnownSize512KiB 26.28µ ± 0% 16.41µ ± 0% -37.53% (p=0.000 n=10) +geomean 624.0n 397.1n -36.37% + +Change-Id: I702b9c1991cf13f9338c189c5ef59cb2c6f279de +--- + src/runtime/cpuflags.go | 3 +- + src/runtime/memclr_loong64.s | 214 ++++++++++++++++++++++++----------- + 2 files changed, 152 insertions(+), 65 deletions(-) + +diff --git a/src/runtime/cpuflags.go b/src/runtime/cpuflags.go +index e81e50f5df..06424642c7 100644 +--- a/src/runtime/cpuflags.go ++++ b/src/runtime/cpuflags.go +@@ -20,7 +20,8 @@ const ( + + offsetMIPS64XHasMSA = unsafe.Offsetof(cpu.MIPS64X.HasMSA) + +- offsetLOONG64HasLSX = unsafe.Offsetof(cpu.Loong64.HasLSX) ++ offsetLOONG64HasLSX = unsafe.Offsetof(cpu.Loong64.HasLSX) ++ offsetLOONG64HasLASX = unsafe.Offsetof(cpu.Loong64.HasLASX) + ) + + var ( +diff --git a/src/runtime/memclr_loong64.s b/src/runtime/memclr_loong64.s +index 346b210c8d..0d0d9f0cbb 100644 +--- a/src/runtime/memclr_loong64.s ++++ b/src/runtime/memclr_loong64.s +@@ -11,6 +11,7 @@ + // R5: n + // R6: ptrend + // R7: tmp ++// R8: tmp + + // Algorithm: + // +@@ -38,44 +39,129 @@ + + // func memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr) + TEXT runtime·memclrNoHeapPointers(SB),NOSPLIT,$0-16 +- BEQ R5, clr_0 ++ // <=64 bytes, clear directly, not check aligned ++generic_small: + ADDV R4, R5, R6 ++ BEQ R4, R6, clr_0 ++ MOVV $2, R7 ++ BLT R5, R7, clr_1 ++ MOVV $3, R7 ++ BLT R5, R7, clr_2 ++ MOVV $4, R7 ++ BLT R5, R7, clr_3 ++ MOVV $5, R7 ++ BLT R5, R7, clr_4 ++ MOVV $8, R7 ++ BLT R5, R7, clr_5_7 ++ MOVV $9, R7 ++ BLT R5, R7, clr_8 ++ MOVV $17, R7 ++ BLT R5, R7, clr_9_16 ++ MOVV $33, R7 ++ BLT R5, R7, clr_17_32 ++ MOVV $65, R7 ++ BLT R5, R7, clr_33_64 + +-tail: +- // <=64 bytes, clear directly, not check aligned +- SGTU $2, R5, R7 +- BNE R7, clr_1 +- SGTU $3, R5, R7 +- BNE R7, clr_2 +- SGTU $4, R5, R7 +- BNE R7, clr_3 +- SGTU $5, R5, R7 +- BNE R7, clr_4 +- SGTU $8, R5, R7 +- BNE R7, clr_5through7 +- SGTU $9, R5, R7 +- BNE R7, clr_8 +- SGTU $17, R5, R7 +- BNE R7, clr_9through16 +- SGTU $33, R5, R7 +- BNE R7, clr_17through32 +- SGTU $65, R5, R7 +- BNE R7, clr_33through64 ++lasx_large: ++ MOVBU internal∕cpu·Loong64+const_offsetLOONG64HasLASX(SB), R7 ++ BEQ R7, lsx_large ++ ++ // X0 = 0 ++ XVMOVQ R0, X0.V4 ++ ++ // check 32-byte alignment ++ AND $31, R4, R7 ++ BEQ R7, lasx_large_aligned ++ XVMOVQ X0, (R4) ++ SUBV R7, R4 ++ ADDV R7, R5 ++ SUBV $32, R5 // newn = n - (32 - (ptr & 31)) ++ ADDV $32, R4 // newptr = ptr + (32 - (ptr & 31)) ++ ++lasx_large_aligned: ++ MOVV $256, R8 ++ BLT R5, R8, lasx_small ++lasx_large_body: ++ XVMOVQ X0, 0(R4) ++ XVMOVQ X0, 32(R4) ++ XVMOVQ X0, 64(R4) ++ XVMOVQ X0, 96(R4) ++ XVMOVQ X0, 128(R4) ++ XVMOVQ X0, 160(R4) ++ XVMOVQ X0, 192(R4) ++ XVMOVQ X0, 224(R4) ++ SUBV $256, R5 ++ ADDV $256, R4 ++ BGE R5, R8, lasx_large_body ++ ++lasx_small: ++ MOVV $32, R8 ++ BLT R5, R8, generic_small ++lasx_small_body: ++ XVMOVQ X0, (R4) ++ SUBV $32, R5 ++ ADDV $32, R4 ++ BGE R5, R8, lasx_small_body ++lasx_tail: ++ JMP generic_small ++ ++lsx_large: ++ MOVBU internal∕cpu·Loong64+const_offsetLOONG64HasLSX(SB), R7 ++ BEQ R7, generic_large ++ ++ // V0 = 0 ++ VMOVQ R0, V0.V2 + ++ // check 16-byte alignment ++ AND $15, R4, R7 ++ BEQ R7, lsx_large_aligned ++ VMOVQ V0, (R4) ++ SUBV R7, R4 ++ ADDV R7, R5 ++ SUBV $16, R5 // newn = n - (16 - (ptr & 15)) ++ ADDV $16, R4 // newptr = ptr + (16 - (ptr & 15)) ++ ++lsx_large_aligned: ++ MOVV $128, R8 ++ BLT R5, R8, lsx_small ++lsx_large_body: ++ VMOVQ V0, 0(R4) ++ VMOVQ V0, 16(R4) ++ VMOVQ V0, 32(R4) ++ VMOVQ V0, 48(R4) ++ VMOVQ V0, 64(R4) ++ VMOVQ V0, 80(R4) ++ VMOVQ V0, 96(R4) ++ VMOVQ V0, 112(R4) ++ SUBV $128, R5 ++ ADDV $128, R4 ++ BGE R5, R8, lsx_large_body ++ ++lsx_small: ++ MOVV $16, R8 ++ BLT R5, R8, generic_small ++lsx_small_body: ++ VMOVQ V0, (R4) ++ SUBV $16, R5 ++ ADDV $16, R4 ++ BGE R5, R8, lsx_small_body ++lsx_tail: ++ JMP generic_small ++ ++generic_large: + // n > 64 bytes, check aligned + AND $7, R4, R7 +- BEQ R7, body +- +-head: ++ BEQ R7, generic_large_aligned + MOVV R0, (R4) +- SUBV R7, R4 + ADDV R7, R5 +- ADDV $8, R4 // newptr = ptr + (8 - (ptr & 7)) ++ SUBV R7, R4 + SUBV $8, R5 // newn = n - (8 - (ptr & 7)) +- SGTU $65, R5, R7 +- BNE R7, clr_33through64 ++ ADDV $8, R4 // newptr = ptr + (8 - (ptr & 7)) + +-body: ++generic_large_aligned: ++ MOVV $65, R7 ++ BLT R5, R7, generic_small ++generic_large_body: + MOVV R0, (R4) + MOVV R0, 8(R4) + MOVV R0, 16(R4) +@@ -84,52 +170,52 @@ body: + MOVV R0, 40(R4) + MOVV R0, 48(R4) + MOVV R0, 56(R4) +- ADDV $-64, R5 ++ SUBV $64, R5 + ADDV $64, R4 +- SGTU $65, R5, R7 +- BEQ R7, body +- BEQ R5, clr_0 +- JMP tail ++ BGE R5, R7, generic_large_body ++generic_tail: ++ JMP generic_small + +-clr_0: ++clr_33_64: ++ MOVV R0, (R4) ++ MOVV R0, 8(R4) ++ MOVV R0, 16(R4) ++ MOVV R0, 24(R4) ++ MOVV R0, -32(R6) ++ MOVV R0, -24(R6) ++ MOVV R0, -16(R6) ++ MOVV R0, -8(R6) + RET +-clr_1: +- MOVB R0, (R4) ++ ++clr_17_32: ++ MOVV R0, (R4) ++ MOVV R0, 8(R4) ++ MOVV R0, -16(R6) ++ MOVV R0, -8(R6) + RET +-clr_2: +- MOVH R0, (R4) ++clr_9_16: ++ MOVV R0, (R4) ++ MOVV R0, -8(R6) + RET +-clr_3: +- MOVH R0, (R4) +- MOVB R0, 2(R4) ++clr_8: ++ MOVV R0, (R4) + RET +-clr_4: ++clr_5_7: + MOVW R0, (R4) ++ MOVW R0, -4(R6) + RET +-clr_5through7: ++clr_4: + MOVW R0, (R4) +- MOVW R0, -4(R6) + RET +-clr_8: +- MOVV R0, (R4) ++clr_3: ++ MOVH R0, (R4) ++ MOVB R0, 2(R4) + RET +-clr_9through16: +- MOVV R0, (R4) +- MOVV R0, -8(R6) ++clr_2: ++ MOVH R0, (R4) + RET +-clr_17through32: +- MOVV R0, (R4) +- MOVV R0, 8(R4) +- MOVV R0, -16(R6) +- MOVV R0, -8(R6) ++clr_1: ++ MOVB R0, (R4) + RET +-clr_33through64: +- MOVV R0, (R4) +- MOVV R0, 8(R4) +- MOVV R0, 16(R4) +- MOVV R0, 24(R4) +- MOVV R0, -32(R6) +- MOVV R0, -24(R6) +- MOVV R0, -16(R6) +- MOVV R0, -8(R6) ++clr_0: + RET +-- +2.38.1 + diff --git a/0040-runtime-race-add-the-implementation-of-atomic.-Or-An.patch b/0040-runtime-race-add-the-implementation-of-atomic.-Or-An.patch new file mode 100644 index 0000000000000000000000000000000000000000..39a261b130f8233e6a4ef7081b817fd0c5160f66 --- /dev/null +++ b/0040-runtime-race-add-the-implementation-of-atomic.-Or-An.patch @@ -0,0 +1,75 @@ +From 88b165cf7d4cb6a77f47d3c291d3ee7e1f13695e Mon Sep 17 00:00:00 2001 +From: Guoqi Chen +Date: Fri, 10 Jan 2025 10:31:47 +0800 +Subject: [PATCH 40/44] runtime/race: add the implementation of atomic.{Or,And} + on loong64 + +Change-Id: Ia4298a4d92fce210e3c743b2d5ce2b28b82d4971 +--- + src/runtime/race_loong64.s | 50 +++++++++++++++++++++++ + 2 files changed, 50 insertions(+) + +diff --git a/src/runtime/race_loong64.s b/src/runtime/race_loong64.s +index 04f264b21b..e6c11d44f7 100644 +--- a/src/runtime/race_loong64.s ++++ b/src/runtime/race_loong64.s +@@ -308,6 +308,56 @@ TEXT sync∕atomic·AddUintptr(SB), NOSPLIT, $0-24 + GO_ARGS + JMP sync∕atomic·AddInt64(SB) + ++// And ++TEXT sync∕atomic·AndInt32(SB), NOSPLIT, $0-20 ++ GO_ARGS ++ MOVV $__tsan_go_atomic32_fetch_and(SB), RCALL ++ JAL racecallatomic<>(SB) ++ RET ++ ++TEXT sync∕atomic·AndInt64(SB), NOSPLIT, $0-24 ++ GO_ARGS ++ MOVV $__tsan_go_atomic64_fetch_and(SB), RCALL ++ JAL racecallatomic<>(SB) ++ RET ++ ++TEXT sync∕atomic·AndUint32(SB), NOSPLIT, $0-20 ++ GO_ARGS ++ JMP sync∕atomic·AndInt32(SB) ++ ++TEXT sync∕atomic·AndUint64(SB), NOSPLIT, $0-24 ++ GO_ARGS ++ JMP sync∕atomic·AndInt64(SB) ++ ++TEXT sync∕atomic·AndUintptr(SB), NOSPLIT, $0-24 ++ GO_ARGS ++ JMP sync∕atomic·AndInt64(SB) ++ ++// Or ++TEXT sync∕atomic·OrInt32(SB), NOSPLIT, $0-20 ++ GO_ARGS ++ MOVV $__tsan_go_atomic32_fetch_or(SB), RCALL ++ JAL racecallatomic<>(SB) ++ RET ++ ++TEXT sync∕atomic·OrInt64(SB), NOSPLIT, $0-24 ++ GO_ARGS ++ MOVV $__tsan_go_atomic64_fetch_or(SB), RCALL ++ JAL racecallatomic<>(SB) ++ RET ++ ++TEXT sync∕atomic·OrUint32(SB), NOSPLIT, $0-20 ++ GO_ARGS ++ JMP sync∕atomic·OrInt32(SB) ++ ++TEXT sync∕atomic·OrUint64(SB), NOSPLIT, $0-24 ++ GO_ARGS ++ JMP sync∕atomic·OrInt64(SB) ++ ++TEXT sync∕atomic·OrUintptr(SB), NOSPLIT, $0-24 ++ GO_ARGS ++ JMP sync∕atomic·OrInt64(SB) ++ + // CompareAndSwap + TEXT sync∕atomic·CompareAndSwapInt32(SB), NOSPLIT, $0-17 + GO_ARGS +-- +2.38.1 + diff --git a/0041-cmd-internal-obj-loong64-add-F-MAXA-MINA-.-S-D-instr.patch b/0041-cmd-internal-obj-loong64-add-F-MAXA-MINA-.-S-D-instr.patch new file mode 100644 index 0000000000000000000000000000000000000000..847b4b1f3f22a9f0cb249f5e573e8f6c950ac84f --- /dev/null +++ b/0041-cmd-internal-obj-loong64-add-F-MAXA-MINA-.-S-D-instr.patch @@ -0,0 +1,107 @@ +From e652e32e37bfd898af333a32b73cfde6ab2116fa Mon Sep 17 00:00:00 2001 +From: Xiaolin Zhao +Date: Mon, 30 Dec 2024 10:08:58 +0800 +Subject: [PATCH 41/44] cmd/internal/obj/loong64: add F{MAXA/MINA}.{S/D} + instructions + +Go asm syntax: + F{MAXA/MINA}{F/D} FK, FJ, FD + +Equivalent platform assembler syntax: + f{maxa/mina}.{s/d} fd, fj, fk + +Ref: https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html + +Change-Id: I6790657d2f36bdf5e6818b6c0aaa48117e782b8d +--- + src/cmd/asm/internal/asm/testdata/loong64enc1.s | 9 +++++++++ + src/cmd/internal/obj/loong64/a.out.go | 6 ++++++ + src/cmd/internal/obj/loong64/anames.go | 4 ++++ + src/cmd/internal/obj/loong64/asm.go | 12 ++++++++++++ + 4 files changed, 31 insertions(+) + +diff --git a/src/cmd/asm/internal/asm/testdata/loong64enc1.s b/src/cmd/asm/internal/asm/testdata/loong64enc1.s +index b40d86e596..32d3b3f0a2 100644 +--- a/src/cmd/asm/internal/asm/testdata/loong64enc1.s ++++ b/src/cmd/asm/internal/asm/testdata/loong64enc1.s +@@ -346,6 +346,15 @@ lable2: + FTINTVF F0, F1 // 01241b01 + FTINTVD F0, F1 // 01281b01 + ++ FMAXAF F4, F5, F6 // a6900c01 ++ FMAXAF F4, F5 // a5900c01 ++ FMAXAD F4, F5, F6 // a6100d01 ++ FMAXAD F4, F5 // a5100d01 ++ FMINAF F4, F5, F6 // a6900e01 ++ FMINAF F4, F5 // a5900e01 ++ FMINAD F4, F5, F6 // a6100f01 ++ FMINAD F4, F5 // a5100f01 ++ + FTINTRMWF F0, F2 // 02041a01 + FTINTRMWD F0, F2 // 02081a01 + FTINTRMVF F0, F2 // 02241a01 +diff --git a/src/cmd/internal/obj/loong64/a.out.go b/src/cmd/internal/obj/loong64/a.out.go +index f2d4c41d68..857ea649e7 100644 +--- a/src/cmd/internal/obj/loong64/a.out.go ++++ b/src/cmd/internal/obj/loong64/a.out.go +@@ -688,6 +688,12 @@ const ( + AFMAXF + AFMAXD + ++ // 3.2.1.4 ++ AFMAXAF ++ AFMAXAD ++ AFMINAF ++ AFMINAD ++ + // 3.2.1.7 + AFCOPYSGF + AFCOPYSGD +diff --git a/src/cmd/internal/obj/loong64/anames.go b/src/cmd/internal/obj/loong64/anames.go +index aee0da0a6e..d2acdf7042 100644 +--- a/src/cmd/internal/obj/loong64/anames.go ++++ b/src/cmd/internal/obj/loong64/anames.go +@@ -223,6 +223,10 @@ var Anames = []string{ + "FMIND", + "FMAXF", + "FMAXD", ++ "FMAXAF", ++ "FMAXAD", ++ "FMINAF", ++ "FMINAD", + "FCOPYSGF", + "FCOPYSGD", + "FSCALEBF", +diff --git a/src/cmd/internal/obj/loong64/asm.go b/src/cmd/internal/obj/loong64/asm.go +index 2480cf9382..31f5376f8e 100644 +--- a/src/cmd/internal/obj/loong64/asm.go ++++ b/src/cmd/internal/obj/loong64/asm.go +@@ -1347,6 +1347,10 @@ func buildop(ctxt *obj.Link) { + opset(AFCOPYSGD, r0) + opset(AFSCALEBF, r0) + opset(AFSCALEBD, r0) ++ opset(AFMAXAF, r0) ++ opset(AFMAXAD, r0) ++ opset(AFMINAF, r0) ++ opset(AFMINAD, r0) + + case AFMADDF: + opset(AFMADDD, r0) +@@ -2811,6 +2815,14 @@ func (c *ctxt0) oprrr(a obj.As) uint32 { + return 0x211 << 15 // fmax.s + case AFMAXD: + return 0x212 << 15 // fmax.d ++ case AFMAXAF: ++ return 0x219 << 15 // fmaxa.s ++ case AFMAXAD: ++ return 0x21a << 15 // fmaxa.d ++ case AFMINAF: ++ return 0x21d << 15 // fmina.s ++ case AFMINAD: ++ return 0x21e << 15 // fmina.d + case AFSCALEBF: + return 0x221 << 15 // fscaleb.s + case AFSCALEBD: +-- +2.38.1 + diff --git a/0042-math-implement-func-archExp-and-archExp2-in-assembly.patch b/0042-math-implement-func-archExp-and-archExp2-in-assembly.patch new file mode 100644 index 0000000000000000000000000000000000000000..a9303c24b03f58fa52421ec53e6a08ff1d6c7e5f --- /dev/null +++ b/0042-math-implement-func-archExp-and-archExp2-in-assembly.patch @@ -0,0 +1,358 @@ +From f463c4a1db9ac0e4be9d67bc53f4ddb8515232d3 Mon Sep 17 00:00:00 2001 +From: Xiaolin Zhao +Date: Tue, 31 Dec 2024 21:02:47 +0800 +Subject: [PATCH 42/44] math: implement func archExp and archExp2 in assembly + on loong64 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +goos: linux +goarch: loong64 +pkg: math +cpu: Loongson-3A6000 @ 2500.00MHz + | bench.old | bench.new | + | sec/op | sec/op vs base | +Exp 26.30n ± 0% 12.93n ± 0% -50.85% (p=0.000 n=10) +ExpGo 26.86n ± 0% 26.92n ± 0% +0.22% (p=0.000 n=10) +Expm1 16.76n ± 0% 16.75n ± 0% ~ (p=0.060 n=10) +Exp2 23.05n ± 0% 12.12n ± 0% -47.42% (p=0.000 n=10) +Exp2Go 23.41n ± 0% 23.47n ± 0% +0.28% (p=0.000 n=10) +geomean 22.97n 17.54n -23.64% + +goos: linux +goarch: loong64 +pkg: math/cmplx +cpu: Loongson-3A6000 @ 2500.00MHz + | bench.old | bench.new | + | sec/op | sec/op vs base | +Exp 51.32n ± 0% 35.41n ± 0% -30.99% (p=0.000 n=10) + +goos: linux +goarch: loong64 +pkg: math +cpu: Loongson-3A5000 @ 2500.00MHz + | bench.old | bench.new | + | sec/op | sec/op vs base | +Exp 50.27n ± 0% 48.75n ± 1% -3.01% (p=0.000 n=10) +ExpGo 50.72n ± 0% 50.44n ± 0% -0.55% (p=0.000 n=10) +Expm1 28.40n ± 0% 28.32n ± 0% ~ (p=0.360 n=10) +Exp2 50.09n ± 0% 21.49n ± 1% -57.10% (p=0.000 n=10) +Exp2Go 50.05n ± 0% 49.69n ± 0% -0.72% (p=0.000 n=10) +geomean 44.85n 37.52n -16.35% + +goos: linux +goarch: loong64 +pkg: math/cmplx +cpu: Loongson-3A5000 @ 2500.00MHz + | bench.old | bench.new | + | sec/op | sec/op vs base | +Exp 88.56n ± 0% 67.29n ± 0% -24.03% (p=0.000 n=10) + +Change-Id: I89e456d26fc075d83335ee4a31227d2aface5714 +--- + src/math/exp2_asm.go | 2 +- + src/math/exp2_noasm.go | 2 +- + src/math/exp_asm.go | 2 +- + src/math/exp_loong64.s | 236 +++++++++++++++++++++++++++++++++++++++++ + src/math/exp_noasm.go | 2 +- + 5 files changed, 240 insertions(+), 4 deletions(-) + create mode 100644 src/math/exp_loong64.s + +diff --git a/src/math/exp2_asm.go b/src/math/exp2_asm.go +index c26b2c3fab..1e78759374 100644 +--- a/src/math/exp2_asm.go ++++ b/src/math/exp2_asm.go +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build arm64 ++//go:build arm64 || loong64 + + package math + +diff --git a/src/math/exp2_noasm.go b/src/math/exp2_noasm.go +index c2b409329f..847138b622 100644 +--- a/src/math/exp2_noasm.go ++++ b/src/math/exp2_noasm.go +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build !arm64 ++//go:build !arm64 && !loong64 + + package math + +diff --git a/src/math/exp_asm.go b/src/math/exp_asm.go +index 424442845b..125529fca3 100644 +--- a/src/math/exp_asm.go ++++ b/src/math/exp_asm.go +@@ -2,7 +2,7 @@ + // 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 ++//go:build amd64 || arm64 || loong64 || s390x + + package math + +diff --git a/src/math/exp_loong64.s b/src/math/exp_loong64.s +new file mode 100644 +index 0000000000..3d24214289 +--- /dev/null ++++ b/src/math/exp_loong64.s +@@ -0,0 +1,236 @@ ++// Copyright 2024 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" ++ ++#define NearZero 0x3e30000000000000 // 2**-28 ++#define PosInf 0x7ff0000000000000 ++#define FracMask 0x000fffffffffffff ++#define C1 0x3cb0000000000000 // 2**-52 ++ ++DATA exprodata<>+0(SB)/8, $0.0 ++DATA exprodata<>+8(SB)/8, $0.5 ++DATA exprodata<>+16(SB)/8, $1.0 ++DATA exprodata<>+24(SB)/8, $2.0 ++DATA exprodata<>+32(SB)/8, $6.93147180369123816490e-01 // Ln2Hi ++DATA exprodata<>+40(SB)/8, $1.90821492927058770002e-10 // Ln2Lo ++DATA exprodata<>+48(SB)/8, $1.44269504088896338700e+00 // Log2e ++DATA exprodata<>+56(SB)/8, $7.09782712893383973096e+02 // Overflow ++DATA exprodata<>+64(SB)/8, $-7.45133219101941108420e+02 // Underflow ++DATA exprodata<>+72(SB)/8, $1.0239999999999999e+03 // Overflow2 ++DATA exprodata<>+80(SB)/8, $-1.0740e+03 // Underflow2 ++DATA exprodata<>+88(SB)/8, $3.7252902984619141e-09 // NearZero ++GLOBL exprodata<>+0(SB), NOPTR|RODATA, $96 ++ ++DATA expmultirodata<>+0(SB)/8, $1.66666666666666657415e-01 // P1 ++DATA expmultirodata<>+8(SB)/8, $-2.77777777770155933842e-03 // P2 ++DATA expmultirodata<>+16(SB)/8, $6.61375632143793436117e-05 // P3 ++DATA expmultirodata<>+24(SB)/8, $-1.65339022054652515390e-06 // P4 ++DATA expmultirodata<>+32(SB)/8, $4.13813679705723846039e-08 // P5 ++GLOBL expmultirodata<>+0(SB), NOPTR|RODATA, $40 ++ ++// Exp returns e**x, the base-e exponential of x. ++// This is an assembly implementation of the method used for function Exp in file exp.go. ++// ++// func Exp(x float64) float64 ++TEXT ·archExp(SB),$0-16 ++ MOVD x+0(FP), F0 // F0 = x ++ ++ MOVV $exprodata<>+0(SB), R10 ++ MOVD 56(R10), F1 // Overflow ++ MOVD 64(R10), F2 // Underflow ++ MOVD 88(R10), F3 // NearZero ++ MOVD 16(R10), F17 // 1.0 ++ ++ CMPEQD F0, F0, FCC0 ++ BFPF isNaN // x = NaN, return NaN ++ ++ CMPGTD F0, F1, FCC0 ++ BFPT overflow // x > Overflow, return PosInf ++ ++ CMPGTD F2, F0, FCC0 ++ BFPT underflow // x < Underflow, return 0 ++ ++ ABSD F0, F5 ++ CMPGTD F3, F5, FCC0 ++ BFPT nearzero // fabs(x) < NearZero, return 1 + x ++ ++ // argument reduction, x = k*ln2 + r, |r| <= 0.5*ln2 ++ // computed as r = hi - lo for extra precision. ++ MOVD 0(R10), F5 // 0.0 ++ MOVD 8(R10), F3 // 0.5 ++ MOVD 48(R10), F2 // Log2e ++ CMPGTD F0, F5, FCC0 ++ BFPT add // x > 0 ++sub: ++ FMSUBD F3, F2, F0, F3 // Log2e*x - 0.5 ++ JMP 2(PC) ++add: ++ FMADDD F3, F2, F0, F3 // Log2e*x + 0.5 ++ ++ FTINTRZVD F3, F4 // float64 -> int64 ++ MOVV F4, R5 // R5 = int(k) ++ FFINTDV F4, F3 // int64 -> float64 ++ ++ MOVD 32(R10), F4 // F4 = Ln2Hi ++ MOVD 40(R10), F5 // F5 = Ln2Lo ++ FNMSUBD F0, F3, F4, F4 // F4 = hi = x - float64(int(k))*Ln2Hi ++ MULD F3, F5, F5 // F5 = lo = float64(int(k)) * Ln2Lo ++ SUBD F5, F4, F6 // F6 = r = hi - lo ++ MULD F6, F6, F7 // F7 = t = r * r ++ ++ // compute c ++ MOVV $expmultirodata<>+0(SB), R11 ++ MOVD 32(R11), F8 // F8 = P5 ++ MOVD 24(R11), F9 // F9 = P4 ++ FMADDD F9, F8, F7, F13 // P4+t*P5 ++ MOVD 16(R11), F10 // F10 = P3 ++ FMADDD F10, F13, F7, F13 // P3+t*(P4+t*P5) ++ MOVD 8(R11), F11 // F11 = P2 ++ FMADDD F11, F13, F7, F13 // P2+t*(P3+t*(P4+t*P5)) ++ MOVD 0(R11), F12 // F12 = P1 ++ FMADDD F12, F13, F7, F13 // P1+t*(P2+t*(P3+t*(P4+t*P5))) ++ FNMSUBD F6, F13, F7, F13 // F13 = c = r - t*(P1+t*(P2+t*(P3+t*(P4+t*P5)))) ++ ++ // compute y ++ MOVD 24(R10), F14 // F14 = 2.0 ++ SUBD F13, F14, F14 // F14 = 2 - c ++ MULD F6, F13, F15 // F15 = r*c ++ DIVD F14, F15, F15 // F15 = (r*c)/(2-c) ++ SUBD F15, F5, F15 // F15 = lo-(r*c)/(2-c) ++ SUBD F4, F15, F15 // F15 = (lo-(r*c)/(2-c))-hi ++ SUBD F15, F17, F16 // F16 = y = 1-((lo-(r*c)/(2-c))-hi) ++ ++ // inline Ldexp(y, k), benefit: ++ // 1, no parameter pass overhead. ++ // 2, skip unnecessary checks for Inf/NaN/Zero ++ MOVV F16, R4 ++ MOVV $FracMask, R9 ++ AND R9, R4, R6 // fraction ++ SRLV $52, R4, R7 // exponent ++ ADDV R5, R7 // R5 = int(k) ++ MOVV $1, R12 ++ BGE R7, R12, normal ++ ADDV $52, R7 // denormal ++ MOVV $C1, R8 ++ MOVV R8, F17 // m = 2**-52 ++normal: ++ SLLV $52, R7 ++ OR R7, R6, R4 ++ MOVV R4, F0 ++ MULD F17, F0 // return m * x ++ MOVD F0, ret+8(FP) ++ RET ++nearzero: ++ ADDD F17, F0, F0 ++isNaN: ++ MOVD F0, ret+8(FP) ++ RET ++underflow: ++ MOVV R0, ret+8(FP) ++ RET ++overflow: ++ MOVV $PosInf, R4 ++ MOVV R4, ret+8(FP) ++ RET ++ ++ ++// Exp2 returns 2**x, the base-2 exponential of x. ++// This is an assembly implementation of the method used for function Exp2 in file exp.go. ++// ++// func Exp2(x float64) float64 ++TEXT ·archExp2(SB),$0-16 ++ MOVD x+0(FP), F0 // F0 = x ++ ++ MOVV $exprodata<>+0(SB), R10 ++ MOVD 72(R10), F1 // Overflow2 ++ MOVD 80(R10), F2 // Underflow2 ++ MOVD 88(R10), F3 // NearZero ++ ++ CMPEQD F0, F0, FCC0 ++ BFPF isNaN // x = NaN, return NaN ++ ++ CMPGTD F0, F1, FCC0 ++ BFPT overflow // x > Overflow, return PosInf ++ ++ CMPGTD F2, F0, FCC0 ++ BFPT underflow // x < Underflow, return 0 ++ ++ // argument reduction; x = r*lg(e) + k with |r| <= ln(2)/2 ++ // computed as r = hi - lo for extra precision. ++ MOVD 0(R10), F10 // 0.0 ++ MOVD 8(R10), F2 // 0.5 ++ CMPGTD F0, F10, FCC0 ++ BFPT add ++sub: ++ SUBD F2, F0, F3 // x - 0.5 ++ JMP 2(PC) ++add: ++ ADDD F2, F0, F3 // x + 0.5 ++ ++ FTINTRZVD F3, F4 // float64 -> int64 ++ MOVV F4, R5 // R5 = int(k) ++ FFINTDV F4, F3 // F3 = float64(int(k)) ++ ++ MOVD 32(R10), F4 // F4 = Ln2Hi ++ MOVD 40(R10), F5 // F5 = Ln2Lo ++ SUBD F3, F0, F3 // t = x - float64(int(k)) ++ MULD F3, F4 // F4 = hi = t * Ln2Hi ++ FNMSUBD F10, F3, F5, F5 // F5 = lo = -t * Ln2Lo ++ SUBD F5, F4, F6 // F6 = r = hi - lo ++ MULD F6, F6, F7 // F7 = t = r * r ++ ++ // compute c ++ MOVV $expmultirodata<>+0(SB), R11 ++ MOVD 32(R11), F8 // F8 = P5 ++ MOVD 24(R11), F9 // F9 = P4 ++ FMADDD F9, F8, F7, F13 // P4+t*P5 ++ MOVD 16(R11), F10 // F10 = P3 ++ FMADDD F10, F13, F7, F13 // P3+t*(P4+t*P5) ++ MOVD 8(R11), F11 // F11 = P2 ++ FMADDD F11, F13, F7, F13 // P2+t*(P3+t*(P4+t*P5)) ++ MOVD 0(R11), F12 // F12 = P1 ++ FMADDD F12, F13, F7, F13 // P1+t*(P2+t*(P3+t*(P4+t*P5))) ++ FNMSUBD F6, F13, F7, F13 // F13 = c = r - t*(P1+t*(P2+t*(P3+t*(P4+t*P5)))) ++ ++ // compute y ++ MOVD 24(R10), F14 // F14 = 2.0 ++ SUBD F13, F14, F14 // F14 = 2 - c ++ MULD F6, F13, F15 // F15 = r*c ++ DIVD F14, F15 // F15 = (r*c)/(2-c) ++ ++ MOVD 16(R10), F17 // 1.0 ++ SUBD F15, F5, F15 // lo-(r*c)/(2-c) ++ SUBD F4, F15, F15 // (lo-(r*c)/(2-c))-hi ++ SUBD F15, F17, F16 // F16 = y = 1-((lo-(r*c)/(2-c))-hi) ++ ++ // inline Ldexp(y, k), benefit: ++ // 1, no parameter pass overhead. ++ // 2, skip unnecessary checks for Inf/NaN/Zero ++ MOVV F16, R4 ++ MOVV $FracMask, R9 ++ SRLV $52, R4, R7 // exponent ++ AND R9, R4, R6 // fraction ++ ADDV R5, R7 // R5 = int(k) ++ MOVV $1, R12 ++ BGE R7, R12, normal ++ ++ ADDV $52, R7 // denormal ++ MOVV $C1, R8 ++ MOVV R8, F17 // m = 2**-52 ++normal: ++ SLLV $52, R7 ++ OR R7, R6, R4 ++ MOVV R4, F0 ++ MULD F17, F0 // return m * x ++isNaN: ++ MOVD F0, ret+8(FP) ++ RET ++underflow: ++ MOVV R0, ret+8(FP) ++ RET ++overflow: ++ MOVV $PosInf, R4 ++ MOVV R4, ret+8(FP) ++ RET +diff --git a/src/math/exp_noasm.go b/src/math/exp_noasm.go +index bd3f02412a..bf5e84b736 100644 +--- a/src/math/exp_noasm.go ++++ b/src/math/exp_noasm.go +@@ -2,7 +2,7 @@ + // 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 ++//go:build !amd64 && !arm64 && !loong64 && !s390x + + package math + +-- +2.38.1 + diff --git a/0043-math-implement-func-archLog-in-assembly-on-loong64.patch b/0043-math-implement-func-archLog-in-assembly-on-loong64.patch new file mode 100644 index 0000000000000000000000000000000000000000..f01c831480e7521902cef28d0a507e0a1dfbf614 --- /dev/null +++ b/0043-math-implement-func-archLog-in-assembly-on-loong64.patch @@ -0,0 +1,217 @@ +From 066bd3bf1a03e21cc27b463164461a56ce107d59 Mon Sep 17 00:00:00 2001 +From: Xiaolin Zhao +Date: Mon, 6 Jan 2025 15:40:06 +0800 +Subject: [PATCH 43/44] math: implement func archLog in assembly on loong64 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +goos: linux +goarch: loong64 +pkg: math +cpu: Loongson-3A6000 @ 2500.00MHz + | bench.old | bench.new | + | sec/op | sec/op vs base | +Log 18.87n ± 0% 12.85n ± 0% -31.90% (p=0.000 n=10) +Logb 5.203n ± 0% 5.604n ± 0% +7.71% (p=0.000 n=10) +Log1p 16.78n ± 0% 16.78n ± 0% ~ (p=0.450 n=10) +Log10 20.47n ± 0% 13.59n ± 0% -33.61% (p=0.000 n=10) +Log2 6.804n ± 0% 8.805n ± 0% +29.40% (p=0.000 n=10) +geomean 11.81n 10.77n -8.82% + +goos: linux +goarch: loong64 +pkg: math +cpu: Loongson-3A5000 @ 2500.00MHz + | bench.old | bench.new | + | sec/op | sec/op vs base | +Log 28.28n ± 0% 24.95n ± 1% -11.78% (p=0.000 n=10) +Logb 7.609n ± 0% 7.207n ± 0% -5.29% (p=0.000 n=10) +Log1p 27.27n ± 0% 27.18n ± 1% ~ (p=0.078 n=10) +Log10 29.56n ± 0% 26.56n ± 0% -10.16% (p=0.000 n=10) +Log2 11.43n ± 0% 10.41n ± 0% -8.92% (p=0.000 n=10) +geomean 18.17n 16.83n -7.38% + +Change-Id: I42a17280874c28b31a3b5c75fc19ddac90c92f32 +--- + src/math/log_asm.go | 2 +- + src/math/log_loong64.s | 140 +++++++++++++++++++++++++++++++++++++++++ + src/math/log_stub.go | 2 +- + 3 files changed, 142 insertions(+), 2 deletions(-) + create mode 100644 src/math/log_loong64.s + +diff --git a/src/math/log_asm.go b/src/math/log_asm.go +index 848cce13b2..82372d1e64 100644 +--- a/src/math/log_asm.go ++++ b/src/math/log_asm.go +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build amd64 || s390x ++//go:build amd64 || loong64 || s390x + + package math + +diff --git a/src/math/log_loong64.s b/src/math/log_loong64.s +new file mode 100644 +index 0000000000..534295cb53 +--- /dev/null ++++ b/src/math/log_loong64.s +@@ -0,0 +1,140 @@ ++// Copyright 2025 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" ++ ++DATA logrodata<>+0(SB)/8, $0.5 ++DATA logrodata<>+8(SB)/8, $1.0 ++DATA logrodata<>+16(SB)/8, $2.0 ++DATA logrodata<>+24(SB)/8, $7.07106781186547524401e-01 // sqrt(2)/2 ++DATA logrodata<>+32(SB)/8, $6.93147180369123816490e-01 // Ln2Hi ++DATA logrodata<>+40(SB)/8, $1.90821492927058770002e-10 // Ln2Lo ++DATA logrodata<>+48(SB)/8, $6.666666666666735130e-01 // L1 ++DATA logrodata<>+56(SB)/8, $3.999999999940941908e-01 // L2 ++DATA logrodata<>+64(SB)/8, $2.857142874366239149e-01 // L3 ++DATA logrodata<>+72(SB)/8, $2.222219843214978396e-01 // L4 ++DATA logrodata<>+80(SB)/8, $1.818357216161805012e-01 // L5 ++DATA logrodata<>+88(SB)/8, $1.531383769920937332e-01 // L6 ++DATA logrodata<>+96(SB)/8, $1.479819860511658591e-01 // L7 ++DATA logrodata<>+104(SB)/8, $2.2250738585072014e-308 // 2**-1022 ++GLOBL logrodata<>+0(SB), NOPTR|RODATA, $112 ++ ++#define NaN 0x7FF8000000000001 ++#define NegInf 0xFFF0000000000000 ++#define PosInf 0x7FF0000000000000 ++ ++// func Log(x float64) float64 ++TEXT ·archLog(SB),NOSPLIT,$0 ++ // test bits for special cases ++ MOVD x+0(FP), F0 ++ MOVV x+0(FP), R4 ++ MOVV $logrodata<>+0(SB), R10 ++ FCLASSD F0, F4 ++ MOVV F4, R5 ++ AND $67, R5, R6 // NaN or +Inf ++ AND $544, R5, R7 // +0 or -0 ++ AND $28, R5, R8 // <0 ++ BNE R6, R0, isInfOrNaN ++ BNE R7, R0, isZero ++ BNE R8, R0, isNegative ++ ++ // reduce ++ // f1, ki := Frexp(x) FIXME ++ MOVD 104(R10), F4 ++ ABSD F0, F1 ++ CMPGED F1, F4, FCC0 ++ BFPT direct_return ++ MOVV $0x10000000000000, R5 // 1 << 52 ++ MULV R4, R5, R4 // R4 = y ++ MOVV $-52, R15 // R15 = ki (exp) ++ JMP 2(PC) ++direct_return: ++ MOVV $0, R15 // R15 = ki (exp) F0 = y ++ ++ MOVV $0x000FFFFFFFFFFFFF, R5 ++ AND R4, R5, R7 // x &^= mask << shift ++ MOVV $0x3FE0000000000000, R6 // (-1 + bias) << shift ++ OR R6, R7 // x |= (-1 + bias) << shift ++ MOVV R7, F2 // F2 = f1 ++ SRLV $52, R4 // x >> shift ++ AND $0x7FF, R4 // (x>>shift)&mask ++ SUBV $0x3FE, R4 // int((x>>shift)&mask) - bias + 1 ++ ADDV R4, R15, R4 // R4 = exp ++ ++ // if f1 < math.Sqrt2/2 { k -= 1; f1 *= 2 } ++ MOVD 0(R10), F10 // 0.5 ++ MOVD 8(R10), F3 // 1.0 ++ MOVD 16(R10), F4 // 2.0 ++ MOVD 24(R10), F0 // sqrt(2)/2 ++ CMPGED F2, F0, FCC0 // if f1 >= Sqrt2/2 ++ BFPT next ++ MULD F4, F2, F2 // f1 *= 2 ++ SUBV $1, R4, R4 ++next: ++ MOVV R4, F1 // k-- ++ FFINTDV F1, F1 // F1 = k ++ // f := f1 - 1 ++ SUBD F3, F2, F2 ++ ++ // compute ++ MOVD 96(R10), F17 // L7 ++ MOVD 80(R10), F15 // L5 ++ MOVD 64(R10), F13 // L3 ++ MOVD 48(R10), F11 // L1 ++ ADDD F4, F2, F3 // 2 + f ++ DIVD F3, F2, F4 // s := f / (2 + f) ++ MULD F4, F4, F5 // s2 := s * s ++ MULD F5, F5, F6 // s4 := s2 * s2 ++ // t1 := s2 * (L1 + s4*(L3+s4*(L5+s4*L7))) ++ MULD F17, F6, F7 // s4*L7 ++ ADDD F15, F7 // L5+s4*L7 ++ MULD F6, F7 // s4*(L5+s4*L7) ++ ADDD F13, F7 // L3+s4*(L5+s4*L7) ++ MULD F6, F7 // s4*(L3+s4*(L5+s4*L7)) ++ ADDD F11, F7 // L1 + s4*(L3+s4*(L5+s4*L7)) ++ MULD F5, F7 // s2 * (L1 + s4*(L3+s4*(L5+s4*L7))) ++ ++ MOVD 88(R10), F16 // L6 ++ MOVD 72(R10), F14 // L4 ++ MOVD 56(R10), F12 // L2 ++ // t2 := s4 * (L2 + s4*(L4+s4*L6)) ++ MULD F6, F16, F8 // s4*L6 ++ ADDD F14, F8 // L4+s4*L6 ++ MULD F6, F8 // s4*(L4+s4*L6) ++ ADDD F12, F8 // L2 + s4*(L4+s4*L6) ++ MULD F6, F8 // s4 * (L2 + s4*(L4+s4*L6)) ++ ++ // R := t1 + t2 ++ ADDD F7, F8 ++ ++ // hfsq := 0.5 * f * f ++ MULD F2, F2, F12 // f * f ++ MULD F10, F12, F9 // 0.5 * f * f ++ ++ // return k*Ln2Hi - ((hfsq - (s*(hfsq+R) + k*Ln2Lo)) - f) ++ MOVD 40(R10), F19 // Ln2Lo ++ MOVD 32(R10), F18 // Ln2Hi ++ // f9=hfsq, f1=k, f4=s, f8=R, f2=f ++ ADDD F9, F8, F10 // F10 = hfsq+R ++ MULD F1, F19, F11 // F11 = k*Ln2Lo ++ MULD F10, F4, F12 // F12 = s*(hfsq+R) ++ MULD F1, F18, F15 // F15 = k*Ln2Hi ++ ADDD F12, F11, F13 // F13 = s*(hfsq+R) + k*Ln2Lo ++ SUBD F13, F9, F14 // F14 = hfsq - (s*(hfsq+R) + k*Ln2Lo) ++ SUBD F2, F14, F14 // F14 = (hfsq - (s*(hfsq+R) + k*Ln2Lo)) - f ++ SUBD F14, F15, F0 ++ MOVD F0, ret+8(FP) ++ RET ++ ++isInfOrNaN: ++ MOVV R4, ret+8(FP) // +Inf or NaN, return x ++ RET ++isNegative: ++ MOVV $NaN, R4 ++ MOVV R4, ret+8(FP) // return NaN ++ RET ++isZero: ++ MOVV $NegInf, R4 ++ MOVV R4, ret+8(FP) // return -Inf ++ RET +diff --git a/src/math/log_stub.go b/src/math/log_stub.go +index d35992bf37..1dd4058435 100644 +--- a/src/math/log_stub.go ++++ b/src/math/log_stub.go +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build !amd64 && !s390x ++//go:build !amd64 && !loong64 && !s390x + + package math + +-- +2.38.1 + diff --git a/0044-cmd-go-internal-work-allow-a-bunch-of-loong64-specif.patch b/0044-cmd-go-internal-work-allow-a-bunch-of-loong64-specif.patch new file mode 100644 index 0000000000000000000000000000000000000000..40422df348c4672d8c6836dd29ad3fe19709142c --- /dev/null +++ b/0044-cmd-go-internal-work-allow-a-bunch-of-loong64-specif.patch @@ -0,0 +1,126 @@ +From fc3470aafbb3facc619e4813eaf0ea10d5c7eda9 Mon Sep 17 00:00:00 2001 +From: WANG Xuerui +Date: Sun, 9 Feb 2025 18:57:49 +0800 +Subject: [PATCH 44/44] cmd/go/internal/work: allow a bunch of loong64-specific + flags + +Recognize and allow all LoongArch-specific CFLAGS as standardized +in the LoongArch Toolchain Conventions v1.1, and implemented in current +versions of GCC and Clang, to enable advanced cgo use cases on loong64. +These flags are also allowed for linker invocations in case of possible +LTO. + +See: https://github.com/loongson/la-toolchain-conventions/blob/releases/v1.1/LoongArch-toolchain-conventions-EN.adoc#list + +While at it, also add support for -mtls-dialect as some C programs +may benefit performance-wise from the optional TLSDESC usage. This flag +is not specific to loong64 though; it is available for amd64, arm, +arm64, loong64, riscv64 and x86. + +Fixes #71597. + +Change-Id: I35d2507edb71fa324ae429a3ae3c739644a9cac1 +--- + src/cmd/go/internal/work/security.go | 13 ++++++++-- + src/cmd/go/internal/work/security_test.go | 31 +++++++++++++++++++++++ + 2 files changed, 42 insertions(+), 2 deletions(-) + +diff --git a/src/cmd/go/internal/work/security.go b/src/cmd/go/internal/work/security.go +index 50bfd0ab70..c3d62ddc23 100644 +--- a/src/cmd/go/internal/work/security.go ++++ b/src/cmd/go/internal/work/security.go +@@ -96,17 +96,21 @@ var validCompilerFlags = []*lazyregexp.Regexp{ + re(`-g([^@\-].*)?`), + re(`-m32`), + re(`-m64`), +- re(`-m(abi|arch|cpu|fpu|tune)=([^@\-].*)`), ++ re(`-m(abi|arch|cpu|fpu|simd|tls-dialect|tune)=([^@\-].*)`), + re(`-m(no-)?v?aes`), + re(`-marm`), + re(`-m(no-)?avx[0-9a-z]*`), + re(`-mcmodel=[0-9a-z-]+`), + re(`-mfloat-abi=([^@\-].*)`), ++ re(`-m(soft|single|double)-float`), + re(`-mfpmath=[0-9a-z,+]*`), + re(`-m(no-)?avx[0-9a-z.]*`), + re(`-m(no-)?ms-bitfields`), + re(`-m(no-)?stack-(.+)`), + re(`-mmacosx-(.+)`), ++ re(`-m(no-)?relax`), ++ re(`-m(no-)?strict-align`), ++ re(`-m(no-)?(lsx|lasx|frecipe|div32|lam-bh|lamcas|ld-seq-sa)`), + re(`-mios-simulator-version-min=(.+)`), + re(`-miphoneos-version-min=(.+)`), + re(`-mlarge-data-threshold=[0-9]+`), +@@ -166,8 +170,13 @@ var validLinkerFlags = []*lazyregexp.Regexp{ + re(`-flat_namespace`), + re(`-g([^@\-].*)?`), + re(`-headerpad_max_install_names`), +- re(`-m(abi|arch|cpu|fpu|tune)=([^@\-].*)`), ++ re(`-m(abi|arch|cpu|fpu|simd|tls-dialect|tune)=([^@\-].*)`), ++ re(`-mcmodel=[0-9a-z-]+`), + re(`-mfloat-abi=([^@\-].*)`), ++ re(`-m(soft|single|double)-float`), ++ re(`-m(no-)?relax`), ++ re(`-m(no-)?strict-align`), ++ re(`-m(no-)?(lsx|lasx|frecipe|div32|lam-bh|lamcas|ld-seq-sa)`), + re(`-mmacosx-(.+)`), + re(`-mios-simulator-version-min=(.+)`), + re(`-miphoneos-version-min=(.+)`), +diff --git a/src/cmd/go/internal/work/security_test.go b/src/cmd/go/internal/work/security_test.go +index 35af621764..48f98100a5 100644 +--- a/src/cmd/go/internal/work/security_test.go ++++ b/src/cmd/go/internal/work/security_test.go +@@ -50,10 +50,35 @@ var goodCompilerFlags = [][]string{ + {"-ftls-model=local-dynamic"}, + {"-g"}, + {"-ggdb"}, ++ {"-mabi=lp64d"}, + {"-march=souza"}, + {"-mcmodel=medium"}, + {"-mcpu=123"}, + {"-mfpu=123"}, ++ {"-mtls-dialect=gnu"}, ++ {"-mtls-dialect=gnu2"}, ++ {"-mtls-dialect=trad"}, ++ {"-mtls-dialect=desc"}, ++ {"-mtls-dialect=xyz"}, ++ {"-msimd=lasx"}, ++ {"-msimd=xyz"}, ++ {"-mdouble-float"}, ++ {"-mrelax"}, ++ {"-mstrict-align"}, ++ {"-mlsx"}, ++ {"-mlasx"}, ++ {"-mfrecipe"}, ++ {"-mlam-bh"}, ++ {"-mlamcas"}, ++ {"-mld-seq-sa"}, ++ {"-mno-relax"}, ++ {"-mno-strict-align"}, ++ {"-mno-lsx"}, ++ {"-mno-lasx"}, ++ {"-mno-frecipe"}, ++ {"-mno-lam-bh"}, ++ {"-mno-lamcas"}, ++ {"-mno-ld-seq-sa"}, + {"-mlarge-data-threshold=16"}, + {"-mtune=happybirthday"}, + {"-mstack-overflow"}, +@@ -96,7 +121,13 @@ var badCompilerFlags = [][]string{ + {"-march=@dawn"}, + {"-march=-dawn"}, + {"-mcmodel=@model"}, ++ {"-mfpu=@0"}, ++ {"-mfpu=-0"}, + {"-mlarge-data-threshold=@12"}, ++ {"-mtls-dialect=@gnu"}, ++ {"-mtls-dialect=-gnu"}, ++ {"-msimd=@none"}, ++ {"-msimd=-none"}, + {"-std=@c99"}, + {"-std=-c99"}, + {"-x@c"}, +-- +2.38.1 + diff --git a/anolis.go b/anolis.go new file mode 100644 index 0000000000000000000000000000000000000000..6fca3e7a72d217153d1d17acef0f52f9217271e0 --- /dev/null +++ b/anolis.go @@ -0,0 +1,11 @@ +//go:build rpm_crashtraceback +// +build rpm_crashtraceback + +// Copyright 2023 OpenAnolis Community. All rights reserved. +// Use of this source code is governed by the MIT license. + +package runtime + +func init() { + setTraceback("crash") +} diff --git a/bundled-deps.sh b/bundled-deps.sh new file mode 100755 index 0000000000000000000000000000000000000000..bdcbd306f3a952559b028da8e75844504d6c0c96 --- /dev/null +++ b/bundled-deps.sh @@ -0,0 +1,23 @@ +#! /bin/bash +# Copyright (C) 2021 Jakub Čajka jcajka@redhat.com +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +provides="" +for bundle in $(find -name modules.txt); do +provides="$provides\n$(cat "$bundle" | grep "^# " | grep -v "# explicit" | sed -r s/"^#.* => "// | sed -r "s/# //" | sed -r "s:(.*) v(.*):Provides\: bundled(golang(\1)) = \2:")" +done +#TODO replace - with . in version per packaging guidelines +echo -e "$provides" | sort -u diff --git a/cookie b/cookie new file mode 100644 index 0000000000000000000000000000000000000000..6a303a2c251d20648cc93bea1397465e04f57aa2 --- /dev/null +++ b/cookie @@ -0,0 +1,5 @@ +# Netscape HTTP Cookie File +# https://curl.haxx.se/docs/http-cookies.html +# This file was generated by libcurl! Edit at your own risk. + +#HttpOnly_39.105.20.176 FALSE / FALSE 0 session .eJwly7kNgDAMAMBdXFMYEuOEZZCfWFQ8ElSI3RGiv7tBrnOZ1221BhMUIaQxEalyoJlabn01D7PMxgHd77ddjusLVbOWHj9dOZVCjoE-sAziHinD8wLm6h2t.aSgTaw.LZRJXbIXqM0HS7BPD7AMsSqF7CY diff --git a/download b/download new file mode 100644 index 0000000000000000000000000000000000000000..26ed1dccb10934a2de6bcfa2a1415a5a37071b86 --- /dev/null +++ b/download @@ -0,0 +1 @@ +22c7cfa0b7160a0bb2283226b9964967 go1.24.8.src.tar.gz diff --git a/golang-gdbinit b/golang-gdbinit new file mode 100644 index 0000000000000000000000000000000000000000..ecddca6d67c41fa3f5f8e3f1a47b4cedcb4afd3c --- /dev/null +++ b/golang-gdbinit @@ -0,0 +1 @@ +add-auto-load-safe-path /usr/lib/golang/src/runtime/runtime-gdb.py diff --git a/golang.spec b/golang.spec new file mode 100644 index 0000000000000000000000000000000000000000..16571d915eef36f7c2127c4cde9db8679d575bee --- /dev/null +++ b/golang.spec @@ -0,0 +1,814 @@ +%define anolis_release 1 + +# Disable debuginfo packages +%global debug_package %{nil} +%global _binaries_in_noarch_packages_terminate_build 0 + +# Do not check any files in doc or src for requires +%global __requires_exclude_from ^(%{_datadir}|/usr/lib)/%{name}/(doc|src)/.*$ + +# Don't alter timestamps of especially the .a files (or else go will rebuild later) +# Actually, don't strip at all since we are not even building debug packages and this corrupts the dwarf testdata +%global __strip /bin/true + +# Set goroot golibdir path +%global golibdir %{_libdir}/golang +%global goroot /usr/lib/%{name} + +# This macro may not always be defined, ensure it is +%{!?gopath: %global gopath %{_datadir}/gocode} + +# rpmbuild magic to keep from having meta dependency on libc.so.6 +%define _use_internal_dependency_generator 0 +%define __find_requires %{nil} +%global __spec_install_post /usr/lib/rpm/check-rpaths /usr/lib/rpm/check-buildroot \ + /usr/lib/rpm/brp-compress + +#### Golang build options. +# Build golang with cgo enabled/disabled(later equals more or less to internal linking). +%bcond_without cgo + +# Build golang using external/internal(close to cgo disabled) linking. +%bcond_without external_linker + +# Use golang/gcc-go as bootstrap compiler +%bcond_with bootstrap + +# Controls what ever we fail on failed tests +%ifarch aarch64 loongarch64 riscv64 sw_64 +%bcond_with fail_on_tests +%else +%bcond_without fail_on_tests +%endif + +# Build golang shared objects for stdlib +%ifarch loongarch64 riscv64 sw_64 +%bcond_with shared +%else +%bcond_without shared +%endif + +# Pre build std lib with -race enabled +# Disabled due to 1.20 new cache usage, see 1.20 upstream release notes +%bcond_with race + + +%ifarch x86_64 +%global gohostarch amd64 +%endif +%ifarch aarch64 +%global gohostarch arm64 +%endif +%ifarch loongarch64 +%global gohostarch loong64 +%endif +%ifarch riscv64 +%global gohostarch riscv64 +%endif +%ifarch sw_64 +%global gohostarch sw64 +%endif + +# Comment out go_patch as needed +%global go_api 1.24 +%global go_patch 8 + +Name: golang +Version: %{go_api}%{?go_patch:.%{go_patch}} +Release: %{anolis_release}%{?dist} +Summary: The Go Programming Language +License: BSD and Public Domain +URL: https://go.dev +Source0: https://go.dev/dl/go%{go_api}%{?go_patch:.%{go_patch}}.src.tar.gz +# make possible to override default traceback level at build time by setting build tag rpm_crashtraceback +Source1: anolis.go + +Patch1: 0001-cmd-link-internal-add-support-for-internal-linking-o.patch +Patch2: 0002-cmd-dist-internal-platform-enable-internal-linking-f.patch +Patch3: 0003-cmd-runtime-enable-race-detector-on-loong64.patch +Patch4: 0004-runtime-delete-on-register-ABI-fallback-path-for-rac.patch +Patch5: 0005-cmd-internal-obj-loong64-remove-unused-register-alia.patch +Patch6: 0006-internal-bytealg-optimize-IndexByte-and-IndexByteStr.patch +Patch7: 0007-internal-bytealg-optimize-memequal-and-memequal_varl.patch +Patch8: 0008-internal-bytealg-optimize-Index-and-IndexString-func.patch +Patch9: 0009-internal-bytealg-optimize-Count-and-CountString-func.patch +Patch10: 0010-internal-bytealg-adjust-the-format-of-assembly-files.patch +Patch11: 0011-cmd-internal-obj-loong64-optimize-immediate-loading.patch +Patch12: 0012-math-big-optimize-addVV-function-for-loong64.patch +Patch13: 0013-math-big-optimize-addVW-function-for-loong64.patch +Patch14: 0014-math-big-optimize-subVV-function-for-loong64.patch +Patch15: 0015-math-big-optimize-subVW-function-for-loong64.patch +Patch16: 0016-math-big-optimize-shlVU-function-for-loong64.patch +Patch17: 0017-math-big-optimize-shrVU-function-for-loong64.patch +Patch18: 0018-math-big-optimize-mulAddVWW-function-for-loong64.patch +Patch19: 0019-math-big-optimize-addMulVVW-function-for-loong64.patch +Patch20: 0020-cmd-compile-fold-constant-shift-with-extension-on-lo.patch +Patch21: 0021-test-codegen-fix-the-matching-instructions-inside-pl.patch +Patch22: 0022-cmd-compile-optimize-shifts-of-int32-and-uint32-on-l.patch +Patch23: 0023-cmd-compile-simplify-bounded-shift-on-loong64.patch +Patch24: 0024-runtime-use-ABIInternal-on-syscall-and-other-sys.stu.patch +Patch25: 0025-runtime-use-correct-memory-barrier-in-exitThread-fun.patch +Patch26: 0026-cmd-internal-obj-loong64-add-V-XV-SEQI-V-XV-.-AND-OR.patch +Patch27: 0027-cmd-internal-obj-loong64-add-V-XV-ADD-SUB-.-B-H-W-D-.patch +Patch28: 0028-cmd-internal-obj-loong64-add-V-XV-ILV-L-H-.-B-H-W-D-.patch +Patch29: 0029-cmd-internal-obj-loong64-add-V-XV-SLL-SRL-SRA-ROTR-I.patch +Patch30: 0030-cmd-internal-obj-loong64-add-V-XV-FSQRT-FRECIP-FRSQR.patch +Patch31: 0031-cmd-internal-obj-loong64-add-V-XV-NEG-B-H-W-V-instru.patch +Patch32: 0032-cmd-internal-obj-loong64-add-V-XV-MUL-B-H-W-V-and-V-.patch +Patch33: 0033-cmd-internal-obj-loong64-add-V-XV-DIV-B-H-W-V-U-and-.patch +Patch34: 0034-cmd-internal-obj-loong64-add-V-XV-BITCLR-BITSET-BITR.patch +Patch35: 0035-crypto-chacha20-add-loong64-SIMD-implementation.patch +Patch36: 0036-internal-bytealg-optimize-Count-String-in-loong64.patch +Patch37: 0037-cmd-internal-obj-cmd-asm-reclassify-32-bit-immediate.patch +Patch38: 0038-crypto-internal-poly1305-implement-function-update-i.patch +Patch39: 0039-runtime-optimize-the-implementation-of-memclrNoHeapP.patch +Patch40: 0040-runtime-race-add-the-implementation-of-atomic.-Or-An.patch +Patch41: 0041-cmd-internal-obj-loong64-add-F-MAXA-MINA-.-S-D-instr.patch +Patch42: 0042-math-implement-func-archExp-and-archExp2-in-assembly.patch +Patch43: 0043-math-implement-func-archLog-in-assembly-on-loong64.patch +Patch44: 0044-cmd-go-internal-work-allow-a-bunch-of-loong64-specif.patch + +# Part 1001-1999 for sw_64 +Patch1001: 0001-cmd-comile-Add-sw64-port.patch +Patch1002: 0002-cmd-internal-obj-Add-sw64-port.patch +Patch1003: 0003-cmd-link-Add-sw64-port.patch +Patch1004: 0004-cmd-asm-Add-sw64-port.patch +Patch1005: 0005-runtime-Add-sw64-port.patch +Patch1006: 0006-syscall-Add-sw64-port.patch +Patch1007: 0007-cmd-dist-Add-sw64-port.patch +Patch1008: 0008-cmd-cgo-Add-sw64-port.patch +Patch1009: 0009-reflect-Add-sw64-port.patch +Patch1010: 0010-cmd-vendor-vendor-Add-sw64-port.patch +Patch1011: 0011-cmd-go-go-Add-sw64-port.patch +Patch1012: 0012-src-internal-Add-sw64-port.patch +Patch1013: 0013-crypto-hash-math-Add-sw64-port.patch +Patch1014: 0014-api-Add-sw64-port.patch +Patch1015: 0015-debug-Add-sw64-port.patch +Patch1016: 0016-encoding-os-sw64-add-var-NativeEndian.patch + +# The compiler is written in Go. Needs go(1.4+) compiler for build. +%if %{with bootstrap} +BuildRequires: gcc-go >= 5 +%else +BuildRequires: golang > 1.4 +%endif +BuildRequires: hostname +# for tests +BuildRequires: pcre-devel +BuildRequires: glibc-static +BuildRequires: perl-interpreter +BuildRequires: procps-ng + +Provides: go = %{version}-%{release} + +# Bundled/Vendored provides can be found in `find . -name modules.txt` on the in tree module data +# - in version filed substituted with . per versioning guidelines +Provides: bundled(golang(github.com/google/pprof)) = 0.0.0.20221118152302.e6195bd50e26 +Provides: bundled(golang(github.com/ianlancetaylor/demangle)) = 0.0.0.20220319035150.800ac71e25c2 +Provides: bundled(golang(golang.org/x/arch)) = 0.1.1.0.20221116201807.1bb480fc256a +Provides: bundled(golang(golang.org/x/crypto)) = 0.3.1.0.20221117191849.2c476679df9a +Provides: bundled(golang(golang.org/x/mod)) = 0.7.0 +Provides: bundled(golang(golang.org/x/net)) = 0.4.1.0.20230214201333.88ed8ca3307d +Provides: bundled(golang(golang.org/x/sync)) = 0.1.0 +Provides: bundled(golang(golang.org/x/sys)) = 0.3.0 +Provides: bundled(golang(golang.org/x/term)) = 0.2.0 +Provides: bundled(golang(golang.org/x/text)) = 0.5.0 +Provides: bundled(golang(golang.org/x/tools)) = 0.3.1.0.20230118190848.070db2996ebe + +Requires: %{name}-bin = %{version}-%{release} +Requires: %{name}-src = %{version}-%{release} + +Source100: golang-gdbinit + +## git binary diffs are not supported. (Patch1051) +Source102: race_linux_loong64.syso + +%description +The Go programming language is an open source project to make programmers more productive. + +Go is expressive, concise, clean, and efficient. Its concurrency mechanisms +make it easy to write programs that get the most out of multicore and networked +machines, while its novel type system enables flexible and modular program +construction. + +Go compiles quickly to machine code yet has the convenience of garbage +collection and the power of run-time reflection. It's a fast, statically typed, +compiled language that feels like a dynamically typed, interpreted language. + +%package docs +Summary: Golang compiler docs +Requires: %{name} = %{version}-%{release} +BuildArch: noarch + +%description docs +The Go programming language is an open source project to make programmers more productive. + +Go is expressive, concise, clean, and efficient. Its concurrency mechanisms +make it easy to write programs that get the most out of multicore and networked +machines, while its novel type system enables flexible and modular program +construction. + +Go compiles quickly to machine code yet has the convenience of garbage +collection and the power of run-time reflection. It's a fast, statically typed, +compiled language that feels like a dynamically typed, interpreted language. + +This package includes compiler documents of Go. + +%package misc +Summary: Golang compiler miscellaneous sources +Requires: %{name} = %{version}-%{release} +BuildArch: noarch + +%description misc +The Go programming language is an open source project to make programmers more productive. + +Go is expressive, concise, clean, and efficient. Its concurrency mechanisms +make it easy to write programs that get the most out of multicore and networked +machines, while its novel type system enables flexible and modular program +construction. + +Go compiles quickly to machine code yet has the convenience of garbage +collection and the power of run-time reflection. It's a fast, statically typed, +compiled language that feels like a dynamically typed, interpreted language. + +This package includes misc of Go. + +%package tests +Summary: Golang compiler tests for stdlib +Requires: %{name} = %{version}-%{release} +BuildArch: noarch + +%description tests +The Go programming language is an open source project to make programmers more productive. + +Go is expressive, concise, clean, and efficient. Its concurrency mechanisms +make it easy to write programs that get the most out of multicore and networked +machines, while its novel type system enables flexible and modular program +construction. + +Go compiles quickly to machine code yet has the convenience of garbage +collection and the power of run-time reflection. It's a fast, statically typed, +compiled language that feels like a dynamically typed, interpreted language. + +This package includes compiler tests for stdlib of Go. + +%package src +Summary: Golang compiler source tree +BuildArch: noarch +%description src +The Go programming language is an open source project to make programmers more productive. + +Go is expressive, concise, clean, and efficient. Its concurrency mechanisms +make it easy to write programs that get the most out of multicore and networked +machines, while its novel type system enables flexible and modular program +construction. + +Go compiles quickly to machine code yet has the convenience of garbage +collection and the power of run-time reflection. It's a fast, statically typed, +compiled language that feels like a dynamically typed, interpreted language. + +This package includes compiler source tree of Go. + +%package bin +Summary: Golang core compiler tools +# Some distributions refer to this package by this name +Provides: %{name}-go = %{version}-%{release} +Requires: go = %{version}-%{release} +Requires(post): %{_sbindir}/update-alternatives +Requires(preun): %{_sbindir}/update-alternatives + +# We strip the meta dependency, but go does require glibc. +# This is an odd issue, still looking for a better fix. +Requires: glibc +Requires: gcc +Recommends: git, subversion, mercurial + +%description bin +The Go programming language is an open source project to make programmers more productive. + +Go is expressive, concise, clean, and efficient. Its concurrency mechanisms +make it easy to write programs that get the most out of multicore and networked +machines, while its novel type system enables flexible and modular program +construction. + +Go compiles quickly to machine code yet has the convenience of garbage +collection and the power of run-time reflection. It's a fast, statically typed, +compiled language that feels like a dynamically typed, interpreted language. + +This package includes core compiler tools of Go. + +# Workaround old RPM bug of symlink-replaced-with-dir failure +%pretrans -p +for _,d in pairs({"api", "doc", "include", "lib", "src"}) do + path = "%{goroot}/" .. d + if posix.stat(path, "type") == "link" then + os.remove(path) + posix.mkdir(path) + end +end + +%if %{with shared} +%package shared +Summary: Golang shared object libraries + +%description shared +The Go programming language is an open source project to make programmers more productive. + +Go is expressive, concise, clean, and efficient. Its concurrency mechanisms +make it easy to write programs that get the most out of multicore and networked +machines, while its novel type system enables flexible and modular program +construction. + +Go compiles quickly to machine code yet has the convenience of garbage +collection and the power of run-time reflection. It's a fast, statically typed, +compiled language that feels like a dynamically typed, interpreted language. + +This package includes shared object libraries of Go. +%endif + +%if %{with race} +%package race +Summary: Golang std library with -race enabled + +Requires: %{name} = %{version}-%{release} + +%description race +The Go programming language is an open source project to make programmers more productive. + +Go is expressive, concise, clean, and efficient. Its concurrency mechanisms +make it easy to write programs that get the most out of multicore and networked +machines, while its novel type system enables flexible and modular program +construction. + +Go compiles quickly to machine code yet has the convenience of garbage +collection and the power of run-time reflection. It's a fast, statically typed, +compiled language that feels like a dynamically typed, interpreted language. + +This package includes std library with -race enabled of Go. +%endif + +%prep +%autosetup -p1 -n go + +cp %{SOURCE1} ./src/runtime/ +cp %{SOURCE102} ./src/runtime/race + +%build +# print out system information +uname -a +cat /proc/cpuinfo +cat /proc/meminfo + +# bootstrap compiler GOROOT +%if %{with bootstrap} +export GOROOT_BOOTSTRAP=/ +%else +export GOROOT_BOOTSTRAP=%{goroot} +%endif + +# set up final install location +export GOROOT_FINAL=%{goroot} + +export GOHOSTOS=linux +export GOHOSTARCH=%{gohostarch} + +pushd src +# use our gcc options for this build, but store gcc as default for compiler +export CFLAGS="$RPM_OPT_FLAGS" +export LDFLAGS="$RPM_LD_FLAGS" +export CC="gcc" +export CC_FOR_TARGET="gcc" +export GOOS=linux +export GOARCH=%{gohostarch} +%if !%{with external_linker} +export GO_LDFLAGS="-linkmode internal" +%endif +%if !%{with cgo} +export CGO_ENABLED=0 +%endif +./make.bash --no-clean -v +popd + +# build shared std lib +%if %{with shared} +GOROOT=$(pwd) PATH=$(pwd)/bin:$PATH go install -buildmode=shared -v -x std +%endif + +%if %{with race} +GOROOT=$(pwd) PATH=$(pwd)/bin:$PATH go install -race -v -x std +%endif + +%install +echo "== 1 ==" +rm -rf %{buildroot} +# remove GC build cache +rm -rf pkg/obj/go-build/* + +# create the top level directories +mkdir -p %{buildroot}%{_bindir} +mkdir -p %{buildroot}%{goroot} + +# install everything into libdir (until symlink problems are fixed) +# https://code.google.com/p/go/issues/detail?id=5830 +cp -apv api bin doc lib pkg src misc test VERSION \ + %{buildroot}%{goroot} +echo "== 2 ==" +# bz1099206 +find %{buildroot}%{goroot}/src -exec touch -r %{buildroot}%{goroot}/VERSION "{}" \; +# and level out all the built archives +touch %{buildroot}%{goroot}/pkg +find %{buildroot}%{goroot}/pkg -exec touch -r %{buildroot}%{goroot}/pkg "{}" \; +# generate the spec file ownership of this source tree and packages +cwd=$(pwd) +src_list=$cwd/go-src.list +pkg_list=$cwd/go-pkg.list +shared_list=$cwd/go-shared.list +race_list=$cwd/go-race.list +misc_list=$cwd/go-misc.list +docs_list=$cwd/go-docs.list +tests_list=$cwd/go-tests.list +rm -f $src_list $pkg_list $docs_list $misc_list $tests_list $shared_list $race_list +touch $src_list $pkg_list $docs_list $misc_list $tests_list $shared_list $race_list +pushd %{buildroot}%{goroot} + echo "== 3 ==" + find src/ -type d -a \( ! -name testdata -a ! -ipath '*/testdata/*' \) \ + -printf '%%%dir %{goroot}/%p\n' >> $src_list + find src/ ! -type d -a \( ! -ipath '*/testdata/*' -a ! -name '*_test.go' \) \ + -printf '%{goroot}/%p\n' >> $src_list + + find bin/ pkg/ -type d -a ! -path '*_dynlink/*' -a ! -path '*_race/*' \ + -printf '%%%dir %{goroot}/%p\n' >> $pkg_list + find bin/ pkg/ ! -type d -a ! -path '*_dynlink/*' -a ! -path '*_race/*' \ + -printf '%{goroot}/%p\n' >> $pkg_list + + find doc/ -type d \ + -printf '%%%dir %{goroot}/%p\n' >> $docs_list + find doc/ ! -type d \ + -printf '%{goroot}/%p\n' >> $docs_list + + find misc/ -type d \ + -printf '%%%dir %{goroot}/%p\n' >> $misc_list + find misc/ ! -type d \ + -printf '%{goroot}/%p\n' >> $misc_list + +%if %{with shared} +echo "== 4 ==" + mkdir -p %{buildroot}/%{_libdir}/ + mkdir -p %{buildroot}/%{golibdir}/ + for file in $(find . -iname "*.so" ); do + chmod 755 $file + mv $file %{buildroot}/%{golibdir} + pushd $(dirname $file) + ln -fs %{golibdir}/$(basename $file) $(basename $file) + popd + echo "%%{goroot}/$file" >> $shared_list + echo "%%{golibdir}/$(basename $file)" >> $shared_list + done + + find pkg/*_dynlink/ -type d \ + -printf '%%%dir %{goroot}/%p\n' >> $shared_list + find pkg/*_dynlink/ ! -type d \ + -printf '%{goroot}/%p\n' >> $shared_list +%endif + +echo "== 5 ==" + +%if %{with race} + find pkg/*_race/ -type d \ + -printf '%%%dir %{goroot}/%p\n' >> $race_list + find pkg/*_race/ ! -type d \ + -printf '%{goroot}/%p\n' >> $race_list +%endif + + find test/ -type d \ + -printf '%%%dir %{goroot}/%p\n' >> $tests_list + find test/ ! -type d \ + -printf '%{goroot}/%p\n' >> $tests_list + find src/ -type d -a \( -name testdata -o -ipath '*/testdata/*' \) \ + -printf '%%%dir %{goroot}/%p\n' >> $tests_list + find src/ ! -type d -a \( -ipath '*/testdata/*' -o -name '*_test.go' \) \ + -printf '%{goroot}/%p\n' >> $tests_list + # this is only the zoneinfo.zip + find lib/ -type d \ + -printf '%%%dir %{goroot}/%p\n' >> $tests_list + find lib/ ! -type d \ + -printf '%{goroot}/%p\n' >> $tests_list +popd +echo "== 6 ==" +# remove the doc Makefile +rm -rfv %{buildroot}%{goroot}/doc/Makefile + +# put binaries to bindir, linked to the arch we're building, +# leave the arch independent pieces in {goroot} +mkdir -p %{buildroot}%{goroot}/bin/linux_%{gohostarch} +ln -sf %{goroot}/bin/go %{buildroot}%{goroot}/bin/linux_%{gohostarch}/go +ln -sf %{goroot}/bin/gofmt %{buildroot}%{goroot}/bin/linux_%{gohostarch}/gofmt + +# ensure these exist and are owned +mkdir -p %{buildroot}%{gopath}/src/github.com \ + %{buildroot}%{gopath}/src/bitbucket.org \ + %{buildroot}%{gopath}/src/code.google.com/p \ + %{buildroot}%{gopath}/src/golang.org/x +echo "== 7 ==" +# make sure these files exist and point to alternatives +rm -f %{buildroot}%{_bindir}/go +ln -sf /etc/alternatives/go %{buildroot}%{_bindir}/go +rm -f %{buildroot}%{_bindir}/gofmt +ln -sf /etc/alternatives/gofmt %{buildroot}%{_bindir}/gofmt + +# gdbinit +mkdir -p %{buildroot}%{_sysconfdir}/gdbinit.d +cp -av %{SOURCE100} %{buildroot}%{_sysconfdir}/gdbinit.d/golang.gdb + +echo "== END OF INSTALL ==" + +%check +export GOMAXPROCS=2 +echo "GOMAXPROCS set to: $GOMAXPROCS" +export GOROOT=$(pwd -P) +export PATH="$GOROOT"/bin:"$PATH" +cd src + +export CC="gcc" +export CFLAGS="$RPM_OPT_FLAGS" +export LDFLAGS="$RPM_LD_FLAGS" +%if !%{with external_linker} +export GO_LDFLAGS="-linkmode internal" +## %else +## export GO_LDFLAGS="-extldflags '$RPM_LD_FLAGS'" +%endif +%if !%{with cgo} || !%{with external_linker} +export CGO_ENABLED=0 +%endif +# workaround for https://github.com/golang/go/issues/39466 until it gests fixed +# Commented until the patch is ready, this workaround suggested in the link above +# doesn't work properly +#ifarch aarch64 +#export CGO_CFLAGS="-mno-outline-atomics" +#endif + +# make sure to not timeout +%ifnarch riscv64 +export GO_TEST_TIMEOUT_SCALE=2 +%else +# NOTE(davidlt): 20 is probably too much, but it's only for riscv and it works +export GO_TEST_TIMEOUT_SCALE=20 +%endif + +%if %{with fail_on_tests} +./run.bash --no-rebuild -v -v -v -k +%else +./run.bash --no-rebuild -v -v -v -k || : +%endif +cd .. + +%post bin +%{_sbindir}/update-alternatives \ + --install %{_bindir}/go \ + go %{goroot}/bin/go 90 \ + --slave %{_bindir}/gofmt \ + gofmt %{goroot}/bin/gofmt + +%preun bin +if [ $1 = 0 ]; then + %{_sbindir}/update-alternatives \ + --remove go %{goroot}/bin/go +fi + +%files +%license LICENSE PATENTS +# VERSION has to be present in the GOROOT, for `go install std` to work +%doc %{goroot}/VERSION +%dir %{goroot}/doc + +# go files +%dir %{goroot} +%{goroot}/api/ +%{goroot}/lib/time/ + +# gdbinit (for gdb debugging) +%{_sysconfdir}/gdbinit.d + +# ensure directory ownership, so they are cleaned up if empty +%dir %{gopath} +%dir %{gopath}/src +%dir %{gopath}/src/bitbucket.org/ +%dir %{gopath}/src/code.google.com/ +%dir %{gopath}/src/code.google.com/p/ +%dir %{gopath}/src/github.com/ +%dir %{gopath}/src/golang.org +%dir %{gopath}/src/golang.org/x + +%files bin -f go-pkg.list +%{_bindir}/go +%{_bindir}/gofmt +%{goroot}/bin/linux_%{gohostarch}/go +%{goroot}/bin/linux_%{gohostarch}/gofmt + +%files src -f go-src.list + +%files misc -f go-misc.list + +%files tests -f go-tests.list + +%if %{with shared} +%files shared -f go-shared.list +%endif + +%if %{with race} +%files race -f go-race.list +%endif + +%files docs -f go-docs.list + +%changelog +* Thu Nov 27 2025 zhoujiajia111 - 1.24.8.1 +- update to 1.24.8 to fix CVE-2025-4673,CVE-2025-58183 +- remove patches new version included + +* Mon Nov 17 2025 lzq11122 - 1.24.0-12 +- Add patch to fix CVE-2025-58185 and CVE-2025-61723 + +* Mon Nov 3 2025 wh02252983 - 1.24.0-11 +- add patch to fix CVE-2025-58189 + +* Mon Oct 27 2025 mgb01105731 - 1.24.0-10 +- Add patch to fix CVE-2025-22870 + +* Fri Oct 10 2025 wh02252983 - 1.24.0-9 +- Add patch to fix CVE-2025-47906 + +* Fri Aug 15 2025 Yang Cheng - 1.24.0-8 +- fix sw_64 build error + +* Wed Jul 30 2025 swcompiler - 1.24.0-7 +- Add sw64 ISA support. + +* Wed Jul 23 2025 Cheng Yang - 1.24.0-6 +- add patch to Fix CVE-2025-22871 and CVE-2025-22874 + +* Fri Jun 6 2025 Yihao Yan - 1.24.0-5 +- fix check fail in riscv build + +* Tue Jun 3 2025 zhoujiajia111 - 1.24.0-4 +- Provide tar package using download file + +* Fri Apr 25 2025 Shangtong Guo - 1.24.0-3 +- add support for riscv64 build + +* Mon Feb 24 2025 limeidan - 1.24.0-2 +- add internal linker support on loong64 +- optimize the internal/bytealg package on loong64 +- optimize the math/big package on loong64 +- add new instructions support on loong64 +- optimize memory operation function of runtime on loong64 + +* Tue Feb 18 2025 gaochang - 1.24.0-1 +- update to 1.24.0 + +* Tue Feb 18 2025 gaochang - 1.22.12-1 +- update to 1.22.12 + +* Wed Jul 10 2024 yangxinyu - 1.21.11-1 +- update to 1.21.11 fix cve-2024-24789 + +* Thu Jun 13 2024 chenguoqi - 1.21.10-2 +- add buildmode={plugin,shared} support on linux/loong64 +- asan and msan support on linux/loong64 +- loong64 disassembler support +- add atomic memory access instructions support +- optimize atomic xchg and xchg64 on loong64 +- optimize atomic xadd and xadd64 on loong64 +- optimize atomic And{32,8} and Or{32,8} on loong64 +- asm: recheck jump offset boundary after auto-aligning loop heads +- cmd/link/internal/loadelf: correct the relocation size of R_LARCH_64 +- enable regabi support on loong64 +- add race support on loong64 + +* Thu May 09 2024 mgb01105731 - 1.21.10-1 +- update to 1.21.10 + +* Mon Dec 11 2023 Funda Wang - 1.20.12-1 +- New version 1.20.12 + +* Sat Oct 28 2023 Funda Wang - 1.20.10-1 +- New version 1.20.10 + +* Fri Oct 27 2023 Meidan Li - 1.20.9-3 +- api: add new relocations numbered 101 to 109 for loong64 +- cmd/link: add new relocations numbered 101 to 109 for loong64 +- cmd/link/internal/loadelf: add additional relocations for loong64 +- cmd/link/internal/loadelf: remove useless relocation size information of loong64 +- cmd/internal, cmd/link: unify the relocation naming style of loong64 +- cmd/internal/obj/loong64: using LookupABI to find duff{copy,zero} when rewriting GOT +- all: delete loong64 non-register ABI fallback path +- internal/abi, internal/buildcfg: always enable register ABI on loong64 +- cmd/compile, internal/buildcfg: enable regABI on loong64, and add loong64 in test func hasRegisterABI +- runtime/internal/syscall: use ABIInternal for Syscall6 on loong64 +- cmd/compile: fix If lowering on loong64 +- cmd/internal/obj: set morestack arg spilling and regabi prologue on loong64 +- runtime: add regABI support in memclr and memmove functions on loong64 +- internal/bytealg: add regABI support in bytealg functions on loong64 +- reflect, runtime: add reflect support for regABI on loong64 +- runtime: support regABI and add spill functions in runtime for loong64 +- runtime: make duff device as ABIInternal for loong64 +- cmd/compile: update loong64 CALL* ops +- cmd/compile/internal: add spill support for loong64 regABI +- cmd/compile/internal: add register info for loong64 regABI +- internal/abi: define loong64 regABI constants +- cmd/compile,cmd/internal,runtime: change registers on loong64 to avoid regABI arguments +- cmd/compile: add ABI register definations for loong64 +- cmd/compile, cmd/internal, runtime: change the registers used by the duff device for loong64 +- cmd/link/internal/loadelf: correct the relocation size of R_LARCH_64 +- cmd/link/internal/loong64: correct the glibc dynamic linker path. +- cmd/internal/obj/loong64: recheck jump offset boundary after auto-aligning loop heads +- cmd/internal/obj/loong64: correct the instruction format of plan9 assembly NOOP +- cmd/compiler,runtime/internal/atomic: Implementing {And,Or}{32,8} using am{and,or}dbw on loong64 +- cmd/compiler,runtime/internal/atomic: Implementing xadd{,64} using amadddb{w,d} on loong64 +- cmd/compiler,runtime/internal/atomic: Implementing xchg{,64} using amswapdb{w,d} on loong64 +- internal/sysinfo: print cpu type from cpuinfo when internal cpu name is empty on Linux + +* Wed Oct 18 2023 Meidan Li - 1.20.9-2 +- cmd/asm: add RDTIME{L,H}.W, RDTIME.D support for loong64 +- runtime: implement cputicks with the stable counter on loong64 +- runtime: remove the fake mstart caller in systemstack on linux/loong64 +- cmd/internal/obj/loong64: save LR after decrementing SP +- runtime: refactor the linux/loong64 entrypoint +- cmd/internal/obj/loong64: remove invalid branch delay slots +- runtime: calculate nanoseconds in usleep on linux/loong64 +- cmd/internal/obj: remove redundant cnames on loong64 +- runtime: save/fetch g register during VDSO on loong64 +- runtime: save/restore callee-saved registers in loong64's sigtramp +- runtime: add comment for sys_linux_loong64 +- runtime: mark morestack_noctxt SPWRITE for linux/loong64 +- cmd/internal/obj/loong64: add the PCALAU12I instruction for reloc use +- cmd/internal/obj/loong64, cmd/link/internal/loong64: switch to LoongArch ELF psABI v2 relocs +- runtime: add support for --buildmode=c-shared on loong64 +- cmd/compile: add support for --buildmode=c-shared on loong64 +- cmd/internal/obj/loong64, cmd/internal/objabi: add c-shared relocations on loong64 +- cmd/link: add support for --buildmode=c-shared on loong64 +- cmd/internal/sys: enable c-shared feature on loong64 +- cmd/dist, misc/cgo/testcshared: enable c-shared test on loong64 +- cmd/link, cmd/internal: in shared mode, change to use IE mode to access TLS variables +- cmd/compile, cmd/dist, cmd/go, internal: enable buildmode=pie for linux/loong64 +- net: disable TestLookupDotsWithRemoteSource and TestLookupGoogleSRV +- enable c-archive test on linux/loong64 +- cmd/internal, cmd/link: remove invalid GOT relative relocations +- runtime: no need to save these registers in load_g&save_g +- cmd/internal/obj/loong64: add support for movgr2cf and movcf2gr instructions +- runtime: save and restore fcc registers in async preempt on loong64 +- cmd,cmd/vendor: pick up updates for golang.org/x/arch/loong64 +- cmd/internal/objfile: add loong64 disassembler support +- cmd/{compile,link,internal},runtime: support -buildmode=shared for loong64 +- cmd/{link,internal}: support -buildmode=plugin for loong64 +- cmd/dist/test: enable buildmode={shared,plugin} test for loong64 +- runtime: enable memory sanitizer on loong64 +- runtime: enable address sanitizer on loong64 +- cmd/link: workaround linkshared test errors on loong64. +- runtime: remove the meaningless offset of 8 for duffzero on loong64 +- cmd/compiler: remove the meaningless offset of 8 for Lowered{Zero,Move} on loong64 +- cmd/compile/internal, runtime: use NOOP for hardware NOPs on loong64 +- cmd/link/internal/loong64: use BREAK 0 as the code pad sequence +- cmd/asm, runtime: remove the RSB register from loong64 +- cmd/internal/obj/loong64: realize all unconditional jumps with B/BL +- cmd/internal/obj/loong64: clean up code for short conditional branches +- cmd/internal/obj/loong64: assemble BEQ/BNEs comparing with 0 as beqz/bnez +- cmd/internal/obj/loong64: remove Optab.family and reorganize operand class fields +- cmd/asm: support the PCALIGN directive on loong64 +- internal/bytealg, runtime: align some loong64 asm loops to 16-byte boundaries +- cmd/link: bump loong64 function alignment to 16 bytes +- cmd/compile: optimize multiplication on loong64 +- cmd/compile: split DIVV/DIVVU op on loong64 +- cmd/internal/obj/loong64: auto-align loop heads to 16-byte boundaries +- cmd/internal/obj/loong64: add atomic memory access instructions support +- cmd/compiler,runtime/internal/atomic: optimize xchg and xchg64 on loong64 +- cmd/compiler,runtime/internal/atomic: optimize xadd and xadd64 on loong64 +- cmd/compiler,runtime/internal/atomic: optimize And{32,8} and Or{32,8} on loong64 +- Revert "cmd/link: workaround linkshared test errors on loong64." +- syscall: implement Ptrace{Set,Get}Regs using PTRACE_{GET,SET}REGSET on all linux platforms +- cmd/internal/obj/loong64: remove the invalid plan9 format of the BREAK instruction + +* Mon Oct 9 2023 Funda Wang - 1.20.9-1 +- New version 1.20.9 +- Use local sumdb rather than disable it + +* Fri Jun 09 2023 Funda Wang - 1.20.5-1 +- New version 1.20.5 + +* Wed May 03 2023 Funda Wang - 1.20.4-1 +- New version 1.20.4 + +* Thu Apr 13 2023 DengXiewei - 1.20.3-2 +- Remove the useless obsoletes +- Make the description clearer + +* Thu Apr 06 2023 Funda Wang - 1.20.3-1 +- New version 1.20.3 +- Disable race package due go 1.20 new feature +- Drop abi generation, it produces unexpanded provides for this package + +* Tue Jan 3 2023 Kun(llfl) - 1.19.4-1 +- update version to 1.19.4 + +* Tue Jun 14 2022 happy_orange - 1.18.3-1 +- init from upstream diff --git a/race_linux_loong64.syso b/race_linux_loong64.syso new file mode 100644 index 0000000000000000000000000000000000000000..0d2b4946fbf31abc042ea4ee852785cb13cce5a6 Binary files /dev/null and b/race_linux_loong64.syso differ