1// Copyright 2020 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
5package cpu_test
6
7import (
8	"runtime"
9	"testing"
10	"unsafe"
11
12	"golang.org/x/sys/cpu"
13)
14
15var s390xTests = []struct {
16	name      string
17	feature   bool
18	facility  uint
19	mandatory bool
20}{
21	{"ZARCH", cpu.S390X.HasZARCH, 1, true},
22	{"STFLE", cpu.S390X.HasSTFLE, 7, true},
23	{"LDISP", cpu.S390X.HasLDISP, 18, true},
24	{"EIMM", cpu.S390X.HasEIMM, 21, true},
25	{"DFP", cpu.S390X.HasDFP, 42, false},
26	{"MSA", cpu.S390X.HasMSA, 17, false},
27	{"VX", cpu.S390X.HasVX, 129, false},
28	{"VXE", cpu.S390X.HasVXE, 135, false},
29}
30
31// bitIsSet reports whether the bit at index is set. The bit index
32// is in big endian order, so bit index 0 is the leftmost bit.
33func bitIsSet(bits [4]uint64, i uint) bool {
34	return bits[i/64]&((1<<63)>>(i%64)) != 0
35}
36
37// facilityList contains the contents of location 200 on zos.
38// Bits are numbered in big endian order so the
39// leftmost bit (the MSB) is at index 0.
40type facilityList struct {
41	bits [4]uint64
42}
43
44func TestS390XVectorFacilityFeatures(t *testing.T) {
45	// vector-enhancements require vector facility to be enabled
46	if cpu.S390X.HasVXE && !cpu.S390X.HasVX {
47		t.Error("HasVX expected true, got false (VXE is true)")
48	}
49}
50
51func TestS390XMandatoryFeatures(t *testing.T) {
52	for _, tc := range s390xTests {
53		if tc.mandatory && !tc.feature {
54			t.Errorf("Feature %s is mandatory but is not present", tc.name)
55		}
56	}
57}
58
59func TestS390XFeatures(t *testing.T) {
60	if runtime.GOOS != "zos" {
61		return
62	}
63	// Read available facilities from address 200.
64	facilitiesAddress := uintptr(200)
65	var facilities facilityList
66	for i := 0; i < 4; i++ {
67		facilities.bits[i] = *(*uint64)(unsafe.Pointer(facilitiesAddress + uintptr(8*i)))
68	}
69
70	for _, tc := range s390xTests {
71		if want := bitIsSet(facilities.bits, tc.facility); want != tc.feature {
72			t.Errorf("Feature %s expected %v, got %v", tc.name, want, tc.feature)
73		}
74	}
75}
76