(root)/
gcc-13.2.0/
libgo/
go/
internal/
cpu/
cpu_gccgo.c
       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_1cpu.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_1cpu.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_1cpu.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_1cpu.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_1cpu.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_1cpu.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_1cpu.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_1cpu.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_1cpu.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_1cpu.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__)  */
     203  
     204  #ifdef __aarch64__
     205  
     206  uint64_t getisar0(void)
     207    __asm__(GOSYM_PREFIX "internal_1cpu.getisar0")
     208    __attribute__((no_split_stack));
     209  
     210  uint64_t getisar0() {
     211         uint64_t isar0;
     212  
     213         __asm__("mrs %0,id_aa64isar0_el1" : "=r"(isar0));
     214         return isar0;
     215  }
     216  
     217  uint64_t getMIDR(void)
     218    __asm__(GOSYM_PREFIX "internal_1cpu.getMIDR")
     219    __attribute__((no_split_stack));
     220  
     221  uint64_t getMIDR() {
     222         uint64_t MIDR;
     223  
     224         __asm__("mrs %0,midr_el1" : "=r"(MIDR));
     225         return MIDR;
     226  }
     227  
     228  #endif /* defined(__aarch64__) */