1 //===- NeonEmitter.cpp - Generate arm_neon.h for use with clang -*- 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 tablegen backend is responsible for emitting arm_neon.h, which includes 10 // a declaration and definition of each function specified by the ARM NEON 11 // compiler interface. See ARM document DUI0348B. 12 // 13 // Each NEON instruction is implemented in terms of 1 or more functions which 14 // are suffixed with the element type of the input vectors. Functions may be 15 // implemented in terms of generic vector operations such as +, *, -, etc. or 16 // by calling a __builtin_-prefixed function which will be handled by clang's 17 // CodeGen library. 18 // 19 // Additional validation code can be generated by this file when runHeader() is 20 // called, rather than the normal run() entry point. 21 // 22 // See also the documentation in include/clang/Basic/arm_neon.td. 23 // 24 //===----------------------------------------------------------------------===// 25 26 #include "TableGenBackends.h" 27 #include "llvm/ADT/ArrayRef.h" 28 #include "llvm/ADT/DenseMap.h" 29 #include "llvm/ADT/None.h" 30 #include "llvm/ADT/SmallVector.h" 31 #include "llvm/ADT/STLExtras.h" 32 #include "llvm/ADT/StringExtras.h" 33 #include "llvm/ADT/StringRef.h" 34 #include "llvm/Support/Casting.h" 35 #include "llvm/Support/ErrorHandling.h" 36 #include "llvm/Support/raw_ostream.h" 37 #include "llvm/TableGen/Error.h" 38 #include "llvm/TableGen/Record.h" 39 #include "llvm/TableGen/SetTheory.h" 40 #include <algorithm> 41 #include <cassert> 42 #include <cctype> 43 #include <cstddef> 44 #include <cstdint> 45 #include <deque> 46 #include <map> 47 #include <set> 48 #include <sstream> 49 #include <string> 50 #include <utility> 51 #include <vector> 52 53 using namespace llvm; 54 55 namespace { 56 57 // While globals are generally bad, this one allows us to perform assertions 58 // liberally and somehow still trace them back to the def they indirectly 59 // came from. 60 static Record *CurrentRecord = nullptr; 61 static void assert_with_loc(bool Assertion, const std::string &Str) { 62 if (!Assertion) { 63 if (CurrentRecord) 64 PrintFatalError(CurrentRecord->getLoc(), Str); 65 else 66 PrintFatalError(Str); 67 } 68 } 69 70 enum ClassKind { 71 ClassNone, 72 ClassI, // generic integer instruction, e.g., "i8" suffix 73 ClassS, // signed/unsigned/poly, e.g., "s8", "u8" or "p8" suffix 74 ClassW, // width-specific instruction, e.g., "8" suffix 75 ClassB, // bitcast arguments with enum argument to specify type 76 ClassL, // Logical instructions which are op instructions 77 // but we need to not emit any suffix for in our 78 // tests. 79 ClassNoTest // Instructions which we do not test since they are 80 // not TRUE instructions. 81 }; 82 83 /// NeonTypeFlags - Flags to identify the types for overloaded Neon 84 /// builtins. These must be kept in sync with the flags in 85 /// include/clang/Basic/TargetBuiltins.h. 86 namespace NeonTypeFlags { 87 88 enum { EltTypeMask = 0xf, UnsignedFlag = 0x10, QuadFlag = 0x20 }; 89 90 enum EltType { 91 Int8, 92 Int16, 93 Int32, 94 Int64, 95 Poly8, 96 Poly16, 97 Poly64, 98 Poly128, 99 Float16, 100 Float32, 101 Float64 102 }; 103 104 } // end namespace NeonTypeFlags 105 106 class NeonEmitter; 107 108 //===----------------------------------------------------------------------===// 109 // TypeSpec 110 //===----------------------------------------------------------------------===// 111 112 /// A TypeSpec is just a simple wrapper around a string, but gets its own type 113 /// for strong typing purposes. 114 /// 115 /// A TypeSpec can be used to create a type. 116 class TypeSpec : public std::string { 117 public: 118 static std::vector<TypeSpec> fromTypeSpecs(StringRef Str) { 119 std::vector<TypeSpec> Ret; 120 TypeSpec Acc; 121 for (char I : Str.str()) { 122 if (islower(I)) { 123 Acc.push_back(I); 124 Ret.push_back(TypeSpec(Acc)); 125 Acc.clear(); 126 } else { 127 Acc.push_back(I); 128 } 129 } 130 return Ret; 131 } 132 }; 133 134 //===----------------------------------------------------------------------===// 135 // Type 136 //===----------------------------------------------------------------------===// 137 138 /// A Type. Not much more to say here. 139 class Type { 140 private: 141 TypeSpec TS; 142 143 enum TypeKind { 144 Void, 145 Float, 146 SInt, 147 UInt, 148 Poly, 149 }; 150 TypeKind Kind; 151 bool Immediate, Constant, Pointer; 152 // ScalarForMangling and NoManglingQ are really not suited to live here as 153 // they are not related to the type. But they live in the TypeSpec (not the 154 // prototype), so this is really the only place to store them. 155 bool ScalarForMangling, NoManglingQ; 156 unsigned Bitwidth, ElementBitwidth, NumVectors; 157 158 public: 159 Type() 160 : Kind(Void), Immediate(false), Constant(false), 161 Pointer(false), ScalarForMangling(false), NoManglingQ(false), 162 Bitwidth(0), ElementBitwidth(0), NumVectors(0) {} 163 164 Type(TypeSpec TS, StringRef CharMods) 165 : TS(std::move(TS)), Kind(Void), Immediate(false), 166 Constant(false), Pointer(false), ScalarForMangling(false), 167 NoManglingQ(false), Bitwidth(0), ElementBitwidth(0), NumVectors(0) { 168 applyModifiers(CharMods); 169 } 170 171 /// Returns a type representing "void". 172 static Type getVoid() { return Type(); } 173 174 bool operator==(const Type &Other) const { return str() == Other.str(); } 175 bool operator!=(const Type &Other) const { return !operator==(Other); } 176 177 // 178 // Query functions 179 // 180 bool isScalarForMangling() const { return ScalarForMangling; } 181 bool noManglingQ() const { return NoManglingQ; } 182 183 bool isPointer() const { return Pointer; } 184 bool isValue() const { return !isVoid() && !isPointer(); } 185 bool isScalar() const { return isValue() && NumVectors == 0; } 186 bool isVector() const { return isValue() && NumVectors > 0; } 187 bool isConstPointer() const { return Constant; } 188 bool isFloating() const { return Kind == Float; } 189 bool isInteger() const { return Kind == SInt || Kind == UInt; } 190 bool isPoly() const { return Kind == Poly; } 191 bool isSigned() const { return Kind == SInt; } 192 bool isImmediate() const { return Immediate; } 193 bool isFloat() const { return isFloating() && ElementBitwidth == 32; } 194 bool isDouble() const { return isFloating() && ElementBitwidth == 64; } 195 bool isHalf() const { return isFloating() && ElementBitwidth == 16; } 196 bool isChar() const { return ElementBitwidth == 8; } 197 bool isShort() const { return isInteger() && ElementBitwidth == 16; } 198 bool isInt() const { return isInteger() && ElementBitwidth == 32; } 199 bool isLong() const { return isInteger() && ElementBitwidth == 64; } 200 bool isVoid() const { return Kind == Void; } 201 unsigned getNumElements() const { return Bitwidth / ElementBitwidth; } 202 unsigned getSizeInBits() const { return Bitwidth; } 203 unsigned getElementSizeInBits() const { return ElementBitwidth; } 204 unsigned getNumVectors() const { return NumVectors; } 205 206 // 207 // Mutator functions 208 // 209 void makeUnsigned() { 210 assert(!isVoid() && "not a potentially signed type"); 211 Kind = UInt; 212 } 213 void makeSigned() { 214 assert(!isVoid() && "not a potentially signed type"); 215 Kind = SInt; 216 } 217 218 void makeInteger(unsigned ElemWidth, bool Sign) { 219 assert(!isVoid() && "converting void to int probably not useful"); 220 Kind = Sign ? SInt : UInt; 221 Immediate = false; 222 ElementBitwidth = ElemWidth; 223 } 224 225 void makeImmediate(unsigned ElemWidth) { 226 Kind = SInt; 227 Immediate = true; 228 ElementBitwidth = ElemWidth; 229 } 230 231 void makeScalar() { 232 Bitwidth = ElementBitwidth; 233 NumVectors = 0; 234 } 235 236 void makeOneVector() { 237 assert(isVector()); 238 NumVectors = 1; 239 } 240 241 void doubleLanes() { 242 assert_with_loc(Bitwidth != 128, "Can't get bigger than 128!"); 243 Bitwidth = 128; 244 } 245 246 void halveLanes() { 247 assert_with_loc(Bitwidth != 64, "Can't get smaller than 64!"); 248 Bitwidth = 64; 249 } 250 251 /// Return the C string representation of a type, which is the typename 252 /// defined in stdint.h or arm_neon.h. 253 std::string str() const; 254 255 /// Return the string representation of a type, which is an encoded 256 /// string for passing to the BUILTIN() macro in Builtins.def. 257 std::string builtin_str() const; 258 259 /// Return the value in NeonTypeFlags for this type. 260 unsigned getNeonEnum() const; 261 262 /// Parse a type from a stdint.h or arm_neon.h typedef name, 263 /// for example uint32x2_t or int64_t. 264 static Type fromTypedefName(StringRef Name); 265 266 private: 267 /// Creates the type based on the typespec string in TS. 268 /// Sets "Quad" to true if the "Q" or "H" modifiers were 269 /// seen. This is needed by applyModifier as some modifiers 270 /// only take effect if the type size was changed by "Q" or "H". 271 void applyTypespec(bool &Quad); 272 /// Applies prototype modifiers to the type. 273 void applyModifiers(StringRef Mods); 274 }; 275 276 //===----------------------------------------------------------------------===// 277 // Variable 278 //===----------------------------------------------------------------------===// 279 280 /// A variable is a simple class that just has a type and a name. 281 class Variable { 282 Type T; 283 std::string N; 284 285 public: 286 Variable() : T(Type::getVoid()), N("") {} 287 Variable(Type T, std::string N) : T(std::move(T)), N(std::move(N)) {} 288 289 Type getType() const { return T; } 290 std::string getName() const { return "__" + N; } 291 }; 292 293 //===----------------------------------------------------------------------===// 294 // Intrinsic 295 //===----------------------------------------------------------------------===// 296 297 /// The main grunt class. This represents an instantiation of an intrinsic with 298 /// a particular typespec and prototype. 299 class Intrinsic { 300 friend class DagEmitter; 301 302 /// The Record this intrinsic was created from. 303 Record *R; 304 /// The unmangled name. 305 std::string Name; 306 /// The input and output typespecs. InTS == OutTS except when 307 /// CartesianProductOfTypes is 1 - this is the case for vreinterpret. 308 TypeSpec OutTS, InTS; 309 /// The base class kind. Most intrinsics use ClassS, which has full type 310 /// info for integers (s32/u32). Some use ClassI, which doesn't care about 311 /// signedness (i32), while some (ClassB) have no type at all, only a width 312 /// (32). 313 ClassKind CK; 314 /// The list of DAGs for the body. May be empty, in which case we should 315 /// emit a builtin call. 316 ListInit *Body; 317 /// The architectural #ifdef guard. 318 std::string Guard; 319 /// Set if the Unavailable bit is 1. This means we don't generate a body, 320 /// just an "unavailable" attribute on a declaration. 321 bool IsUnavailable; 322 /// Is this intrinsic safe for big-endian? or does it need its arguments 323 /// reversing? 324 bool BigEndianSafe; 325 326 /// The types of return value [0] and parameters [1..]. 327 std::vector<Type> Types; 328 /// The index of the key type passed to CGBuiltin.cpp for polymorphic calls. 329 int PolymorphicKeyType; 330 /// The local variables defined. 331 std::map<std::string, Variable> Variables; 332 /// NeededEarly - set if any other intrinsic depends on this intrinsic. 333 bool NeededEarly; 334 /// UseMacro - set if we should implement using a macro or unset for a 335 /// function. 336 bool UseMacro; 337 /// The set of intrinsics that this intrinsic uses/requires. 338 std::set<Intrinsic *> Dependencies; 339 /// The "base type", which is Type('d', OutTS). InBaseType is only 340 /// different if CartesianProductOfTypes = 1 (for vreinterpret). 341 Type BaseType, InBaseType; 342 /// The return variable. 343 Variable RetVar; 344 /// A postfix to apply to every variable. Defaults to "". 345 std::string VariablePostfix; 346 347 NeonEmitter &Emitter; 348 std::stringstream OS; 349 350 bool isBigEndianSafe() const { 351 if (BigEndianSafe) 352 return true; 353 354 for (const auto &T : Types){ 355 if (T.isVector() && T.getNumElements() > 1) 356 return false; 357 } 358 return true; 359 } 360 361 public: 362 Intrinsic(Record *R, StringRef Name, StringRef Proto, TypeSpec OutTS, 363 TypeSpec InTS, ClassKind CK, ListInit *Body, NeonEmitter &Emitter, 364 StringRef Guard, bool IsUnavailable, bool BigEndianSafe) 365 : R(R), Name(Name.str()), OutTS(OutTS), InTS(InTS), CK(CK), Body(Body), 366 Guard(Guard.str()), IsUnavailable(IsUnavailable), 367 BigEndianSafe(BigEndianSafe), PolymorphicKeyType(0), NeededEarly(false), 368 UseMacro(false), BaseType(OutTS, "."), InBaseType(InTS, "."), 369 Emitter(Emitter) { 370 // Modify the TypeSpec per-argument to get a concrete Type, and create 371 // known variables for each. 372 // Types[0] is the return value. 373 unsigned Pos = 0; 374 Types.emplace_back(OutTS, getNextModifiers(Proto, Pos)); 375 StringRef Mods = getNextModifiers(Proto, Pos); 376 while (!Mods.empty()) { 377 Types.emplace_back(InTS, Mods); 378 if (Mods.find("!") != StringRef::npos) 379 PolymorphicKeyType = Types.size() - 1; 380 381 Mods = getNextModifiers(Proto, Pos); 382 } 383 384 for (auto Type : Types) { 385 // If this builtin takes an immediate argument, we need to #define it rather 386 // than use a standard declaration, so that SemaChecking can range check 387 // the immediate passed by the user. 388 389 // Pointer arguments need to use macros to avoid hiding aligned attributes 390 // from the pointer type. 391 392 // It is not permitted to pass or return an __fp16 by value, so intrinsics 393 // taking a scalar float16_t must be implemented as macros. 394 if (Type.isImmediate() || Type.isPointer() || 395 (Type.isScalar() && Type.isHalf())) 396 UseMacro = true; 397 } 398 } 399 400 /// Get the Record that this intrinsic is based off. 401 Record *getRecord() const { return R; } 402 /// Get the set of Intrinsics that this intrinsic calls. 403 /// this is the set of immediate dependencies, NOT the 404 /// transitive closure. 405 const std::set<Intrinsic *> &getDependencies() const { return Dependencies; } 406 /// Get the architectural guard string (#ifdef). 407 std::string getGuard() const { return Guard; } 408 /// Get the non-mangled name. 409 std::string getName() const { return Name; } 410 411 /// Return true if the intrinsic takes an immediate operand. 412 bool hasImmediate() const { 413 return std::any_of(Types.begin(), Types.end(), 414 [](const Type &T) { return T.isImmediate(); }); 415 } 416 417 /// Return the parameter index of the immediate operand. 418 unsigned getImmediateIdx() const { 419 for (unsigned Idx = 0; Idx < Types.size(); ++Idx) 420 if (Types[Idx].isImmediate()) 421 return Idx - 1; 422 llvm_unreachable("Intrinsic has no immediate"); 423 } 424 425 426 unsigned getNumParams() const { return Types.size() - 1; } 427 Type getReturnType() const { return Types[0]; } 428 Type getParamType(unsigned I) const { return Types[I + 1]; } 429 Type getBaseType() const { return BaseType; } 430 Type getPolymorphicKeyType() const { return Types[PolymorphicKeyType]; } 431 432 /// Return true if the prototype has a scalar argument. 433 bool protoHasScalar() const; 434 435 /// Return the index that parameter PIndex will sit at 436 /// in a generated function call. This is often just PIndex, 437 /// but may not be as things such as multiple-vector operands 438 /// and sret parameters need to be taken into accont. 439 unsigned getGeneratedParamIdx(unsigned PIndex) { 440 unsigned Idx = 0; 441 if (getReturnType().getNumVectors() > 1) 442 // Multiple vectors are passed as sret. 443 ++Idx; 444 445 for (unsigned I = 0; I < PIndex; ++I) 446 Idx += std::max(1U, getParamType(I).getNumVectors()); 447 448 return Idx; 449 } 450 451 bool hasBody() const { return Body && !Body->getValues().empty(); } 452 453 void setNeededEarly() { NeededEarly = true; } 454 455 bool operator<(const Intrinsic &Other) const { 456 // Sort lexicographically on a two-tuple (Guard, Name) 457 if (Guard != Other.Guard) 458 return Guard < Other.Guard; 459 return Name < Other.Name; 460 } 461 462 ClassKind getClassKind(bool UseClassBIfScalar = false) { 463 if (UseClassBIfScalar && !protoHasScalar()) 464 return ClassB; 465 return CK; 466 } 467 468 /// Return the name, mangled with type information. 469 /// If ForceClassS is true, use ClassS (u32/s32) instead 470 /// of the intrinsic's own type class. 471 std::string getMangledName(bool ForceClassS = false) const; 472 /// Return the type code for a builtin function call. 473 std::string getInstTypeCode(Type T, ClassKind CK) const; 474 /// Return the type string for a BUILTIN() macro in Builtins.def. 475 std::string getBuiltinTypeStr(); 476 477 /// Generate the intrinsic, returning code. 478 std::string generate(); 479 /// Perform type checking and populate the dependency graph, but 480 /// don't generate code yet. 481 void indexBody(); 482 483 private: 484 StringRef getNextModifiers(StringRef Proto, unsigned &Pos) const; 485 486 std::string mangleName(std::string Name, ClassKind CK) const; 487 488 void initVariables(); 489 std::string replaceParamsIn(std::string S); 490 491 void emitBodyAsBuiltinCall(); 492 493 void generateImpl(bool ReverseArguments, 494 StringRef NamePrefix, StringRef CallPrefix); 495 void emitReturn(); 496 void emitBody(StringRef CallPrefix); 497 void emitShadowedArgs(); 498 void emitArgumentReversal(); 499 void emitReturnReversal(); 500 void emitReverseVariable(Variable &Dest, Variable &Src); 501 void emitNewLine(); 502 void emitClosingBrace(); 503 void emitOpeningBrace(); 504 void emitPrototype(StringRef NamePrefix); 505 506 class DagEmitter { 507 Intrinsic &Intr; 508 StringRef CallPrefix; 509 510 public: 511 DagEmitter(Intrinsic &Intr, StringRef CallPrefix) : 512 Intr(Intr), CallPrefix(CallPrefix) { 513 } 514 std::pair<Type, std::string> emitDagArg(Init *Arg, std::string ArgName); 515 std::pair<Type, std::string> emitDagSaveTemp(DagInit *DI); 516 std::pair<Type, std::string> emitDagSplat(DagInit *DI); 517 std::pair<Type, std::string> emitDagDup(DagInit *DI); 518 std::pair<Type, std::string> emitDagDupTyped(DagInit *DI); 519 std::pair<Type, std::string> emitDagShuffle(DagInit *DI); 520 std::pair<Type, std::string> emitDagCast(DagInit *DI, bool IsBitCast); 521 std::pair<Type, std::string> emitDagCall(DagInit *DI); 522 std::pair<Type, std::string> emitDagNameReplace(DagInit *DI); 523 std::pair<Type, std::string> emitDagLiteral(DagInit *DI); 524 std::pair<Type, std::string> emitDagOp(DagInit *DI); 525 std::pair<Type, std::string> emitDag(DagInit *DI); 526 }; 527 }; 528 529 //===----------------------------------------------------------------------===// 530 // NeonEmitter 531 //===----------------------------------------------------------------------===// 532 533 class NeonEmitter { 534 RecordKeeper &Records; 535 DenseMap<Record *, ClassKind> ClassMap; 536 std::map<std::string, std::deque<Intrinsic>> IntrinsicMap; 537 unsigned UniqueNumber; 538 539 void createIntrinsic(Record *R, SmallVectorImpl<Intrinsic *> &Out); 540 void genBuiltinsDef(raw_ostream &OS, SmallVectorImpl<Intrinsic *> &Defs); 541 void genOverloadTypeCheckCode(raw_ostream &OS, 542 SmallVectorImpl<Intrinsic *> &Defs); 543 void genIntrinsicRangeCheckCode(raw_ostream &OS, 544 SmallVectorImpl<Intrinsic *> &Defs); 545 546 public: 547 /// Called by Intrinsic - this attempts to get an intrinsic that takes 548 /// the given types as arguments. 549 Intrinsic &getIntrinsic(StringRef Name, ArrayRef<Type> Types); 550 551 /// Called by Intrinsic - returns a globally-unique number. 552 unsigned getUniqueNumber() { return UniqueNumber++; } 553 554 NeonEmitter(RecordKeeper &R) : Records(R), UniqueNumber(0) { 555 Record *SI = R.getClass("SInst"); 556 Record *II = R.getClass("IInst"); 557 Record *WI = R.getClass("WInst"); 558 Record *SOpI = R.getClass("SOpInst"); 559 Record *IOpI = R.getClass("IOpInst"); 560 Record *WOpI = R.getClass("WOpInst"); 561 Record *LOpI = R.getClass("LOpInst"); 562 Record *NoTestOpI = R.getClass("NoTestOpInst"); 563 564 ClassMap[SI] = ClassS; 565 ClassMap[II] = ClassI; 566 ClassMap[WI] = ClassW; 567 ClassMap[SOpI] = ClassS; 568 ClassMap[IOpI] = ClassI; 569 ClassMap[WOpI] = ClassW; 570 ClassMap[LOpI] = ClassL; 571 ClassMap[NoTestOpI] = ClassNoTest; 572 } 573 574 // run - Emit arm_neon.h.inc 575 void run(raw_ostream &o); 576 577 // runFP16 - Emit arm_fp16.h.inc 578 void runFP16(raw_ostream &o); 579 580 // runHeader - Emit all the __builtin prototypes used in arm_neon.h 581 // and arm_fp16.h 582 void runHeader(raw_ostream &o); 583 584 // runTests - Emit tests for all the Neon intrinsics. 585 void runTests(raw_ostream &o); 586 }; 587 588 } // end anonymous namespace 589 590 //===----------------------------------------------------------------------===// 591 // Type implementation 592 //===----------------------------------------------------------------------===// 593 594 std::string Type::str() const { 595 if (isVoid()) 596 return "void"; 597 std::string S; 598 599 if (isInteger() && !isSigned()) 600 S += "u"; 601 602 if (isPoly()) 603 S += "poly"; 604 else if (isFloating()) 605 S += "float"; 606 else 607 S += "int"; 608 609 S += utostr(ElementBitwidth); 610 if (isVector()) 611 S += "x" + utostr(getNumElements()); 612 if (NumVectors > 1) 613 S += "x" + utostr(NumVectors); 614 S += "_t"; 615 616 if (Constant) 617 S += " const"; 618 if (Pointer) 619 S += " *"; 620 621 return S; 622 } 623 624 std::string Type::builtin_str() const { 625 std::string S; 626 if (isVoid()) 627 return "v"; 628 629 if (isPointer()) { 630 // All pointers are void pointers. 631 S = "v"; 632 if (isConstPointer()) 633 S += "C"; 634 S += "*"; 635 return S; 636 } else if (isInteger()) 637 switch (ElementBitwidth) { 638 case 8: S += "c"; break; 639 case 16: S += "s"; break; 640 case 32: S += "i"; break; 641 case 64: S += "Wi"; break; 642 case 128: S += "LLLi"; break; 643 default: llvm_unreachable("Unhandled case!"); 644 } 645 else 646 switch (ElementBitwidth) { 647 case 16: S += "h"; break; 648 case 32: S += "f"; break; 649 case 64: S += "d"; break; 650 default: llvm_unreachable("Unhandled case!"); 651 } 652 653 // FIXME: NECESSARY??????????????????????????????????????????????????????????????????????? 654 if (isChar() && !isPointer() && isSigned()) 655 // Make chars explicitly signed. 656 S = "S" + S; 657 else if (isInteger() && !isSigned()) 658 S = "U" + S; 659 660 // Constant indices are "int", but have the "constant expression" modifier. 661 if (isImmediate()) { 662 assert(isInteger() && isSigned()); 663 S = "I" + S; 664 } 665 666 if (isScalar()) 667 return S; 668 669 std::string Ret; 670 for (unsigned I = 0; I < NumVectors; ++I) 671 Ret += "V" + utostr(getNumElements()) + S; 672 673 return Ret; 674 } 675 676 unsigned Type::getNeonEnum() const { 677 unsigned Addend; 678 switch (ElementBitwidth) { 679 case 8: Addend = 0; break; 680 case 16: Addend = 1; break; 681 case 32: Addend = 2; break; 682 case 64: Addend = 3; break; 683 case 128: Addend = 4; break; 684 default: llvm_unreachable("Unhandled element bitwidth!"); 685 } 686 687 unsigned Base = (unsigned)NeonTypeFlags::Int8 + Addend; 688 if (isPoly()) { 689 // Adjustment needed because Poly32 doesn't exist. 690 if (Addend >= 2) 691 --Addend; 692 Base = (unsigned)NeonTypeFlags::Poly8 + Addend; 693 } 694 if (isFloating()) { 695 assert(Addend != 0 && "Float8 doesn't exist!"); 696 Base = (unsigned)NeonTypeFlags::Float16 + (Addend - 1); 697 } 698 699 if (Bitwidth == 128) 700 Base |= (unsigned)NeonTypeFlags::QuadFlag; 701 if (isInteger() && !isSigned()) 702 Base |= (unsigned)NeonTypeFlags::UnsignedFlag; 703 704 return Base; 705 } 706 707 Type Type::fromTypedefName(StringRef Name) { 708 Type T; 709 T.Kind = SInt; 710 711 if (Name.front() == 'u') { 712 T.Kind = UInt; 713 Name = Name.drop_front(); 714 } 715 716 if (Name.startswith("float")) { 717 T.Kind = Float; 718 Name = Name.drop_front(5); 719 } else if (Name.startswith("poly")) { 720 T.Kind = Poly; 721 Name = Name.drop_front(4); 722 } else { 723 assert(Name.startswith("int")); 724 Name = Name.drop_front(3); 725 } 726 727 unsigned I = 0; 728 for (I = 0; I < Name.size(); ++I) { 729 if (!isdigit(Name[I])) 730 break; 731 } 732 Name.substr(0, I).getAsInteger(10, T.ElementBitwidth); 733 Name = Name.drop_front(I); 734 735 T.Bitwidth = T.ElementBitwidth; 736 T.NumVectors = 1; 737 738 if (Name.front() == 'x') { 739 Name = Name.drop_front(); 740 unsigned I = 0; 741 for (I = 0; I < Name.size(); ++I) { 742 if (!isdigit(Name[I])) 743 break; 744 } 745 unsigned NumLanes; 746 Name.substr(0, I).getAsInteger(10, NumLanes); 747 Name = Name.drop_front(I); 748 T.Bitwidth = T.ElementBitwidth * NumLanes; 749 } else { 750 // Was scalar. 751 T.NumVectors = 0; 752 } 753 if (Name.front() == 'x') { 754 Name = Name.drop_front(); 755 unsigned I = 0; 756 for (I = 0; I < Name.size(); ++I) { 757 if (!isdigit(Name[I])) 758 break; 759 } 760 Name.substr(0, I).getAsInteger(10, T.NumVectors); 761 Name = Name.drop_front(I); 762 } 763 764 assert(Name.startswith("_t") && "Malformed typedef!"); 765 return T; 766 } 767 768 void Type::applyTypespec(bool &Quad) { 769 std::string S = TS; 770 ScalarForMangling = false; 771 Kind = SInt; 772 ElementBitwidth = ~0U; 773 NumVectors = 1; 774 775 for (char I : S) { 776 switch (I) { 777 case 'S': 778 ScalarForMangling = true; 779 break; 780 case 'H': 781 NoManglingQ = true; 782 Quad = true; 783 break; 784 case 'Q': 785 Quad = true; 786 break; 787 case 'P': 788 Kind = Poly; 789 break; 790 case 'U': 791 Kind = UInt; 792 break; 793 case 'c': 794 ElementBitwidth = 8; 795 break; 796 case 'h': 797 Kind = Float; 798 LLVM_FALLTHROUGH; 799 case 's': 800 ElementBitwidth = 16; 801 break; 802 case 'f': 803 Kind = Float; 804 LLVM_FALLTHROUGH; 805 case 'i': 806 ElementBitwidth = 32; 807 break; 808 case 'd': 809 Kind = Float; 810 LLVM_FALLTHROUGH; 811 case 'l': 812 ElementBitwidth = 64; 813 break; 814 case 'k': 815 ElementBitwidth = 128; 816 // Poly doesn't have a 128x1 type. 817 if (isPoly()) 818 NumVectors = 0; 819 break; 820 default: 821 llvm_unreachable("Unhandled type code!"); 822 } 823 } 824 assert(ElementBitwidth != ~0U && "Bad element bitwidth!"); 825 826 Bitwidth = Quad ? 128 : 64; 827 } 828 829 void Type::applyModifiers(StringRef Mods) { 830 bool AppliedQuad = false; 831 applyTypespec(AppliedQuad); 832 833 for (char Mod : Mods) { 834 switch (Mod) { 835 case '.': 836 break; 837 case 'v': 838 Kind = Void; 839 break; 840 case 'S': 841 Kind = SInt; 842 break; 843 case 'U': 844 Kind = UInt; 845 break; 846 case 'F': 847 Kind = Float; 848 break; 849 case 'P': 850 Kind = Poly; 851 break; 852 case '>': 853 assert(ElementBitwidth < 128); 854 ElementBitwidth *= 2; 855 break; 856 case '<': 857 assert(ElementBitwidth > 8); 858 ElementBitwidth /= 2; 859 break; 860 case '1': 861 NumVectors = 0; 862 break; 863 case '2': 864 NumVectors = 2; 865 break; 866 case '3': 867 NumVectors = 3; 868 break; 869 case '4': 870 NumVectors = 4; 871 break; 872 case '*': 873 Pointer = true; 874 break; 875 case 'c': 876 Constant = true; 877 break; 878 case 'Q': 879 Bitwidth = 128; 880 break; 881 case 'q': 882 Bitwidth = 64; 883 break; 884 case 'I': 885 Kind = SInt; 886 ElementBitwidth = Bitwidth = 32; 887 NumVectors = 0; 888 Immediate = true; 889 break; 890 case 'p': 891 if (isPoly()) 892 Kind = UInt; 893 break; 894 case '!': 895 // Key type, handled elsewhere. 896 break; 897 default: 898 llvm_unreachable("Unhandled character!"); 899 } 900 } 901 } 902 903 //===----------------------------------------------------------------------===// 904 // Intrinsic implementation 905 //===----------------------------------------------------------------------===// 906 907 StringRef Intrinsic::getNextModifiers(StringRef Proto, unsigned &Pos) const { 908 if (Proto.size() == Pos) 909 return StringRef(); 910 else if (Proto[Pos] != '(') 911 return Proto.substr(Pos++, 1); 912 913 size_t Start = Pos + 1; 914 size_t End = Proto.find(')', Start); 915 assert_with_loc(End != StringRef::npos, "unmatched modifier group paren"); 916 Pos = End + 1; 917 return Proto.slice(Start, End); 918 } 919 920 std::string Intrinsic::getInstTypeCode(Type T, ClassKind CK) const { 921 char typeCode = '\0'; 922 bool printNumber = true; 923 924 if (CK == ClassB) 925 return ""; 926 927 if (T.isPoly()) 928 typeCode = 'p'; 929 else if (T.isInteger()) 930 typeCode = T.isSigned() ? 's' : 'u'; 931 else 932 typeCode = 'f'; 933 934 if (CK == ClassI) { 935 switch (typeCode) { 936 default: 937 break; 938 case 's': 939 case 'u': 940 case 'p': 941 typeCode = 'i'; 942 break; 943 } 944 } 945 if (CK == ClassB) { 946 typeCode = '\0'; 947 } 948 949 std::string S; 950 if (typeCode != '\0') 951 S.push_back(typeCode); 952 if (printNumber) 953 S += utostr(T.getElementSizeInBits()); 954 955 return S; 956 } 957 958 std::string Intrinsic::getBuiltinTypeStr() { 959 ClassKind LocalCK = getClassKind(true); 960 std::string S; 961 962 Type RetT = getReturnType(); 963 if ((LocalCK == ClassI || LocalCK == ClassW) && RetT.isScalar() && 964 !RetT.isFloating()) 965 RetT.makeInteger(RetT.getElementSizeInBits(), false); 966 967 // Since the return value must be one type, return a vector type of the 968 // appropriate width which we will bitcast. An exception is made for 969 // returning structs of 2, 3, or 4 vectors which are returned in a sret-like 970 // fashion, storing them to a pointer arg. 971 if (RetT.getNumVectors() > 1) { 972 S += "vv*"; // void result with void* first argument 973 } else { 974 if (RetT.isPoly()) 975 RetT.makeInteger(RetT.getElementSizeInBits(), false); 976 if (!RetT.isScalar() && RetT.isInteger() && !RetT.isSigned()) 977 RetT.makeSigned(); 978 979 if (LocalCK == ClassB && RetT.isValue() && !RetT.isScalar()) 980 // Cast to vector of 8-bit elements. 981 RetT.makeInteger(8, true); 982 983 S += RetT.builtin_str(); 984 } 985 986 for (unsigned I = 0; I < getNumParams(); ++I) { 987 Type T = getParamType(I); 988 if (T.isPoly()) 989 T.makeInteger(T.getElementSizeInBits(), false); 990 991 if (LocalCK == ClassB && !T.isScalar()) 992 T.makeInteger(8, true); 993 // Halves always get converted to 8-bit elements. 994 if (T.isHalf() && T.isVector() && !T.isScalarForMangling()) 995 T.makeInteger(8, true); 996 997 if (LocalCK == ClassI && T.isInteger()) 998 T.makeSigned(); 999 1000 if (hasImmediate() && getImmediateIdx() == I) 1001 T.makeImmediate(32); 1002 1003 S += T.builtin_str(); 1004 } 1005 1006 // Extra constant integer to hold type class enum for this function, e.g. s8 1007 if (LocalCK == ClassB) 1008 S += "i"; 1009 1010 return S; 1011 } 1012 1013 std::string Intrinsic::getMangledName(bool ForceClassS) const { 1014 // Check if the prototype has a scalar operand with the type of the vector 1015 // elements. If not, bitcasting the args will take care of arg checking. 1016 // The actual signedness etc. will be taken care of with special enums. 1017 ClassKind LocalCK = CK; 1018 if (!protoHasScalar()) 1019 LocalCK = ClassB; 1020 1021 return mangleName(Name, ForceClassS ? ClassS : LocalCK); 1022 } 1023 1024 std::string Intrinsic::mangleName(std::string Name, ClassKind LocalCK) const { 1025 std::string typeCode = getInstTypeCode(BaseType, LocalCK); 1026 std::string S = Name; 1027 1028 if (Name == "vcvt_f16_f32" || Name == "vcvt_f32_f16" || 1029 Name == "vcvt_f32_f64" || Name == "vcvt_f64_f32") 1030 return Name; 1031 1032 if (!typeCode.empty()) { 1033 // If the name ends with _xN (N = 2,3,4), insert the typeCode before _xN. 1034 if (Name.size() >= 3 && isdigit(Name.back()) && 1035 Name[Name.length() - 2] == 'x' && Name[Name.length() - 3] == '_') 1036 S.insert(S.length() - 3, "_" + typeCode); 1037 else 1038 S += "_" + typeCode; 1039 } 1040 1041 if (BaseType != InBaseType) { 1042 // A reinterpret - out the input base type at the end. 1043 S += "_" + getInstTypeCode(InBaseType, LocalCK); 1044 } 1045 1046 if (LocalCK == ClassB) 1047 S += "_v"; 1048 1049 // Insert a 'q' before the first '_' character so that it ends up before 1050 // _lane or _n on vector-scalar operations. 1051 if (BaseType.getSizeInBits() == 128 && !BaseType.noManglingQ()) { 1052 size_t Pos = S.find('_'); 1053 S.insert(Pos, "q"); 1054 } 1055 1056 char Suffix = '\0'; 1057 if (BaseType.isScalarForMangling()) { 1058 switch (BaseType.getElementSizeInBits()) { 1059 case 8: Suffix = 'b'; break; 1060 case 16: Suffix = 'h'; break; 1061 case 32: Suffix = 's'; break; 1062 case 64: Suffix = 'd'; break; 1063 default: llvm_unreachable("Bad suffix!"); 1064 } 1065 } 1066 if (Suffix != '\0') { 1067 size_t Pos = S.find('_'); 1068 S.insert(Pos, &Suffix, 1); 1069 } 1070 1071 return S; 1072 } 1073 1074 std::string Intrinsic::replaceParamsIn(std::string S) { 1075 while (S.find('$') != std::string::npos) { 1076 size_t Pos = S.find('$'); 1077 size_t End = Pos + 1; 1078 while (isalpha(S[End])) 1079 ++End; 1080 1081 std::string VarName = S.substr(Pos + 1, End - Pos - 1); 1082 assert_with_loc(Variables.find(VarName) != Variables.end(), 1083 "Variable not defined!"); 1084 S.replace(Pos, End - Pos, Variables.find(VarName)->second.getName()); 1085 } 1086 1087 return S; 1088 } 1089 1090 void Intrinsic::initVariables() { 1091 Variables.clear(); 1092 1093 // Modify the TypeSpec per-argument to get a concrete Type, and create 1094 // known variables for each. 1095 for (unsigned I = 1; I < Types.size(); ++I) { 1096 char NameC = '0' + (I - 1); 1097 std::string Name = "p"; 1098 Name.push_back(NameC); 1099 1100 Variables[Name] = Variable(Types[I], Name + VariablePostfix); 1101 } 1102 RetVar = Variable(Types[0], "ret" + VariablePostfix); 1103 } 1104 1105 void Intrinsic::emitPrototype(StringRef NamePrefix) { 1106 if (UseMacro) 1107 OS << "#define "; 1108 else 1109 OS << "__ai " << Types[0].str() << " "; 1110 1111 OS << NamePrefix.str() << mangleName(Name, ClassS) << "("; 1112 1113 for (unsigned I = 0; I < getNumParams(); ++I) { 1114 if (I != 0) 1115 OS << ", "; 1116 1117 char NameC = '0' + I; 1118 std::string Name = "p"; 1119 Name.push_back(NameC); 1120 assert(Variables.find(Name) != Variables.end()); 1121 Variable &V = Variables[Name]; 1122 1123 if (!UseMacro) 1124 OS << V.getType().str() << " "; 1125 OS << V.getName(); 1126 } 1127 1128 OS << ")"; 1129 } 1130 1131 void Intrinsic::emitOpeningBrace() { 1132 if (UseMacro) 1133 OS << " __extension__ ({"; 1134 else 1135 OS << " {"; 1136 emitNewLine(); 1137 } 1138 1139 void Intrinsic::emitClosingBrace() { 1140 if (UseMacro) 1141 OS << "})"; 1142 else 1143 OS << "}"; 1144 } 1145 1146 void Intrinsic::emitNewLine() { 1147 if (UseMacro) 1148 OS << " \\\n"; 1149 else 1150 OS << "\n"; 1151 } 1152 1153 void Intrinsic::emitReverseVariable(Variable &Dest, Variable &Src) { 1154 if (Dest.getType().getNumVectors() > 1) { 1155 emitNewLine(); 1156 1157 for (unsigned K = 0; K < Dest.getType().getNumVectors(); ++K) { 1158 OS << " " << Dest.getName() << ".val[" << K << "] = " 1159 << "__builtin_shufflevector(" 1160 << Src.getName() << ".val[" << K << "], " 1161 << Src.getName() << ".val[" << K << "]"; 1162 for (int J = Dest.getType().getNumElements() - 1; J >= 0; --J) 1163 OS << ", " << J; 1164 OS << ");"; 1165 emitNewLine(); 1166 } 1167 } else { 1168 OS << " " << Dest.getName() 1169 << " = __builtin_shufflevector(" << Src.getName() << ", " << Src.getName(); 1170 for (int J = Dest.getType().getNumElements() - 1; J >= 0; --J) 1171 OS << ", " << J; 1172 OS << ");"; 1173 emitNewLine(); 1174 } 1175 } 1176 1177 void Intrinsic::emitArgumentReversal() { 1178 if (isBigEndianSafe()) 1179 return; 1180 1181 // Reverse all vector arguments. 1182 for (unsigned I = 0; I < getNumParams(); ++I) { 1183 std::string Name = "p" + utostr(I); 1184 std::string NewName = "rev" + utostr(I); 1185 1186 Variable &V = Variables[Name]; 1187 Variable NewV(V.getType(), NewName + VariablePostfix); 1188 1189 if (!NewV.getType().isVector() || NewV.getType().getNumElements() == 1) 1190 continue; 1191 1192 OS << " " << NewV.getType().str() << " " << NewV.getName() << ";"; 1193 emitReverseVariable(NewV, V); 1194 V = NewV; 1195 } 1196 } 1197 1198 void Intrinsic::emitReturnReversal() { 1199 if (isBigEndianSafe()) 1200 return; 1201 if (!getReturnType().isVector() || getReturnType().isVoid() || 1202 getReturnType().getNumElements() == 1) 1203 return; 1204 emitReverseVariable(RetVar, RetVar); 1205 } 1206 1207 void Intrinsic::emitShadowedArgs() { 1208 // Macro arguments are not type-checked like inline function arguments, 1209 // so assign them to local temporaries to get the right type checking. 1210 if (!UseMacro) 1211 return; 1212 1213 for (unsigned I = 0; I < getNumParams(); ++I) { 1214 // Do not create a temporary for an immediate argument. 1215 // That would defeat the whole point of using a macro! 1216 if (getParamType(I).isImmediate()) 1217 continue; 1218 // Do not create a temporary for pointer arguments. The input 1219 // pointer may have an alignment hint. 1220 if (getParamType(I).isPointer()) 1221 continue; 1222 1223 std::string Name = "p" + utostr(I); 1224 1225 assert(Variables.find(Name) != Variables.end()); 1226 Variable &V = Variables[Name]; 1227 1228 std::string NewName = "s" + utostr(I); 1229 Variable V2(V.getType(), NewName + VariablePostfix); 1230 1231 OS << " " << V2.getType().str() << " " << V2.getName() << " = " 1232 << V.getName() << ";"; 1233 emitNewLine(); 1234 1235 V = V2; 1236 } 1237 } 1238 1239 bool Intrinsic::protoHasScalar() const { 1240 return std::any_of(Types.begin(), Types.end(), [](const Type &T) { 1241 return T.isScalar() && !T.isImmediate(); 1242 }); 1243 } 1244 1245 void Intrinsic::emitBodyAsBuiltinCall() { 1246 std::string S; 1247 1248 // If this builtin returns a struct 2, 3, or 4 vectors, pass it as an implicit 1249 // sret-like argument. 1250 bool SRet = getReturnType().getNumVectors() >= 2; 1251 1252 StringRef N = Name; 1253 ClassKind LocalCK = CK; 1254 if (!protoHasScalar()) 1255 LocalCK = ClassB; 1256 1257 if (!getReturnType().isVoid() && !SRet) 1258 S += "(" + RetVar.getType().str() + ") "; 1259 1260 S += "__builtin_neon_" + mangleName(N, LocalCK) + "("; 1261 1262 if (SRet) 1263 S += "&" + RetVar.getName() + ", "; 1264 1265 for (unsigned I = 0; I < getNumParams(); ++I) { 1266 Variable &V = Variables["p" + utostr(I)]; 1267 Type T = V.getType(); 1268 1269 // Handle multiple-vector values specially, emitting each subvector as an 1270 // argument to the builtin. 1271 if (T.getNumVectors() > 1) { 1272 // Check if an explicit cast is needed. 1273 std::string Cast; 1274 if (LocalCK == ClassB) { 1275 Type T2 = T; 1276 T2.makeOneVector(); 1277 T2.makeInteger(8, /*Signed=*/true); 1278 Cast = "(" + T2.str() + ")"; 1279 } 1280 1281 for (unsigned J = 0; J < T.getNumVectors(); ++J) 1282 S += Cast + V.getName() + ".val[" + utostr(J) + "], "; 1283 continue; 1284 } 1285 1286 std::string Arg = V.getName(); 1287 Type CastToType = T; 1288 1289 // Check if an explicit cast is needed. 1290 if (CastToType.isVector() && 1291 (LocalCK == ClassB || (T.isHalf() && !T.isScalarForMangling()))) { 1292 CastToType.makeInteger(8, true); 1293 Arg = "(" + CastToType.str() + ")" + Arg; 1294 } else if (CastToType.isVector() && LocalCK == ClassI) { 1295 if (CastToType.isInteger()) 1296 CastToType.makeSigned(); 1297 Arg = "(" + CastToType.str() + ")" + Arg; 1298 } 1299 1300 S += Arg + ", "; 1301 } 1302 1303 // Extra constant integer to hold type class enum for this function, e.g. s8 1304 if (getClassKind(true) == ClassB) { 1305 S += utostr(getPolymorphicKeyType().getNeonEnum()); 1306 } else { 1307 // Remove extraneous ", ". 1308 S.pop_back(); 1309 S.pop_back(); 1310 } 1311 S += ");"; 1312 1313 std::string RetExpr; 1314 if (!SRet && !RetVar.getType().isVoid()) 1315 RetExpr = RetVar.getName() + " = "; 1316 1317 OS << " " << RetExpr << S; 1318 emitNewLine(); 1319 } 1320 1321 void Intrinsic::emitBody(StringRef CallPrefix) { 1322 std::vector<std::string> Lines; 1323 1324 assert(RetVar.getType() == Types[0]); 1325 // Create a return variable, if we're not void. 1326 if (!RetVar.getType().isVoid()) { 1327 OS << " " << RetVar.getType().str() << " " << RetVar.getName() << ";"; 1328 emitNewLine(); 1329 } 1330 1331 if (!Body || Body->getValues().empty()) { 1332 // Nothing specific to output - must output a builtin. 1333 emitBodyAsBuiltinCall(); 1334 return; 1335 } 1336 1337 // We have a list of "things to output". The last should be returned. 1338 for (auto *I : Body->getValues()) { 1339 if (StringInit *SI = dyn_cast<StringInit>(I)) { 1340 Lines.push_back(replaceParamsIn(SI->getAsString())); 1341 } else if (DagInit *DI = dyn_cast<DagInit>(I)) { 1342 DagEmitter DE(*this, CallPrefix); 1343 Lines.push_back(DE.emitDag(DI).second + ";"); 1344 } 1345 } 1346 1347 assert(!Lines.empty() && "Empty def?"); 1348 if (!RetVar.getType().isVoid()) 1349 Lines.back().insert(0, RetVar.getName() + " = "); 1350 1351 for (auto &L : Lines) { 1352 OS << " " << L; 1353 emitNewLine(); 1354 } 1355 } 1356 1357 void Intrinsic::emitReturn() { 1358 if (RetVar.getType().isVoid()) 1359 return; 1360 if (UseMacro) 1361 OS << " " << RetVar.getName() << ";"; 1362 else 1363 OS << " return " << RetVar.getName() << ";"; 1364 emitNewLine(); 1365 } 1366 1367 std::pair<Type, std::string> Intrinsic::DagEmitter::emitDag(DagInit *DI) { 1368 // At this point we should only be seeing a def. 1369 DefInit *DefI = cast<DefInit>(DI->getOperator()); 1370 std::string Op = DefI->getAsString(); 1371 1372 if (Op == "cast" || Op == "bitcast") 1373 return emitDagCast(DI, Op == "bitcast"); 1374 if (Op == "shuffle") 1375 return emitDagShuffle(DI); 1376 if (Op == "dup") 1377 return emitDagDup(DI); 1378 if (Op == "dup_typed") 1379 return emitDagDupTyped(DI); 1380 if (Op == "splat") 1381 return emitDagSplat(DI); 1382 if (Op == "save_temp") 1383 return emitDagSaveTemp(DI); 1384 if (Op == "op") 1385 return emitDagOp(DI); 1386 if (Op == "call") 1387 return emitDagCall(DI); 1388 if (Op == "name_replace") 1389 return emitDagNameReplace(DI); 1390 if (Op == "literal") 1391 return emitDagLiteral(DI); 1392 assert_with_loc(false, "Unknown operation!"); 1393 return std::make_pair(Type::getVoid(), ""); 1394 } 1395 1396 std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagOp(DagInit *DI) { 1397 std::string Op = cast<StringInit>(DI->getArg(0))->getAsUnquotedString(); 1398 if (DI->getNumArgs() == 2) { 1399 // Unary op. 1400 std::pair<Type, std::string> R = 1401 emitDagArg(DI->getArg(1), DI->getArgNameStr(1)); 1402 return std::make_pair(R.first, Op + R.second); 1403 } else { 1404 assert(DI->getNumArgs() == 3 && "Can only handle unary and binary ops!"); 1405 std::pair<Type, std::string> R1 = 1406 emitDagArg(DI->getArg(1), DI->getArgNameStr(1)); 1407 std::pair<Type, std::string> R2 = 1408 emitDagArg(DI->getArg(2), DI->getArgNameStr(2)); 1409 assert_with_loc(R1.first == R2.first, "Argument type mismatch!"); 1410 return std::make_pair(R1.first, R1.second + " " + Op + " " + R2.second); 1411 } 1412 } 1413 1414 std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagCall(DagInit *DI) { 1415 std::vector<Type> Types; 1416 std::vector<std::string> Values; 1417 for (unsigned I = 0; I < DI->getNumArgs() - 1; ++I) { 1418 std::pair<Type, std::string> R = 1419 emitDagArg(DI->getArg(I + 1), DI->getArgNameStr(I + 1)); 1420 Types.push_back(R.first); 1421 Values.push_back(R.second); 1422 } 1423 1424 // Look up the called intrinsic. 1425 std::string N; 1426 if (StringInit *SI = dyn_cast<StringInit>(DI->getArg(0))) 1427 N = SI->getAsUnquotedString(); 1428 else 1429 N = emitDagArg(DI->getArg(0), "").second; 1430 Intrinsic &Callee = Intr.Emitter.getIntrinsic(N, Types); 1431 1432 // Make sure the callee is known as an early def. 1433 Callee.setNeededEarly(); 1434 Intr.Dependencies.insert(&Callee); 1435 1436 // Now create the call itself. 1437 std::string S = ""; 1438 if (!Callee.isBigEndianSafe()) 1439 S += CallPrefix.str(); 1440 S += Callee.getMangledName(true) + "("; 1441 for (unsigned I = 0; I < DI->getNumArgs() - 1; ++I) { 1442 if (I != 0) 1443 S += ", "; 1444 S += Values[I]; 1445 } 1446 S += ")"; 1447 1448 return std::make_pair(Callee.getReturnType(), S); 1449 } 1450 1451 std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagCast(DagInit *DI, 1452 bool IsBitCast){ 1453 // (cast MOD* VAL) -> cast VAL to type given by MOD. 1454 std::pair<Type, std::string> R = emitDagArg( 1455 DI->getArg(DI->getNumArgs() - 1), 1456 DI->getArgNameStr(DI->getNumArgs() - 1)); 1457 Type castToType = R.first; 1458 for (unsigned ArgIdx = 0; ArgIdx < DI->getNumArgs() - 1; ++ArgIdx) { 1459 1460 // MOD can take several forms: 1461 // 1. $X - take the type of parameter / variable X. 1462 // 2. The value "R" - take the type of the return type. 1463 // 3. a type string 1464 // 4. The value "U" or "S" to switch the signedness. 1465 // 5. The value "H" or "D" to half or double the bitwidth. 1466 // 6. The value "8" to convert to 8-bit (signed) integer lanes. 1467 if (!DI->getArgNameStr(ArgIdx).empty()) { 1468 assert_with_loc(Intr.Variables.find(DI->getArgNameStr(ArgIdx)) != 1469 Intr.Variables.end(), 1470 "Variable not found"); 1471 castToType = Intr.Variables[DI->getArgNameStr(ArgIdx)].getType(); 1472 } else { 1473 StringInit *SI = dyn_cast<StringInit>(DI->getArg(ArgIdx)); 1474 assert_with_loc(SI, "Expected string type or $Name for cast type"); 1475 1476 if (SI->getAsUnquotedString() == "R") { 1477 castToType = Intr.getReturnType(); 1478 } else if (SI->getAsUnquotedString() == "U") { 1479 castToType.makeUnsigned(); 1480 } else if (SI->getAsUnquotedString() == "S") { 1481 castToType.makeSigned(); 1482 } else if (SI->getAsUnquotedString() == "H") { 1483 castToType.halveLanes(); 1484 } else if (SI->getAsUnquotedString() == "D") { 1485 castToType.doubleLanes(); 1486 } else if (SI->getAsUnquotedString() == "8") { 1487 castToType.makeInteger(8, true); 1488 } else { 1489 castToType = Type::fromTypedefName(SI->getAsUnquotedString()); 1490 assert_with_loc(!castToType.isVoid(), "Unknown typedef"); 1491 } 1492 } 1493 } 1494 1495 std::string S; 1496 if (IsBitCast) { 1497 // Emit a reinterpret cast. The second operand must be an lvalue, so create 1498 // a temporary. 1499 std::string N = "reint"; 1500 unsigned I = 0; 1501 while (Intr.Variables.find(N) != Intr.Variables.end()) 1502 N = "reint" + utostr(++I); 1503 Intr.Variables[N] = Variable(R.first, N + Intr.VariablePostfix); 1504 1505 Intr.OS << R.first.str() << " " << Intr.Variables[N].getName() << " = " 1506 << R.second << ";"; 1507 Intr.emitNewLine(); 1508 1509 S = "*(" + castToType.str() + " *) &" + Intr.Variables[N].getName() + ""; 1510 } else { 1511 // Emit a normal (static) cast. 1512 S = "(" + castToType.str() + ")(" + R.second + ")"; 1513 } 1514 1515 return std::make_pair(castToType, S); 1516 } 1517 1518 std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagShuffle(DagInit *DI){ 1519 // See the documentation in arm_neon.td for a description of these operators. 1520 class LowHalf : public SetTheory::Operator { 1521 public: 1522 void apply(SetTheory &ST, DagInit *Expr, SetTheory::RecSet &Elts, 1523 ArrayRef<SMLoc> Loc) override { 1524 SetTheory::RecSet Elts2; 1525 ST.evaluate(Expr->arg_begin(), Expr->arg_end(), Elts2, Loc); 1526 Elts.insert(Elts2.begin(), Elts2.begin() + (Elts2.size() / 2)); 1527 } 1528 }; 1529 1530 class HighHalf : public SetTheory::Operator { 1531 public: 1532 void apply(SetTheory &ST, DagInit *Expr, SetTheory::RecSet &Elts, 1533 ArrayRef<SMLoc> Loc) override { 1534 SetTheory::RecSet Elts2; 1535 ST.evaluate(Expr->arg_begin(), Expr->arg_end(), Elts2, Loc); 1536 Elts.insert(Elts2.begin() + (Elts2.size() / 2), Elts2.end()); 1537 } 1538 }; 1539 1540 class Rev : public SetTheory::Operator { 1541 unsigned ElementSize; 1542 1543 public: 1544 Rev(unsigned ElementSize) : ElementSize(ElementSize) {} 1545 1546 void apply(SetTheory &ST, DagInit *Expr, SetTheory::RecSet &Elts, 1547 ArrayRef<SMLoc> Loc) override { 1548 SetTheory::RecSet Elts2; 1549 ST.evaluate(Expr->arg_begin() + 1, Expr->arg_end(), Elts2, Loc); 1550 1551 int64_t VectorSize = cast<IntInit>(Expr->getArg(0))->getValue(); 1552 VectorSize /= ElementSize; 1553 1554 std::vector<Record *> Revved; 1555 for (unsigned VI = 0; VI < Elts2.size(); VI += VectorSize) { 1556 for (int LI = VectorSize - 1; LI >= 0; --LI) { 1557 Revved.push_back(Elts2[VI + LI]); 1558 } 1559 } 1560 1561 Elts.insert(Revved.begin(), Revved.end()); 1562 } 1563 }; 1564 1565 class MaskExpander : public SetTheory::Expander { 1566 unsigned N; 1567 1568 public: 1569 MaskExpander(unsigned N) : N(N) {} 1570 1571 void expand(SetTheory &ST, Record *R, SetTheory::RecSet &Elts) override { 1572 unsigned Addend = 0; 1573 if (R->getName() == "mask0") 1574 Addend = 0; 1575 else if (R->getName() == "mask1") 1576 Addend = N; 1577 else 1578 return; 1579 for (unsigned I = 0; I < N; ++I) 1580 Elts.insert(R->getRecords().getDef("sv" + utostr(I + Addend))); 1581 } 1582 }; 1583 1584 // (shuffle arg1, arg2, sequence) 1585 std::pair<Type, std::string> Arg1 = 1586 emitDagArg(DI->getArg(0), DI->getArgNameStr(0)); 1587 std::pair<Type, std::string> Arg2 = 1588 emitDagArg(DI->getArg(1), DI->getArgNameStr(1)); 1589 assert_with_loc(Arg1.first == Arg2.first, 1590 "Different types in arguments to shuffle!"); 1591 1592 SetTheory ST; 1593 SetTheory::RecSet Elts; 1594 ST.addOperator("lowhalf", std::make_unique<LowHalf>()); 1595 ST.addOperator("highhalf", std::make_unique<HighHalf>()); 1596 ST.addOperator("rev", 1597 std::make_unique<Rev>(Arg1.first.getElementSizeInBits())); 1598 ST.addExpander("MaskExpand", 1599 std::make_unique<MaskExpander>(Arg1.first.getNumElements())); 1600 ST.evaluate(DI->getArg(2), Elts, None); 1601 1602 std::string S = "__builtin_shufflevector(" + Arg1.second + ", " + Arg2.second; 1603 for (auto &E : Elts) { 1604 StringRef Name = E->getName(); 1605 assert_with_loc(Name.startswith("sv"), 1606 "Incorrect element kind in shuffle mask!"); 1607 S += ", " + Name.drop_front(2).str(); 1608 } 1609 S += ")"; 1610 1611 // Recalculate the return type - the shuffle may have halved or doubled it. 1612 Type T(Arg1.first); 1613 if (Elts.size() > T.getNumElements()) { 1614 assert_with_loc( 1615 Elts.size() == T.getNumElements() * 2, 1616 "Can only double or half the number of elements in a shuffle!"); 1617 T.doubleLanes(); 1618 } else if (Elts.size() < T.getNumElements()) { 1619 assert_with_loc( 1620 Elts.size() == T.getNumElements() / 2, 1621 "Can only double or half the number of elements in a shuffle!"); 1622 T.halveLanes(); 1623 } 1624 1625 return std::make_pair(T, S); 1626 } 1627 1628 std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagDup(DagInit *DI) { 1629 assert_with_loc(DI->getNumArgs() == 1, "dup() expects one argument"); 1630 std::pair<Type, std::string> A = emitDagArg(DI->getArg(0), 1631 DI->getArgNameStr(0)); 1632 assert_with_loc(A.first.isScalar(), "dup() expects a scalar argument"); 1633 1634 Type T = Intr.getBaseType(); 1635 assert_with_loc(T.isVector(), "dup() used but default type is scalar!"); 1636 std::string S = "(" + T.str() + ") {"; 1637 for (unsigned I = 0; I < T.getNumElements(); ++I) { 1638 if (I != 0) 1639 S += ", "; 1640 S += A.second; 1641 } 1642 S += "}"; 1643 1644 return std::make_pair(T, S); 1645 } 1646 1647 std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagDupTyped(DagInit *DI) { 1648 assert_with_loc(DI->getNumArgs() == 2, "dup_typed() expects two arguments"); 1649 std::pair<Type, std::string> A = emitDagArg(DI->getArg(0), 1650 DI->getArgNameStr(0)); 1651 std::pair<Type, std::string> B = emitDagArg(DI->getArg(1), 1652 DI->getArgNameStr(1)); 1653 assert_with_loc(B.first.isScalar(), 1654 "dup_typed() requires a scalar as the second argument"); 1655 1656 Type T = A.first; 1657 assert_with_loc(T.isVector(), "dup_typed() used but target type is scalar!"); 1658 std::string S = "(" + T.str() + ") {"; 1659 for (unsigned I = 0; I < T.getNumElements(); ++I) { 1660 if (I != 0) 1661 S += ", "; 1662 S += B.second; 1663 } 1664 S += "}"; 1665 1666 return std::make_pair(T, S); 1667 } 1668 1669 std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagSplat(DagInit *DI) { 1670 assert_with_loc(DI->getNumArgs() == 2, "splat() expects two arguments"); 1671 std::pair<Type, std::string> A = emitDagArg(DI->getArg(0), 1672 DI->getArgNameStr(0)); 1673 std::pair<Type, std::string> B = emitDagArg(DI->getArg(1), 1674 DI->getArgNameStr(1)); 1675 1676 assert_with_loc(B.first.isScalar(), 1677 "splat() requires a scalar int as the second argument"); 1678 1679 std::string S = "__builtin_shufflevector(" + A.second + ", " + A.second; 1680 for (unsigned I = 0; I < Intr.getBaseType().getNumElements(); ++I) { 1681 S += ", " + B.second; 1682 } 1683 S += ")"; 1684 1685 return std::make_pair(Intr.getBaseType(), S); 1686 } 1687 1688 std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagSaveTemp(DagInit *DI) { 1689 assert_with_loc(DI->getNumArgs() == 2, "save_temp() expects two arguments"); 1690 std::pair<Type, std::string> A = emitDagArg(DI->getArg(1), 1691 DI->getArgNameStr(1)); 1692 1693 assert_with_loc(!A.first.isVoid(), 1694 "Argument to save_temp() must have non-void type!"); 1695 1696 std::string N = DI->getArgNameStr(0); 1697 assert_with_loc(!N.empty(), 1698 "save_temp() expects a name as the first argument"); 1699 1700 assert_with_loc(Intr.Variables.find(N) == Intr.Variables.end(), 1701 "Variable already defined!"); 1702 Intr.Variables[N] = Variable(A.first, N + Intr.VariablePostfix); 1703 1704 std::string S = 1705 A.first.str() + " " + Intr.Variables[N].getName() + " = " + A.second; 1706 1707 return std::make_pair(Type::getVoid(), S); 1708 } 1709 1710 std::pair<Type, std::string> 1711 Intrinsic::DagEmitter::emitDagNameReplace(DagInit *DI) { 1712 std::string S = Intr.Name; 1713 1714 assert_with_loc(DI->getNumArgs() == 2, "name_replace requires 2 arguments!"); 1715 std::string ToReplace = cast<StringInit>(DI->getArg(0))->getAsUnquotedString(); 1716 std::string ReplaceWith = cast<StringInit>(DI->getArg(1))->getAsUnquotedString(); 1717 1718 size_t Idx = S.find(ToReplace); 1719 1720 assert_with_loc(Idx != std::string::npos, "name should contain '" + ToReplace + "'!"); 1721 S.replace(Idx, ToReplace.size(), ReplaceWith); 1722 1723 return std::make_pair(Type::getVoid(), S); 1724 } 1725 1726 std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagLiteral(DagInit *DI){ 1727 std::string Ty = cast<StringInit>(DI->getArg(0))->getAsUnquotedString(); 1728 std::string Value = cast<StringInit>(DI->getArg(1))->getAsUnquotedString(); 1729 return std::make_pair(Type::fromTypedefName(Ty), Value); 1730 } 1731 1732 std::pair<Type, std::string> 1733 Intrinsic::DagEmitter::emitDagArg(Init *Arg, std::string ArgName) { 1734 if (!ArgName.empty()) { 1735 assert_with_loc(!Arg->isComplete(), 1736 "Arguments must either be DAGs or names, not both!"); 1737 assert_with_loc(Intr.Variables.find(ArgName) != Intr.Variables.end(), 1738 "Variable not defined!"); 1739 Variable &V = Intr.Variables[ArgName]; 1740 return std::make_pair(V.getType(), V.getName()); 1741 } 1742 1743 assert(Arg && "Neither ArgName nor Arg?!"); 1744 DagInit *DI = dyn_cast<DagInit>(Arg); 1745 assert_with_loc(DI, "Arguments must either be DAGs or names!"); 1746 1747 return emitDag(DI); 1748 } 1749 1750 std::string Intrinsic::generate() { 1751 // Avoid duplicated code for big and little endian 1752 if (isBigEndianSafe()) { 1753 generateImpl(false, "", ""); 1754 return OS.str(); 1755 } 1756 // Little endian intrinsics are simple and don't require any argument 1757 // swapping. 1758 OS << "#ifdef __LITTLE_ENDIAN__\n"; 1759 1760 generateImpl(false, "", ""); 1761 1762 OS << "#else\n"; 1763 1764 // Big endian intrinsics are more complex. The user intended these 1765 // intrinsics to operate on a vector "as-if" loaded by (V)LDR, 1766 // but we load as-if (V)LD1. So we should swap all arguments and 1767 // swap the return value too. 1768 // 1769 // If we call sub-intrinsics, we should call a version that does 1770 // not re-swap the arguments! 1771 generateImpl(true, "", "__noswap_"); 1772 1773 // If we're needed early, create a non-swapping variant for 1774 // big-endian. 1775 if (NeededEarly) { 1776 generateImpl(false, "__noswap_", "__noswap_"); 1777 } 1778 OS << "#endif\n\n"; 1779 1780 return OS.str(); 1781 } 1782 1783 void Intrinsic::generateImpl(bool ReverseArguments, 1784 StringRef NamePrefix, StringRef CallPrefix) { 1785 CurrentRecord = R; 1786 1787 // If we call a macro, our local variables may be corrupted due to 1788 // lack of proper lexical scoping. So, add a globally unique postfix 1789 // to every variable. 1790 // 1791 // indexBody() should have set up the Dependencies set by now. 1792 for (auto *I : Dependencies) 1793 if (I->UseMacro) { 1794 VariablePostfix = "_" + utostr(Emitter.getUniqueNumber()); 1795 break; 1796 } 1797 1798 initVariables(); 1799 1800 emitPrototype(NamePrefix); 1801 1802 if (IsUnavailable) { 1803 OS << " __attribute__((unavailable));"; 1804 } else { 1805 emitOpeningBrace(); 1806 emitShadowedArgs(); 1807 if (ReverseArguments) 1808 emitArgumentReversal(); 1809 emitBody(CallPrefix); 1810 if (ReverseArguments) 1811 emitReturnReversal(); 1812 emitReturn(); 1813 emitClosingBrace(); 1814 } 1815 OS << "\n"; 1816 1817 CurrentRecord = nullptr; 1818 } 1819 1820 void Intrinsic::indexBody() { 1821 CurrentRecord = R; 1822 1823 initVariables(); 1824 emitBody(""); 1825 OS.str(""); 1826 1827 CurrentRecord = nullptr; 1828 } 1829 1830 //===----------------------------------------------------------------------===// 1831 // NeonEmitter implementation 1832 //===----------------------------------------------------------------------===// 1833 1834 Intrinsic &NeonEmitter::getIntrinsic(StringRef Name, ArrayRef<Type> Types) { 1835 // First, look up the name in the intrinsic map. 1836 assert_with_loc(IntrinsicMap.find(Name.str()) != IntrinsicMap.end(), 1837 ("Intrinsic '" + Name + "' not found!").str()); 1838 auto &V = IntrinsicMap.find(Name.str())->second; 1839 std::vector<Intrinsic *> GoodVec; 1840 1841 // Create a string to print if we end up failing. 1842 std::string ErrMsg = "looking up intrinsic '" + Name.str() + "("; 1843 for (unsigned I = 0; I < Types.size(); ++I) { 1844 if (I != 0) 1845 ErrMsg += ", "; 1846 ErrMsg += Types[I].str(); 1847 } 1848 ErrMsg += ")'\n"; 1849 ErrMsg += "Available overloads:\n"; 1850 1851 // Now, look through each intrinsic implementation and see if the types are 1852 // compatible. 1853 for (auto &I : V) { 1854 ErrMsg += " - " + I.getReturnType().str() + " " + I.getMangledName(); 1855 ErrMsg += "("; 1856 for (unsigned A = 0; A < I.getNumParams(); ++A) { 1857 if (A != 0) 1858 ErrMsg += ", "; 1859 ErrMsg += I.getParamType(A).str(); 1860 } 1861 ErrMsg += ")\n"; 1862 1863 if (I.getNumParams() != Types.size()) 1864 continue; 1865 1866 bool Good = true; 1867 for (unsigned Arg = 0; Arg < Types.size(); ++Arg) { 1868 if (I.getParamType(Arg) != Types[Arg]) { 1869 Good = false; 1870 break; 1871 } 1872 } 1873 if (Good) 1874 GoodVec.push_back(&I); 1875 } 1876 1877 assert_with_loc(!GoodVec.empty(), 1878 "No compatible intrinsic found - " + ErrMsg); 1879 assert_with_loc(GoodVec.size() == 1, "Multiple overloads found - " + ErrMsg); 1880 1881 return *GoodVec.front(); 1882 } 1883 1884 void NeonEmitter::createIntrinsic(Record *R, 1885 SmallVectorImpl<Intrinsic *> &Out) { 1886 std::string Name = R->getValueAsString("Name"); 1887 std::string Proto = R->getValueAsString("Prototype"); 1888 std::string Types = R->getValueAsString("Types"); 1889 Record *OperationRec = R->getValueAsDef("Operation"); 1890 bool CartesianProductOfTypes = R->getValueAsBit("CartesianProductOfTypes"); 1891 bool BigEndianSafe = R->getValueAsBit("BigEndianSafe"); 1892 std::string Guard = R->getValueAsString("ArchGuard"); 1893 bool IsUnavailable = OperationRec->getValueAsBit("Unavailable"); 1894 1895 // Set the global current record. This allows assert_with_loc to produce 1896 // decent location information even when highly nested. 1897 CurrentRecord = R; 1898 1899 ListInit *Body = OperationRec->getValueAsListInit("Ops"); 1900 1901 std::vector<TypeSpec> TypeSpecs = TypeSpec::fromTypeSpecs(Types); 1902 1903 ClassKind CK = ClassNone; 1904 if (R->getSuperClasses().size() >= 2) 1905 CK = ClassMap[R->getSuperClasses()[1].first]; 1906 1907 std::vector<std::pair<TypeSpec, TypeSpec>> NewTypeSpecs; 1908 for (auto TS : TypeSpecs) { 1909 if (CartesianProductOfTypes) { 1910 Type DefaultT(TS, "."); 1911 for (auto SrcTS : TypeSpecs) { 1912 Type DefaultSrcT(SrcTS, "."); 1913 if (TS == SrcTS || 1914 DefaultSrcT.getSizeInBits() != DefaultT.getSizeInBits()) 1915 continue; 1916 NewTypeSpecs.push_back(std::make_pair(TS, SrcTS)); 1917 } 1918 } else { 1919 NewTypeSpecs.push_back(std::make_pair(TS, TS)); 1920 } 1921 } 1922 1923 llvm::sort(NewTypeSpecs); 1924 NewTypeSpecs.erase(std::unique(NewTypeSpecs.begin(), NewTypeSpecs.end()), 1925 NewTypeSpecs.end()); 1926 auto &Entry = IntrinsicMap[Name]; 1927 1928 for (auto &I : NewTypeSpecs) { 1929 Entry.emplace_back(R, Name, Proto, I.first, I.second, CK, Body, *this, 1930 Guard, IsUnavailable, BigEndianSafe); 1931 Out.push_back(&Entry.back()); 1932 } 1933 1934 CurrentRecord = nullptr; 1935 } 1936 1937 /// genBuiltinsDef: Generate the BuiltinsARM.def and BuiltinsAArch64.def 1938 /// declaration of builtins, checking for unique builtin declarations. 1939 void NeonEmitter::genBuiltinsDef(raw_ostream &OS, 1940 SmallVectorImpl<Intrinsic *> &Defs) { 1941 OS << "#ifdef GET_NEON_BUILTINS\n"; 1942 1943 // We only want to emit a builtin once, and we want to emit them in 1944 // alphabetical order, so use a std::set. 1945 std::set<std::string> Builtins; 1946 1947 for (auto *Def : Defs) { 1948 if (Def->hasBody()) 1949 continue; 1950 1951 std::string S = "BUILTIN(__builtin_neon_" + Def->getMangledName() + ", \""; 1952 1953 S += Def->getBuiltinTypeStr(); 1954 S += "\", \"n\")"; 1955 1956 Builtins.insert(S); 1957 } 1958 1959 for (auto &S : Builtins) 1960 OS << S << "\n"; 1961 OS << "#endif\n\n"; 1962 } 1963 1964 /// Generate the ARM and AArch64 overloaded type checking code for 1965 /// SemaChecking.cpp, checking for unique builtin declarations. 1966 void NeonEmitter::genOverloadTypeCheckCode(raw_ostream &OS, 1967 SmallVectorImpl<Intrinsic *> &Defs) { 1968 OS << "#ifdef GET_NEON_OVERLOAD_CHECK\n"; 1969 1970 // We record each overload check line before emitting because subsequent Inst 1971 // definitions may extend the number of permitted types (i.e. augment the 1972 // Mask). Use std::map to avoid sorting the table by hash number. 1973 struct OverloadInfo { 1974 uint64_t Mask; 1975 int PtrArgNum; 1976 bool HasConstPtr; 1977 OverloadInfo() : Mask(0ULL), PtrArgNum(0), HasConstPtr(false) {} 1978 }; 1979 std::map<std::string, OverloadInfo> OverloadMap; 1980 1981 for (auto *Def : Defs) { 1982 // If the def has a body (that is, it has Operation DAGs), it won't call 1983 // __builtin_neon_* so we don't need to generate a definition for it. 1984 if (Def->hasBody()) 1985 continue; 1986 // Functions which have a scalar argument cannot be overloaded, no need to 1987 // check them if we are emitting the type checking code. 1988 if (Def->protoHasScalar()) 1989 continue; 1990 1991 uint64_t Mask = 0ULL; 1992 Mask |= 1ULL << Def->getPolymorphicKeyType().getNeonEnum(); 1993 1994 // Check if the function has a pointer or const pointer argument. 1995 int PtrArgNum = -1; 1996 bool HasConstPtr = false; 1997 for (unsigned I = 0; I < Def->getNumParams(); ++I) { 1998 const auto &Type = Def->getParamType(I); 1999 if (Type.isPointer()) { 2000 PtrArgNum = I; 2001 HasConstPtr = Type.isConstPointer(); 2002 } 2003 } 2004 2005 // For sret builtins, adjust the pointer argument index. 2006 if (PtrArgNum >= 0 && Def->getReturnType().getNumVectors() > 1) 2007 PtrArgNum += 1; 2008 2009 std::string Name = Def->getName(); 2010 // Omit type checking for the pointer arguments of vld1_lane, vld1_dup, 2011 // and vst1_lane intrinsics. Using a pointer to the vector element 2012 // type with one of those operations causes codegen to select an aligned 2013 // load/store instruction. If you want an unaligned operation, 2014 // the pointer argument needs to have less alignment than element type, 2015 // so just accept any pointer type. 2016 if (Name == "vld1_lane" || Name == "vld1_dup" || Name == "vst1_lane") { 2017 PtrArgNum = -1; 2018 HasConstPtr = false; 2019 } 2020 2021 if (Mask) { 2022 std::string Name = Def->getMangledName(); 2023 OverloadMap.insert(std::make_pair(Name, OverloadInfo())); 2024 OverloadInfo &OI = OverloadMap[Name]; 2025 OI.Mask |= Mask; 2026 OI.PtrArgNum |= PtrArgNum; 2027 OI.HasConstPtr = HasConstPtr; 2028 } 2029 } 2030 2031 for (auto &I : OverloadMap) { 2032 OverloadInfo &OI = I.second; 2033 2034 OS << "case NEON::BI__builtin_neon_" << I.first << ": "; 2035 OS << "mask = 0x" << Twine::utohexstr(OI.Mask) << "ULL"; 2036 if (OI.PtrArgNum >= 0) 2037 OS << "; PtrArgNum = " << OI.PtrArgNum; 2038 if (OI.HasConstPtr) 2039 OS << "; HasConstPtr = true"; 2040 OS << "; break;\n"; 2041 } 2042 OS << "#endif\n\n"; 2043 } 2044 2045 void NeonEmitter::genIntrinsicRangeCheckCode(raw_ostream &OS, 2046 SmallVectorImpl<Intrinsic *> &Defs) { 2047 OS << "#ifdef GET_NEON_IMMEDIATE_CHECK\n"; 2048 2049 std::set<std::string> Emitted; 2050 2051 for (auto *Def : Defs) { 2052 if (Def->hasBody()) 2053 continue; 2054 // Functions which do not have an immediate do not need to have range 2055 // checking code emitted. 2056 if (!Def->hasImmediate()) 2057 continue; 2058 if (Emitted.find(Def->getMangledName()) != Emitted.end()) 2059 continue; 2060 2061 std::string LowerBound, UpperBound; 2062 2063 Record *R = Def->getRecord(); 2064 if (R->getValueAsBit("isVCVT_N")) { 2065 // VCVT between floating- and fixed-point values takes an immediate 2066 // in the range [1, 32) for f32 or [1, 64) for f64 or [1, 16) for f16. 2067 LowerBound = "1"; 2068 if (Def->getBaseType().getElementSizeInBits() == 16 || 2069 Def->getName().find('h') != std::string::npos) 2070 // VCVTh operating on FP16 intrinsics in range [1, 16) 2071 UpperBound = "15"; 2072 else if (Def->getBaseType().getElementSizeInBits() == 32) 2073 UpperBound = "31"; 2074 else 2075 UpperBound = "63"; 2076 } else if (R->getValueAsBit("isScalarShift")) { 2077 // Right shifts have an 'r' in the name, left shifts do not. Convert 2078 // instructions have the same bounds and right shifts. 2079 if (Def->getName().find('r') != std::string::npos || 2080 Def->getName().find("cvt") != std::string::npos) 2081 LowerBound = "1"; 2082 2083 UpperBound = utostr(Def->getReturnType().getElementSizeInBits() - 1); 2084 } else if (R->getValueAsBit("isShift")) { 2085 // Builtins which are overloaded by type will need to have their upper 2086 // bound computed at Sema time based on the type constant. 2087 2088 // Right shifts have an 'r' in the name, left shifts do not. 2089 if (Def->getName().find('r') != std::string::npos) 2090 LowerBound = "1"; 2091 UpperBound = "RFT(TV, true)"; 2092 } else if (Def->getClassKind(true) == ClassB) { 2093 // ClassB intrinsics have a type (and hence lane number) that is only 2094 // known at runtime. 2095 if (R->getValueAsBit("isLaneQ")) 2096 UpperBound = "RFT(TV, false, true)"; 2097 else 2098 UpperBound = "RFT(TV, false, false)"; 2099 } else { 2100 // The immediate generally refers to a lane in the preceding argument. 2101 assert(Def->getImmediateIdx() > 0); 2102 Type T = Def->getParamType(Def->getImmediateIdx() - 1); 2103 UpperBound = utostr(T.getNumElements() - 1); 2104 } 2105 2106 // Calculate the index of the immediate that should be range checked. 2107 unsigned Idx = Def->getNumParams(); 2108 if (Def->hasImmediate()) 2109 Idx = Def->getGeneratedParamIdx(Def->getImmediateIdx()); 2110 2111 OS << "case NEON::BI__builtin_neon_" << Def->getMangledName() << ": " 2112 << "i = " << Idx << ";"; 2113 if (!LowerBound.empty()) 2114 OS << " l = " << LowerBound << ";"; 2115 if (!UpperBound.empty()) 2116 OS << " u = " << UpperBound << ";"; 2117 OS << " break;\n"; 2118 2119 Emitted.insert(Def->getMangledName()); 2120 } 2121 2122 OS << "#endif\n\n"; 2123 } 2124 2125 /// runHeader - Emit a file with sections defining: 2126 /// 1. the NEON section of BuiltinsARM.def and BuiltinsAArch64.def. 2127 /// 2. the SemaChecking code for the type overload checking. 2128 /// 3. the SemaChecking code for validation of intrinsic immediate arguments. 2129 void NeonEmitter::runHeader(raw_ostream &OS) { 2130 std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst"); 2131 2132 SmallVector<Intrinsic *, 128> Defs; 2133 for (auto *R : RV) 2134 createIntrinsic(R, Defs); 2135 2136 // Generate shared BuiltinsXXX.def 2137 genBuiltinsDef(OS, Defs); 2138 2139 // Generate ARM overloaded type checking code for SemaChecking.cpp 2140 genOverloadTypeCheckCode(OS, Defs); 2141 2142 // Generate ARM range checking code for shift/lane immediates. 2143 genIntrinsicRangeCheckCode(OS, Defs); 2144 } 2145 2146 /// run - Read the records in arm_neon.td and output arm_neon.h. arm_neon.h 2147 /// is comprised of type definitions and function declarations. 2148 void NeonEmitter::run(raw_ostream &OS) { 2149 OS << "/*===---- arm_neon.h - ARM Neon intrinsics " 2150 "------------------------------" 2151 "---===\n" 2152 " *\n" 2153 " * Permission is hereby granted, free of charge, to any person " 2154 "obtaining " 2155 "a copy\n" 2156 " * of this software and associated documentation files (the " 2157 "\"Software\")," 2158 " to deal\n" 2159 " * in the Software without restriction, including without limitation " 2160 "the " 2161 "rights\n" 2162 " * to use, copy, modify, merge, publish, distribute, sublicense, " 2163 "and/or sell\n" 2164 " * copies of the Software, and to permit persons to whom the Software " 2165 "is\n" 2166 " * furnished to do so, subject to the following conditions:\n" 2167 " *\n" 2168 " * The above copyright notice and this permission notice shall be " 2169 "included in\n" 2170 " * all copies or substantial portions of the Software.\n" 2171 " *\n" 2172 " * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, " 2173 "EXPRESS OR\n" 2174 " * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF " 2175 "MERCHANTABILITY,\n" 2176 " * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT " 2177 "SHALL THE\n" 2178 " * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR " 2179 "OTHER\n" 2180 " * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, " 2181 "ARISING FROM,\n" 2182 " * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER " 2183 "DEALINGS IN\n" 2184 " * THE SOFTWARE.\n" 2185 " *\n" 2186 " *===-----------------------------------------------------------------" 2187 "---" 2188 "---===\n" 2189 " */\n\n"; 2190 2191 OS << "#ifndef __ARM_NEON_H\n"; 2192 OS << "#define __ARM_NEON_H\n\n"; 2193 2194 OS << "#if !defined(__ARM_NEON)\n"; 2195 OS << "#error \"NEON support not enabled\"\n"; 2196 OS << "#endif\n\n"; 2197 2198 OS << "#include <stdint.h>\n\n"; 2199 2200 // Emit NEON-specific scalar typedefs. 2201 OS << "typedef float float32_t;\n"; 2202 OS << "typedef __fp16 float16_t;\n"; 2203 2204 OS << "#ifdef __aarch64__\n"; 2205 OS << "typedef double float64_t;\n"; 2206 OS << "#endif\n\n"; 2207 2208 // For now, signedness of polynomial types depends on target 2209 OS << "#ifdef __aarch64__\n"; 2210 OS << "typedef uint8_t poly8_t;\n"; 2211 OS << "typedef uint16_t poly16_t;\n"; 2212 OS << "typedef uint64_t poly64_t;\n"; 2213 OS << "typedef __uint128_t poly128_t;\n"; 2214 OS << "#else\n"; 2215 OS << "typedef int8_t poly8_t;\n"; 2216 OS << "typedef int16_t poly16_t;\n"; 2217 OS << "#endif\n"; 2218 2219 // Emit Neon vector typedefs. 2220 std::string TypedefTypes( 2221 "cQcsQsiQilQlUcQUcUsQUsUiQUiUlQUlhQhfQfdQdPcQPcPsQPsPlQPl"); 2222 std::vector<TypeSpec> TDTypeVec = TypeSpec::fromTypeSpecs(TypedefTypes); 2223 2224 // Emit vector typedefs. 2225 bool InIfdef = false; 2226 for (auto &TS : TDTypeVec) { 2227 bool IsA64 = false; 2228 Type T(TS, "."); 2229 if (T.isDouble() || (T.isPoly() && T.getElementSizeInBits() == 64)) 2230 IsA64 = true; 2231 2232 if (InIfdef && !IsA64) { 2233 OS << "#endif\n"; 2234 InIfdef = false; 2235 } 2236 if (!InIfdef && IsA64) { 2237 OS << "#ifdef __aarch64__\n"; 2238 InIfdef = true; 2239 } 2240 2241 if (T.isPoly()) 2242 OS << "typedef __attribute__((neon_polyvector_type("; 2243 else 2244 OS << "typedef __attribute__((neon_vector_type("; 2245 2246 Type T2 = T; 2247 T2.makeScalar(); 2248 OS << T.getNumElements() << "))) "; 2249 OS << T2.str(); 2250 OS << " " << T.str() << ";\n"; 2251 } 2252 if (InIfdef) 2253 OS << "#endif\n"; 2254 OS << "\n"; 2255 2256 // Emit struct typedefs. 2257 InIfdef = false; 2258 for (unsigned NumMembers = 2; NumMembers <= 4; ++NumMembers) { 2259 for (auto &TS : TDTypeVec) { 2260 bool IsA64 = false; 2261 Type T(TS, "."); 2262 if (T.isDouble() || (T.isPoly() && T.getElementSizeInBits() == 64)) 2263 IsA64 = true; 2264 2265 if (InIfdef && !IsA64) { 2266 OS << "#endif\n"; 2267 InIfdef = false; 2268 } 2269 if (!InIfdef && IsA64) { 2270 OS << "#ifdef __aarch64__\n"; 2271 InIfdef = true; 2272 } 2273 2274 const char Mods[] = { static_cast<char>('2' + (NumMembers - 2)), 0}; 2275 Type VT(TS, Mods); 2276 OS << "typedef struct " << VT.str() << " {\n"; 2277 OS << " " << T.str() << " val"; 2278 OS << "[" << NumMembers << "]"; 2279 OS << ";\n} "; 2280 OS << VT.str() << ";\n"; 2281 OS << "\n"; 2282 } 2283 } 2284 if (InIfdef) 2285 OS << "#endif\n"; 2286 OS << "\n"; 2287 2288 OS << "#define __ai static __inline__ __attribute__((__always_inline__, " 2289 "__nodebug__))\n\n"; 2290 2291 SmallVector<Intrinsic *, 128> Defs; 2292 std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst"); 2293 for (auto *R : RV) 2294 createIntrinsic(R, Defs); 2295 2296 for (auto *I : Defs) 2297 I->indexBody(); 2298 2299 llvm::stable_sort(Defs, llvm::deref<std::less<>>()); 2300 2301 // Only emit a def when its requirements have been met. 2302 // FIXME: This loop could be made faster, but it's fast enough for now. 2303 bool MadeProgress = true; 2304 std::string InGuard; 2305 while (!Defs.empty() && MadeProgress) { 2306 MadeProgress = false; 2307 2308 for (SmallVector<Intrinsic *, 128>::iterator I = Defs.begin(); 2309 I != Defs.end(); /*No step*/) { 2310 bool DependenciesSatisfied = true; 2311 for (auto *II : (*I)->getDependencies()) { 2312 if (llvm::is_contained(Defs, II)) 2313 DependenciesSatisfied = false; 2314 } 2315 if (!DependenciesSatisfied) { 2316 // Try the next one. 2317 ++I; 2318 continue; 2319 } 2320 2321 // Emit #endif/#if pair if needed. 2322 if ((*I)->getGuard() != InGuard) { 2323 if (!InGuard.empty()) 2324 OS << "#endif\n"; 2325 InGuard = (*I)->getGuard(); 2326 if (!InGuard.empty()) 2327 OS << "#if " << InGuard << "\n"; 2328 } 2329 2330 // Actually generate the intrinsic code. 2331 OS << (*I)->generate(); 2332 2333 MadeProgress = true; 2334 I = Defs.erase(I); 2335 } 2336 } 2337 assert(Defs.empty() && "Some requirements were not satisfied!"); 2338 if (!InGuard.empty()) 2339 OS << "#endif\n"; 2340 2341 OS << "\n"; 2342 OS << "#undef __ai\n\n"; 2343 OS << "#endif /* __ARM_NEON_H */\n"; 2344 } 2345 2346 /// run - Read the records in arm_fp16.td and output arm_fp16.h. arm_fp16.h 2347 /// is comprised of type definitions and function declarations. 2348 void NeonEmitter::runFP16(raw_ostream &OS) { 2349 OS << "/*===---- arm_fp16.h - ARM FP16 intrinsics " 2350 "------------------------------" 2351 "---===\n" 2352 " *\n" 2353 " * Permission is hereby granted, free of charge, to any person " 2354 "obtaining a copy\n" 2355 " * of this software and associated documentation files (the " 2356 "\"Software\"), to deal\n" 2357 " * in the Software without restriction, including without limitation " 2358 "the rights\n" 2359 " * to use, copy, modify, merge, publish, distribute, sublicense, " 2360 "and/or sell\n" 2361 " * copies of the Software, and to permit persons to whom the Software " 2362 "is\n" 2363 " * furnished to do so, subject to the following conditions:\n" 2364 " *\n" 2365 " * The above copyright notice and this permission notice shall be " 2366 "included in\n" 2367 " * all copies or substantial portions of the Software.\n" 2368 " *\n" 2369 " * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, " 2370 "EXPRESS OR\n" 2371 " * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF " 2372 "MERCHANTABILITY,\n" 2373 " * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT " 2374 "SHALL THE\n" 2375 " * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR " 2376 "OTHER\n" 2377 " * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, " 2378 "ARISING FROM,\n" 2379 " * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER " 2380 "DEALINGS IN\n" 2381 " * THE SOFTWARE.\n" 2382 " *\n" 2383 " *===-----------------------------------------------------------------" 2384 "---" 2385 "---===\n" 2386 " */\n\n"; 2387 2388 OS << "#ifndef __ARM_FP16_H\n"; 2389 OS << "#define __ARM_FP16_H\n\n"; 2390 2391 OS << "#include <stdint.h>\n\n"; 2392 2393 OS << "typedef __fp16 float16_t;\n"; 2394 2395 OS << "#define __ai static __inline__ __attribute__((__always_inline__, " 2396 "__nodebug__))\n\n"; 2397 2398 SmallVector<Intrinsic *, 128> Defs; 2399 std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst"); 2400 for (auto *R : RV) 2401 createIntrinsic(R, Defs); 2402 2403 for (auto *I : Defs) 2404 I->indexBody(); 2405 2406 llvm::stable_sort(Defs, llvm::deref<std::less<>>()); 2407 2408 // Only emit a def when its requirements have been met. 2409 // FIXME: This loop could be made faster, but it's fast enough for now. 2410 bool MadeProgress = true; 2411 std::string InGuard; 2412 while (!Defs.empty() && MadeProgress) { 2413 MadeProgress = false; 2414 2415 for (SmallVector<Intrinsic *, 128>::iterator I = Defs.begin(); 2416 I != Defs.end(); /*No step*/) { 2417 bool DependenciesSatisfied = true; 2418 for (auto *II : (*I)->getDependencies()) { 2419 if (llvm::is_contained(Defs, II)) 2420 DependenciesSatisfied = false; 2421 } 2422 if (!DependenciesSatisfied) { 2423 // Try the next one. 2424 ++I; 2425 continue; 2426 } 2427 2428 // Emit #endif/#if pair if needed. 2429 if ((*I)->getGuard() != InGuard) { 2430 if (!InGuard.empty()) 2431 OS << "#endif\n"; 2432 InGuard = (*I)->getGuard(); 2433 if (!InGuard.empty()) 2434 OS << "#if " << InGuard << "\n"; 2435 } 2436 2437 // Actually generate the intrinsic code. 2438 OS << (*I)->generate(); 2439 2440 MadeProgress = true; 2441 I = Defs.erase(I); 2442 } 2443 } 2444 assert(Defs.empty() && "Some requirements were not satisfied!"); 2445 if (!InGuard.empty()) 2446 OS << "#endif\n"; 2447 2448 OS << "\n"; 2449 OS << "#undef __ai\n\n"; 2450 OS << "#endif /* __ARM_FP16_H */\n"; 2451 } 2452 2453 void clang::EmitNeon(RecordKeeper &Records, raw_ostream &OS) { 2454 NeonEmitter(Records).run(OS); 2455 } 2456 2457 void clang::EmitFP16(RecordKeeper &Records, raw_ostream &OS) { 2458 NeonEmitter(Records).runFP16(OS); 2459 } 2460 2461 void clang::EmitNeonSema(RecordKeeper &Records, raw_ostream &OS) { 2462 NeonEmitter(Records).runHeader(OS); 2463 } 2464 2465 void clang::EmitNeonTest(RecordKeeper &Records, raw_ostream &OS) { 2466 llvm_unreachable("Neon test generation no longer implemented!"); 2467 } 2468