github.com/guyezi/gofrontend@v0.0.0-20200228202240-7a62a49e62c0/libgo/go/internal/cpu/cpu_gccgo.c (about) 1 // Copyright 2018 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 #include <stdint.h> 6 7 #if defined(__i386__) || defined(__x86_64__) 8 #include <cpuid.h> 9 #include <x86intrin.h> 10 #endif 11 12 #include "runtime.h" 13 14 #if defined(__i386__) || defined(__x86_64__) 15 16 struct cpuid_ret { 17 uint32_t eax; 18 uint32_t ebx; 19 uint32_t ecx; 20 uint32_t edx; 21 }; 22 23 struct cpuid_ret cpuid(uint32_t, uint32_t) 24 __asm__(GOSYM_PREFIX "internal..z2fcpu.cpuid") 25 __attribute__((no_split_stack)); 26 27 struct cpuid_ret cpuid(uint32_t eaxArg, uint32_t ecxArg) { 28 unsigned int eax = 0; 29 unsigned int ebx = 0; 30 unsigned int ecx = 0; 31 unsigned int edx = 0; 32 struct cpuid_ret ret; 33 34 __get_cpuid_count(eaxArg, ecxArg, &eax, &ebx, &ecx, &edx); 35 ret.eax = (uint32_t)(eax); 36 ret.ebx = (uint32_t)(ebx); 37 ret.ecx = (uint32_t)(ecx); 38 ret.edx = (uint32_t)(edx); 39 return ret; 40 } 41 42 struct xgetbv_ret { 43 uint32_t eax; 44 uint32_t edx; 45 }; 46 47 struct xgetbv_ret xgetbv(void) 48 __asm__(GOSYM_PREFIX "internal..z2fcpu.xgetbv") 49 __attribute__((no_split_stack)); 50 51 #pragma GCC push_options 52 #pragma GCC target("xsave") 53 54 struct xgetbv_ret xgetbv(void) { 55 struct xgetbv_ret ret; 56 57 // At some point, use call to _xgetbv() instead: 58 // 59 // long long r = _xgetbv(0); 60 // ret.eax = r & 0xffffffff; 61 // ret.edx = r >> 32; 62 // 63 unsigned int __eax, __edx, __xcr_no = 0; 64 __asm__ ("xgetbv" : "=a" (__eax), "=d" (__edx) : "c" (__xcr_no)); 65 ret.eax = __eax; 66 ret.edx = __edx; 67 return ret; 68 } 69 70 #pragma GCC pop_options 71 72 #endif /* defined(__i386__) || defined(__x86_64__) */ 73 74 #ifdef __s390x__ 75 76 struct facilityList { 77 uint64_t bits[4]; 78 }; 79 80 struct queryResult { 81 uint64_t bits[2]; 82 }; 83 84 struct facilityList stfle(void) 85 __asm__(GOSYM_PREFIX "internal..z2fcpu.stfle") 86 __attribute__((no_split_stack)); 87 88 struct facilityList stfle(void) { 89 struct facilityList ret; 90 __asm__ ("la %%r1, %[ret]\t\n" 91 "lghi %%r0, 3\t\n" // last doubleword index to store 92 "xc 0(32,%%r1), 0(%%r1)\t\n" // clear 4 doublewords (32 bytes) 93 ".long 0xb2b01000\t\n" // store facility list extended (STFLE) 94 :[ret] "=Q" (ret) : : "r0", "r1", "cc"); 95 return ret; 96 } 97 98 struct queryResult kmQuery(void) 99 __asm__(GOSYM_PREFIX "internal..z2fcpu.kmQuery") 100 __attribute__((no_split_stack)); 101 102 struct queryResult kmQuery() { 103 struct queryResult ret; 104 105 __asm__ ("lghi %%r0, 0\t\n" // set function code to 0 (KM-Query) 106 "la %%r1, %[ret]\t\n" 107 ".long 0xb92e0024\t\n" // cipher message (KM) 108 :[ret] "=Q" (ret) : : "r0", "r1", "cc"); 109 return ret; 110 } 111 112 struct queryResult kmcQuery(void) 113 __asm__(GOSYM_PREFIX "internal..z2fcpu.kmcQuery") 114 __attribute__((no_split_stack)); 115 116 struct queryResult kmcQuery() { 117 struct queryResult ret; 118 119 __asm__ ("lghi %%r0, 0\t\n" // set function code to 0 (KMC-Query) 120 "la %%r1, %[ret]\t\n" 121 ".long 0xb92f0024\t\n" // cipher message with chaining (KMC) 122 :[ret] "=Q" (ret) : : "r0", "r1", "cc"); 123 124 return ret; 125 } 126 127 struct queryResult kmctrQuery(void) 128 __asm__(GOSYM_PREFIX "internal..z2fcpu.kmctrQuery") 129 __attribute__((no_split_stack)); 130 131 struct queryResult kmctrQuery() { 132 struct queryResult ret; 133 134 __asm__ ("lghi %%r0, 0\t\n" // set function code to 0 (KMCTR-Query) 135 "la %%r1, %[ret]\t\n" 136 ".long 0xb92d4024\t\n" // cipher message with counter (KMCTR) 137 :[ret] "=Q" (ret) : : "r0", "r1", "cc"); 138 139 return ret; 140 } 141 142 struct queryResult kmaQuery(void) 143 __asm__(GOSYM_PREFIX "internal..z2fcpu.kmaQuery") 144 __attribute__((no_split_stack)); 145 146 struct queryResult kmaQuery() { 147 struct queryResult ret; 148 149 __asm__ ("lghi %%r0, 0\t\n" // set function code to 0 (KMA-Query) 150 "la %%r1, %[ret]\t\n" 151 ".long 0xb9296024\t\n" // cipher message with authentication (KMA) 152 :[ret] "=Q" (ret) : : "r0", "r1", "cc"); 153 154 return ret; 155 } 156 157 struct queryResult kimdQuery(void) 158 __asm__(GOSYM_PREFIX "internal..z2fcpu.kimdQuery") 159 __attribute__((no_split_stack)); 160 161 struct queryResult kimdQuery() { 162 struct queryResult ret; 163 164 __asm__ ("lghi %%r0, 0\t\n" // set function code to 0 (KIMD-Query) 165 "la %%r1, %[ret]\t\n" 166 ".long 0xb93e0024\t\n" // compute intermediate message digest (KIMD) 167 :[ret] "=Q" (ret) : : "r0", "r1", "cc"); 168 169 return ret; 170 } 171 172 struct queryResult klmdQuery(void) 173 __asm__(GOSYM_PREFIX "internal..z2fcpu.klmdQuery") 174 __attribute__((no_split_stack)); 175 176 struct queryResult klmdQuery() { 177 struct queryResult ret; 178 179 __asm__ ("lghi %%r0, 0\t\n" // set function code to 0 (KLMD-Query) 180 "la %%r1, %[ret]\t\n" 181 ".long 0xb93f0024\t\n" // compute last message digest (KLMD) 182 :[ret] "=Q" (ret) : : "r0", "r1", "cc"); 183 184 return ret; 185 } 186 187 struct queryResult kdsaQuery(void) 188 __asm__(GOSYM_PREFIX "internal..z2fcpu.kdsaQuery") 189 __attribute__((no_split_stack)); 190 191 struct queryResult kdsaQuery() { 192 struct queryResult ret; 193 194 __asm__ ("lghi %%r0, 0\t\n" // set function code to 0 (KDSA-Query) 195 "la %%r1, %[ret]\t\n" 196 ".long 0xb93a0024\t\n" // kdsa 197 :[ret] "=QRST" (ret) : : "r0", "r1", "cc"); 198 199 return ret; 200 } 201 202 #endif /* defined(__s390x__) */