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__)  */