From a72128258b86afd0a6a2ddeecea213a74b1e580e Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 15 Feb 2019 14:51:10 +0000 Subject: [PATCH] re PR go/89123 (Too many go test failures on s390x-linux) PR go/89123 internal/cpu, runtime: add S/390 CPU capability support Patch by Robin Dapp. Updates https://gcc.gnu.org/PR89123 Reviewed-on: https://go-review.googlesource.com/c/162887 From-SVN: r268941 --- gcc/go/gofrontend/MERGE | 2 +- libgo/go/internal/cpu/cpu_gccgo.c | 115 +++++++++++++++++++++++++++++++++++++ libgo/go/internal/cpu/cpu_s390x.go | 22 +++---- libgo/go/runtime/os_linux_s390x.go | 16 +++++- 4 files changed, 138 insertions(+), 17 deletions(-) diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 00bc1e5..98325a9 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -6877c95a5f44c3ab4f492d2000ce07771341d7b7 +0563f2d018cdb2cd685c254bac5ceb38396d0a27 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/libgo/go/internal/cpu/cpu_gccgo.c b/libgo/go/internal/cpu/cpu_gccgo.c index f9ebd8b..6908d34 100644 --- a/libgo/go/internal/cpu/cpu_gccgo.c +++ b/libgo/go/internal/cpu/cpu_gccgo.c @@ -70,3 +70,118 @@ struct xgetbv_ret xgetbv(void) { #pragma GCC pop_options #endif /* defined(__i386__) || defined(__x86_64__) */ + +#ifdef __s390__ + +struct facilityList { + uint64_t bits[4]; +}; + +struct queryResult { + uint64_t bits[2]; +}; + +struct facilityList stfle(void) + __asm__(GOSYM_PREFIX "internal..z2fcpu.stfle") + __attribute__((no_split_stack)); + +struct facilityList stfle(void) { + struct facilityList ret; + __asm__ ("la %%r1, %[ret]\t\n" + "lghi %%r0, 3\t\n" // last doubleword index to store + "xc 0(32,%%r1), 0(%%r1)\t\n" // clear 4 doublewords (32 bytes) + ".long 0xb2b01000\t\n" // store facility list extended (STFLE) + :[ret] "=Q" (ret) : : "r0", "r1", "cc"); + return ret; +} + +struct queryResult kmQuery(void) + __asm__(GOSYM_PREFIX "internal..z2fcpu.kmQuery") + __attribute__((no_split_stack)); + +struct queryResult kmQuery() { + struct queryResult ret; + + __asm__ ("lghi %%r0, 0\t\n" // set function code to 0 (KM-Query) + "la %%r1, %[ret]\t\n" + ".long 0xb92e0024\t\n" // cipher message (KM) + :[ret] "=Q" (ret) : : "r0", "r1", "cc"); + return ret; +} + +struct queryResult kmcQuery(void) + __asm__(GOSYM_PREFIX "internal..z2fcpu.kmcQuery") + __attribute__((no_split_stack)); + +struct queryResult kmcQuery() { + struct queryResult ret; + + __asm__ ("lghi %%r0, 0\t\n" // set function code to 0 (KMC-Query) + "la %%r1, %[ret]\t\n" + ".long 0xb92f0024\t\n" // cipher message with chaining (KMC) + :[ret] "=Q" (ret) : : "r0", "r1", "cc"); + + return ret; +} + +struct queryResult kmctrQuery(void) + __asm__(GOSYM_PREFIX "internal..z2fcpu.kmctrQuery") + __attribute__((no_split_stack)); + +struct queryResult kmctrQuery() { + struct queryResult ret; + + __asm__ ("lghi %%r0, 0\t\n" // set function code to 0 (KMCTR-Query) + "la %%r1, %[ret]\t\n" + ".long 0xb92d4024\t\n" // cipher message with counter (KMCTR) + :[ret] "=Q" (ret) : : "r0", "r1", "cc"); + + return ret; +} + +struct queryResult kmaQuery(void) + __asm__(GOSYM_PREFIX "internal..z2fcpu.kmaQuery") + __attribute__((no_split_stack)); + +struct queryResult kmaQuery() { + struct queryResult ret; + + __asm__ ("lghi %%r0, 0\t\n" // set function code to 0 (KMA-Query) + "la %%r1, %[ret]\t\n" + ".long 0xb9296024\t\n" // cipher message with authentication (KMA) + :[ret] "=Q" (ret) : : "r0", "r1", "cc"); + + return ret; +} + +struct queryResult kimdQuery(void) + __asm__(GOSYM_PREFIX "internal..z2fcpu.kimdQuery") + __attribute__((no_split_stack)); + +struct queryResult kimdQuery() { + struct queryResult ret; + + __asm__ ("lghi %%r0, 0\t\n" // set function code to 0 (KIMD-Query) + "la %%r1, %[ret]\t\n" + ".long 0xb93e0024\t\n" // compute intermediate message digest (KIMD) + :[ret] "=Q" (ret) : : "r0", "r1", "cc"); + + return ret; +} + +struct queryResult klmdQuery(void) + __asm__(GOSYM_PREFIX "internal..z2fcpu.klmdQuery") + __attribute__((no_split_stack)); + +struct queryResult klmdQuery() { + struct queryResult ret; + + __asm__ ("lghi %%r0, 0\t\n" // set function code to 0 (KLMD-Query) + "la %%r1, %[ret]\t\n" + ".long 0xb93f0024\t\n" // compute last message digest (KLMD) + :[ret] "=Q" (ret) : : "r0", "r1", "cc"); + + return ret; +} + +#endif /* defined(__s390__) */ diff --git a/libgo/go/internal/cpu/cpu_s390x.go b/libgo/go/internal/cpu/cpu_s390x.go index 81d1afa..22d9aef 100644 --- a/libgo/go/internal/cpu/cpu_s390x.go +++ b/libgo/go/internal/cpu/cpu_s390x.go @@ -98,13 +98,13 @@ func (s *facilityList) Has(fs ...facility) bool { // The following feature detection functions are defined in cpu_s390x.s. // They are likely to be expensive to call so the results should be cached. -func stfle() facilityList { panic("not implemented for gccgo") } -func kmQuery() queryResult { panic("not implemented for gccgo") } -func kmcQuery() queryResult { panic("not implemented for gccgo") } -func kmctrQuery() queryResult { panic("not implemented for gccgo") } -func kmaQuery() queryResult { panic("not implemented for gccgo") } -func kimdQuery() queryResult { panic("not implemented for gccgo") } -func klmdQuery() queryResult { panic("not implemented for gccgo") } +func stfle() facilityList +func kmQuery() queryResult +func kmcQuery() queryResult +func kmctrQuery() queryResult +func kmaQuery() queryResult +func kimdQuery() queryResult +func klmdQuery() queryResult func doinit() { options = []option{ @@ -122,14 +122,6 @@ func doinit() { aes := []function{aes128, aes192, aes256} facilities := stfle() - S390X.HasZArch = facilities.Has(zarch) - S390X.HasSTFLE = facilities.Has(stflef) - S390X.HasLDisp = facilities.Has(ldisp) - S390X.HasEImm = facilities.Has(eimm) - S390X.HasDFP = facilities.Has(dfp) - S390X.HasETF3Enhanced = facilities.Has(etf3eh) - S390X.HasMSA = facilities.Has(msa) - if S390X.HasMSA { // cipher message km, kmc := kmQuery(), kmcQuery() diff --git a/libgo/go/runtime/os_linux_s390x.go b/libgo/go/runtime/os_linux_s390x.go index 55d35c7..7640273 100644 --- a/libgo/go/runtime/os_linux_s390x.go +++ b/libgo/go/runtime/os_linux_s390x.go @@ -8,12 +8,26 @@ import "internal/cpu" const ( // bit masks taken from bits/hwcap.h - _HWCAP_S390_VX = 2048 // vector facility + _HWCAP_S390_ZARCH = 2 + _HWCAP_S390_STFLE = 4 + _HWCAP_S390_MSA = 8 + _HWCAP_S390_LDISP = 16 + _HWCAP_S390_EIMM = 32 + _HWCAP_S390_DFP = 64 + _HWCAP_S390_ETF3EH = 256 + _HWCAP_S390_VX = 2048 // vector facility ) func archauxv(tag, val uintptr) { switch tag { case _AT_HWCAP: // CPU capability bit flags + cpu.S390X.HasZArch = val&_HWCAP_S390_ZARCH != 0 + cpu.S390X.HasSTFLE = val&_HWCAP_S390_STFLE != 0 + cpu.S390X.HasMSA = val&_HWCAP_S390_MSA != 0 + cpu.S390X.HasLDisp = val&_HWCAP_S390_LDISP != 0 + cpu.S390X.HasEImm = val&_HWCAP_S390_EIMM != 0 + cpu.S390X.HasDFP = val&_HWCAP_S390_DFP != 0 + cpu.S390X.HasETF3Enhanced = val&_HWCAP_S390_ETF3EH != 0 cpu.S390X.HasVX = val&_HWCAP_S390_VX != 0 } } -- 2.7.4