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