15d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy/* 25d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * Copyright (C) 2016 The Android Open Source Project 35d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * 45d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * Licensed under the Apache License, Version 2.0 (the "License"); 55d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * you may not use this file except in compliance with the License. 65d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * You may obtain a copy of the License at 75d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * 85d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * http://www.apache.org/licenses/LICENSE-2.0 95d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * 105d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * Unless required by applicable law or agreed to in writing, software 115d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * distributed under the License is distributed on an "AS IS" BASIS, 125d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * See the License for the specific language governing permissions and 145d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * limitations under the License. 155d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy */ 165d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 171d77b719d51a01cbd6954a048fb64e79d50a950eMathias Agopian#pragma once 185d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 195d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy#include <stdint.h> 205d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy#include <iosfwd> 215d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy#include <limits> 225d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy#include <type_traits> 235d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 246e1193af40c870c50013affec37c8429986b3c7bPawin Vongmasa#ifndef LIKELY 2547df7e3817badac69c6a875d6c230f930bf73b47Jaesoo Lee#define LIKELY_DEFINED_LOCAL 265d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy#ifdef __cplusplus 275d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy# define LIKELY( exp ) (__builtin_expect( !!(exp), true )) 285d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy# define UNLIKELY( exp ) (__builtin_expect( !!(exp), false )) 295d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy#else 305d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy# define LIKELY( exp ) (__builtin_expect( !!(exp), 1 )) 315d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy# define UNLIKELY( exp ) (__builtin_expect( !!(exp), 0 )) 325d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy#endif 336e1193af40c870c50013affec37c8429986b3c7bPawin Vongmasa#endif 345d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 35caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy#if __cplusplus >= 201402L 36caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy#define CONSTEXPR constexpr 37caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy#else 38caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy#define CONSTEXPR 39caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy#endif 40caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy 415d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guynamespace android { 425d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 435d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy/* 445d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * half-float 455d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * 465d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * 1 5 10 475d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * +-+------+------------+ 485d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * |s|eee.ee|mm.mmmm.mmmm| 495d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * +-+------+------------+ 505d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * 515d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * minimum (denormal) value: 2^-24 = 5.96e-8 525d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * minimum (normal) value: 2^-14 = 6.10e-5 535d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * maximum value: 2-2^-10 = 65504 545d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * 555d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * Integers between 0 and 2048 can be represented exactly 565d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy */ 575d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guyclass half { 585d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy struct fp16 { 594fdbdd1692a549a31382f33f5d529fd141453ea1Yi Kong uint16_t bits; 604fdbdd1692a549a31382f33f5d529fd141453ea1Yi Kong explicit constexpr fp16() noexcept : bits(0) { } 61caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy explicit constexpr fp16(uint16_t b) noexcept : bits(b) { } 625d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy void setS(unsigned int s) noexcept { bits = uint16_t((bits & 0x7FFF) | (s<<15)); } 635d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy void setE(unsigned int s) noexcept { bits = uint16_t((bits & 0xE3FF) | (s<<10)); } 645d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy void setM(unsigned int s) noexcept { bits = uint16_t((bits & 0xFC00) | (s<< 0)); } 65caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy constexpr unsigned int getS() const noexcept { return bits >> 15u; } 66caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy constexpr unsigned int getE() const noexcept { return (bits >> 10u) & 0x1Fu; } 67caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy constexpr unsigned int getM() const noexcept { return bits & 0x3FFu; } 685d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy }; 695d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy struct fp32 { 705d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy union { 714fdbdd1692a549a31382f33f5d529fd141453ea1Yi Kong uint32_t bits; 725d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy float fp; 735d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy }; 744fdbdd1692a549a31382f33f5d529fd141453ea1Yi Kong explicit constexpr fp32() noexcept : bits(0) { } 754fdbdd1692a549a31382f33f5d529fd141453ea1Yi Kong explicit constexpr fp32(float f) noexcept : fp(f) { } 765d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy void setS(unsigned int s) noexcept { bits = uint32_t((bits & 0x7FFFFFFF) | (s<<31)); } 775d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy void setE(unsigned int s) noexcept { bits = uint32_t((bits & 0x807FFFFF) | (s<<23)); } 785d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy void setM(unsigned int s) noexcept { bits = uint32_t((bits & 0xFF800000) | (s<< 0)); } 79caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy constexpr unsigned int getS() const noexcept { return bits >> 31u; } 80caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy constexpr unsigned int getE() const noexcept { return (bits >> 23u) & 0xFFu; } 81caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy constexpr unsigned int getM() const noexcept { return bits & 0x7FFFFFu; } 825d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy }; 835d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 845d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guypublic: 85caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy CONSTEXPR half(float v) noexcept : mBits(ftoh(v)) { } 86caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy CONSTEXPR operator float() const noexcept { return htof(mBits); } 875d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 885d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy uint16_t getBits() const noexcept { return mBits.bits; } 895d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy unsigned int getExponent() const noexcept { return mBits.getE(); } 905d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy unsigned int getMantissa() const noexcept { return mBits.getM(); } 915d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 925d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guyprivate: 935d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy friend class std::numeric_limits<half>; 94caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy friend CONSTEXPR half operator"" _hf(long double v); 955d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 965d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy enum Binary { binary }; 975d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy explicit constexpr half(Binary, uint16_t bits) noexcept : mBits(bits) { } 98caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy static CONSTEXPR fp16 ftoh(float v) noexcept; 99caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy static CONSTEXPR float htof(fp16 v) noexcept; 1005d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy fp16 mBits; 1015d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy}; 1025d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 103caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guyinline CONSTEXPR half::fp16 half::ftoh(float v) noexcept { 1045d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy fp16 out; 1055d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy fp32 in(v); 1065d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy if (UNLIKELY(in.getE() == 0xFF)) { // inf or nan 1075d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy out.setE(0x1F); 1085d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy out.setM(in.getM() ? 0x200 : 0); 1095d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } else { 110caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy int e = static_cast<int>(in.getE()) - 127 + 15; 1115d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy if (e >= 0x1F) { 1125d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy // overflow 1135d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy out.setE(0x31); // +/- inf 1145d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } else if (e <= 0) { 1155d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy // underflow 1165d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy // flush to +/- 0 1175d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } else { 1185d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy unsigned int m = in.getM(); 1195d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy out.setE(uint16_t(e)); 1205d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy out.setM(m >> 13); 1215d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy if (m & 0x1000) { 1225d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy // rounding 1235d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy out.bits++; 1245d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 1255d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 1265d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 1275d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy out.setS(in.getS()); 1285d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return out; 1295d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy} 1305d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 131caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guyinline CONSTEXPR float half::htof(half::fp16 in) noexcept { 1325d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy fp32 out; 1335d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy if (UNLIKELY(in.getE() == 0x1F)) { // inf or nan 1345d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy out.setE(0xFF); 1355d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy out.setM(in.getM() ? 0x400000 : 0); 1365d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } else { 1375d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy if (in.getE() == 0) { 1385d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy if (in.getM()) { 1395d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy // TODO: denormal half float, treat as zero for now 1405d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy // (it's stupid because they can be represented as regular float) 1415d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 1425d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } else { 143caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy int e = static_cast<int>(in.getE()) - 15 + 127; 1445d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy unsigned int m = in.getM(); 1455d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy out.setE(uint32_t(e)); 1465d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy out.setM(m << 13); 1475d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 1485d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 1495d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy out.setS(in.getS()); 1505d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return out.fp; 1515d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy} 1525d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 153caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guyinline CONSTEXPR android::half operator"" _hf(long double v) { 154caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy return android::half(android::half::binary, android::half::ftoh(static_cast<float>(v)).bits); 1555d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy} 1565d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 1575d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy} // namespace android 1585d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 1595d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guynamespace std { 1605d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 1615d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guytemplate<> struct is_floating_point<android::half> : public std::true_type {}; 1625d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 1635d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guytemplate<> 1645d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guyclass numeric_limits<android::half> { 1655d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guypublic: 1665d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy typedef android::half type; 1675d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 1685d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy static constexpr const bool is_specialized = true; 1695d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy static constexpr const bool is_signed = true; 1705d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy static constexpr const bool is_integer = false; 1715d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy static constexpr const bool is_exact = false; 1725d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy static constexpr const bool has_infinity = true; 1735d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy static constexpr const bool has_quiet_NaN = true; 1745d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy static constexpr const bool has_signaling_NaN = false; 1755d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy static constexpr const float_denorm_style has_denorm = denorm_absent; 1765d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy static constexpr const bool has_denorm_loss = true; 1775d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy static constexpr const bool is_iec559 = false; 1785d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy static constexpr const bool is_bounded = true; 1795d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy static constexpr const bool is_modulo = false; 1805d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy static constexpr const bool traps = false; 1815d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy static constexpr const bool tinyness_before = false; 1825d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy static constexpr const float_round_style round_style = round_indeterminate; 1835d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 1845d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy static constexpr const int digits = 11; 1855d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy static constexpr const int digits10 = 3; 1865d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy static constexpr const int max_digits10 = 5; 1875d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy static constexpr const int radix = 2; 1885d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy static constexpr const int min_exponent = -13; 1895d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy static constexpr const int min_exponent10 = -4; 1905d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy static constexpr const int max_exponent = 16; 1915d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy static constexpr const int max_exponent10 = 4; 1925d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 1935d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy inline static constexpr type round_error() noexcept { return android::half(android::half::binary, 0x3800); } 1945d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy inline static constexpr type min() noexcept { return android::half(android::half::binary, 0x0400); } 1955d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy inline static constexpr type max() noexcept { return android::half(android::half::binary, 0x7bff); } 1965d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy inline static constexpr type lowest() noexcept { return android::half(android::half::binary, 0xfbff); } 1975d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy inline static constexpr type epsilon() noexcept { return android::half(android::half::binary, 0x1400); } 1985d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy inline static constexpr type infinity() noexcept { return android::half(android::half::binary, 0x7c00); } 1995d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy inline static constexpr type quiet_NaN() noexcept { return android::half(android::half::binary, 0x7fff); } 2005d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy inline static constexpr type denorm_min() noexcept { return android::half(android::half::binary, 0x0001); } 2015d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy inline static constexpr type signaling_NaN() noexcept { return android::half(android::half::binary, 0x7dff); } 2025d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy}; 2035d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 2045d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy} // namespace std 2055d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 20647df7e3817badac69c6a875d6c230f930bf73b47Jaesoo Lee#ifdef LIKELY_DEFINED_LOCAL 20747df7e3817badac69c6a875d6c230f930bf73b47Jaesoo Lee#undef LIKELY_DEFINED_LOCAL 2085d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy#undef LIKELY 2095d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy#undef UNLIKELY 21047df7e3817badac69c6a875d6c230f930bf73b47Jaesoo Lee#endif // LIKELY_DEFINED_LOCAL 21147df7e3817badac69c6a875d6c230f930bf73b47Jaesoo Lee 212caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy#undef CONSTEXPR 213