1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef RISCV64_TO_X86_64_BERBERIS_INTRINSICS_MACRO_ASSEMBLER_CONSTANTS_POOL_H_ 18 #define RISCV64_TO_X86_64_BERBERIS_INTRINSICS_MACRO_ASSEMBLER_CONSTANTS_POOL_H_ 19 20 #include <cinttypes> 21 22 #include "berberis/base/dependent_false.h" 23 #include "berberis/intrinsics/common/intrinsics_float.h" 24 25 namespace berberis::constants_pool { 26 27 // Vector constants, that is: constants are repeated to fill 128bit SIMD register. 28 template <auto Value> 29 inline constexpr int32_t kVectorConst = kImpossibleValueConst<Value>; 30 template <> 31 extern const int32_t kVectorConst<int8_t{-128}>; 32 template <> 33 extern const int32_t kVectorConst<int8_t{127}>; 34 template <> 35 extern const int32_t kVectorConst<int16_t{-0x8000}>; 36 template <> 37 extern const int32_t kVectorConst<int16_t{0x7fff}>; 38 template <> 39 extern const int32_t kVectorConst<int32_t{static_cast<int32_t>(-0x8000'0000)}>; 40 template <> 41 extern const int32_t kVectorConst<int32_t{-0x0080'0000}>; 42 template <> 43 extern const int32_t kVectorConst<int32_t{0x3f80'0000}>; 44 template <> 45 extern const int32_t kVectorConst<int32_t{0x7f80'0000}>; 46 template <> 47 extern const int32_t kVectorConst<int32_t{0x7fff'ffff}>; 48 template <> 49 extern const int32_t kVectorConst<int64_t{static_cast<int64_t>(-0x8000'0000'0000'0000)}>; 50 template <> 51 extern const int32_t kVectorConst<int64_t{0x3ff0'0000'0000'0000}>; 52 template <> 53 extern const int32_t kVectorConst<int64_t{0x7ff0'0000'0000'0000}>; 54 template <> 55 extern const int32_t kVectorConst<int64_t{0x7fff'ffff'ffff'ffff}>; 56 template <> 57 extern const int32_t kVectorConst<int64_t{-0x0010'0000'0000'0000}>; 58 template <> 59 extern const int32_t kVectorConst<uint64_t{0x0000'0000'0000'0000}>; 60 template <> 61 inline const int32_t& kVectorConst<int8_t{0x00}> = kVectorConst<uint64_t{0x0000'0000'0000'0000}>; 62 template <> 63 inline const int32_t& kVectorConst<uint8_t{0x00}> = kVectorConst<uint64_t{0x0000'0000'0000'0000}>; 64 template <> 65 inline const int32_t& kVectorConst<int16_t{0x0000}> = kVectorConst<uint64_t{0x0000'0000'0000'0000}>; 66 template <> 67 inline const int32_t& kVectorConst<uint16_t{0x0000}> = 68 kVectorConst<uint64_t{0x0000'0000'0000'0000}>; 69 template <> 70 inline const int32_t& kVectorConst<uint8_t{127}> = kVectorConst<int8_t{127}>; 71 template <> 72 inline const int32_t& kVectorConst<uint8_t{128}> = kVectorConst<int8_t{-128}>; 73 template <> 74 inline const int32_t& kVectorConst<uint16_t{0x7fff}> = kVectorConst<int16_t{0x7fff}>; 75 template <> 76 inline const int32_t& kVectorConst<uint16_t{0x8000}> = kVectorConst<int16_t{-0x8000}>; 77 template <> 78 inline const int32_t& kVectorConst<int32_t{0x0000'0000}> = 79 kVectorConst<uint64_t{0x0000'0000'0000'0000}>; 80 template <> 81 inline const int32_t& kVectorConst<uint32_t{0x0000'0000}> = 82 kVectorConst<uint64_t{0x0000'0000'0000'0000}>; 83 template <> 84 inline const int32_t& kVectorConst<uint32_t{0x3f80'0000}> = kVectorConst<int32_t{0x3f80'0000}>; 85 template <> 86 inline const int32_t& kVectorConst<uint32_t{0x7f80'0000}> = kVectorConst<int32_t{0x7f80'0000}>; 87 template <> 88 inline const int32_t& kVectorConst<uint32_t{0x7fff'ffff}> = kVectorConst<int32_t{0x7fff'ffff}>; 89 template <> 90 inline const int32_t& kVectorConst<uint32_t{0x8000'0000}> = 91 kVectorConst<int32_t{static_cast<int32_t>(-0x8000'0000)}>; 92 template <> 93 inline const int32_t& kVectorConst<uint32_t{0xff80'0000}> = kVectorConst<int32_t{-0x0080'0000}>; 94 template <> 95 inline const int32_t& kVectorConst<int64_t{0x0000'0000'0000'0000}> = 96 kVectorConst<uint64_t{0x0000'0000'0000'0000}>; 97 template <> 98 extern const int32_t kVectorConst<uint64_t{0x7fc'00000'7fc'00000}>; 99 template <> 100 inline const int32_t& kVectorConst<uint64_t{0x7ff0'0000'0000'0000}> = 101 kVectorConst<int64_t{0x7ff0'0000'0000'0000}>; 102 template <> 103 extern const int32_t kVectorConst<uint64_t{0x7ff8'0000'0000'0000}>; 104 template <> 105 inline const int32_t& kVectorConst<uint64_t{0xfff0'0000'0000'0000}> = 106 kVectorConst<int64_t{-0x0010'0000'0000'0000}>; 107 template <> 108 extern const int32_t kVectorConst<uint64_t{0xffff'ffff'0000'0000}>; 109 template <> 110 extern const int32_t kVectorConst<uint64_t{0xffff'ffff'7fc0'0000}>; 111 template <> 112 extern const int32_t kVectorConst<uint64_t{0xffff'ffff'ffff'ffff}>; 113 template <> 114 inline const int32_t& kVectorConst<int8_t{-1}> = kVectorConst<uint64_t{0xffff'ffff'ffff'ffff}>; 115 template <> 116 inline const int32_t& kVectorConst<uint8_t{0xff}> = kVectorConst<uint64_t{0xffff'ffff'ffff'ffff}>; 117 template <> 118 inline const int32_t& kVectorConst<int16_t{-1}> = kVectorConst<uint64_t{0xffff'ffff'ffff'ffff}>; 119 template <> 120 inline const int32_t& kVectorConst<uint16_t{0xffff}> = 121 kVectorConst<uint64_t{0xffff'ffff'ffff'ffff}>; 122 template <> 123 inline const int32_t& kVectorConst<int32_t{-1}> = kVectorConst<uint64_t{0xffff'ffff'ffff'ffff}>; 124 template <> 125 inline const int32_t& kVectorConst<uint32_t{0xffff'ffff}> = 126 kVectorConst<uint64_t{0xffff'ffff'ffff'ffff}>; 127 template <> 128 inline const int32_t& kVectorConst<int64_t{-1}> = kVectorConst<uint64_t{0xffff'ffff'ffff'ffff}>; 129 130 // 64 bit constants for use with arithmetic operations. 131 // Used because only 32 bit immediates are supported on x86-64. 132 template <auto Value> 133 inline constexpr int32_t kConst = kImpossibleValueConst<Value>; 134 template <> 135 extern const int32_t kConst<uint32_t{32}>; 136 template <> 137 extern const int32_t kConst<uint32_t{63}>; 138 template <> 139 extern const int32_t kConst<uint64_t{64}>; 140 template <> 141 extern const int32_t kConst<uint64_t{127}>; 142 template <> 143 extern const int32_t kVectorConst<uint64_t{0x0000'0000'0000'0000}>; 144 template <> 145 inline const int32_t& kConst<int8_t{0x00}> = kVectorConst<uint64_t{0x0000'0000'0000'0000}>; 146 template <> 147 inline const int32_t& kConst<uint8_t{0x00}> = kVectorConst<uint64_t{0x0000'0000'0000'0000}>; 148 template <> 149 inline const int32_t& kConst<int16_t{0x0000}> = kVectorConst<uint64_t{0x0000'0000'0000'0000}>; 150 template <> 151 inline const int32_t& kConst<uint16_t{0x0000}> = kVectorConst<uint64_t{0x0000'0000'0000'0000}>; 152 template <> 153 inline const int32_t& kConst<int32_t{0x0000'0000}> = kVectorConst<uint64_t{0x0000'0000'0000'0000}>; 154 template <> 155 inline const int32_t& kConst<uint32_t{0x0000'0000}> = kVectorConst<uint64_t{0x0000'0000'0000'0000}>; 156 template <> 157 inline const int32_t& kConst<int64_t{0x0000'0000'0000'0000}> = 158 kVectorConst<uint64_t{0x0000'0000'0000'0000}>; 159 template <> 160 inline const int32_t& kConst<uint64_t{0x0000'0000'0000'0000}> = 161 kVectorConst<uint64_t{0x0000'0000'0000'0000}>; 162 template <> 163 extern const int32_t kConst<uint64_t{0x8000'0000'0000'00ff}>; 164 template <> 165 extern const int32_t kVectorConst<uint64_t{0xffff'ffff'ffff'ffff}>; 166 template <> 167 inline const int32_t& kConst<int8_t{-1}> = kVectorConst<uint64_t{0xffff'ffff'ffff'ffff}>; 168 template <> 169 inline const int32_t& kConst<uint8_t{0xff}> = kVectorConst<uint64_t{0xffff'ffff'ffff'ffff}>; 170 template <> 171 inline const int32_t& kConst<int16_t{-1}> = kVectorConst<uint64_t{0xffff'ffff'ffff'ffff}>; 172 template <> 173 inline const int32_t& kConst<uint16_t{0xffff}> = kVectorConst<uint64_t{0xffff'ffff'ffff'ffff}>; 174 template <> 175 inline const int32_t& kConst<int32_t{-1}> = kVectorConst<uint64_t{0xffff'ffff'ffff'ffff}>; 176 template <> 177 inline const int32_t& kConst<uint32_t{0xffff'ffff}> = kVectorConst<uint64_t{0xffff'ffff'ffff'ffff}>; 178 template <> 179 inline const int32_t& kConst<int64_t{-1}> = kVectorConst<uint64_t{0xffff'ffff'ffff'ffff}>; 180 template <> 181 inline const int32_t& kConst<uint64_t{0xffff'ffff'ffff'ffff}> = 182 kVectorConst<uint64_t{0xffff'ffff'ffff'ffff}>; 183 184 // Constant suitable for NaN boxing of RISC-V 32bit float with PXor. 185 // Note: technically we only need to Nan-box Float32 since we don't support Float16 yet. 186 template <typename FloatType> 187 inline constexpr int32_t kNanBox = kImpossibleTypeConst<FloatType>; 188 template <> 189 inline const int32_t& kNanBox<intrinsics::Float32> = kVectorConst<uint64_t{0xffff'ffff'0000'0000}>; 190 191 // Canonically Nan boxed canonical NaN. 192 // Note: technically we only need to Nan-box Float32 since we don't support Float16 yet. 193 template <typename FloatType> 194 inline constexpr int32_t kNanBoxedNans = kImpossibleTypeConst<FloatType>; 195 template <> 196 inline const int32_t& kNanBoxedNans<intrinsics::Float32> = 197 kVectorConst<uint64_t{0xffff'ffff'7fc0'0000}>; 198 199 // Canonical NaNs. Float32 and Float64 are supported. 200 template <typename FloatType> 201 inline constexpr int32_t kCanonicalNans = kImpossibleTypeConst<FloatType>; 202 template <> 203 inline const int32_t& kCanonicalNans<intrinsics::Float32> = 204 kVectorConst<uint64_t{0x7fc0'0000'7fc0'0000}>; 205 template <> 206 inline const int32_t& kCanonicalNans<intrinsics::Float64> = 207 kVectorConst<uint64_t{0x7ff8'0000'0000'0000}>; 208 209 // Helper constant for BsrToClz conversion. 63 for int32_t, 127 for int64_t. 210 template <typename IntType> 211 inline constexpr int32_t kBsrToClz = kImpossibleTypeConst<IntType>; 212 template <> 213 inline const int32_t kBsrToClz<int32_t> = kConst<uint32_t{63}>; 214 template <> 215 inline const int32_t kBsrToClz<int64_t> = kConst<uint64_t{127}>; 216 217 // Helper constant for width of the type. 32 for int32_t, 64 for int64_t. 218 template <typename IntType> 219 inline constexpr int32_t kWidthInBits = kImpossibleTypeConst<IntType>; 220 template <> 221 inline const int32_t kWidthInBits<int32_t> = kConst<uint32_t{32}>; 222 template <> 223 inline const int32_t kWidthInBits<int64_t> = kConst<uint64_t{64}>; 224 225 extern const int32_t kRiscVToX87Exceptions; 226 extern const int32_t kX87ToRiscVExceptions; 227 228 extern const int32_t kVid64Bit; 229 extern const int32_t kVid32Bit; 230 extern const int32_t kVid16Bit; 231 extern const int32_t kVid8Bit; 232 233 extern const int32_t kBitMaskTable; 234 extern const int32_t kBitMaskTo32bitMask; 235 extern const int32_t kBitMaskTo16bitMask; 236 extern const int32_t kBitMaskTo8bitMask; 237 238 extern const int32_t kPMovmskwToPMovmskb; 239 extern const int32_t kPMovmskdToPMovmskb; 240 extern const int32_t kPMovmskqToPMovmskb; 241 242 } // namespace berberis::constants_pool 243 244 #endif // RISCV64_TO_X86_64_BERBERIS_INTRINSICS_MACRO_ASSEMBLER_CONSTANTS_POOL_H_ 245