10b57cec5SDimitry Andric //===- CodeGenTarget.cpp - CodeGen Target Class Wrapper -------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This class wraps target description classes used by the various code 100b57cec5SDimitry Andric // generation TableGen backends. This makes it easier to access the data and 110b57cec5SDimitry Andric // provides a single place that needs to check it for validity. All of these 120b57cec5SDimitry Andric // classes abort on error conditions. 130b57cec5SDimitry Andric // 140b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #include "CodeGenTarget.h" 1781ad6265SDimitry Andric #include "CodeGenInstruction.h" 18*fe013be4SDimitry Andric #include "CodeGenRegisters.h" 190b57cec5SDimitry Andric #include "CodeGenSchedule.h" 200b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 21*fe013be4SDimitry Andric #include "llvm/ADT/Twine.h" 220b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h" 23*fe013be4SDimitry Andric #include "llvm/Support/ErrorHandling.h" 240b57cec5SDimitry Andric #include "llvm/TableGen/Error.h" 250b57cec5SDimitry Andric #include "llvm/TableGen/Record.h" 260b57cec5SDimitry Andric #include <algorithm> 27*fe013be4SDimitry Andric #include <iterator> 28*fe013be4SDimitry Andric #include <tuple> 290b57cec5SDimitry Andric using namespace llvm; 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric cl::OptionCategory AsmParserCat("Options for -gen-asm-parser"); 320b57cec5SDimitry Andric cl::OptionCategory AsmWriterCat("Options for -gen-asm-writer"); 330b57cec5SDimitry Andric 340b57cec5SDimitry Andric static cl::opt<unsigned> 350b57cec5SDimitry Andric AsmParserNum("asmparsernum", cl::init(0), 360b57cec5SDimitry Andric cl::desc("Make -gen-asm-parser emit assembly parser #N"), 370b57cec5SDimitry Andric cl::cat(AsmParserCat)); 380b57cec5SDimitry Andric 390b57cec5SDimitry Andric static cl::opt<unsigned> 400b57cec5SDimitry Andric AsmWriterNum("asmwriternum", cl::init(0), 410b57cec5SDimitry Andric cl::desc("Make -gen-asm-writer emit assembly writer #N"), 420b57cec5SDimitry Andric cl::cat(AsmWriterCat)); 430b57cec5SDimitry Andric 440b57cec5SDimitry Andric /// getValueType - Return the MVT::SimpleValueType that the specified TableGen 450b57cec5SDimitry Andric /// record corresponds to. 460b57cec5SDimitry Andric MVT::SimpleValueType llvm::getValueType(Record *Rec) { 470b57cec5SDimitry Andric return (MVT::SimpleValueType)Rec->getValueAsInt("Value"); 480b57cec5SDimitry Andric } 490b57cec5SDimitry Andric 500b57cec5SDimitry Andric StringRef llvm::getName(MVT::SimpleValueType T) { 510b57cec5SDimitry Andric switch (T) { 520b57cec5SDimitry Andric case MVT::Other: return "UNKNOWN"; 530b57cec5SDimitry Andric case MVT::iPTR: return "TLI.getPointerTy()"; 540b57cec5SDimitry Andric case MVT::iPTRAny: return "TLI.getPointerTy()"; 550b57cec5SDimitry Andric default: return getEnumName(T); 560b57cec5SDimitry Andric } 570b57cec5SDimitry Andric } 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric StringRef llvm::getEnumName(MVT::SimpleValueType T) { 6081ad6265SDimitry Andric // clang-format off 610b57cec5SDimitry Andric switch (T) { 620b57cec5SDimitry Andric case MVT::Other: return "MVT::Other"; 630b57cec5SDimitry Andric case MVT::i1: return "MVT::i1"; 6481ad6265SDimitry Andric case MVT::i2: return "MVT::i2"; 6581ad6265SDimitry Andric case MVT::i4: return "MVT::i4"; 660b57cec5SDimitry Andric case MVT::i8: return "MVT::i8"; 670b57cec5SDimitry Andric case MVT::i16: return "MVT::i16"; 680b57cec5SDimitry Andric case MVT::i32: return "MVT::i32"; 690b57cec5SDimitry Andric case MVT::i64: return "MVT::i64"; 700b57cec5SDimitry Andric case MVT::i128: return "MVT::i128"; 710b57cec5SDimitry Andric case MVT::Any: return "MVT::Any"; 720b57cec5SDimitry Andric case MVT::iAny: return "MVT::iAny"; 730b57cec5SDimitry Andric case MVT::fAny: return "MVT::fAny"; 740b57cec5SDimitry Andric case MVT::vAny: return "MVT::vAny"; 750b57cec5SDimitry Andric case MVT::f16: return "MVT::f16"; 765ffd83dbSDimitry Andric case MVT::bf16: return "MVT::bf16"; 770b57cec5SDimitry Andric case MVT::f32: return "MVT::f32"; 780b57cec5SDimitry Andric case MVT::f64: return "MVT::f64"; 790b57cec5SDimitry Andric case MVT::f80: return "MVT::f80"; 800b57cec5SDimitry Andric case MVT::f128: return "MVT::f128"; 810b57cec5SDimitry Andric case MVT::ppcf128: return "MVT::ppcf128"; 820b57cec5SDimitry Andric case MVT::x86mmx: return "MVT::x86mmx"; 83e8d8bef9SDimitry Andric case MVT::x86amx: return "MVT::x86amx"; 84*fe013be4SDimitry Andric case MVT::aarch64svcount: return "MVT::aarch64svcount"; 856e75b2fbSDimitry Andric case MVT::i64x8: return "MVT::i64x8"; 860b57cec5SDimitry Andric case MVT::Glue: return "MVT::Glue"; 870b57cec5SDimitry Andric case MVT::isVoid: return "MVT::isVoid"; 880b57cec5SDimitry Andric case MVT::v1i1: return "MVT::v1i1"; 890b57cec5SDimitry Andric case MVT::v2i1: return "MVT::v2i1"; 900b57cec5SDimitry Andric case MVT::v4i1: return "MVT::v4i1"; 910b57cec5SDimitry Andric case MVT::v8i1: return "MVT::v8i1"; 920b57cec5SDimitry Andric case MVT::v16i1: return "MVT::v16i1"; 930b57cec5SDimitry Andric case MVT::v32i1: return "MVT::v32i1"; 940b57cec5SDimitry Andric case MVT::v64i1: return "MVT::v64i1"; 950b57cec5SDimitry Andric case MVT::v128i1: return "MVT::v128i1"; 96e8d8bef9SDimitry Andric case MVT::v256i1: return "MVT::v256i1"; 970b57cec5SDimitry Andric case MVT::v512i1: return "MVT::v512i1"; 980b57cec5SDimitry Andric case MVT::v1024i1: return "MVT::v1024i1"; 99bdd1243dSDimitry Andric case MVT::v2048i1: return "MVT::v2048i1"; 10081ad6265SDimitry Andric case MVT::v128i2: return "MVT::v128i2"; 101bdd1243dSDimitry Andric case MVT::v256i2: return "MVT::v256i2"; 10281ad6265SDimitry Andric case MVT::v64i4: return "MVT::v64i4"; 103bdd1243dSDimitry Andric case MVT::v128i4: return "MVT::v128i4"; 1040b57cec5SDimitry Andric case MVT::v1i8: return "MVT::v1i8"; 1050b57cec5SDimitry Andric case MVT::v2i8: return "MVT::v2i8"; 1060b57cec5SDimitry Andric case MVT::v4i8: return "MVT::v4i8"; 1070b57cec5SDimitry Andric case MVT::v8i8: return "MVT::v8i8"; 1080b57cec5SDimitry Andric case MVT::v16i8: return "MVT::v16i8"; 1090b57cec5SDimitry Andric case MVT::v32i8: return "MVT::v32i8"; 1100b57cec5SDimitry Andric case MVT::v64i8: return "MVT::v64i8"; 1110b57cec5SDimitry Andric case MVT::v128i8: return "MVT::v128i8"; 1120b57cec5SDimitry Andric case MVT::v256i8: return "MVT::v256i8"; 113fe6060f1SDimitry Andric case MVT::v512i8: return "MVT::v512i8"; 114fe6060f1SDimitry Andric case MVT::v1024i8: return "MVT::v1024i8"; 1150b57cec5SDimitry Andric case MVT::v1i16: return "MVT::v1i16"; 1160b57cec5SDimitry Andric case MVT::v2i16: return "MVT::v2i16"; 1178bcb0991SDimitry Andric case MVT::v3i16: return "MVT::v3i16"; 1180b57cec5SDimitry Andric case MVT::v4i16: return "MVT::v4i16"; 1190b57cec5SDimitry Andric case MVT::v8i16: return "MVT::v8i16"; 1200b57cec5SDimitry Andric case MVT::v16i16: return "MVT::v16i16"; 1210b57cec5SDimitry Andric case MVT::v32i16: return "MVT::v32i16"; 1220b57cec5SDimitry Andric case MVT::v64i16: return "MVT::v64i16"; 1230b57cec5SDimitry Andric case MVT::v128i16: return "MVT::v128i16"; 124fe6060f1SDimitry Andric case MVT::v256i16: return "MVT::v256i16"; 125fe6060f1SDimitry Andric case MVT::v512i16: return "MVT::v512i16"; 1260b57cec5SDimitry Andric case MVT::v1i32: return "MVT::v1i32"; 1270b57cec5SDimitry Andric case MVT::v2i32: return "MVT::v2i32"; 1280b57cec5SDimitry Andric case MVT::v3i32: return "MVT::v3i32"; 1290b57cec5SDimitry Andric case MVT::v4i32: return "MVT::v4i32"; 1300b57cec5SDimitry Andric case MVT::v5i32: return "MVT::v5i32"; 131fe6060f1SDimitry Andric case MVT::v6i32: return "MVT::v6i32"; 132fe6060f1SDimitry Andric case MVT::v7i32: return "MVT::v7i32"; 1330b57cec5SDimitry Andric case MVT::v8i32: return "MVT::v8i32"; 134bdd1243dSDimitry Andric case MVT::v9i32: return "MVT::v9i32"; 135bdd1243dSDimitry Andric case MVT::v10i32: return "MVT::v10i32"; 136bdd1243dSDimitry Andric case MVT::v11i32: return "MVT::v11i32"; 137bdd1243dSDimitry Andric case MVT::v12i32: return "MVT::v12i32"; 1380b57cec5SDimitry Andric case MVT::v16i32: return "MVT::v16i32"; 1390b57cec5SDimitry Andric case MVT::v32i32: return "MVT::v32i32"; 1400b57cec5SDimitry Andric case MVT::v64i32: return "MVT::v64i32"; 1410b57cec5SDimitry Andric case MVT::v128i32: return "MVT::v128i32"; 1420b57cec5SDimitry Andric case MVT::v256i32: return "MVT::v256i32"; 1430b57cec5SDimitry Andric case MVT::v512i32: return "MVT::v512i32"; 1440b57cec5SDimitry Andric case MVT::v1024i32: return "MVT::v1024i32"; 1450b57cec5SDimitry Andric case MVT::v2048i32: return "MVT::v2048i32"; 1460b57cec5SDimitry Andric case MVT::v1i64: return "MVT::v1i64"; 1470b57cec5SDimitry Andric case MVT::v2i64: return "MVT::v2i64"; 148fe6060f1SDimitry Andric case MVT::v3i64: return "MVT::v3i64"; 1490b57cec5SDimitry Andric case MVT::v4i64: return "MVT::v4i64"; 1500b57cec5SDimitry Andric case MVT::v8i64: return "MVT::v8i64"; 1510b57cec5SDimitry Andric case MVT::v16i64: return "MVT::v16i64"; 1520b57cec5SDimitry Andric case MVT::v32i64: return "MVT::v32i64"; 153e8d8bef9SDimitry Andric case MVT::v64i64: return "MVT::v64i64"; 154e8d8bef9SDimitry Andric case MVT::v128i64: return "MVT::v128i64"; 155e8d8bef9SDimitry Andric case MVT::v256i64: return "MVT::v256i64"; 1560b57cec5SDimitry Andric case MVT::v1i128: return "MVT::v1i128"; 157fe6060f1SDimitry Andric case MVT::v1f16: return "MVT::v1f16"; 1580b57cec5SDimitry Andric case MVT::v2f16: return "MVT::v2f16"; 1598bcb0991SDimitry Andric case MVT::v3f16: return "MVT::v3f16"; 1600b57cec5SDimitry Andric case MVT::v4f16: return "MVT::v4f16"; 1610b57cec5SDimitry Andric case MVT::v8f16: return "MVT::v8f16"; 1628bcb0991SDimitry Andric case MVT::v16f16: return "MVT::v16f16"; 1638bcb0991SDimitry Andric case MVT::v32f16: return "MVT::v32f16"; 1645ffd83dbSDimitry Andric case MVT::v64f16: return "MVT::v64f16"; 1655ffd83dbSDimitry Andric case MVT::v128f16: return "MVT::v128f16"; 166fe6060f1SDimitry Andric case MVT::v256f16: return "MVT::v256f16"; 167fe6060f1SDimitry Andric case MVT::v512f16: return "MVT::v512f16"; 1685ffd83dbSDimitry Andric case MVT::v2bf16: return "MVT::v2bf16"; 1695ffd83dbSDimitry Andric case MVT::v3bf16: return "MVT::v3bf16"; 1705ffd83dbSDimitry Andric case MVT::v4bf16: return "MVT::v4bf16"; 1715ffd83dbSDimitry Andric case MVT::v8bf16: return "MVT::v8bf16"; 1725ffd83dbSDimitry Andric case MVT::v16bf16: return "MVT::v16bf16"; 1735ffd83dbSDimitry Andric case MVT::v32bf16: return "MVT::v32bf16"; 1745ffd83dbSDimitry Andric case MVT::v64bf16: return "MVT::v64bf16"; 1755ffd83dbSDimitry Andric case MVT::v128bf16: return "MVT::v128bf16"; 1760b57cec5SDimitry Andric case MVT::v1f32: return "MVT::v1f32"; 1770b57cec5SDimitry Andric case MVT::v2f32: return "MVT::v2f32"; 1780b57cec5SDimitry Andric case MVT::v3f32: return "MVT::v3f32"; 1790b57cec5SDimitry Andric case MVT::v4f32: return "MVT::v4f32"; 1800b57cec5SDimitry Andric case MVT::v5f32: return "MVT::v5f32"; 181fe6060f1SDimitry Andric case MVT::v6f32: return "MVT::v6f32"; 182fe6060f1SDimitry Andric case MVT::v7f32: return "MVT::v7f32"; 1830b57cec5SDimitry Andric case MVT::v8f32: return "MVT::v8f32"; 184bdd1243dSDimitry Andric case MVT::v9f32: return "MVT::v9f32"; 185bdd1243dSDimitry Andric case MVT::v10f32: return "MVT::v10f32"; 186bdd1243dSDimitry Andric case MVT::v11f32: return "MVT::v11f32"; 187bdd1243dSDimitry Andric case MVT::v12f32: return "MVT::v12f32"; 1880b57cec5SDimitry Andric case MVT::v16f32: return "MVT::v16f32"; 1890b57cec5SDimitry Andric case MVT::v32f32: return "MVT::v32f32"; 1900b57cec5SDimitry Andric case MVT::v64f32: return "MVT::v64f32"; 1910b57cec5SDimitry Andric case MVT::v128f32: return "MVT::v128f32"; 1920b57cec5SDimitry Andric case MVT::v256f32: return "MVT::v256f32"; 1930b57cec5SDimitry Andric case MVT::v512f32: return "MVT::v512f32"; 1940b57cec5SDimitry Andric case MVT::v1024f32: return "MVT::v1024f32"; 1950b57cec5SDimitry Andric case MVT::v2048f32: return "MVT::v2048f32"; 1960b57cec5SDimitry Andric case MVT::v1f64: return "MVT::v1f64"; 1970b57cec5SDimitry Andric case MVT::v2f64: return "MVT::v2f64"; 198fe6060f1SDimitry Andric case MVT::v3f64: return "MVT::v3f64"; 1990b57cec5SDimitry Andric case MVT::v4f64: return "MVT::v4f64"; 2000b57cec5SDimitry Andric case MVT::v8f64: return "MVT::v8f64"; 2015ffd83dbSDimitry Andric case MVT::v16f64: return "MVT::v16f64"; 2025ffd83dbSDimitry Andric case MVT::v32f64: return "MVT::v32f64"; 203e8d8bef9SDimitry Andric case MVT::v64f64: return "MVT::v64f64"; 204e8d8bef9SDimitry Andric case MVT::v128f64: return "MVT::v128f64"; 205e8d8bef9SDimitry Andric case MVT::v256f64: return "MVT::v256f64"; 2060b57cec5SDimitry Andric case MVT::nxv1i1: return "MVT::nxv1i1"; 2070b57cec5SDimitry Andric case MVT::nxv2i1: return "MVT::nxv2i1"; 2080b57cec5SDimitry Andric case MVT::nxv4i1: return "MVT::nxv4i1"; 2090b57cec5SDimitry Andric case MVT::nxv8i1: return "MVT::nxv8i1"; 2100b57cec5SDimitry Andric case MVT::nxv16i1: return "MVT::nxv16i1"; 2110b57cec5SDimitry Andric case MVT::nxv32i1: return "MVT::nxv32i1"; 2125ffd83dbSDimitry Andric case MVT::nxv64i1: return "MVT::nxv64i1"; 2130b57cec5SDimitry Andric case MVT::nxv1i8: return "MVT::nxv1i8"; 2140b57cec5SDimitry Andric case MVT::nxv2i8: return "MVT::nxv2i8"; 2150b57cec5SDimitry Andric case MVT::nxv4i8: return "MVT::nxv4i8"; 2160b57cec5SDimitry Andric case MVT::nxv8i8: return "MVT::nxv8i8"; 2170b57cec5SDimitry Andric case MVT::nxv16i8: return "MVT::nxv16i8"; 2180b57cec5SDimitry Andric case MVT::nxv32i8: return "MVT::nxv32i8"; 2195ffd83dbSDimitry Andric case MVT::nxv64i8: return "MVT::nxv64i8"; 2200b57cec5SDimitry Andric case MVT::nxv1i16: return "MVT::nxv1i16"; 2210b57cec5SDimitry Andric case MVT::nxv2i16: return "MVT::nxv2i16"; 2220b57cec5SDimitry Andric case MVT::nxv4i16: return "MVT::nxv4i16"; 2230b57cec5SDimitry Andric case MVT::nxv8i16: return "MVT::nxv8i16"; 2240b57cec5SDimitry Andric case MVT::nxv16i16: return "MVT::nxv16i16"; 2250b57cec5SDimitry Andric case MVT::nxv32i16: return "MVT::nxv32i16"; 2260b57cec5SDimitry Andric case MVT::nxv1i32: return "MVT::nxv1i32"; 2270b57cec5SDimitry Andric case MVT::nxv2i32: return "MVT::nxv2i32"; 2280b57cec5SDimitry Andric case MVT::nxv4i32: return "MVT::nxv4i32"; 2290b57cec5SDimitry Andric case MVT::nxv8i32: return "MVT::nxv8i32"; 2300b57cec5SDimitry Andric case MVT::nxv16i32: return "MVT::nxv16i32"; 2315ffd83dbSDimitry Andric case MVT::nxv32i32: return "MVT::nxv32i32"; 2320b57cec5SDimitry Andric case MVT::nxv1i64: return "MVT::nxv1i64"; 2330b57cec5SDimitry Andric case MVT::nxv2i64: return "MVT::nxv2i64"; 2340b57cec5SDimitry Andric case MVT::nxv4i64: return "MVT::nxv4i64"; 2350b57cec5SDimitry Andric case MVT::nxv8i64: return "MVT::nxv8i64"; 2360b57cec5SDimitry Andric case MVT::nxv16i64: return "MVT::nxv16i64"; 2375ffd83dbSDimitry Andric case MVT::nxv32i64: return "MVT::nxv32i64"; 2385ffd83dbSDimitry Andric case MVT::nxv1f16: return "MVT::nxv1f16"; 2390b57cec5SDimitry Andric case MVT::nxv2f16: return "MVT::nxv2f16"; 2400b57cec5SDimitry Andric case MVT::nxv4f16: return "MVT::nxv4f16"; 2410b57cec5SDimitry Andric case MVT::nxv8f16: return "MVT::nxv8f16"; 2425ffd83dbSDimitry Andric case MVT::nxv16f16: return "MVT::nxv16f16"; 2435ffd83dbSDimitry Andric case MVT::nxv32f16: return "MVT::nxv32f16"; 244fe6060f1SDimitry Andric case MVT::nxv1bf16: return "MVT::nxv1bf16"; 2455ffd83dbSDimitry Andric case MVT::nxv2bf16: return "MVT::nxv2bf16"; 2465ffd83dbSDimitry Andric case MVT::nxv4bf16: return "MVT::nxv4bf16"; 2475ffd83dbSDimitry Andric case MVT::nxv8bf16: return "MVT::nxv8bf16"; 24881ad6265SDimitry Andric case MVT::nxv16bf16: return "MVT::nxv16bf16"; 24981ad6265SDimitry Andric case MVT::nxv32bf16: return "MVT::nxv32bf16"; 2500b57cec5SDimitry Andric case MVT::nxv1f32: return "MVT::nxv1f32"; 2510b57cec5SDimitry Andric case MVT::nxv2f32: return "MVT::nxv2f32"; 2520b57cec5SDimitry Andric case MVT::nxv4f32: return "MVT::nxv4f32"; 2530b57cec5SDimitry Andric case MVT::nxv8f32: return "MVT::nxv8f32"; 2540b57cec5SDimitry Andric case MVT::nxv16f32: return "MVT::nxv16f32"; 2550b57cec5SDimitry Andric case MVT::nxv1f64: return "MVT::nxv1f64"; 2560b57cec5SDimitry Andric case MVT::nxv2f64: return "MVT::nxv2f64"; 2570b57cec5SDimitry Andric case MVT::nxv4f64: return "MVT::nxv4f64"; 2580b57cec5SDimitry Andric case MVT::nxv8f64: return "MVT::nxv8f64"; 2590b57cec5SDimitry Andric case MVT::token: return "MVT::token"; 2600b57cec5SDimitry Andric case MVT::Metadata: return "MVT::Metadata"; 2610b57cec5SDimitry Andric case MVT::iPTR: return "MVT::iPTR"; 2620b57cec5SDimitry Andric case MVT::iPTRAny: return "MVT::iPTRAny"; 2630b57cec5SDimitry Andric case MVT::Untyped: return "MVT::Untyped"; 264e8d8bef9SDimitry Andric case MVT::funcref: return "MVT::funcref"; 265e8d8bef9SDimitry Andric case MVT::externref: return "MVT::externref"; 2660b57cec5SDimitry Andric default: llvm_unreachable("ILLEGAL VALUE TYPE!"); 2670b57cec5SDimitry Andric } 26881ad6265SDimitry Andric // clang-format on 2690b57cec5SDimitry Andric } 2700b57cec5SDimitry Andric 2710b57cec5SDimitry Andric /// getQualifiedName - Return the name of the specified record, with a 2720b57cec5SDimitry Andric /// namespace qualifier if the record contains one. 2730b57cec5SDimitry Andric /// 2740b57cec5SDimitry Andric std::string llvm::getQualifiedName(const Record *R) { 2750b57cec5SDimitry Andric std::string Namespace; 2760b57cec5SDimitry Andric if (R->getValue("Namespace")) 2775ffd83dbSDimitry Andric Namespace = std::string(R->getValueAsString("Namespace")); 2785ffd83dbSDimitry Andric if (Namespace.empty()) 2795ffd83dbSDimitry Andric return std::string(R->getName()); 2800b57cec5SDimitry Andric return Namespace + "::" + R->getName().str(); 2810b57cec5SDimitry Andric } 2820b57cec5SDimitry Andric 2830b57cec5SDimitry Andric 2840b57cec5SDimitry Andric /// getTarget - Return the current instance of the Target class. 2850b57cec5SDimitry Andric /// 2860b57cec5SDimitry Andric CodeGenTarget::CodeGenTarget(RecordKeeper &records) 2870b57cec5SDimitry Andric : Records(records), CGH(records) { 2880b57cec5SDimitry Andric std::vector<Record*> Targets = Records.getAllDerivedDefinitions("Target"); 2890b57cec5SDimitry Andric if (Targets.size() == 0) 290fe6060f1SDimitry Andric PrintFatalError("No 'Target' subclasses defined!"); 2910b57cec5SDimitry Andric if (Targets.size() != 1) 292fe6060f1SDimitry Andric PrintFatalError("Multiple subclasses of Target defined!"); 2930b57cec5SDimitry Andric TargetRec = Targets[0]; 2940b57cec5SDimitry Andric } 2950b57cec5SDimitry Andric 2960b57cec5SDimitry Andric CodeGenTarget::~CodeGenTarget() { 2970b57cec5SDimitry Andric } 2980b57cec5SDimitry Andric 299e8d8bef9SDimitry Andric StringRef CodeGenTarget::getName() const { return TargetRec->getName(); } 3000b57cec5SDimitry Andric 301e8d8bef9SDimitry Andric /// getInstNamespace - Find and return the target machine's instruction 302e8d8bef9SDimitry Andric /// namespace. The namespace is cached because it is requested multiple times. 3030b57cec5SDimitry Andric StringRef CodeGenTarget::getInstNamespace() const { 304e8d8bef9SDimitry Andric if (InstNamespace.empty()) { 3050b57cec5SDimitry Andric for (const CodeGenInstruction *Inst : getInstructionsByEnumValue()) { 306e8d8bef9SDimitry Andric // We are not interested in the "TargetOpcode" namespace. 307e8d8bef9SDimitry Andric if (Inst->Namespace != "TargetOpcode") { 308e8d8bef9SDimitry Andric InstNamespace = Inst->Namespace; 309e8d8bef9SDimitry Andric break; 310e8d8bef9SDimitry Andric } 311e8d8bef9SDimitry Andric } 3120b57cec5SDimitry Andric } 3130b57cec5SDimitry Andric 314e8d8bef9SDimitry Andric return InstNamespace; 315e8d8bef9SDimitry Andric } 316e8d8bef9SDimitry Andric 317e8d8bef9SDimitry Andric StringRef CodeGenTarget::getRegNamespace() const { 318e8d8bef9SDimitry Andric auto &RegClasses = RegBank->getRegClasses(); 319e8d8bef9SDimitry Andric return RegClasses.size() > 0 ? RegClasses.front().Namespace : ""; 3200b57cec5SDimitry Andric } 3210b57cec5SDimitry Andric 3220b57cec5SDimitry Andric Record *CodeGenTarget::getInstructionSet() const { 3230b57cec5SDimitry Andric return TargetRec->getValueAsDef("InstructionSet"); 3240b57cec5SDimitry Andric } 3250b57cec5SDimitry Andric 3260b57cec5SDimitry Andric bool CodeGenTarget::getAllowRegisterRenaming() const { 3270b57cec5SDimitry Andric return TargetRec->getValueAsInt("AllowRegisterRenaming"); 3280b57cec5SDimitry Andric } 3290b57cec5SDimitry Andric 3300b57cec5SDimitry Andric /// getAsmParser - Return the AssemblyParser definition for this target. 3310b57cec5SDimitry Andric /// 3320b57cec5SDimitry Andric Record *CodeGenTarget::getAsmParser() const { 3330b57cec5SDimitry Andric std::vector<Record*> LI = TargetRec->getValueAsListOfDefs("AssemblyParsers"); 3340b57cec5SDimitry Andric if (AsmParserNum >= LI.size()) 3350b57cec5SDimitry Andric PrintFatalError("Target does not have an AsmParser #" + 3360b57cec5SDimitry Andric Twine(AsmParserNum) + "!"); 3370b57cec5SDimitry Andric return LI[AsmParserNum]; 3380b57cec5SDimitry Andric } 3390b57cec5SDimitry Andric 340480093f4SDimitry Andric /// getAsmParserVariant - Return the AssemblyParserVariant definition for 3410b57cec5SDimitry Andric /// this target. 3420b57cec5SDimitry Andric /// 3430b57cec5SDimitry Andric Record *CodeGenTarget::getAsmParserVariant(unsigned i) const { 3440b57cec5SDimitry Andric std::vector<Record*> LI = 3450b57cec5SDimitry Andric TargetRec->getValueAsListOfDefs("AssemblyParserVariants"); 3460b57cec5SDimitry Andric if (i >= LI.size()) 3470b57cec5SDimitry Andric PrintFatalError("Target does not have an AsmParserVariant #" + Twine(i) + 3480b57cec5SDimitry Andric "!"); 3490b57cec5SDimitry Andric return LI[i]; 3500b57cec5SDimitry Andric } 3510b57cec5SDimitry Andric 352480093f4SDimitry Andric /// getAsmParserVariantCount - Return the AssemblyParserVariant definition 3530b57cec5SDimitry Andric /// available for this target. 3540b57cec5SDimitry Andric /// 3550b57cec5SDimitry Andric unsigned CodeGenTarget::getAsmParserVariantCount() const { 3560b57cec5SDimitry Andric std::vector<Record*> LI = 3570b57cec5SDimitry Andric TargetRec->getValueAsListOfDefs("AssemblyParserVariants"); 3580b57cec5SDimitry Andric return LI.size(); 3590b57cec5SDimitry Andric } 3600b57cec5SDimitry Andric 3610b57cec5SDimitry Andric /// getAsmWriter - Return the AssemblyWriter definition for this target. 3620b57cec5SDimitry Andric /// 3630b57cec5SDimitry Andric Record *CodeGenTarget::getAsmWriter() const { 3640b57cec5SDimitry Andric std::vector<Record*> LI = TargetRec->getValueAsListOfDefs("AssemblyWriters"); 3650b57cec5SDimitry Andric if (AsmWriterNum >= LI.size()) 3660b57cec5SDimitry Andric PrintFatalError("Target does not have an AsmWriter #" + 3670b57cec5SDimitry Andric Twine(AsmWriterNum) + "!"); 3680b57cec5SDimitry Andric return LI[AsmWriterNum]; 3690b57cec5SDimitry Andric } 3700b57cec5SDimitry Andric 3710b57cec5SDimitry Andric CodeGenRegBank &CodeGenTarget::getRegBank() const { 3720b57cec5SDimitry Andric if (!RegBank) 3738bcb0991SDimitry Andric RegBank = std::make_unique<CodeGenRegBank>(Records, getHwModes()); 3740b57cec5SDimitry Andric return *RegBank; 3750b57cec5SDimitry Andric } 3760b57cec5SDimitry Andric 377bdd1243dSDimitry Andric std::optional<CodeGenRegisterClass *> CodeGenTarget::getSuperRegForSubReg( 378bdd1243dSDimitry Andric const ValueTypeByHwMode &ValueTy, CodeGenRegBank &RegBank, 379bdd1243dSDimitry Andric const CodeGenSubRegIndex *SubIdx, bool MustBeAllocatable) const { 3808bcb0991SDimitry Andric std::vector<CodeGenRegisterClass *> Candidates; 3818bcb0991SDimitry Andric auto &RegClasses = RegBank.getRegClasses(); 3828bcb0991SDimitry Andric 3838bcb0991SDimitry Andric // Try to find a register class which supports ValueTy, and also contains 3848bcb0991SDimitry Andric // SubIdx. 3858bcb0991SDimitry Andric for (CodeGenRegisterClass &RC : RegClasses) { 3868bcb0991SDimitry Andric // Is there a subclass of this class which contains this subregister index? 3878bcb0991SDimitry Andric CodeGenRegisterClass *SubClassWithSubReg = RC.getSubClassWithSubReg(SubIdx); 3888bcb0991SDimitry Andric if (!SubClassWithSubReg) 3898bcb0991SDimitry Andric continue; 3908bcb0991SDimitry Andric 3918bcb0991SDimitry Andric // We have a class. Check if it supports this value type. 392e8d8bef9SDimitry Andric if (!llvm::is_contained(SubClassWithSubReg->VTs, ValueTy)) 393e8d8bef9SDimitry Andric continue; 394e8d8bef9SDimitry Andric 395e8d8bef9SDimitry Andric // If necessary, check that it is allocatable. 396e8d8bef9SDimitry Andric if (MustBeAllocatable && !SubClassWithSubReg->Allocatable) 3978bcb0991SDimitry Andric continue; 3988bcb0991SDimitry Andric 3998bcb0991SDimitry Andric // We have a register class which supports both the value type and 4008bcb0991SDimitry Andric // subregister index. Remember it. 4018bcb0991SDimitry Andric Candidates.push_back(SubClassWithSubReg); 4028bcb0991SDimitry Andric } 4038bcb0991SDimitry Andric 4048bcb0991SDimitry Andric // If we didn't find anything, we're done. 4058bcb0991SDimitry Andric if (Candidates.empty()) 406bdd1243dSDimitry Andric return std::nullopt; 4078bcb0991SDimitry Andric 4088bcb0991SDimitry Andric // Find and return the largest of our candidate classes. 4098bcb0991SDimitry Andric llvm::stable_sort(Candidates, [&](const CodeGenRegisterClass *A, 4108bcb0991SDimitry Andric const CodeGenRegisterClass *B) { 4118bcb0991SDimitry Andric if (A->getMembers().size() > B->getMembers().size()) 4128bcb0991SDimitry Andric return true; 4138bcb0991SDimitry Andric 4148bcb0991SDimitry Andric if (A->getMembers().size() < B->getMembers().size()) 4158bcb0991SDimitry Andric return false; 4168bcb0991SDimitry Andric 4178bcb0991SDimitry Andric // Order by name as a tie-breaker. 4188bcb0991SDimitry Andric return StringRef(A->getName()) < B->getName(); 4198bcb0991SDimitry Andric }); 4208bcb0991SDimitry Andric 4218bcb0991SDimitry Andric return Candidates[0]; 4228bcb0991SDimitry Andric } 4238bcb0991SDimitry Andric 4240b57cec5SDimitry Andric void CodeGenTarget::ReadRegAltNameIndices() const { 4250b57cec5SDimitry Andric RegAltNameIndices = Records.getAllDerivedDefinitions("RegAltNameIndex"); 4260b57cec5SDimitry Andric llvm::sort(RegAltNameIndices, LessRecord()); 4270b57cec5SDimitry Andric } 4280b57cec5SDimitry Andric 4290b57cec5SDimitry Andric /// getRegisterByName - If there is a register with the specific AsmName, 4300b57cec5SDimitry Andric /// return it. 4310b57cec5SDimitry Andric const CodeGenRegister *CodeGenTarget::getRegisterByName(StringRef Name) const { 432e8d8bef9SDimitry Andric return getRegBank().getRegistersByName().lookup(Name); 4330b57cec5SDimitry Andric } 4340b57cec5SDimitry Andric 435*fe013be4SDimitry Andric const CodeGenRegisterClass &CodeGenTarget::getRegisterClass(Record *R) const { 436*fe013be4SDimitry Andric return *getRegBank().getRegClass(R); 437*fe013be4SDimitry Andric } 438*fe013be4SDimitry Andric 4390b57cec5SDimitry Andric std::vector<ValueTypeByHwMode> CodeGenTarget::getRegisterVTs(Record *R) 4400b57cec5SDimitry Andric const { 4410b57cec5SDimitry Andric const CodeGenRegister *Reg = getRegBank().getReg(R); 4420b57cec5SDimitry Andric std::vector<ValueTypeByHwMode> Result; 4430b57cec5SDimitry Andric for (const auto &RC : getRegBank().getRegClasses()) { 4440b57cec5SDimitry Andric if (RC.contains(Reg)) { 4450b57cec5SDimitry Andric ArrayRef<ValueTypeByHwMode> InVTs = RC.getValueTypes(); 446e8d8bef9SDimitry Andric llvm::append_range(Result, InVTs); 4470b57cec5SDimitry Andric } 4480b57cec5SDimitry Andric } 4490b57cec5SDimitry Andric 4500b57cec5SDimitry Andric // Remove duplicates. 4510b57cec5SDimitry Andric llvm::sort(Result); 4520b57cec5SDimitry Andric Result.erase(std::unique(Result.begin(), Result.end()), Result.end()); 4530b57cec5SDimitry Andric return Result; 4540b57cec5SDimitry Andric } 4550b57cec5SDimitry Andric 4560b57cec5SDimitry Andric 4570b57cec5SDimitry Andric void CodeGenTarget::ReadLegalValueTypes() const { 4580b57cec5SDimitry Andric for (const auto &RC : getRegBank().getRegClasses()) 459e8d8bef9SDimitry Andric llvm::append_range(LegalValueTypes, RC.VTs); 4600b57cec5SDimitry Andric 4610b57cec5SDimitry Andric // Remove duplicates. 4620b57cec5SDimitry Andric llvm::sort(LegalValueTypes); 4630b57cec5SDimitry Andric LegalValueTypes.erase(std::unique(LegalValueTypes.begin(), 4640b57cec5SDimitry Andric LegalValueTypes.end()), 4650b57cec5SDimitry Andric LegalValueTypes.end()); 4660b57cec5SDimitry Andric } 4670b57cec5SDimitry Andric 4680b57cec5SDimitry Andric CodeGenSchedModels &CodeGenTarget::getSchedModels() const { 4690b57cec5SDimitry Andric if (!SchedModels) 4708bcb0991SDimitry Andric SchedModels = std::make_unique<CodeGenSchedModels>(Records, *this); 4710b57cec5SDimitry Andric return *SchedModels; 4720b57cec5SDimitry Andric } 4730b57cec5SDimitry Andric 4740b57cec5SDimitry Andric void CodeGenTarget::ReadInstructions() const { 4750b57cec5SDimitry Andric std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction"); 4760b57cec5SDimitry Andric if (Insts.size() <= 2) 4770b57cec5SDimitry Andric PrintFatalError("No 'Instruction' subclasses defined!"); 4780b57cec5SDimitry Andric 4790b57cec5SDimitry Andric // Parse the instructions defined in the .td file. 4800b57cec5SDimitry Andric for (unsigned i = 0, e = Insts.size(); i != e; ++i) 4818bcb0991SDimitry Andric Instructions[Insts[i]] = std::make_unique<CodeGenInstruction>(Insts[i]); 4820b57cec5SDimitry Andric } 4830b57cec5SDimitry Andric 4840b57cec5SDimitry Andric static const CodeGenInstruction * 4850b57cec5SDimitry Andric GetInstByName(const char *Name, 4860b57cec5SDimitry Andric const DenseMap<const Record*, 4870b57cec5SDimitry Andric std::unique_ptr<CodeGenInstruction>> &Insts, 4880b57cec5SDimitry Andric RecordKeeper &Records) { 4890b57cec5SDimitry Andric const Record *Rec = Records.getDef(Name); 4900b57cec5SDimitry Andric 4910b57cec5SDimitry Andric const auto I = Insts.find(Rec); 4920b57cec5SDimitry Andric if (!Rec || I == Insts.end()) 4930b57cec5SDimitry Andric PrintFatalError(Twine("Could not find '") + Name + "' instruction!"); 4940b57cec5SDimitry Andric return I->second.get(); 4950b57cec5SDimitry Andric } 4960b57cec5SDimitry Andric 49781ad6265SDimitry Andric static const char *FixedInstrs[] = { 4980b57cec5SDimitry Andric #define HANDLE_TARGET_OPCODE(OPC) #OPC, 4990b57cec5SDimitry Andric #include "llvm/Support/TargetOpcodes.def" 5000b57cec5SDimitry Andric nullptr}; 5010b57cec5SDimitry Andric 5020b57cec5SDimitry Andric unsigned CodeGenTarget::getNumFixedInstructions() { 503bdd1243dSDimitry Andric return std::size(FixedInstrs) - 1; 5040b57cec5SDimitry Andric } 5050b57cec5SDimitry Andric 5060b57cec5SDimitry Andric /// Return all of the instructions defined by the target, ordered by 5070b57cec5SDimitry Andric /// their enum value. 5080b57cec5SDimitry Andric void CodeGenTarget::ComputeInstrsByEnum() const { 5090b57cec5SDimitry Andric const auto &Insts = getInstructions(); 5100b57cec5SDimitry Andric for (const char *const *p = FixedInstrs; *p; ++p) { 5110b57cec5SDimitry Andric const CodeGenInstruction *Instr = GetInstByName(*p, Insts, Records); 5120b57cec5SDimitry Andric assert(Instr && "Missing target independent instruction"); 5130b57cec5SDimitry Andric assert(Instr->Namespace == "TargetOpcode" && "Bad namespace"); 5140b57cec5SDimitry Andric InstrsByEnum.push_back(Instr); 5150b57cec5SDimitry Andric } 5160b57cec5SDimitry Andric unsigned EndOfPredefines = InstrsByEnum.size(); 5170b57cec5SDimitry Andric assert(EndOfPredefines == getNumFixedInstructions() && 5180b57cec5SDimitry Andric "Missing generic opcode"); 5190b57cec5SDimitry Andric 5200b57cec5SDimitry Andric for (const auto &I : Insts) { 5210b57cec5SDimitry Andric const CodeGenInstruction *CGI = I.second.get(); 5220b57cec5SDimitry Andric if (CGI->Namespace != "TargetOpcode") { 5230b57cec5SDimitry Andric InstrsByEnum.push_back(CGI); 5240b57cec5SDimitry Andric if (CGI->TheDef->getValueAsBit("isPseudo")) 5250b57cec5SDimitry Andric ++NumPseudoInstructions; 5260b57cec5SDimitry Andric } 5270b57cec5SDimitry Andric } 5280b57cec5SDimitry Andric 5290b57cec5SDimitry Andric assert(InstrsByEnum.size() == Insts.size() && "Missing predefined instr"); 5300b57cec5SDimitry Andric 5310b57cec5SDimitry Andric // All of the instructions are now in random order based on the map iteration. 5320b57cec5SDimitry Andric llvm::sort( 5330b57cec5SDimitry Andric InstrsByEnum.begin() + EndOfPredefines, InstrsByEnum.end(), 5340b57cec5SDimitry Andric [](const CodeGenInstruction *Rec1, const CodeGenInstruction *Rec2) { 5350b57cec5SDimitry Andric const auto &D1 = *Rec1->TheDef; 5360b57cec5SDimitry Andric const auto &D2 = *Rec2->TheDef; 5370b57cec5SDimitry Andric return std::make_tuple(!D1.getValueAsBit("isPseudo"), D1.getName()) < 5380b57cec5SDimitry Andric std::make_tuple(!D2.getValueAsBit("isPseudo"), D2.getName()); 5390b57cec5SDimitry Andric }); 5400b57cec5SDimitry Andric } 5410b57cec5SDimitry Andric 5420b57cec5SDimitry Andric 5430b57cec5SDimitry Andric /// isLittleEndianEncoding - Return whether this target encodes its instruction 5440b57cec5SDimitry Andric /// in little-endian format, i.e. bits laid out in the order [0..n] 5450b57cec5SDimitry Andric /// 5460b57cec5SDimitry Andric bool CodeGenTarget::isLittleEndianEncoding() const { 5470b57cec5SDimitry Andric return getInstructionSet()->getValueAsBit("isLittleEndianEncoding"); 5480b57cec5SDimitry Andric } 5490b57cec5SDimitry Andric 5500b57cec5SDimitry Andric /// reverseBitsForLittleEndianEncoding - For little-endian instruction bit 5510b57cec5SDimitry Andric /// encodings, reverse the bit order of all instructions. 5520b57cec5SDimitry Andric void CodeGenTarget::reverseBitsForLittleEndianEncoding() { 5530b57cec5SDimitry Andric if (!isLittleEndianEncoding()) 5540b57cec5SDimitry Andric return; 5550b57cec5SDimitry Andric 5568bcb0991SDimitry Andric std::vector<Record *> Insts = 5578bcb0991SDimitry Andric Records.getAllDerivedDefinitions("InstructionEncoding"); 5580b57cec5SDimitry Andric for (Record *R : Insts) { 5590b57cec5SDimitry Andric if (R->getValueAsString("Namespace") == "TargetOpcode" || 5600b57cec5SDimitry Andric R->getValueAsBit("isPseudo")) 5610b57cec5SDimitry Andric continue; 5620b57cec5SDimitry Andric 5630b57cec5SDimitry Andric BitsInit *BI = R->getValueAsBitsInit("Inst"); 5640b57cec5SDimitry Andric 5650b57cec5SDimitry Andric unsigned numBits = BI->getNumBits(); 5660b57cec5SDimitry Andric 5670b57cec5SDimitry Andric SmallVector<Init *, 16> NewBits(numBits); 5680b57cec5SDimitry Andric 5690b57cec5SDimitry Andric for (unsigned bit = 0, end = numBits / 2; bit != end; ++bit) { 5700b57cec5SDimitry Andric unsigned bitSwapIdx = numBits - bit - 1; 5710b57cec5SDimitry Andric Init *OrigBit = BI->getBit(bit); 5720b57cec5SDimitry Andric Init *BitSwap = BI->getBit(bitSwapIdx); 5730b57cec5SDimitry Andric NewBits[bit] = BitSwap; 5740b57cec5SDimitry Andric NewBits[bitSwapIdx] = OrigBit; 5750b57cec5SDimitry Andric } 5760b57cec5SDimitry Andric if (numBits % 2) { 5770b57cec5SDimitry Andric unsigned middle = (numBits + 1) / 2; 5780b57cec5SDimitry Andric NewBits[middle] = BI->getBit(middle); 5790b57cec5SDimitry Andric } 5800b57cec5SDimitry Andric 58181ad6265SDimitry Andric BitsInit *NewBI = BitsInit::get(Records, NewBits); 5820b57cec5SDimitry Andric 5830b57cec5SDimitry Andric // Update the bits in reversed order so that emitInstrOpBits will get the 5840b57cec5SDimitry Andric // correct endianness. 5850b57cec5SDimitry Andric R->getValue("Inst")->setValue(NewBI); 5860b57cec5SDimitry Andric } 5870b57cec5SDimitry Andric } 5880b57cec5SDimitry Andric 5890b57cec5SDimitry Andric /// guessInstructionProperties - Return true if it's OK to guess instruction 5900b57cec5SDimitry Andric /// properties instead of raising an error. 5910b57cec5SDimitry Andric /// 5920b57cec5SDimitry Andric /// This is configurable as a temporary migration aid. It will eventually be 5930b57cec5SDimitry Andric /// permanently false. 5940b57cec5SDimitry Andric bool CodeGenTarget::guessInstructionProperties() const { 5950b57cec5SDimitry Andric return getInstructionSet()->getValueAsBit("guessInstructionProperties"); 5960b57cec5SDimitry Andric } 5970b57cec5SDimitry Andric 5980b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 5990b57cec5SDimitry Andric // ComplexPattern implementation 6000b57cec5SDimitry Andric // 6010b57cec5SDimitry Andric ComplexPattern::ComplexPattern(Record *R) { 6020eae32dcSDimitry Andric Ty = R->getValueAsDef("Ty"); 6030b57cec5SDimitry Andric NumOperands = R->getValueAsInt("NumOperands"); 6045ffd83dbSDimitry Andric SelectFunc = std::string(R->getValueAsString("SelectFunc")); 6050b57cec5SDimitry Andric RootNodes = R->getValueAsListOfDefs("RootNodes"); 6060b57cec5SDimitry Andric 6070b57cec5SDimitry Andric // FIXME: This is a hack to statically increase the priority of patterns which 6080b57cec5SDimitry Andric // maps a sub-dag to a complex pattern. e.g. favors LEA over ADD. To get best 6090b57cec5SDimitry Andric // possible pattern match we'll need to dynamically calculate the complexity 6100b57cec5SDimitry Andric // of all patterns a dag can potentially map to. 6110b57cec5SDimitry Andric int64_t RawComplexity = R->getValueAsInt("Complexity"); 6120b57cec5SDimitry Andric if (RawComplexity == -1) 6130b57cec5SDimitry Andric Complexity = NumOperands * 3; 6140b57cec5SDimitry Andric else 6150b57cec5SDimitry Andric Complexity = RawComplexity; 6160b57cec5SDimitry Andric 6170b57cec5SDimitry Andric // FIXME: Why is this different from parseSDPatternOperatorProperties? 6180b57cec5SDimitry Andric // Parse the properties. 6190b57cec5SDimitry Andric Properties = 0; 6200b57cec5SDimitry Andric std::vector<Record*> PropList = R->getValueAsListOfDefs("Properties"); 6210b57cec5SDimitry Andric for (unsigned i = 0, e = PropList.size(); i != e; ++i) 6220b57cec5SDimitry Andric if (PropList[i]->getName() == "SDNPHasChain") { 6230b57cec5SDimitry Andric Properties |= 1 << SDNPHasChain; 6240b57cec5SDimitry Andric } else if (PropList[i]->getName() == "SDNPOptInGlue") { 6250b57cec5SDimitry Andric Properties |= 1 << SDNPOptInGlue; 6260b57cec5SDimitry Andric } else if (PropList[i]->getName() == "SDNPMayStore") { 6270b57cec5SDimitry Andric Properties |= 1 << SDNPMayStore; 6280b57cec5SDimitry Andric } else if (PropList[i]->getName() == "SDNPMayLoad") { 6290b57cec5SDimitry Andric Properties |= 1 << SDNPMayLoad; 6300b57cec5SDimitry Andric } else if (PropList[i]->getName() == "SDNPSideEffect") { 6310b57cec5SDimitry Andric Properties |= 1 << SDNPSideEffect; 6320b57cec5SDimitry Andric } else if (PropList[i]->getName() == "SDNPMemOperand") { 6330b57cec5SDimitry Andric Properties |= 1 << SDNPMemOperand; 6340b57cec5SDimitry Andric } else if (PropList[i]->getName() == "SDNPVariadic") { 6350b57cec5SDimitry Andric Properties |= 1 << SDNPVariadic; 6360b57cec5SDimitry Andric } else if (PropList[i]->getName() == "SDNPWantRoot") { 6370b57cec5SDimitry Andric Properties |= 1 << SDNPWantRoot; 6380b57cec5SDimitry Andric } else if (PropList[i]->getName() == "SDNPWantParent") { 6390b57cec5SDimitry Andric Properties |= 1 << SDNPWantParent; 6400b57cec5SDimitry Andric } else { 6410b57cec5SDimitry Andric PrintFatalError(R->getLoc(), "Unsupported SD Node property '" + 6420b57cec5SDimitry Andric PropList[i]->getName() + 6430b57cec5SDimitry Andric "' on ComplexPattern '" + R->getName() + 6440b57cec5SDimitry Andric "'!"); 6450b57cec5SDimitry Andric } 6460b57cec5SDimitry Andric } 647