]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj/loong64: add [X]VSHUF4I.{B/H/W/D} instructions support
authorXiaolin Zhao <zhaoxiaolin@loongson.cn>
Mon, 17 Mar 2025 07:56:12 +0000 (15:56 +0800)
committerabner chenc <chenguoqi@loongson.cn>
Wed, 26 Mar 2025 01:02:50 +0000 (18:02 -0700)
Go asm syntax:
 VSHUF4I{B/H/W/V} $1, V1, V2
XVSHUF4I{B/H/W/V} $2, X1, X2

Equivalent platform assembler syntax:
 vshuf4i.{b/h/w/d} v2, v1, $1
xvshuf4i.{b/h/w/d} x2, x1, $2

Change-Id: I6a847ccbd2c93432d87bd1390b5cf1508da06496
Reviewed-on: https://go-review.googlesource.com/c/go/+/658376
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: abner chenc <chenguoqi@loongson.cn>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>

src/cmd/asm/internal/asm/endtoend_test.go
src/cmd/asm/internal/asm/testdata/loong64enc1.s
src/cmd/asm/internal/asm/testdata/loong64error.s [new file with mode: 0644]
src/cmd/internal/obj/loong64/a.out.go
src/cmd/internal/obj/loong64/anames.go
src/cmd/internal/obj/loong64/asm.go

index f33b1e75bf6c0627bdb3096226e6d2c812fc68c5..afaf02815f94a28f097a873deae0c056b15efbb6 100644 (file)
@@ -470,6 +470,10 @@ func TestLOONG64Encoder(t *testing.T) {
        testEndToEnd(t, "loong64", "loong64")
 }
 
+func TestLOONG64Errors(t *testing.T) {
+       testErrors(t, "loong64", "loong64error")
+}
+
 func TestPPC64EndToEnd(t *testing.T) {
        defer func(old int) { buildcfg.GOPPC64 = old }(buildcfg.GOPPC64)
        for _, goppc64 := range []int{8, 9, 10} {
index d6a0762aa8df780af3620be92d8cb9f3510cdc06..b557625ff3fbfc567187eaf2cba888295e7d88d3 100644 (file)
@@ -911,3 +911,29 @@ lable2:
        XVMULWODWHUH    X1, X2, X3      // 4384a274
        XVMULWODVWUW    X1, X2, X3      // 4304a374
        XVMULWODQVUV    X1, X2, X3      // 4384a374
+
+       // [X]VSHUF4I.{B/H/W/D} instructions
+       VSHUF4IB        $0, V2, V1      // 41009073
+       VSHUF4IB        $16, V2, V1     // 41409073
+       VSHUF4IB        $255, V2, V1    // 41fc9373
+       VSHUF4IH        $0, V2, V1      // 41009473
+       VSHUF4IH        $128, V2, V1    // 41009673
+       VSHUF4IH        $255, V2, V1    // 41fc9773
+       VSHUF4IW        $0, V2, V1      // 41009873
+       VSHUF4IW        $96, V2, V1     // 41809973
+       VSHUF4IW        $255, V2, V1    // 41fc9b73
+       VSHUF4IV        $0, V2, V1      // 41009c73
+       VSHUF4IV        $8, V2, V1      // 41209c73
+       VSHUF4IV        $15, V2, V1     // 413c9c73
+       XVSHUF4IB       $0, X1, X2      // 22009077
+       XVSHUF4IB       $16, X1, X2     // 22409077
+       XVSHUF4IB       $255, X1, X2    // 22fc9377
+       XVSHUF4IH       $0, X1, X2      // 22009477
+       XVSHUF4IH       $128, X1, X2    // 22009677
+       XVSHUF4IH       $255, X1, X2    // 22fc9777
+       XVSHUF4IW       $0, X1, X2      // 22009877
+       XVSHUF4IW       $96, X1, X2     // 22809977
+       XVSHUF4IW       $255, X1, X2    // 22fc9b77
+       XVSHUF4IV       $0, X1, X2      // 22009c77
+       XVSHUF4IV       $8, X1, X2      // 22209c77
+       XVSHUF4IV       $15, X1, X2     // 223c9c77
diff --git a/src/cmd/asm/internal/asm/testdata/loong64error.s b/src/cmd/asm/internal/asm/testdata/loong64error.s
new file mode 100644 (file)
index 0000000..9272ce5
--- /dev/null
@@ -0,0 +1,7 @@
+// 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.
+
+TEXT errors(SB),$0
+       VSHUF4IV        $16, V1, V2     // ERROR "operand out of range 0 to 15"
+       XVSHUF4IV       $16, X1, X2     // ERROR "operand out of range 0 to 15"
index 782691754feff3c97a0dd64ceb2fd4aad03ae99c..a3e81ba5319cbbcd6d93b3c0dc9f9dba74db0f60 100644 (file)
@@ -1010,6 +1010,15 @@ const (
        AXVMULWODVWUW
        AXVMULWODQVUV
 
+       AVSHUF4IB
+       AVSHUF4IH
+       AVSHUF4IW
+       AVSHUF4IV
+       AXVSHUF4IB
+       AXVSHUF4IH
+       AXVSHUF4IW
+       AXVSHUF4IV
+
        ALAST
 
        // aliases
index 887ada8a170c96446d68cdd279aa68bd93b282a9..8e656c844a166a13b1c14366b2c8bb07b372de52 100644 (file)
@@ -505,5 +505,13 @@ var Anames = []string{
        "XVMULWODWHUH",
        "XVMULWODVWUW",
        "XVMULWODQVUV",
+       "VSHUF4IB",
+       "VSHUF4IH",
+       "VSHUF4IW",
+       "VSHUF4IV",
+       "XVSHUF4IB",
+       "XVSHUF4IH",
+       "XVSHUF4IW",
+       "XVSHUF4IV",
        "LAST",
 }
index f0e3cd77b7f60578de577d3cfafa376b26499fa8..401cab11cc17dc0e9e936b387e007ee51723f103 100644 (file)
@@ -1677,11 +1677,19 @@ func buildop(ctxt *obj.Link) {
                        opset(AVORB, r0)
                        opset(AVXORB, r0)
                        opset(AVNORB, r0)
+                       opset(AVSHUF4IB, r0)
+                       opset(AVSHUF4IH, r0)
+                       opset(AVSHUF4IW, r0)
+                       opset(AVSHUF4IV, r0)
 
                case AXVANDB:
                        opset(AXVORB, r0)
                        opset(AXVXORB, r0)
                        opset(AXVNORB, r0)
+                       opset(AXVSHUF4IB, r0)
+                       opset(AXVSHUF4IH, r0)
+                       opset(AXVSHUF4IW, r0)
+                       opset(AXVSHUF4IV, r0)
 
                case AVANDV:
                        opset(AVORV, r0)
@@ -2155,6 +2163,12 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) {
                        r = int(p.To.Reg)
                }
 
+               // the operand range available for instructions VSHUF4IV and XVSHUF4IV is [0, 15]
+               if p.As == AVSHUF4IV || p.As == AXVSHUF4IV {
+                       operand := uint32(v)
+                       c.checkoperand(p, operand, 15)
+               }
+
                o1 = OP_8IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.To.Reg))
 
        case 24: // add $lcon,r1,r2
@@ -2695,6 +2709,13 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) {
        out[4] = o5
 }
 
+// checkoperand checks if operand >= 0 && operand <= maxoperand
+func (c *ctxt0) checkoperand(p *obj.Prog, operand uint32, mask uint32) {
+       if (operand & ^mask) != 0 {
+               c.ctxt.Diag("operand out of range 0 to %d: %v", mask, p)
+       }
+}
+
 // checkindex checks if index >= 0 && index <= maxindex
 func (c *ctxt0) checkindex(p *obj.Prog, index uint32, mask uint32) {
        if (index & ^mask) != 0 {
@@ -3813,6 +3834,22 @@ func (c *ctxt0) opirr(a obj.As) uint32 {
                return 0xed1a << 15 // xvsubi.wu
        case AXVSUBVU:
                return 0xed1b << 15 // xvsubi.du
+       case AVSHUF4IB:
+               return 0x1ce4 << 18 // vshuf4i.b
+       case AVSHUF4IH:
+               return 0x1ce5 << 18 // vshuf4i.h
+       case AVSHUF4IW:
+               return 0x1ce6 << 18 // vshuf4i.w
+       case AVSHUF4IV:
+               return 0x1ce7 << 18 // vshuf4i.d
+       case AXVSHUF4IB:
+               return 0x1de4 << 18 // xvshuf4i.b
+       case AXVSHUF4IH:
+               return 0x1de5 << 18 // xvshuf4i.h
+       case AXVSHUF4IW:
+               return 0x1de6 << 18 // xvshuf4i.w
+       case AXVSHUF4IV:
+               return 0x1de7 << 18 // xvshuf4i.d
        }
 
        if a < 0 {