| 1 | //===- X86InstrFMA3Info.h - X86 FMA3 Instruction Information ----*- C++ -*-===// |
| 2 | // |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | // |
| 9 | // This file contains the implementation of the classes providing information |
| 10 | // about existing X86 FMA3 opcodes, classifying and grouping them. |
| 11 | // |
| 12 | //===----------------------------------------------------------------------===// |
| 13 | |
| 14 | #ifndef LLVM_LIB_TARGET_X86_UTILS_X86INSTRFMA3INFO_H |
| 15 | #define LLVM_LIB_TARGET_X86_UTILS_X86INSTRFMA3INFO_H |
| 16 | |
| 17 | #include <cstdint> |
| 18 | |
| 19 | namespace llvm { |
| 20 | |
| 21 | /// This class is used to group {132, 213, 231} forms of FMA opcodes together. |
| 22 | /// Each of the groups has either 3 opcodes, Also, each group has an attributes |
| 23 | /// field describing it. |
| 24 | struct X86InstrFMA3Group { |
| 25 | /// An array holding 3 forms of FMA opcodes. |
| 26 | uint16_t Opcodes[3]; |
| 27 | |
| 28 | /// This bitfield specifies the attributes associated with the created |
| 29 | /// FMA groups of opcodes. |
| 30 | uint16_t Attributes; |
| 31 | |
| 32 | enum { |
| 33 | Form132, |
| 34 | Form213, |
| 35 | Form231, |
| 36 | }; |
| 37 | |
| 38 | enum : uint16_t { |
| 39 | /// This bit must be set in the 'Attributes' field of FMA group if such |
| 40 | /// group of FMA opcodes consists of FMA intrinsic opcodes. |
| 41 | Intrinsic = 0x1, |
| 42 | |
| 43 | /// This bit must be set in the 'Attributes' field of FMA group if such |
| 44 | /// group of FMA opcodes consists of AVX512 opcodes accepting a k-mask and |
| 45 | /// passing the elements from the 1st operand to the result of the operation |
| 46 | /// when the correpondings bits in the k-mask are unset. |
| 47 | KMergeMasked = 0x2, |
| 48 | |
| 49 | /// This bit must be set in the 'Attributes' field of FMA group if such |
| 50 | /// group of FMA opcodes consists of AVX512 opcodes accepting a k-zeromask. |
| 51 | KZeroMasked = 0x4, |
| 52 | }; |
| 53 | |
| 54 | /// Returns the 132 form of FMA opcode. |
| 55 | unsigned get132Opcode() const { |
| 56 | return Opcodes[Form132]; |
| 57 | } |
| 58 | |
| 59 | /// Returns the 213 form of FMA opcode. |
| 60 | unsigned get213Opcode() const { |
| 61 | return Opcodes[Form213]; |
| 62 | } |
| 63 | |
| 64 | /// Returns the 231 form of FMA opcode. |
| 65 | unsigned get231Opcode() const { |
| 66 | return Opcodes[Form231]; |
| 67 | } |
| 68 | |
| 69 | /// Returns true iff the group of FMA opcodes holds intrinsic opcodes. |
| 70 | bool isIntrinsic() const { return (Attributes & Intrinsic) != 0; } |
| 71 | |
| 72 | /// Returns true iff the group of FMA opcodes holds k-merge-masked opcodes. |
| 73 | bool isKMergeMasked() const { |
| 74 | return (Attributes & KMergeMasked) != 0; |
| 75 | } |
| 76 | |
| 77 | /// Returns true iff the group of FMA opcodes holds k-zero-masked opcodes. |
| 78 | bool isKZeroMasked() const { return (Attributes &KZeroMasked) != 0; } |
| 79 | |
| 80 | /// Returns true iff the group of FMA opcodes holds any of k-masked opcodes. |
| 81 | bool isKMasked() const { |
| 82 | return (Attributes & (KMergeMasked | KZeroMasked)) != 0; |
| 83 | } |
| 84 | |
| 85 | bool operator<(const X86InstrFMA3Group &RHS) const { |
| 86 | return Opcodes[0] < RHS.Opcodes[0]; |
| 87 | } |
| 88 | }; |
| 89 | |
| 90 | /// Returns a reference to a group of FMA3 opcodes to where the given |
| 91 | /// \p Opcode is included. If the given \p Opcode is not recognized as FMA3 |
| 92 | /// and not included into any FMA3 group, then nullptr is returned. |
| 93 | const X86InstrFMA3Group *getFMA3Group(unsigned Opcode, uint64_t TSFlags); |
| 94 | |
| 95 | } // end namespace llvm |
| 96 | |
| 97 | #endif // LLVM_LIB_TARGET_X86_UTILS_X86INSTRFMA3INFO_H |
| 98 | |