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