re PR go/89123 (Too many go test failures on s390x-linux)
authorIan Lance Taylor <ian@gcc.gnu.org>
Fri, 15 Feb 2019 14:51:10 +0000 (14:51 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Fri, 15 Feb 2019 14:51:10 +0000 (14:51 +0000)
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
libgo/go/internal/cpu/cpu_gccgo.c
libgo/go/internal/cpu/cpu_s390x.go
libgo/go/runtime/os_linux_s390x.go

index 00bc1e514b4294b3395b3c4f1ac166700011ece9..98325a9e876482f8d7c6ba6596128d3f05484031 100644 (file)
@@ -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.
index f9ebd8be45d630592a9a5c52ef122303709d20de..6908d348d79f130fb09c69908e836a0615d0b4ad 100644 (file)
@@ -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__)  */
index 81d1afab24f078fdf10f42b8c85180fefe1831dd..22d9aef178a8db7c789cb17f8e128670b1ff2ad0 100644 (file)
@@ -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()
index 55d35c7cff1cf34aba3b8665a554a866f2763bf5..7640273e202d4d3a9e7200dbfd1c08fdd4aa3578 100644 (file)
@@ -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
        }
 }