1 // Copyright (c) Facebook, Inc. and its affiliates.
2 // All rights reserved.
3 //
4 // Copyright 2019 Google LLC
5 //
6 // This source code is licensed under the BSD-style license found in the
7 // LICENSE file in the root directory of this source tree.
8
9 #pragma once
10
11 #include <stddef.h>
12 #include <stdint.h>
13 #include <assert.h>
14
15 #include <xnnpack/common.h>
16
17
18 // stdlib.h from Windows 10 SDK defines min & max macros.
19 // Undefine them before defining the corresponding functions.
20 #ifdef min
21 #undef min
22 #endif
23 #ifdef max
24 #undef max
25 #endif
26
27
min(size_t a,size_t b)28 inline static size_t min(size_t a, size_t b) {
29 return XNN_UNPREDICTABLE(b < a) ? b : a;
30 }
31
max(size_t a,size_t b)32 inline static size_t max(size_t a, size_t b) {
33 return XNN_UNPREDICTABLE(b < a) ? a : b;
34 }
35
doz(size_t a,size_t b)36 inline static size_t doz(size_t a, size_t b) {
37 return XNN_UNPREDICTABLE(b < a) ? a - b : 0;
38 }
39
divide_round_up(size_t n,size_t q)40 inline static size_t divide_round_up(size_t n, size_t q) {
41 return XNN_UNPREDICTABLE(n % q == 0) ? n / q : n / q + 1;
42 }
43
round_up(size_t n,size_t q)44 inline static size_t round_up(size_t n, size_t q) {
45 return divide_round_up(n, q) * q;
46 }
47
round_down_po2(size_t n,size_t q)48 inline static size_t round_down_po2(size_t n, size_t q) {
49 assert(q != 0);
50 assert((q & (q - 1)) == 0);
51 return n & -q;
52 }
53
round_up_po2(size_t n,size_t q)54 inline static size_t round_up_po2(size_t n, size_t q) {
55 return round_down_po2(n + q - 1, q);
56 }
57
subtract_modulo(size_t a,size_t b,size_t m)58 inline static size_t subtract_modulo(size_t a, size_t b, size_t m) {
59 assert(a < m);
60 assert(b < m);
61 return XNN_UNPREDICTABLE(a >= b) ? a - b : a - b + m;
62 }
63
math_min_u32(uint32_t a,uint32_t b)64 inline static uint32_t math_min_u32(uint32_t a, uint32_t b) {
65 return XNN_UNPREDICTABLE(a < b) ? a : b;
66 }
67
math_max_u32(uint32_t a,uint32_t b)68 inline static uint32_t math_max_u32(uint32_t a, uint32_t b) {
69 return XNN_UNPREDICTABLE(a > b) ? a : b;
70 }
71
math_min_f32(float a,float b)72 inline static float math_min_f32(float a, float b) {
73 #if defined(__GNUC__) && defined(__ARM_ARCH) && (__ARM_ARCH >= 8)
74 return __builtin_fminf(a, b);
75 #elif defined(__clang__) && defined(__riscv)
76 return __builtin_fminf(a, b);
77 #else
78 return XNN_UNPREDICTABLE(b < a) ? b : a;
79 #endif
80 }
81
math_max_f32(float a,float b)82 inline static float math_max_f32(float a, float b) {
83 #if defined(__GNUC__) && defined(__ARM_ARCH) && (__ARM_ARCH >= 8)
84 return __builtin_fmaxf(a, b);
85 #elif defined(__clang__) && defined(__riscv)
86 return __builtin_fmaxf(a, b);
87 #else
88 return XNN_UNPREDICTABLE(b < a) ? a : b;
89 #endif
90 }
91
math_nonsign_mask_f32()92 inline static float math_nonsign_mask_f32() {
93 #if defined(__INTEL_COMPILER)
94 // Suprisingly, Intel compiler ignores __builtin_nanf payload
95 return _castu32_f32(0x7FFFFFFF);
96 #elif defined(__GNUC__)
97 return __builtin_nanf("0x7FFFFF");
98 #else
99 union {
100 uint32_t as_word;
101 float as_float;
102 } f;
103 f.as_word = 0x7FFFFFFF;
104 return f.as_float;
105 #endif
106 }
107
108