Source file src/simd/archsimd/internal/simd_test/arm64_simd_test.go

     1  // Copyright 2026 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build goexperiment.simd && arm64
     6  
     7  package simd_test
     8  
     9  import (
    10  	"simd/archsimd"
    11  	"testing"
    12  )
    13  
    14  func TestBroadcastUint32x4(t *testing.T) {
    15  	s := make([]uint32, 4, 4)
    16  	archsimd.BroadcastUint32x4(123456789).Store(s)
    17  	checkSlices(t, s, []uint32{123456789, 123456789, 123456789, 123456789})
    18  }
    19  
    20  func TestBroadcastFloat32x4(t *testing.T) {
    21  	s := make([]float32, 4, 4)
    22  	archsimd.BroadcastFloat32x4(3.14).Store(s)
    23  	checkSlices(t, s, []float32{3.14, 3.14, 3.14, 3.14})
    24  }
    25  
    26  func TestBroadcastFloat64x2(t *testing.T) {
    27  	s := make([]float64, 2, 2)
    28  	archsimd.BroadcastFloat64x2(3.14).Store(s)
    29  	checkSlices(t, s, []float64{3.14, 3.14})
    30  }
    31  
    32  func TestBroadcastUint64x2(t *testing.T) {
    33  	s := make([]uint64, 2, 2)
    34  	archsimd.BroadcastUint64x2(123456789012345).Store(s)
    35  	checkSlices(t, s, []uint64{123456789012345, 123456789012345})
    36  }
    37  
    38  func TestString(t *testing.T) {
    39  	x := archsimd.LoadUint32x4([]uint32{0, 1, 2, 3})
    40  	y := archsimd.LoadInt64x2([]int64{-44, -5})
    41  	z := archsimd.LoadFloat32x4([]float32{0.5, 1.5, -2.5, 3.5e9})
    42  	w := archsimd.LoadFloat64x2([]float64{-2.5, 3.5e9})
    43  
    44  	sx := "{0,1,2,3}"
    45  	sy := "{-44,-5}"
    46  	sz := "{0.5,1.5,-2.5,3.5e+09}"
    47  	sw := "{-2.5,3.5e+09}"
    48  
    49  	if x.String() != sx {
    50  		t.Errorf("x=%s wanted %s", x, sx)
    51  	}
    52  	if y.String() != sy {
    53  		t.Errorf("y=%s wanted %s", y, sy)
    54  	}
    55  	if z.String() != sz {
    56  		t.Errorf("z=%s wanted %s", z, sz)
    57  	}
    58  	if w.String() != sw {
    59  		t.Errorf("w=%s wanted %s", w, sw)
    60  	}
    61  	t.Logf("w=%s", w)
    62  	t.Logf("x=%s", x)
    63  	t.Logf("y=%s", y)
    64  	t.Logf("z=%s", z)
    65  }
    66  
    67  func TestBroadcastUint16x8(t *testing.T) {
    68  	s := make([]uint16, 8, 8)
    69  	archsimd.BroadcastUint16x8(12345).Store(s)
    70  	checkSlices(t, s, []uint16{12345, 12345, 12345, 12345, 12345, 12345, 12345, 12345})
    71  }
    72  
    73  func TestBroadcastInt8x16(t *testing.T) {
    74  	s := make([]int8, 16, 16)
    75  	archsimd.BroadcastInt8x16(-123).Store(s)
    76  	checkSlices(t, s, []int8{-123, -123, -123, -123, -123, -123, -123, -123,
    77  		-123, -123, -123, -123, -123, -123, -123, -123})
    78  }
    79  
    80  func TestBroadcastUint8x16(t *testing.T) {
    81  	s := make([]uint8, 16, 16)
    82  	archsimd.BroadcastUint8x16(200).Store(s)
    83  	checkSlices(t, s, []uint8{200, 200, 200, 200, 200, 200, 200, 200,
    84  		200, 200, 200, 200, 200, 200, 200, 200})
    85  }
    86  
    87  func TestBroadcastInt16x8(t *testing.T) {
    88  	s := make([]int16, 8, 8)
    89  	archsimd.BroadcastInt16x8(-12345).Store(s)
    90  	checkSlices(t, s, []int16{-12345, -12345, -12345, -12345, -12345, -12345, -12345, -12345})
    91  }
    92  
    93  func TestBroadcastInt32x4(t *testing.T) {
    94  	s := make([]int32, 4, 4)
    95  	archsimd.BroadcastInt32x4(-123456789).Store(s)
    96  	checkSlices(t, s, []int32{-123456789, -123456789, -123456789, -123456789})
    97  }
    98  
    99  func TestBroadcastInt64x2(t *testing.T) {
   100  	s := make([]int64, 2, 2)
   101  	archsimd.BroadcastInt64x2(-123456789).Store(s)
   102  	checkSlices(t, s, []int64{-123456789, -123456789})
   103  }
   104  
   105  func TestLookupOrZero(t *testing.T) {
   106  	// Out-of-range indices produce zero lane value.
   107  	x := []uint8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
   108  	indices := []uint8{7, 6, 5, 4, 3, 2, 1, 0, 0xff, 8, 16, 9, 128, 10, 20, 11}
   109  	want := []uint8{8, 7, 6, 5, 4, 3, 2, 1, 0, 9, 0, 10, 0, 11, 0, 12}
   110  	got := make([]uint8, len(x))
   111  	archsimd.LoadUint8x16(x).LookupOrZero(archsimd.LoadUint8x16(indices)).Store(got)
   112  	checkSlices(t, got, want)
   113  }
   114  
   115  func TestClMul(t *testing.T) {
   116  	var x = archsimd.LoadUint64x2([]uint64{1, 5})
   117  	var y = archsimd.LoadUint64x2([]uint64{3, 9})
   118  
   119  	foo := func(v archsimd.Uint64x2, s []uint64) {
   120  		r := make([]uint64, 2, 2)
   121  		v.Store(r)
   122  		checkSlices[uint64](t, r, s)
   123  	}
   124  
   125  	foo(x.CarrylessMultiplyEven(y), []uint64{3, 0})
   126  	foo(x.CarrylessMultiplyEvenOdd(y), []uint64{9, 0})
   127  	foo(x.CarrylessMultiplyOddEven(y), []uint64{15, 0})
   128  	foo(x.CarrylessMultiplyOdd(y), []uint64{45, 0})
   129  	foo(y.CarrylessMultiplyEven(y), []uint64{5, 0})
   130  }
   131  

View as plain text