1*06c3fb27SDimitry Andric //===- VTEmitter.cpp - Generate properties from ValueTypes.td -------------===// 2*06c3fb27SDimitry Andric // 3*06c3fb27SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*06c3fb27SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*06c3fb27SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*06c3fb27SDimitry Andric // 7*06c3fb27SDimitry Andric //===----------------------------------------------------------------------===// 8*06c3fb27SDimitry Andric 9*06c3fb27SDimitry Andric #include "llvm/ADT/StringRef.h" 10*06c3fb27SDimitry Andric #include "llvm/Support/raw_ostream.h" 11*06c3fb27SDimitry Andric #include "llvm/TableGen/Record.h" 12*06c3fb27SDimitry Andric #include "llvm/TableGen/TableGenBackend.h" 13*06c3fb27SDimitry Andric #include <array> 14*06c3fb27SDimitry Andric #include <cassert> 15*06c3fb27SDimitry Andric #include <map> 16*06c3fb27SDimitry Andric using namespace llvm; 17*06c3fb27SDimitry Andric 18*06c3fb27SDimitry Andric namespace { 19*06c3fb27SDimitry Andric 20*06c3fb27SDimitry Andric class VTEmitter { 21*06c3fb27SDimitry Andric private: 22*06c3fb27SDimitry Andric RecordKeeper &Records; 23*06c3fb27SDimitry Andric 24*06c3fb27SDimitry Andric public: 25*06c3fb27SDimitry Andric VTEmitter(RecordKeeper &R) : Records(R) {} 26*06c3fb27SDimitry Andric 27*06c3fb27SDimitry Andric void run(raw_ostream &OS); 28*06c3fb27SDimitry Andric }; 29*06c3fb27SDimitry Andric 30*06c3fb27SDimitry Andric } // End anonymous namespace. 31*06c3fb27SDimitry Andric 32*06c3fb27SDimitry Andric void VTEmitter::run(raw_ostream &OS) { 33*06c3fb27SDimitry Andric emitSourceFileHeader("ValueTypes Source Fragment", OS); 34*06c3fb27SDimitry Andric 35*06c3fb27SDimitry Andric std::array<const Record *, 256> VTsByNumber = {}; 36*06c3fb27SDimitry Andric auto ValueTypes = Records.getAllDerivedDefinitions("ValueType"); 37*06c3fb27SDimitry Andric for (auto *VT : ValueTypes) { 38*06c3fb27SDimitry Andric auto Number = VT->getValueAsInt("Value"); 39*06c3fb27SDimitry Andric assert(0 <= Number && Number < (int)VTsByNumber.size() && 40*06c3fb27SDimitry Andric "ValueType should be uint8_t"); 41*06c3fb27SDimitry Andric assert(!VTsByNumber[Number] && "Duplicate ValueType"); 42*06c3fb27SDimitry Andric VTsByNumber[Number] = VT; 43*06c3fb27SDimitry Andric } 44*06c3fb27SDimitry Andric 45*06c3fb27SDimitry Andric struct VTRange { 46*06c3fb27SDimitry Andric StringRef First; 47*06c3fb27SDimitry Andric StringRef Last; 48*06c3fb27SDimitry Andric bool Closed; 49*06c3fb27SDimitry Andric }; 50*06c3fb27SDimitry Andric 51*06c3fb27SDimitry Andric std::map<StringRef, VTRange> VTRanges; 52*06c3fb27SDimitry Andric 53*06c3fb27SDimitry Andric auto UpdateVTRange = [&VTRanges](const char *Key, StringRef Name, 54*06c3fb27SDimitry Andric bool Valid) { 55*06c3fb27SDimitry Andric if (Valid) { 56*06c3fb27SDimitry Andric if (!VTRanges.count(Key)) 57*06c3fb27SDimitry Andric VTRanges[Key].First = Name; 58*06c3fb27SDimitry Andric assert(!VTRanges[Key].Closed && "Gap detected!"); 59*06c3fb27SDimitry Andric VTRanges[Key].Last = Name; 60*06c3fb27SDimitry Andric } else if (VTRanges.count(Key)) { 61*06c3fb27SDimitry Andric VTRanges[Key].Closed = true; 62*06c3fb27SDimitry Andric } 63*06c3fb27SDimitry Andric }; 64*06c3fb27SDimitry Andric 65*06c3fb27SDimitry Andric OS << "#ifdef GET_VT_ATTR // (Ty, n, sz, Any, Int, FP, Vec, Sc)\n"; 66*06c3fb27SDimitry Andric for (const auto *VT : VTsByNumber) { 67*06c3fb27SDimitry Andric if (!VT) 68*06c3fb27SDimitry Andric continue; 69*06c3fb27SDimitry Andric auto Name = VT->getValueAsString("LLVMName"); 70*06c3fb27SDimitry Andric auto Value = VT->getValueAsInt("Value"); 71*06c3fb27SDimitry Andric bool IsInteger = VT->getValueAsInt("isInteger"); 72*06c3fb27SDimitry Andric bool IsFP = VT->getValueAsInt("isFP"); 73*06c3fb27SDimitry Andric bool IsVector = VT->getValueAsInt("isVector"); 74*06c3fb27SDimitry Andric bool IsScalable = VT->getValueAsInt("isScalable"); 75*06c3fb27SDimitry Andric 76*06c3fb27SDimitry Andric UpdateVTRange("INTEGER_FIXEDLEN_VECTOR_VALUETYPE", Name, 77*06c3fb27SDimitry Andric IsInteger && IsVector && !IsScalable); 78*06c3fb27SDimitry Andric UpdateVTRange("INTEGER_SCALABLE_VECTOR_VALUETYPE", Name, 79*06c3fb27SDimitry Andric IsInteger && IsScalable); 80*06c3fb27SDimitry Andric UpdateVTRange("FP_FIXEDLEN_VECTOR_VALUETYPE", Name, 81*06c3fb27SDimitry Andric IsFP && IsVector && !IsScalable); 82*06c3fb27SDimitry Andric UpdateVTRange("FP_SCALABLE_VECTOR_VALUETYPE", Name, IsFP && IsScalable); 83*06c3fb27SDimitry Andric UpdateVTRange("FIXEDLEN_VECTOR_VALUETYPE", Name, IsVector && !IsScalable); 84*06c3fb27SDimitry Andric UpdateVTRange("SCALABLE_VECTOR_VALUETYPE", Name, IsScalable); 85*06c3fb27SDimitry Andric UpdateVTRange("VECTOR_VALUETYPE", Name, IsVector); 86*06c3fb27SDimitry Andric UpdateVTRange("INTEGER_VALUETYPE", Name, IsInteger && !IsVector); 87*06c3fb27SDimitry Andric UpdateVTRange("FP_VALUETYPE", Name, IsFP && !IsVector); 88*06c3fb27SDimitry Andric UpdateVTRange("VALUETYPE", Name, Value < 224); 89*06c3fb27SDimitry Andric 90*06c3fb27SDimitry Andric // clang-format off 91*06c3fb27SDimitry Andric OS << " GET_VT_ATTR(" 92*06c3fb27SDimitry Andric << Name << ", " 93*06c3fb27SDimitry Andric << Value << ", " 94*06c3fb27SDimitry Andric << VT->getValueAsInt("Size") << ", " 95*06c3fb27SDimitry Andric << VT->getValueAsInt("isOverloaded") << ", " 96*06c3fb27SDimitry Andric << (IsInteger ? Name[0] == 'i' ? 3 : 1 : 0) << ", " 97*06c3fb27SDimitry Andric << (IsFP ? Name[0] == 'f' ? 3 : 1 : 0) << ", " 98*06c3fb27SDimitry Andric << IsVector << ", " 99*06c3fb27SDimitry Andric << IsScalable << ")\n"; 100*06c3fb27SDimitry Andric // clang-format on 101*06c3fb27SDimitry Andric } 102*06c3fb27SDimitry Andric OS << "#endif\n\n"; 103*06c3fb27SDimitry Andric 104*06c3fb27SDimitry Andric OS << "#ifdef GET_VT_RANGES\n"; 105*06c3fb27SDimitry Andric for (const auto &KV : VTRanges) { 106*06c3fb27SDimitry Andric assert(KV.second.Closed); 107*06c3fb27SDimitry Andric OS << " FIRST_" << KV.first << " = " << KV.second.First << ",\n" 108*06c3fb27SDimitry Andric << " LAST_" << KV.first << " = " << KV.second.Last << ",\n"; 109*06c3fb27SDimitry Andric } 110*06c3fb27SDimitry Andric OS << "#endif\n\n"; 111*06c3fb27SDimitry Andric 112*06c3fb27SDimitry Andric OS << "#ifdef GET_VT_VECATTR // (Ty, Sc, nElem, ElTy, ElSz)\n"; 113*06c3fb27SDimitry Andric for (const auto *VT : VTsByNumber) { 114*06c3fb27SDimitry Andric if (!VT || !VT->getValueAsInt("isVector")) 115*06c3fb27SDimitry Andric continue; 116*06c3fb27SDimitry Andric const auto *ElTy = VT->getValueAsDef("ElementType"); 117*06c3fb27SDimitry Andric assert(ElTy); 118*06c3fb27SDimitry Andric // clang-format off 119*06c3fb27SDimitry Andric OS << " GET_VT_VECATTR(" 120*06c3fb27SDimitry Andric << VT->getValueAsString("LLVMName") << ", " 121*06c3fb27SDimitry Andric << VT->getValueAsInt("isScalable") << ", " 122*06c3fb27SDimitry Andric << VT->getValueAsInt("nElem") << ", " 123*06c3fb27SDimitry Andric << ElTy->getName() << ", " 124*06c3fb27SDimitry Andric << ElTy->getValueAsInt("Size") << ")\n"; 125*06c3fb27SDimitry Andric // clang-format on 126*06c3fb27SDimitry Andric } 127*06c3fb27SDimitry Andric OS << "#endif\n\n"; 128*06c3fb27SDimitry Andric } 129*06c3fb27SDimitry Andric 130*06c3fb27SDimitry Andric static TableGen::Emitter::OptClass<VTEmitter> X("gen-vt", "Generate ValueType"); 131