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