From a9a68a6753aa26b1c833ae881b9cb57f2e99595c Mon Sep 17 00:00:00 2001 From: shupiaoyang Date: Tue, 2 Dec 2025 10:36:06 +0800 Subject: [PATCH] Add intrinsic implementation for ctrlGroupMatchH2 in Goarm64Features --- src/cmd/compile/internal/ssagen/intrinsics.go | 27 +++++++++++++++++-- src/internal/buildcfg/cfg.go | 23 ++++++++++++---- 2 files changed, 43 insertions(+), 7 deletions(-) diff --git a/src/cmd/compile/internal/ssagen/intrinsics.go b/src/cmd/compile/internal/ssagen/intrinsics.go index 45a27428b..ead19efb7 100644 --- a/src/cmd/compile/internal/ssagen/intrinsics.go +++ b/src/cmd/compile/internal/ssagen/intrinsics.go @@ -380,9 +380,9 @@ func initIntrinsics(cfg *intrinsicBuildConfig) { makeAtomicGuardedIntrinsicARM64common := func(op0, op1 ssa.Op, typ types.Kind, emit atomicOpEmitter, needReturn bool) intrinsicBuilder { return func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { - if buildcfg.GOARM64.LSE { + if buildcfg.GOARM64.LSE { emit(s, n, args, op0, typ, needReturn) - } else if cfg.goarm64.LSE { + } else if cfg.goarm64.LSE { emit(s, n, args, op1, typ, needReturn) } else { // Target Atomic feature is identified by dynamic detection @@ -1553,6 +1553,29 @@ func initIntrinsics(cfg *intrinsicBuildConfig) { return s.newValue1(ssa.OpZeroExt8to64, types.Types[types.TUINT64], out) }, sys.AMD64) + + if cfg.goarm64.IntrinsicMatchH2 { + addF("internal/runtime/maps", "ctrlGroupMatchH2", + func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value { + g := args[0] + h := args[1] + + const bitsetLSB int64 = 0x0101010101010101 + const bitsetMSB int64 = 0x8080808080808080 + const bitsetL7B int64 = 0x7f7f7f7f7f7f7f7f + + lsb := s.constInt64(types.Types[types.TUINT64], bitsetLSB) + h1 := s.newValue2(ssa.OpARM64MUL, types.Types[types.TUINT64], h, lsb) + v := s.newValue2(ssa.OpARM64EON, types.Types[types.TUINT64], g, h1) + + clr := s.newValue1I(ssa.OpARM64ANDconst, types.Types[types.TUINT64], bitsetL7B, v) + msk := s.newValue1I(ssa.OpARM64ANDconst, types.Types[types.TUINT64], bitsetMSB, v) + + res := s.newValue1I(ssa.OpARM64ADDconst, types.Types[types.TUINT64], bitsetLSB, clr) + return s.newValue2(ssa.OpARM64AND, types.Types[types.TUINT64], res, msk) + }, + sys.ARM64) + } } // findIntrinsic returns a function which builds the SSA equivalent of the diff --git a/src/internal/buildcfg/cfg.go b/src/internal/buildcfg/cfg.go index e115d7f95..c8bb6c1d7 100644 --- a/src/internal/buildcfg/cfg.go +++ b/src/internal/buildcfg/cfg.go @@ -181,6 +181,8 @@ type Goarm64Features struct { Crypto bool // Kunpeng atomic optimize KPAtomicOpt bool + // Hashmap func controlGroupMatchH2 with intrinsic implementation + IntrinsicMatchH2 bool } func (g Goarm64Features) String() string { @@ -194,19 +196,24 @@ func (g Goarm64Features) String() string { if g.KPAtomicOpt { arm64Str += ",kpatomicopt" } + if g.IntrinsicMatchH2 { + arm64Str += ",intrinsicmatchh2" + } return arm64Str } func ParseGoarm64(v string) (g Goarm64Features, e error) { const ( - lseOpt = ",lse" - cryptoOpt = ",crypto" - kpAtomicOpt = ",kpatomicopt" + lseOpt = ",lse" + cryptoOpt = ",crypto" + kpAtomicOpt = ",kpatomicopt" + intrinsicMatchH2 = ",intrinsicmatchh2" ) g.LSE = false g.Crypto = false g.KPAtomicOpt = false + g.IntrinsicMatchH2 = false // We allow any combination of suffixes, in any order for { if strings.HasSuffix(v, lseOpt) { @@ -229,6 +236,12 @@ func ParseGoarm64(v string) (g Goarm64Features, e error) { continue } + if strings.HasSuffix(v, intrinsicMatchH2) { + g.IntrinsicMatchH2 = true + v = v[:len(v)-len(intrinsicMatchH2)] + continue + } + break } @@ -237,8 +250,8 @@ func ParseGoarm64(v string) (g Goarm64Features, e error) { "v9.0", "v9.1", "v9.2", "v9.3", "v9.4", "v9.5": g.Version = v default: - e = fmt.Errorf("invalid GOARM64: must start with v8.{0-9} or v9.{0-5} and may optionally end in %q, %q and/or %q", - lseOpt, cryptoOpt, kpAtomicOpt) + e = fmt.Errorf("invalid GOARM64: must start with v8.{0-9} or v9.{0-5} and may optionally end in %q, %q, %q and/or %q", + lseOpt, cryptoOpt, kpAtomicOpt, intrinsicMatchH2) g.Version = DefaultGOARM64 } -- Gitee