XNNPACK Team | b455b12 | 2019-09-27 18:10:33 -0700 | [diff] [blame] | 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> |
Marat Dukhan | 6972249 | 2019-11-11 19:55:50 -0800 | [diff] [blame] | 12 | #include <stdint.h> |
XNNPACK Team | b455b12 | 2019-09-27 18:10:33 -0700 | [diff] [blame] | 13 | #include <assert.h> |
| 14 | |
Marat Dukhan | 6972249 | 2019-11-11 19:55:50 -0800 | [diff] [blame] | 15 | #include <xnnpack/common.h> |
| 16 | |
Marat Dukhan | 72b3250 | 2019-11-12 17:10:50 -0800 | [diff] [blame] | 17 | |
Marat Dukhan | 9fe932e | 2020-04-11 17:14:15 -0700 | [diff] [blame] | 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 | |
XNNPACK Team | b455b12 | 2019-09-27 18:10:33 -0700 | [diff] [blame] | 28 | inline static size_t min(size_t a, size_t b) { |
Marat Dukhan | 72b3250 | 2019-11-12 17:10:50 -0800 | [diff] [blame] | 29 | return XNN_UNPREDICTABLE(b < a) ? b : a; |
XNNPACK Team | b455b12 | 2019-09-27 18:10:33 -0700 | [diff] [blame] | 30 | } |
| 31 | |
| 32 | inline static size_t max(size_t a, size_t b) { |
Marat Dukhan | 72b3250 | 2019-11-12 17:10:50 -0800 | [diff] [blame] | 33 | return XNN_UNPREDICTABLE(b < a) ? a : b; |
XNNPACK Team | b455b12 | 2019-09-27 18:10:33 -0700 | [diff] [blame] | 34 | } |
| 35 | |
| 36 | inline static size_t doz(size_t a, size_t b) { |
Marat Dukhan | 72b3250 | 2019-11-12 17:10:50 -0800 | [diff] [blame] | 37 | return XNN_UNPREDICTABLE(b < a) ? a - b : 0; |
XNNPACK Team | b455b12 | 2019-09-27 18:10:33 -0700 | [diff] [blame] | 38 | } |
| 39 | |
| 40 | inline static size_t divide_round_up(size_t n, size_t q) { |
Marat Dukhan | 72b3250 | 2019-11-12 17:10:50 -0800 | [diff] [blame] | 41 | return XNN_UNPREDICTABLE(n % q == 0) ? n / q : n / q + 1; |
XNNPACK Team | b455b12 | 2019-09-27 18:10:33 -0700 | [diff] [blame] | 42 | } |
| 43 | |
| 44 | inline static size_t round_up(size_t n, size_t q) { |
| 45 | return divide_round_up(n, q) * q; |
| 46 | } |
| 47 | |
| 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 | |
| 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 | |
| 58 | inline static size_t subtract_modulo(size_t a, size_t b, size_t m) { |
| 59 | assert(a < m); |
| 60 | assert(b < m); |
Marat Dukhan | 72b3250 | 2019-11-12 17:10:50 -0800 | [diff] [blame] | 61 | return XNN_UNPREDICTABLE(a >= b) ? a - b : a - b + m; |
XNNPACK Team | b455b12 | 2019-09-27 18:10:33 -0700 | [diff] [blame] | 62 | } |
| 63 | |
Marat Dukhan | 6972249 | 2019-11-11 19:55:50 -0800 | [diff] [blame] | 64 | inline static uint32_t math_min_u32(uint32_t a, uint32_t b) { |
| 65 | return XNN_UNPREDICTABLE(a < b) ? a : b; |
| 66 | } |
| 67 | |
| 68 | inline static uint32_t math_max_u32(uint32_t a, uint32_t b) { |
| 69 | return XNN_UNPREDICTABLE(a > b) ? a : b; |
| 70 | } |
| 71 | |
XNNPACK Team | b455b12 | 2019-09-27 18:10:33 -0700 | [diff] [blame] | 72 | inline static float math_min_f32(float a, float b) { |
Marat Dukhan | b112088 | 2020-05-15 23:50:47 -0700 | [diff] [blame] | 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 |
XNNPACK Team | b455b12 | 2019-09-27 18:10:33 -0700 | [diff] [blame] | 80 | } |
| 81 | |
| 82 | inline static float math_max_f32(float a, float b) { |
Marat Dukhan | b112088 | 2020-05-15 23:50:47 -0700 | [diff] [blame] | 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 |
XNNPACK Team | b455b12 | 2019-09-27 18:10:33 -0700 | [diff] [blame] | 90 | } |
Marat Dukhan | 8853b82 | 2020-05-07 12:19:01 -0700 | [diff] [blame] | 91 | |
| 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); |
Marat Dukhan | 5592e62 | 2020-05-08 01:05:00 -0700 | [diff] [blame] | 96 | #elif defined(__GNUC__) |
Marat Dukhan | 8853b82 | 2020-05-07 12:19:01 -0700 | [diff] [blame] | 97 | return __builtin_nanf("0x7FFFFF"); |
Marat Dukhan | 5592e62 | 2020-05-08 01:05:00 -0700 | [diff] [blame] | 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; |
Marat Dukhan | 8853b82 | 2020-05-07 12:19:01 -0700 | [diff] [blame] | 105 | #endif |
| 106 | } |
Marat Dukhan | 5592e62 | 2020-05-08 01:05:00 -0700 | [diff] [blame] | 107 | |