Coverage Report

Created: 2024-05-04 12:45

/proc/self/cwd/external/pthreadpool/src/threadpool-utils.h
Line
Count
Source (jump to first uncovered line)
1
#pragma once
2
3
#include <stdint.h>
4
#include <stddef.h>
5
6
/* SSE-specific headers */
7
#if defined(__SSE__) || defined(__x86_64__) || defined(_M_X64) && !defined(_M_ARM64EC) || (defined(_M_IX86_FP) && _M_IX86_FP >= 1)
8
  #include <xmmintrin.h>
9
#endif
10
11
/* MSVC-specific headers */
12
#if defined(_MSC_VER)
13
  #include <intrin.h>
14
#endif
15
16
17
struct fpu_state {
18
#if defined(__GNUC__) && defined(__arm__) && defined(__ARM_FP) && (__ARM_FP != 0) || defined(_MSC_VER) && defined(_M_ARM)
19
  uint32_t fpscr;
20
#elif defined(__GNUC__) && defined(__aarch64__) || defined(_MSC_VER) && (defined(_M_ARM64) || defined(_M_ARM64EC))
21
  uint64_t fpcr;
22
#elif defined(__SSE__) || defined(__x86_64__) || defined(_M_X64) || (defined(_M_IX86_FP) && _M_IX86_FP >= 1)
23
  uint32_t mxcsr;
24
#else
25
  char unused;
26
#endif
27
};
28
29
0
static inline struct fpu_state get_fpu_state() {
30
0
  struct fpu_state state = { 0 };
31
#if defined(_MSC_VER) && defined(_M_ARM)
32
  state.fpscr = (uint32_t) _MoveFromCoprocessor(10, 7, 1, 0, 0);
33
#elif defined(_MSC_VER) && (defined(_M_ARM64) || defined(_M_ARM64EC))
34
  state.fpcr = (uint64_t) _ReadStatusReg(0x5A20);
35
#elif defined(__SSE__) || defined(__x86_64__) || defined(_M_X64) || (defined(_M_IX86_FP) && _M_IX86_FP >= 1)
36
0
  state.mxcsr = (uint32_t) _mm_getcsr();
37
#elif defined(__GNUC__) && defined(__arm__) && defined(__ARM_FP) && (__ARM_FP != 0)
38
  __asm__ __volatile__("VMRS %[fpscr], fpscr" : [fpscr] "=r" (state.fpscr));
39
#elif defined(__GNUC__) && defined(__aarch64__)
40
  __asm__ __volatile__("MRS %[fpcr], fpcr" : [fpcr] "=r" (state.fpcr));
41
#endif
42
0
  return state;
43
0
}
44
45
0
static inline void set_fpu_state(const struct fpu_state state) {
46
#if defined(_MSC_VER) && defined(_M_ARM)
47
  _MoveToCoprocessor((int) state.fpscr, 10, 7, 1, 0, 0);
48
#elif defined(_MSC_VER) && (defined(_M_ARM64) || defined(_M_ARM64EC))
49
  _WriteStatusReg(0x5A20, (__int64) state.fpcr);
50
#elif defined(__GNUC__) && defined(__arm__) && defined(__ARM_FP) && (__ARM_FP != 0)
51
  __asm__ __volatile__("VMSR fpscr, %[fpscr]" : : [fpscr] "r" (state.fpscr));
52
#elif defined(__GNUC__) && defined(__aarch64__)
53
  __asm__ __volatile__("MSR fpcr, %[fpcr]" : : [fpcr] "r" (state.fpcr));
54
#elif defined(__SSE__) || defined(__x86_64__) || defined(_M_X64) || (defined(_M_IX86_FP) && _M_IX86_FP >= 1)
55
0
  _mm_setcsr((unsigned int) state.mxcsr);
56
0
#endif
57
0
}
58
59
0
static inline void disable_fpu_denormals() {
60
#if defined(_MSC_VER) && defined(_M_ARM)
61
  int fpscr = _MoveFromCoprocessor(10, 7, 1, 0, 0);
62
  fpscr |= 0x1000000;
63
  _MoveToCoprocessor(fpscr, 10, 7, 1, 0, 0);
64
#elif defined(_MSC_VER) && (defined(_M_ARM64) || defined(_M_ARM64EC))
65
  __int64 fpcr = _ReadStatusReg(0x5A20);
66
  fpcr |= 0x1080000;
67
  _WriteStatusReg(0x5A20, fpcr);
68
#elif defined(__GNUC__) && defined(__arm__) && defined(__ARM_FP) && (__ARM_FP != 0)
69
  uint32_t fpscr;
70
  #if defined(__thumb__) && !defined(__thumb2__)
71
    __asm__ __volatile__(
72
        "VMRS %[fpscr], fpscr\n"
73
        "ORRS %[fpscr], %[bitmask]\n"
74
        "VMSR fpscr, %[fpscr]\n"
75
      : [fpscr] "=l" (fpscr)
76
      : [bitmask] "l" (0x1000000)
77
      : "cc");
78
  #else
79
    __asm__ __volatile__(
80
        "VMRS %[fpscr], fpscr\n"
81
        "ORR %[fpscr], #0x1000000\n"
82
        "VMSR fpscr, %[fpscr]\n"
83
      : [fpscr] "=r" (fpscr));
84
  #endif
85
#elif defined(__GNUC__) && defined(__aarch64__)
86
  uint64_t fpcr;
87
  __asm__ __volatile__(
88
      "MRS %[fpcr], fpcr\n"
89
      "ORR %w[fpcr], %w[fpcr], 0x1000000\n"
90
      "ORR %w[fpcr], %w[fpcr], 0x80000\n"
91
      "MSR fpcr, %[fpcr]\n"
92
    : [fpcr] "=r" (fpcr));
93
#elif defined(__SSE__) || defined(__x86_64__) || defined(_M_X64) || (defined(_M_IX86_FP) && _M_IX86_FP >= 1)
94
0
  _mm_setcsr(_mm_getcsr() | 0x8040);
95
0
#endif
96
0
}
97
98
0
static inline size_t modulo_decrement(size_t i, size_t n) {
99
0
  /* Wrap modulo n, if needed */
100
0
  if (i == 0) {
101
0
    i = n;
102
0
  }
103
0
  /* Decrement input variable */
104
0
  return i - 1;
105
0
}
106
107
0
static inline size_t divide_round_up(size_t dividend, size_t divisor) {
108
0
  if (dividend % divisor == 0) {
109
0
    return dividend / divisor;
110
0
  } else {
111
0
    return dividend / divisor + 1;
112
0
  }
113
0
}
114
115
/* Windows headers define min and max macros; undefine it here */
116
#ifdef min
117
  #undef min
118
#endif
119
120
0
static inline size_t min(size_t a, size_t b) {
121
0
  return a < b ? a : b;
122
0
}