From d65c209b4b5bc99e7e5587817b79e0850cff32cb Mon Sep 17 00:00:00 2001
From: Xiaolin Zhao <zhaoxiaolin@loongson.cn>
Date: Tue, 6 May 2025 10:47:07 +0800
Subject: [PATCH] cmd/internal/obj/loong64: add [X]VF{ADD/SUB/MUL/DIV}.{S/D}
 instructions

Go asm syntax:
	 V{ADD/SUB/MUL/DIV}{F/D}	VK, VJ, VD
	XV{ADD/SUB/MUL/DIV}{F/D}	XK, XJ, XD

Equivalent platform assembler syntax:
	 vf{add/sub/mul/div}.{s/d}	vd, vj, vk
	xvf{add/sub/mul/div}.{s/d}	xd, xj, xk

Change-Id: I4607884212167ac97d7b6448ea3c849fc0fdd506
Reviewed-on: https://go-review.googlesource.com/c/go/+/670255
Reviewed-by: abner chenc <chenguoqi@loongson.cn>
Reviewed-by: Carlos Amedee <carlos@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
---
 .../asm/internal/asm/testdata/loong64enc1.s   | 18 +++++++
 src/cmd/internal/obj/loong64/a.out.go         | 17 +++++++
 src/cmd/internal/obj/loong64/anames.go        | 16 +++++++
 src/cmd/internal/obj/loong64/asm.go           | 48 +++++++++++++++++++
 4 files changed, 99 insertions(+)

diff --git a/src/cmd/asm/internal/asm/testdata/loong64enc1.s b/src/cmd/asm/internal/asm/testdata/loong64enc1.s
index a901da9b69d..3dfe89aab3f 100644
--- a/src/cmd/asm/internal/asm/testdata/loong64enc1.s
+++ b/src/cmd/asm/internal/asm/testdata/loong64enc1.s
@@ -986,3 +986,21 @@ lable2:
 	XVFRINTRMD	X1, X2		// 22489d76
 	XVFRINTF	X1, X2		// 22349d76
 	XVFRINTD	X1, X2		// 22389d76
+
+	// [X]VF{ADD/SUB/MUL/DIV}.{S/D} instructions
+	VADDF		V1, V2, V3	// 43843071
+	VADDD		V1, V2, V3	// 43043171
+	VSUBF		V1, V2, V3	// 43843271
+	VSUBD		V1, V2, V3	// 43043371
+	VMULF		V1, V2, V3	// 43843871
+	VMULD		V1, V2, V3	// 43043971
+	VDIVF		V1, V2, V3	// 43843a71
+	VDIVD		V1, V2, V3	// 43043b71
+	XVADDF		X1, X2, X3	// 43843075
+	XVADDD		X1, X2, X3	// 43043175
+	XVSUBF		X1, X2, X3	// 43843275
+	XVSUBD		X1, X2, X3	// 43043375
+	XVMULF		X1, X2, X3	// 43843875
+	XVMULD		X1, X2, X3	// 43043975
+	XVDIVF		X1, X2, X3	// 43843a75
+	XVDIVD		X1, X2, X3	// 43043b75
diff --git a/src/cmd/internal/obj/loong64/a.out.go b/src/cmd/internal/obj/loong64/a.out.go
index 5e8210d5ddc..c88c556bfe9 100644
--- a/src/cmd/internal/obj/loong64/a.out.go
+++ b/src/cmd/internal/obj/loong64/a.out.go
@@ -950,6 +950,23 @@ const (
 	AXVFRSQRTF
 	AXVFRSQRTD
 
+	AVADDF
+	AVADDD
+	AVSUBF
+	AVSUBD
+	AVMULF
+	AVMULD
+	AVDIVF
+	AVDIVD
+	AXVADDF
+	AXVADDD
+	AXVSUBF
+	AXVSUBD
+	AXVMULF
+	AXVMULD
+	AXVDIVF
+	AXVDIVD
+
 	// LSX and LASX floating point conversion instructions
 	AVFRINTRNEF
 	AVFRINTRNED
diff --git a/src/cmd/internal/obj/loong64/anames.go b/src/cmd/internal/obj/loong64/anames.go
index 86110c217d2..533e5f41540 100644
--- a/src/cmd/internal/obj/loong64/anames.go
+++ b/src/cmd/internal/obj/loong64/anames.go
@@ -449,6 +449,22 @@ var Anames = []string{
 	"XVFRECIPD",
 	"XVFRSQRTF",
 	"XVFRSQRTD",
+	"VADDF",
+	"VADDD",
+	"VSUBF",
+	"VSUBD",
+	"VMULF",
+	"VMULD",
+	"VDIVF",
+	"VDIVD",
+	"XVADDF",
+	"XVADDD",
+	"XVSUBF",
+	"XVSUBD",
+	"XVMULF",
+	"XVMULD",
+	"XVDIVF",
+	"XVDIVD",
 	"VFRINTRNEF",
 	"VFRINTRNED",
 	"VFRINTRZF",
diff --git a/src/cmd/internal/obj/loong64/asm.go b/src/cmd/internal/obj/loong64/asm.go
index 1b46aa68a1f..dc9fafc0e2e 100644
--- a/src/cmd/internal/obj/loong64/asm.go
+++ b/src/cmd/internal/obj/loong64/asm.go
@@ -1610,6 +1610,14 @@ func buildop(ctxt *obj.Link) {
 			opset(AVMULWODWHUH, r0)
 			opset(AVMULWODVWUW, r0)
 			opset(AVMULWODQVUV, r0)
+			opset(AVADDF, r0)
+			opset(AVADDD, r0)
+			opset(AVSUBF, r0)
+			opset(AVSUBD, r0)
+			opset(AVMULF, r0)
+			opset(AVMULD, r0)
+			opset(AVDIVF, r0)
+			opset(AVDIVD, r0)
 
 		case AXVSEQB:
 			opset(AXVSEQH, r0)
@@ -1675,6 +1683,14 @@ func buildop(ctxt *obj.Link) {
 			opset(AXVMULWODWHUH, r0)
 			opset(AXVMULWODVWUW, r0)
 			opset(AXVMULWODQVUV, r0)
+			opset(AXVADDF, r0)
+			opset(AXVADDD, r0)
+			opset(AXVSUBF, r0)
+			opset(AXVSUBD, r0)
+			opset(AXVMULF, r0)
+			opset(AXVMULD, r0)
+			opset(AXVDIVF, r0)
+			opset(AXVDIVD, r0)
 
 		case AVANDB:
 			opset(AVORB, r0)
@@ -3387,6 +3403,38 @@ func (c *ctxt0) oprrr(a obj.As) uint32 {
 		return 0xe912 << 15 // xvmuh.wu
 	case AXVMUHVU:
 		return 0xe913 << 15 // xvmuh.du
+	case AVADDF:
+		return 0xe261 << 15 // vfadd.s
+	case AVADDD:
+		return 0xe262 << 15 // vfadd.d
+	case AVSUBF:
+		return 0xe265 << 15 // vfsub.s
+	case AVSUBD:
+		return 0xe266 << 15 // vfsub.d
+	case AVMULF:
+		return 0xe271 << 15 // vfmul.s
+	case AVMULD:
+		return 0xe272 << 15 // vfmul.d
+	case AVDIVF:
+		return 0xe275 << 15 // vfdiv.s
+	case AVDIVD:
+		return 0xe276 << 15 // vfdiv.d
+	case AXVADDF:
+		return 0xea61 << 15 // xvfadd.s
+	case AXVADDD:
+		return 0xea62 << 15 // xvfadd.d
+	case AXVSUBF:
+		return 0xea65 << 15 // xvfsub.s
+	case AXVSUBD:
+		return 0xea66 << 15 // xvfsub.d
+	case AXVMULF:
+		return 0xea71 << 15 // xvfmul.s
+	case AXVMULD:
+		return 0xea72 << 15 // xvfmul.d
+	case AXVDIVF:
+		return 0xea75 << 15 // xvfdiv.s
+	case AXVDIVD:
+		return 0xea76 << 15 // xvfdiv.d
 	}
 
 	if a < 0 {
-- 
GitLab