1 /* 2 * Copyright (C) 2023 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 BERBERIS_INTRINSICS_ALL_TO_X86_32_OR_x86_64_INTRINSICS_BINDINGS_H_ 18 #define BERBERIS_INTRINSICS_ALL_TO_X86_32_OR_x86_64_INTRINSICS_BINDINGS_H_ 19 20 #include <xmmintrin.h> 21 22 #include <cstdint> 23 24 #include "berberis/base/dependent_false.h" 25 #include "berberis/intrinsics/common/intrinsics_bindings.h" 26 #include "berberis/intrinsics/intrinsics_args.h" 27 #include "berberis/intrinsics/type_traits.h" 28 29 namespace berberis::intrinsics::bindings { 30 31 class Imm2 { 32 public: 33 using Type = int8_t; 34 static constexpr bool kIsImmediate = true; 35 }; 36 37 class Imm8 { 38 public: 39 using Type = int8_t; 40 static constexpr bool kIsImmediate = true; 41 }; 42 43 class Imm16 { 44 public: 45 using Type = int16_t; 46 static constexpr bool kIsImmediate = true; 47 }; 48 49 class Imm32 { 50 public: 51 using Type = int32_t; 52 static constexpr bool kIsImmediate = true; 53 }; 54 55 class Imm64 { 56 public: 57 using Type = int64_t; 58 static constexpr bool kIsImmediate = true; 59 }; 60 61 class AL { 62 public: 63 using Type = uint8_t; 64 static constexpr bool kIsImmediate = false; 65 static constexpr bool kIsImplicitReg = true; 66 static constexpr char kAsRegister = 'a'; 67 template <typename MachineInsnArch> 68 static constexpr auto kRegClass = MachineInsnArch::kAL; 69 }; 70 71 class AX { 72 public: 73 using Type = uint16_t; 74 static constexpr bool kIsImmediate = false; 75 static constexpr bool kIsImplicitReg = true; 76 static constexpr char kAsRegister = 'a'; 77 }; 78 79 class EAX { 80 public: 81 using Type = uint32_t; 82 static constexpr bool kIsImmediate = false; 83 static constexpr bool kIsImplicitReg = true; 84 static constexpr char kAsRegister = 'a'; 85 template <typename MachineInsnArch> 86 static constexpr auto kRegClass = MachineInsnArch::kEAX; 87 }; 88 89 class RAX { 90 public: 91 using Type = uint32_t; 92 static constexpr bool kIsImmediate = false; 93 static constexpr bool kIsImplicitReg = true; 94 static constexpr char kAsRegister = 'a'; 95 template <typename MachineInsnArch> 96 static constexpr auto kRegClass = MachineInsnArch::kRAX; 97 }; 98 99 class CL { 100 public: 101 using Type = uint8_t; 102 static constexpr bool kIsImmediate = false; 103 static constexpr bool kIsImplicitReg = true; 104 static constexpr char kAsRegister = 'c'; 105 template <typename MachineInsnArch> 106 static constexpr auto kRegClass = MachineInsnArch::kCL; 107 }; 108 109 class CX { 110 public: 111 using Type = uint16_t; 112 static constexpr bool kIsImmediate = false; 113 static constexpr bool kIsImplicitReg = true; 114 static constexpr char kAsRegister = 'c'; 115 }; 116 117 class ECX { 118 public: 119 using Type = uint32_t; 120 static constexpr bool kIsImmediate = false; 121 static constexpr bool kIsImplicitReg = true; 122 static constexpr char kAsRegister = 'c'; 123 template <typename MachineInsnArch> 124 static constexpr auto kRegClass = MachineInsnArch::kECX; 125 }; 126 127 class RCX { 128 public: 129 using Type = uint32_t; 130 static constexpr bool kIsImmediate = false; 131 static constexpr bool kIsImplicitReg = true; 132 static constexpr char kAsRegister = 'c'; 133 template <typename MachineInsnArch> 134 static constexpr auto kRegClass = MachineInsnArch::kRCX; 135 }; 136 137 class DL { 138 public: 139 using Type = uint8_t; 140 static constexpr bool kIsImmediate = false; 141 static constexpr bool kIsImplicitReg = true; 142 static constexpr char kAsRegister = 'd'; 143 }; 144 145 class DX { 146 public: 147 using Type = uint16_t; 148 static constexpr bool kIsImmediate = false; 149 static constexpr bool kIsImplicitReg = true; 150 static constexpr char kAsRegister = 'd'; 151 }; 152 153 class EDX { 154 public: 155 using Type = uint32_t; 156 static constexpr bool kIsImmediate = false; 157 static constexpr bool kIsImplicitReg = true; 158 static constexpr char kAsRegister = 'd'; 159 template <typename MachineInsnArch> 160 static constexpr auto kRegClass = MachineInsnArch::kEDX; 161 }; 162 163 class RDX { 164 public: 165 using Type = uint32_t; 166 static constexpr bool kIsImmediate = false; 167 static constexpr bool kIsImplicitReg = true; 168 static constexpr char kAsRegister = 'd'; 169 template <typename MachineInsnArch> 170 static constexpr auto kRegClass = MachineInsnArch::kRDX; 171 }; 172 173 class GeneralReg8 { 174 public: 175 using Type = uint8_t; 176 static constexpr bool kIsImmediate = false; 177 static constexpr bool kIsImplicitReg = false; 178 static constexpr char kAsRegister = 'q'; 179 template <typename MachineInsnArch> 180 static constexpr auto kRegClass = MachineInsnArch::kGeneralReg8; 181 }; 182 183 class GeneralReg16 { 184 public: 185 using Type = uint16_t; 186 static constexpr bool kIsImmediate = false; 187 static constexpr bool kIsImplicitReg = false; 188 static constexpr char kAsRegister = 'r'; 189 template <typename MachineInsnArch> 190 static constexpr auto kRegClass = MachineInsnArch::kGeneralReg16; 191 }; 192 193 class GeneralReg32 { 194 public: 195 using Type = uint32_t; 196 static constexpr bool kIsImmediate = false; 197 static constexpr bool kIsImplicitReg = false; 198 static constexpr char kAsRegister = 'r'; 199 template <typename MachineInsnArch> 200 static constexpr auto kRegClass = MachineInsnArch::kGeneralReg32; 201 }; 202 203 class GeneralReg64 { 204 public: 205 using Type = uint64_t; 206 static constexpr bool kIsImmediate = false; 207 static constexpr bool kIsImplicitReg = false; 208 static constexpr char kAsRegister = 'r'; 209 template <typename MachineInsnArch> 210 static constexpr auto kRegClass = MachineInsnArch::kGeneralReg64; 211 }; 212 213 class FpReg32 { 214 public: 215 using Type = __m128; 216 static constexpr bool kIsImmediate = false; 217 static constexpr bool kIsImplicitReg = false; 218 static constexpr char kAsRegister = 'x'; 219 template <typename MachineInsnArch> 220 static constexpr auto kRegClass = MachineInsnArch::kFpReg32; 221 }; 222 223 class FpReg64 { 224 public: 225 using Type = __m128; 226 static constexpr bool kIsImmediate = false; 227 static constexpr bool kIsImplicitReg = false; 228 static constexpr char kAsRegister = 'x'; 229 template <typename MachineInsnArch> 230 static constexpr auto kRegClass = MachineInsnArch::kFpReg64; 231 }; 232 233 class VecReg128 { 234 public: 235 using Type = __m128; 236 static constexpr bool kIsImmediate = false; 237 static constexpr bool kIsImplicitReg = false; 238 static constexpr char kAsRegister = 'x'; 239 template <typename MachineInsnArch> 240 static constexpr auto kRegClass = MachineInsnArch::kVecReg128; 241 }; 242 243 class XmmReg { 244 public: 245 using Type = __m128; 246 static constexpr bool kIsImmediate = false; 247 static constexpr bool kIsImplicitReg = false; 248 static constexpr char kAsRegister = 'x'; 249 template <typename MachineInsnArch> 250 static constexpr auto kRegClass = MachineInsnArch::kXmmReg; 251 }; 252 253 class MemX87 { 254 public: 255 static constexpr bool kIsImmediate = false; 256 static constexpr char kAsRegister = 'm'; 257 }; 258 259 // Tag classes. They are never instantioned, only used as tags to pass information about 260 // bindings. 261 class NoCPUIDRestriction; 262 class Has3DNOW; 263 class Has3DNOWP; 264 class HasADX; 265 class HasAES; 266 class HasAESAVX; 267 class HasAMXBF16; 268 class HasAMXFP16; 269 class HasAMXINT8; 270 class HasAMXTILE; 271 class HasAVX; 272 class HasAVX2; 273 class HasAVX5124FMAPS; 274 class HasAVX5124VNNIW; 275 class HasAVX512BF16; 276 class HasAVX512BITALG; 277 class HasAVX512BW; 278 class HasAVX512CD; 279 class HasAVX512DQ; 280 class HasAVX512ER; 281 class HasAVX512F; 282 class HasAVX512FP16; 283 class HasAVX512IFMA; 284 class HasAVX512PF; 285 class HasAVX512VBMI; 286 class HasAVX512VBMI2; 287 class HasAVX512VL; 288 class HasAVX512VNNI; 289 class HasAVX512VPOPCNTDQ; 290 class HasBMI; 291 class HasBMI2; 292 class HasCLMUL; 293 class HasCMOV; 294 class HasCMPXCHG16B; 295 class HasCMPXCHG8B; 296 class HasF16C; 297 class HasFMA; 298 class HasFMA4; 299 class HasFXSAVE; 300 class HasLZCNT; 301 // BMI2 is set and PDEP/PEXT are ok to use. See more here: 302 // https://twitter.com/instlatx64/status/1322503571288559617 303 class HashPDEP; 304 class HasPOPCNT; 305 class HasRDSEED; 306 class HasSERIALIZE; 307 class HasSHA; 308 class HasSSE; 309 class HasSSE2; 310 class HasSSE3; 311 class HasSSE4_1; 312 class HasSSE4_2; 313 class HasSSE4a; 314 class HasSSSE3; 315 class HasTBM; 316 class HasVAES; 317 class HasX87; 318 class HasCustomCapability; 319 class IsAuthenticAMD; 320 321 } // namespace berberis::intrinsics::bindings 322 323 #endif // BERBERIS_INTRINSICS_ALL_TO_X86_32_OR_x86_64_INTRINSICS_BINDINGS_H_ 324