cpu: add support for detecting cpu features on loong64

Except for lasx, all other features have been implemented
in the Go mainline.

Change-Id: I61a09396ed23d17991b641a1265e952585cb5636
Reviewed-on: https://go-review.googlesource.com/c/sys/+/655355
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: sophie zhao <zhaoxiaolin@loongson.cn>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Junyang Shao <shaojunyang@google.com>
Reviewed-by: Meidan Li <limeidan@loongson.cn>
This commit is contained in:
Guoqi Chen
2025-03-06 19:41:06 +08:00
committed by abner chenc
parent f2ce62c21a
commit b8f7da6c5a
6 changed files with 93 additions and 1 deletions

View File

@@ -149,6 +149,18 @@ var ARM struct {
_ CacheLinePad
}
// The booleans in Loong64 contain the correspondingly named cpu feature bit.
// The struct is padded to avoid false sharing.
var Loong64 struct {
_ CacheLinePad
HasLSX bool // support 128-bit vector extension
HasLASX bool // support 256-bit vector extension
HasCRC32 bool // support CRC instruction
HasLAM_BH bool // support AM{SWAP/ADD}[_DB].{B/H} instruction
HasLAMCAS bool // support AMCAS[_DB].{B/H/W/D} instruction
_ CacheLinePad
}
// MIPS64X contains the supported CPU features of the current mips64/mips64le
// platforms. If the current platform is not mips64/mips64le or the current
// operating system is not Linux then all feature flags are false.

22
cpu/cpu_linux_loong64.go Normal file
View File

@@ -0,0 +1,22 @@
// 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.
package cpu
// HWCAP bits. These are exposed by the Linux kernel.
const (
hwcap_LOONGARCH_LSX = 1 << 4
hwcap_LOONGARCH_LASX = 1 << 5
)
func doinit() {
// 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 {
return hwc&val != 0
}

View File

@@ -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 && !loong64 && !mips64 && !mips64le && !ppc64 && !ppc64le && !s390x && !riscv64
package cpu

View File

@@ -8,5 +8,43 @@ package cpu
const cacheLineSize = 64
// Bit fields for CPUCFG registers, Related reference documents:
// https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html#_cpucfg
const (
// CPUCFG1 bits
cpucfg1_CRC32 = 1 << 25
// CPUCFG2 bits
cpucfg2_LAM_BH = 1 << 27
cpucfg2_LAMCAS = 1 << 28
)
func initOptions() {
options = []option{
{Name: "lsx", Feature: &Loong64.HasLSX},
{Name: "lasx", Feature: &Loong64.HasLASX},
{Name: "crc32", Feature: &Loong64.HasCRC32},
{Name: "lam_bh", Feature: &Loong64.HasLAM_BH},
{Name: "lamcas", Feature: &Loong64.HasLAMCAS},
}
// The CPUCFG data on Loong64 only reflects the hardware capabilities,
// not the kernel support status, so features such as LSX and LASX that
// require kernel support cannot be obtained from the CPUCFG data.
//
// These features only require hardware capability support and do not
// require kernel specific support, so they can be obtained directly
// through CPUCFG
cfg1 := get_cpucfg(1)
cfg2 := get_cpucfg(2)
Loong64.HasCRC32 = cfgIsSet(cfg1, cpucfg1_CRC32)
Loong64.HasLAMCAS = cfgIsSet(cfg2, cpucfg2_LAMCAS)
Loong64.HasLAM_BH = cfgIsSet(cfg2, cpucfg2_LAM_BH)
}
func get_cpucfg(reg uint32) uint32
func cfgIsSet(cfg uint32, val uint32) bool {
return cfg&val != 0
}

12
cpu/cpu_loong64.s Normal file
View File

@@ -0,0 +1,12 @@
// 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"
// func get_cpucfg(reg uint32) uint32
TEXT ·get_cpucfg(SB), NOSPLIT|NOFRAME, $0
MOVW reg+0(FP), R5
CPUCFG R5, R4
MOVW R4, ret+8(FP)
RET

View File

@@ -87,6 +87,14 @@ func TestARM64minimalFeatures(t *testing.T) {
}
}
func TestLOONG64Initialized(t *testing.T) {
if runtime.GOARCH == "loong64" {
if !cpu.Initialized {
t.Fatal("Initialized expected true, got false")
}
}
}
func TestMIPS64Initialized(t *testing.T) {
if runtime.GOARCH == "mips64" || runtime.GOARCH == "mips64le" {
if !cpu.Initialized {