1 //===-- X86InstrFMA3Info.cpp - X86 FMA3 Instruction Information -----------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file contains the implementation of the classes providing information 11 // about existing X86 FMA3 opcodes, classifying and grouping them. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "X86InstrFMA3Info.h" 16 #include "X86InstrInfo.h" 17 #include "llvm/Support/ManagedStatic.h" 18 #include "llvm/Support/Threading.h" 19 #include <cassert> 20 #include <cstdint> 21 22 using namespace llvm; 23 24 /// This flag is used in the method llvm::call_once() used below to make the 25 /// initialization of the map 'OpcodeToGroup' thread safe. 26 static llvm::once_flag InitGroupsOnceFlag; 27 28 static ManagedStatic<X86InstrFMA3Info> X86InstrFMA3InfoObj; 29 X86InstrFMA3Info *X86InstrFMA3Info::getX86InstrFMA3Info() { 30 return &*X86InstrFMA3InfoObj; 31 } 32 33 #define FMA3BASE(R132, R213, R231, M132, M213, M231, Attrs) \ 34 { { R132, R213, R231 }, { M132, M213, M231 }, Attrs }, 35 36 #define FMA3RMA(R132, R213, R231, M132, M213, M231, Attrs) \ 37 FMA3BASE(X86::R132, X86::R213, X86::R231, X86::M132, X86::M213, X86::M231, Attrs) 38 39 #define FMA3RM(R132, R213, R231, M132, M213, M231) \ 40 FMA3RMA(R132, R213, R231, M132, M213, M231, 0) 41 42 #define FMA3RA(R132, R213, R231, Attrs) \ 43 FMA3BASE(X86::R132, X86::R213, X86::R231, 0, 0, 0, Attrs) 44 45 #define FMA3R(R132, R213, R231) \ 46 FMA3RA(R132, R213, R231, 0) 47 48 #define FMA3MA(M132, M213, M231, Attrs) \ 49 FMA3BASE(0, 0, 0, X86::M132, X86::M213, X86::M231, Attrs) 50 51 #define FMA3M(M132, M213, M231) \ 52 FMA3MA(M132, M213, M231, 0) 53 54 #define FMA3_AVX2_VECTOR_GROUP(Name) \ 55 FMA3RM(Name##132PSr, Name##213PSr, Name##231PSr, \ 56 Name##132PSm, Name##213PSm, Name##231PSm) \ 57 FMA3RM(Name##132PDr, Name##213PDr, Name##231PDr, \ 58 Name##132PDm, Name##213PDm, Name##231PDm) \ 59 FMA3RM(Name##132PSYr, Name##213PSYr, Name##231PSYr, \ 60 Name##132PSYm, Name##213PSYm, Name##231PSYm) \ 61 FMA3RM(Name##132PDYr, Name##213PDYr, Name##231PDYr, \ 62 Name##132PDYm, Name##213PDYm, Name##231PDYm) 63 64 #define FMA3_AVX2_SCALAR_GROUP(Name) \ 65 FMA3RM(Name##132SSr, Name##213SSr, Name##231SSr, \ 66 Name##132SSm, Name##213SSm, Name##231SSm) \ 67 FMA3RM(Name##132SDr, Name##213SDr, Name##231SDr, \ 68 Name##132SDm, Name##213SDm, Name##231SDm) \ 69 FMA3RMA(Name##132SSr_Int, Name##213SSr_Int, Name##231SSr_Int, \ 70 Name##132SSm_Int, Name##213SSm_Int, Name##231SSm_Int, \ 71 X86InstrFMA3Group::X86FMA3Intrinsic) \ 72 FMA3RMA(Name##132SDr_Int, Name##213SDr_Int, Name##231SDr_Int, \ 73 Name##132SDm_Int, Name##213SDm_Int, Name##231SDm_Int, \ 74 X86InstrFMA3Group::X86FMA3Intrinsic) 75 76 #define FMA3_AVX2_FULL_GROUP(Name) \ 77 FMA3_AVX2_VECTOR_GROUP(Name) \ 78 FMA3_AVX2_SCALAR_GROUP(Name) 79 80 #define FMA3_AVX512_VECTOR_GROUP(Name) \ 81 FMA3RM(Name##132PSZ128r, Name##213PSZ128r, Name##231PSZ128r, \ 82 Name##132PSZ128m, Name##213PSZ128m, Name##231PSZ128m) \ 83 FMA3RM(Name##132PDZ128r, Name##213PDZ128r, Name##231PDZ128r, \ 84 Name##132PDZ128m, Name##213PDZ128m, Name##231PDZ128m) \ 85 FMA3RM(Name##132PSZ256r, Name##213PSZ256r, Name##231PSZ256r, \ 86 Name##132PSZ256m, Name##213PSZ256m, Name##231PSZ256m) \ 87 FMA3RM(Name##132PDZ256r, Name##213PDZ256r, Name##231PDZ256r, \ 88 Name##132PDZ256m, Name##213PDZ256m, Name##231PDZ256m) \ 89 FMA3RM(Name##132PSZr, Name##213PSZr, Name##231PSZr, \ 90 Name##132PSZm, Name##213PSZm, Name##231PSZm) \ 91 FMA3RM(Name##132PDZr, Name##213PDZr, Name##231PDZr, \ 92 Name##132PDZm, Name##213PDZm, Name##231PDZm) \ 93 FMA3RMA(Name##132PSZ128rk, Name##213PSZ128rk, Name##231PSZ128rk, \ 94 Name##132PSZ128mk, Name##213PSZ128mk, Name##231PSZ128mk, \ 95 X86InstrFMA3Group::X86FMA3KMergeMasked) \ 96 FMA3RMA(Name##132PDZ128rk, Name##213PDZ128rk, Name##231PDZ128rk, \ 97 Name##132PDZ128mk, Name##213PDZ128mk, Name##231PDZ128mk, \ 98 X86InstrFMA3Group::X86FMA3KMergeMasked) \ 99 FMA3RMA(Name##132PSZ256rk, Name##213PSZ256rk, Name##231PSZ256rk, \ 100 Name##132PSZ256mk, Name##213PSZ256mk, Name##231PSZ256mk, \ 101 X86InstrFMA3Group::X86FMA3KMergeMasked) \ 102 FMA3RMA(Name##132PDZ256rk, Name##213PDZ256rk, Name##231PDZ256rk, \ 103 Name##132PDZ256mk, Name##213PDZ256mk, Name##231PDZ256mk, \ 104 X86InstrFMA3Group::X86FMA3KMergeMasked) \ 105 FMA3RMA(Name##132PSZrk, Name##213PSZrk, Name##231PSZrk, \ 106 Name##132PSZmk, Name##213PSZmk, Name##231PSZmk, \ 107 X86InstrFMA3Group::X86FMA3KMergeMasked) \ 108 FMA3RMA(Name##132PDZrk, Name##213PDZrk, Name##231PDZrk, \ 109 Name##132PDZmk, Name##213PDZmk, Name##231PDZmk, \ 110 X86InstrFMA3Group::X86FMA3KMergeMasked) \ 111 FMA3RMA(Name##132PSZ128rkz, Name##213PSZ128rkz, Name##231PSZ128rkz, \ 112 Name##132PSZ128mkz, Name##213PSZ128mkz, Name##231PSZ128mkz, \ 113 X86InstrFMA3Group::X86FMA3KZeroMasked) \ 114 FMA3RMA(Name##132PDZ128rkz, Name##213PDZ128rkz, Name##231PDZ128rkz, \ 115 Name##132PDZ128mkz, Name##213PDZ128mkz, Name##231PDZ128mkz, \ 116 X86InstrFMA3Group::X86FMA3KZeroMasked) \ 117 FMA3RMA(Name##132PSZ256rkz, Name##213PSZ256rkz, Name##231PSZ256rkz, \ 118 Name##132PSZ256mkz, Name##213PSZ256mkz, Name##231PSZ256mkz, \ 119 X86InstrFMA3Group::X86FMA3KZeroMasked) \ 120 FMA3RMA(Name##132PDZ256rkz, Name##213PDZ256rkz, Name##231PDZ256rkz, \ 121 Name##132PDZ256mkz, Name##213PDZ256mkz, Name##231PDZ256mkz, \ 122 X86InstrFMA3Group::X86FMA3KZeroMasked) \ 123 FMA3RMA(Name##132PSZrkz, Name##213PSZrkz, Name##231PSZrkz, \ 124 Name##132PSZmkz, Name##213PSZmkz, Name##231PSZmkz, \ 125 X86InstrFMA3Group::X86FMA3KZeroMasked) \ 126 FMA3RMA(Name##132PDZrkz, Name##213PDZrkz, Name##231PDZrkz, \ 127 Name##132PDZmkz, Name##213PDZmkz, Name##231PDZmkz, \ 128 X86InstrFMA3Group::X86FMA3KZeroMasked) \ 129 FMA3R(Name##132PSZrb, Name##213PSZrb, Name##231PSZrb) \ 130 FMA3R(Name##132PDZrb, Name##213PDZrb, Name##231PDZrb) \ 131 FMA3RA(Name##132PSZrbk, Name##213PSZrbk, Name##231PSZrbk, \ 132 X86InstrFMA3Group::X86FMA3KMergeMasked) \ 133 FMA3RA(Name##132PDZrbk, Name##213PDZrbk, Name##231PDZrbk, \ 134 X86InstrFMA3Group::X86FMA3KMergeMasked) \ 135 FMA3RA(Name##132PSZrbkz, Name##213PSZrbkz, Name##231PSZrbkz, \ 136 X86InstrFMA3Group::X86FMA3KZeroMasked) \ 137 FMA3RA(Name##132PDZrbkz, Name##213PDZrbkz, Name##231PDZrbkz, \ 138 X86InstrFMA3Group::X86FMA3KZeroMasked) \ 139 FMA3M(Name##132PSZ128mb, Name##213PSZ128mb, Name##231PSZ128mb) \ 140 FMA3M(Name##132PDZ128mb, Name##213PDZ128mb, Name##231PDZ128mb) \ 141 FMA3M(Name##132PSZ256mb, Name##213PSZ256mb, Name##231PSZ256mb) \ 142 FMA3M(Name##132PDZ256mb, Name##213PDZ256mb, Name##231PDZ256mb) \ 143 FMA3M(Name##132PSZmb, Name##213PSZmb, Name##231PSZmb) \ 144 FMA3M(Name##132PDZmb, Name##213PDZmb, Name##231PDZmb) \ 145 FMA3MA(Name##132PSZ128mbk, Name##213PSZ128mbk, Name##231PSZ128mbk, \ 146 X86InstrFMA3Group::X86FMA3KMergeMasked) \ 147 FMA3MA(Name##132PDZ128mbk, Name##213PDZ128mbk, Name##231PDZ128mbk, \ 148 X86InstrFMA3Group::X86FMA3KMergeMasked) \ 149 FMA3MA(Name##132PSZ256mbk, Name##213PSZ256mbk, Name##231PSZ256mbk, \ 150 X86InstrFMA3Group::X86FMA3KMergeMasked) \ 151 FMA3MA(Name##132PDZ256mbk, Name##213PDZ256mbk, Name##231PDZ256mbk, \ 152 X86InstrFMA3Group::X86FMA3KMergeMasked) \ 153 FMA3MA(Name##132PSZmbk, Name##213PSZmbk, Name##231PSZmbk, \ 154 X86InstrFMA3Group::X86FMA3KMergeMasked) \ 155 FMA3MA(Name##132PDZmbk, Name##213PDZmbk, Name##231PDZmbk, \ 156 X86InstrFMA3Group::X86FMA3KMergeMasked) \ 157 FMA3MA(Name##132PSZ128mbkz, Name##213PSZ128mbkz, Name##231PSZ128mbkz, \ 158 X86InstrFMA3Group::X86FMA3KZeroMasked) \ 159 FMA3MA(Name##132PDZ128mbkz, Name##213PDZ128mbkz, Name##231PDZ128mbkz, \ 160 X86InstrFMA3Group::X86FMA3KZeroMasked) \ 161 FMA3MA(Name##132PSZ256mbkz, Name##213PSZ256mbkz, Name##231PSZ256mbkz, \ 162 X86InstrFMA3Group::X86FMA3KZeroMasked) \ 163 FMA3MA(Name##132PDZ256mbkz, Name##213PDZ256mbkz, Name##231PDZ256mbkz, \ 164 X86InstrFMA3Group::X86FMA3KZeroMasked) \ 165 FMA3MA(Name##132PSZmbkz, Name##213PSZmbkz, Name##231PSZmbkz, \ 166 X86InstrFMA3Group::X86FMA3KZeroMasked) \ 167 FMA3MA(Name##132PDZmbkz, Name##213PDZmbkz, Name##231PDZmbkz, \ 168 X86InstrFMA3Group::X86FMA3KZeroMasked) 169 170 #define FMA3_AVX512_SCALAR_GROUP(Name) \ 171 FMA3RM(Name##132SSZr, Name##213SSZr, Name##231SSZr, \ 172 Name##132SSZm, Name##213SSZm, Name##231SSZm) \ 173 FMA3RM(Name##132SDZr, Name##213SDZr, Name##231SDZr, \ 174 Name##132SDZm, Name##213SDZm, Name##231SDZm) \ 175 FMA3RMA(Name##132SSZr_Int, Name##213SSZr_Int, Name##231SSZr_Int, \ 176 Name##132SSZm_Int, Name##213SSZm_Int, Name##231SSZm_Int, \ 177 X86InstrFMA3Group::X86FMA3Intrinsic) \ 178 FMA3RMA(Name##132SDZr_Int, Name##213SDZr_Int, Name##231SDZr_Int, \ 179 Name##132SDZm_Int, Name##213SDZm_Int, Name##231SDZm_Int, \ 180 X86InstrFMA3Group::X86FMA3Intrinsic) \ 181 FMA3RMA(Name##132SSZr_Intk, Name##213SSZr_Intk, Name##231SSZr_Intk, \ 182 Name##132SSZm_Intk, Name##213SSZm_Intk, Name##231SSZm_Intk, \ 183 X86InstrFMA3Group::X86FMA3Intrinsic | \ 184 X86InstrFMA3Group::X86FMA3KMergeMasked) \ 185 FMA3RMA(Name##132SDZr_Intk, Name##213SDZr_Intk, Name##231SDZr_Intk, \ 186 Name##132SDZm_Intk, Name##213SDZm_Intk, Name##231SDZm_Intk, \ 187 X86InstrFMA3Group::X86FMA3Intrinsic | \ 188 X86InstrFMA3Group::X86FMA3KMergeMasked) \ 189 FMA3RMA(Name##132SSZr_Intkz, Name##213SSZr_Intkz, Name##231SSZr_Intkz, \ 190 Name##132SSZm_Intkz, Name##213SSZm_Intkz, Name##231SSZm_Intkz, \ 191 X86InstrFMA3Group::X86FMA3Intrinsic | \ 192 X86InstrFMA3Group::X86FMA3KZeroMasked) \ 193 FMA3RMA(Name##132SDZr_Intkz, Name##213SDZr_Intkz, Name##231SDZr_Intkz, \ 194 Name##132SDZm_Intkz, Name##213SDZm_Intkz, Name##231SDZm_Intkz, \ 195 X86InstrFMA3Group::X86FMA3Intrinsic | \ 196 X86InstrFMA3Group::X86FMA3KZeroMasked) \ 197 FMA3RA(Name##132SSZrb_Int, Name##213SSZrb_Int, Name##231SSZrb_Int, \ 198 X86InstrFMA3Group::X86FMA3Intrinsic) \ 199 FMA3RA(Name##132SDZrb_Int, Name##213SDZrb_Int, Name##231SDZrb_Int, \ 200 X86InstrFMA3Group::X86FMA3Intrinsic) \ 201 FMA3RA(Name##132SSZrb_Intk, Name##213SSZrb_Intk, Name##231SSZrb_Intk, \ 202 X86InstrFMA3Group::X86FMA3Intrinsic | \ 203 X86InstrFMA3Group::X86FMA3KMergeMasked) \ 204 FMA3RA(Name##132SDZrb_Intk, Name##213SDZrb_Intk, Name##231SDZrb_Intk, \ 205 X86InstrFMA3Group::X86FMA3Intrinsic | \ 206 X86InstrFMA3Group::X86FMA3KMergeMasked) \ 207 FMA3RA(Name##132SSZrb_Intkz, Name##213SSZrb_Intkz, Name##231SSZrb_Intkz, \ 208 X86InstrFMA3Group::X86FMA3Intrinsic | \ 209 X86InstrFMA3Group::X86FMA3KZeroMasked) \ 210 FMA3RA(Name##132SDZrb_Intkz, Name##213SDZrb_Intkz, Name##231SDZrb_Intkz, \ 211 X86InstrFMA3Group::X86FMA3Intrinsic | \ 212 X86InstrFMA3Group::X86FMA3KZeroMasked) 213 214 #define FMA3_AVX512_FULL_GROUP(Name) \ 215 FMA3_AVX512_VECTOR_GROUP(Name) \ 216 FMA3_AVX512_SCALAR_GROUP(Name) 217 218 static const X86InstrFMA3Group Groups[] = { 219 FMA3_AVX2_FULL_GROUP(VFMADD) 220 FMA3_AVX2_FULL_GROUP(VFMSUB) 221 FMA3_AVX2_FULL_GROUP(VFNMADD) 222 FMA3_AVX2_FULL_GROUP(VFNMSUB) 223 224 FMA3_AVX2_VECTOR_GROUP(VFMADDSUB) 225 FMA3_AVX2_VECTOR_GROUP(VFMSUBADD) 226 227 FMA3_AVX512_FULL_GROUP(VFMADD) 228 FMA3_AVX512_FULL_GROUP(VFMSUB) 229 FMA3_AVX512_FULL_GROUP(VFNMADD) 230 FMA3_AVX512_FULL_GROUP(VFNMSUB) 231 232 FMA3_AVX512_VECTOR_GROUP(VFMADDSUB) 233 FMA3_AVX512_VECTOR_GROUP(VFMSUBADD) 234 }; 235 236 void X86InstrFMA3Info::initGroupsOnceImpl() { 237 for (const X86InstrFMA3Group &G : Groups) { 238 if (G.RegOpcodes[0]) 239 OpcodeToGroup[G.RegOpcodes[0]] = &G; 240 if (G.RegOpcodes[1]) 241 OpcodeToGroup[G.RegOpcodes[1]] = &G; 242 if (G.RegOpcodes[2]) 243 OpcodeToGroup[G.RegOpcodes[2]] = &G; 244 if (G.MemOpcodes[0]) 245 OpcodeToGroup[G.MemOpcodes[0]] = &G; 246 if (G.MemOpcodes[1]) 247 OpcodeToGroup[G.MemOpcodes[1]] = &G; 248 if (G.MemOpcodes[2]) 249 OpcodeToGroup[G.MemOpcodes[2]] = &G; 250 } 251 } 252 253 void X86InstrFMA3Info::initGroupsOnce() { 254 llvm::call_once(InitGroupsOnceFlag, 255 []() { getX86InstrFMA3Info()->initGroupsOnceImpl(); }); 256 } 257