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.  A complete set of tests
22 // for Neon intrinsics can be generated by calling the runTests() entry point.
23 //
24 //===----------------------------------------------------------------------===//
25 
26 #include "llvm/ADT/DenseMap.h"
27 #include "llvm/ADT/SmallString.h"
28 #include "llvm/ADT/SmallVector.h"
29 #include "llvm/ADT/StringExtras.h"
30 #include "llvm/ADT/StringMap.h"
31 #include "llvm/Support/ErrorHandling.h"
32 #include "llvm/TableGen/Error.h"
33 #include "llvm/TableGen/Record.h"
34 #include "llvm/TableGen/TableGenBackend.h"
35 #include <string>
36 using namespace llvm;
37 
38 enum OpKind {
39   OpNone,
40   OpUnavailable,
41   OpAdd,
42   OpAddl,
43   OpAddlHi,
44   OpAddw,
45   OpAddwHi,
46   OpSub,
47   OpSubl,
48   OpSublHi,
49   OpSubw,
50   OpSubwHi,
51   OpMul,
52   OpMla,
53   OpMlal,
54   OpMullHi,
55   OpMullHiP64,
56   OpMullHiN,
57   OpMlalHi,
58   OpMlalHiN,
59   OpMls,
60   OpMlsl,
61   OpMlslHi,
62   OpMlslHiN,
63   OpMulN,
64   OpMlaN,
65   OpMlsN,
66   OpFMlaN,
67   OpFMlsN,
68   OpMlalN,
69   OpMlslN,
70   OpMulLane,
71   OpMulXLane,
72   OpMullLane,
73   OpMullHiLane,
74   OpMlaLane,
75   OpMlsLane,
76   OpMlalLane,
77   OpMlalHiLane,
78   OpMlslLane,
79   OpMlslHiLane,
80   OpQDMullLane,
81   OpQDMullHiLane,
82   OpQDMlalLane,
83   OpQDMlalHiLane,
84   OpQDMlslLane,
85   OpQDMlslHiLane,
86   OpQDMulhLane,
87   OpQRDMulhLane,
88   OpFMSLane,
89   OpFMSLaneQ,
90   OpTrn1,
91   OpZip1,
92   OpUzp1,
93   OpTrn2,
94   OpZip2,
95   OpUzp2,
96   OpEq,
97   OpGe,
98   OpLe,
99   OpGt,
100   OpLt,
101   OpNeg,
102   OpNot,
103   OpAnd,
104   OpOr,
105   OpXor,
106   OpAndNot,
107   OpOrNot,
108   OpCast,
109   OpConcat,
110   OpDup,
111   OpDupLane,
112   OpHi,
113   OpLo,
114   OpSelect,
115   OpRev16,
116   OpRev32,
117   OpRev64,
118   OpXtnHi,
119   OpSqxtunHi,
120   OpQxtnHi,
121   OpFcvtnHi,
122   OpFcvtlHi,
123   OpFcvtxnHi,
124   OpReinterpret,
125   OpAddhnHi,
126   OpRAddhnHi,
127   OpSubhnHi,
128   OpRSubhnHi,
129   OpAbdl,
130   OpAbdlHi,
131   OpAba,
132   OpAbal,
133   OpAbalHi,
134   OpQDMullHi,
135   OpQDMullHiN,
136   OpQDMlalHi,
137   OpQDMlalHiN,
138   OpQDMlslHi,
139   OpQDMlslHiN,
140   OpDiv,
141   OpLongHi,
142   OpNarrowHi,
143   OpMovlHi,
144   OpCopyLane,
145   OpCopyQLane,
146   OpCopyLaneQ,
147   OpScalarMulLane,
148   OpScalarMulLaneQ,
149   OpScalarMulXLane,
150   OpScalarMulXLaneQ,
151   OpScalarVMulXLane,
152   OpScalarVMulXLaneQ,
153   OpScalarQDMullLane,
154   OpScalarQDMullLaneQ,
155   OpScalarQDMulHiLane,
156   OpScalarQDMulHiLaneQ,
157   OpScalarQRDMulHiLane,
158   OpScalarQRDMulHiLaneQ,
159   OpScalarGetLane,
160   OpScalarSetLane
161 };
162 
163 enum ClassKind {
164   ClassNone,
165   ClassI,           // generic integer instruction, e.g., "i8" suffix
166   ClassS,           // signed/unsigned/poly, e.g., "s8", "u8" or "p8" suffix
167   ClassW,           // width-specific instruction, e.g., "8" suffix
168   ClassB,           // bitcast arguments with enum argument to specify type
169   ClassL,           // Logical instructions which are op instructions
170                     // but we need to not emit any suffix for in our
171                     // tests.
172   ClassNoTest       // Instructions which we do not test since they are
173                     // not TRUE instructions.
174 };
175 
176 /// NeonTypeFlags - Flags to identify the types for overloaded Neon
177 /// builtins.  These must be kept in sync with the flags in
178 /// include/clang/Basic/TargetBuiltins.h.
179 namespace {
180 class NeonTypeFlags {
181   enum {
182     EltTypeMask = 0xf,
183     UnsignedFlag = 0x10,
184     QuadFlag = 0x20
185   };
186   uint32_t Flags;
187 
188 public:
189   enum EltType {
190     Int8,
191     Int16,
192     Int32,
193     Int64,
194     Poly8,
195     Poly16,
196     Poly64,
197     Poly128,
198     Float16,
199     Float32,
200     Float64
201   };
202 
203   NeonTypeFlags(unsigned F) : Flags(F) {}
204   NeonTypeFlags(EltType ET, bool IsUnsigned, bool IsQuad) : Flags(ET) {
205     if (IsUnsigned)
206       Flags |= UnsignedFlag;
207     if (IsQuad)
208       Flags |= QuadFlag;
209   }
210 
211   uint32_t getFlags() const { return Flags; }
212 };
213 } // end anonymous namespace
214 
215 namespace {
216 class NeonEmitter {
217   RecordKeeper &Records;
218   StringMap<OpKind> OpMap;
219   DenseMap<Record*, ClassKind> ClassMap;
220 
221 public:
222   NeonEmitter(RecordKeeper &R) : Records(R) {
223     OpMap["OP_NONE"]  = OpNone;
224     OpMap["OP_UNAVAILABLE"] = OpUnavailable;
225     OpMap["OP_ADD"]   = OpAdd;
226     OpMap["OP_ADDL"]  = OpAddl;
227     OpMap["OP_ADDLHi"] = OpAddlHi;
228     OpMap["OP_ADDW"]  = OpAddw;
229     OpMap["OP_ADDWHi"] = OpAddwHi;
230     OpMap["OP_SUB"]   = OpSub;
231     OpMap["OP_SUBL"]  = OpSubl;
232     OpMap["OP_SUBLHi"] = OpSublHi;
233     OpMap["OP_SUBW"]  = OpSubw;
234     OpMap["OP_SUBWHi"] = OpSubwHi;
235     OpMap["OP_MUL"]   = OpMul;
236     OpMap["OP_MLA"]   = OpMla;
237     OpMap["OP_MLAL"]  = OpMlal;
238     OpMap["OP_MULLHi"]  = OpMullHi;
239     OpMap["OP_MULLHi_P64"]  = OpMullHiP64;
240     OpMap["OP_MULLHi_N"]  = OpMullHiN;
241     OpMap["OP_MLALHi"]  = OpMlalHi;
242     OpMap["OP_MLALHi_N"]  = OpMlalHiN;
243     OpMap["OP_MLS"]   = OpMls;
244     OpMap["OP_MLSL"]  = OpMlsl;
245     OpMap["OP_MLSLHi"] = OpMlslHi;
246     OpMap["OP_MLSLHi_N"] = OpMlslHiN;
247     OpMap["OP_MUL_N"] = OpMulN;
248     OpMap["OP_MLA_N"] = OpMlaN;
249     OpMap["OP_MLS_N"] = OpMlsN;
250     OpMap["OP_FMLA_N"] = OpFMlaN;
251     OpMap["OP_FMLS_N"] = OpFMlsN;
252     OpMap["OP_MLAL_N"] = OpMlalN;
253     OpMap["OP_MLSL_N"] = OpMlslN;
254     OpMap["OP_MUL_LN"]= OpMulLane;
255     OpMap["OP_MULX_LN"]= OpMulXLane;
256     OpMap["OP_MULL_LN"] = OpMullLane;
257     OpMap["OP_MULLHi_LN"] = OpMullHiLane;
258     OpMap["OP_MLA_LN"]= OpMlaLane;
259     OpMap["OP_MLS_LN"]= OpMlsLane;
260     OpMap["OP_MLAL_LN"] = OpMlalLane;
261     OpMap["OP_MLALHi_LN"] = OpMlalHiLane;
262     OpMap["OP_MLSL_LN"] = OpMlslLane;
263     OpMap["OP_MLSLHi_LN"] = OpMlslHiLane;
264     OpMap["OP_QDMULL_LN"] = OpQDMullLane;
265     OpMap["OP_QDMULLHi_LN"] = OpQDMullHiLane;
266     OpMap["OP_QDMLAL_LN"] = OpQDMlalLane;
267     OpMap["OP_QDMLALHi_LN"] = OpQDMlalHiLane;
268     OpMap["OP_QDMLSL_LN"] = OpQDMlslLane;
269     OpMap["OP_QDMLSLHi_LN"] = OpQDMlslHiLane;
270     OpMap["OP_QDMULH_LN"] = OpQDMulhLane;
271     OpMap["OP_QRDMULH_LN"] = OpQRDMulhLane;
272     OpMap["OP_FMS_LN"] = OpFMSLane;
273     OpMap["OP_FMS_LNQ"] = OpFMSLaneQ;
274     OpMap["OP_TRN1"]  = OpTrn1;
275     OpMap["OP_ZIP1"]  = OpZip1;
276     OpMap["OP_UZP1"]  = OpUzp1;
277     OpMap["OP_TRN2"]  = OpTrn2;
278     OpMap["OP_ZIP2"]  = OpZip2;
279     OpMap["OP_UZP2"]  = OpUzp2;
280     OpMap["OP_EQ"]    = OpEq;
281     OpMap["OP_GE"]    = OpGe;
282     OpMap["OP_LE"]    = OpLe;
283     OpMap["OP_GT"]    = OpGt;
284     OpMap["OP_LT"]    = OpLt;
285     OpMap["OP_NEG"]   = OpNeg;
286     OpMap["OP_NOT"]   = OpNot;
287     OpMap["OP_AND"]   = OpAnd;
288     OpMap["OP_OR"]    = OpOr;
289     OpMap["OP_XOR"]   = OpXor;
290     OpMap["OP_ANDN"]  = OpAndNot;
291     OpMap["OP_ORN"]   = OpOrNot;
292     OpMap["OP_CAST"]  = OpCast;
293     OpMap["OP_CONC"]  = OpConcat;
294     OpMap["OP_HI"]    = OpHi;
295     OpMap["OP_LO"]    = OpLo;
296     OpMap["OP_DUP"]   = OpDup;
297     OpMap["OP_DUP_LN"] = OpDupLane;
298     OpMap["OP_SEL"]   = OpSelect;
299     OpMap["OP_REV16"] = OpRev16;
300     OpMap["OP_REV32"] = OpRev32;
301     OpMap["OP_REV64"] = OpRev64;
302     OpMap["OP_XTN"] = OpXtnHi;
303     OpMap["OP_SQXTUN"] = OpSqxtunHi;
304     OpMap["OP_QXTN"] = OpQxtnHi;
305     OpMap["OP_VCVT_NA_HI"] = OpFcvtnHi;
306     OpMap["OP_VCVT_EX_HI"] = OpFcvtlHi;
307     OpMap["OP_VCVTX_HI"] = OpFcvtxnHi;
308     OpMap["OP_REINT"] = OpReinterpret;
309     OpMap["OP_ADDHNHi"] = OpAddhnHi;
310     OpMap["OP_RADDHNHi"] = OpRAddhnHi;
311     OpMap["OP_SUBHNHi"] = OpSubhnHi;
312     OpMap["OP_RSUBHNHi"] = OpRSubhnHi;
313     OpMap["OP_ABDL"]  = OpAbdl;
314     OpMap["OP_ABDLHi"] = OpAbdlHi;
315     OpMap["OP_ABA"]   = OpAba;
316     OpMap["OP_ABAL"]  = OpAbal;
317     OpMap["OP_ABALHi"] = OpAbalHi;
318     OpMap["OP_QDMULLHi"] = OpQDMullHi;
319     OpMap["OP_QDMULLHi_N"] = OpQDMullHiN;
320     OpMap["OP_QDMLALHi"] = OpQDMlalHi;
321     OpMap["OP_QDMLALHi_N"] = OpQDMlalHiN;
322     OpMap["OP_QDMLSLHi"] = OpQDMlslHi;
323     OpMap["OP_QDMLSLHi_N"] = OpQDMlslHiN;
324     OpMap["OP_DIV"] = OpDiv;
325     OpMap["OP_LONG_HI"] = OpLongHi;
326     OpMap["OP_NARROW_HI"] = OpNarrowHi;
327     OpMap["OP_MOVL_HI"] = OpMovlHi;
328     OpMap["OP_COPY_LN"] = OpCopyLane;
329     OpMap["OP_COPYQ_LN"] = OpCopyQLane;
330     OpMap["OP_COPY_LNQ"] = OpCopyLaneQ;
331     OpMap["OP_SCALAR_MUL_LN"]= OpScalarMulLane;
332     OpMap["OP_SCALAR_MUL_LNQ"]= OpScalarMulLaneQ;
333     OpMap["OP_SCALAR_MULX_LN"]= OpScalarMulXLane;
334     OpMap["OP_SCALAR_MULX_LNQ"]= OpScalarMulXLaneQ;
335     OpMap["OP_SCALAR_VMULX_LN"]= OpScalarVMulXLane;
336     OpMap["OP_SCALAR_VMULX_LNQ"]= OpScalarVMulXLaneQ;
337     OpMap["OP_SCALAR_QDMULL_LN"] = OpScalarQDMullLane;
338     OpMap["OP_SCALAR_QDMULL_LNQ"] = OpScalarQDMullLaneQ;
339     OpMap["OP_SCALAR_QDMULH_LN"] = OpScalarQDMulHiLane;
340     OpMap["OP_SCALAR_QDMULH_LNQ"] = OpScalarQDMulHiLaneQ;
341     OpMap["OP_SCALAR_QRDMULH_LN"] = OpScalarQRDMulHiLane;
342     OpMap["OP_SCALAR_QRDMULH_LNQ"] = OpScalarQRDMulHiLaneQ;
343     OpMap["OP_SCALAR_GET_LN"] = OpScalarGetLane;
344     OpMap["OP_SCALAR_SET_LN"] = OpScalarSetLane;
345 
346     Record *SI = R.getClass("SInst");
347     Record *II = R.getClass("IInst");
348     Record *WI = R.getClass("WInst");
349     Record *SOpI = R.getClass("SOpInst");
350     Record *IOpI = R.getClass("IOpInst");
351     Record *WOpI = R.getClass("WOpInst");
352     Record *LOpI = R.getClass("LOpInst");
353     Record *NoTestOpI = R.getClass("NoTestOpInst");
354 
355     ClassMap[SI] = ClassS;
356     ClassMap[II] = ClassI;
357     ClassMap[WI] = ClassW;
358     ClassMap[SOpI] = ClassS;
359     ClassMap[IOpI] = ClassI;
360     ClassMap[WOpI] = ClassW;
361     ClassMap[LOpI] = ClassL;
362     ClassMap[NoTestOpI] = ClassNoTest;
363   }
364 
365   // run - Emit arm_neon.h.inc
366   void run(raw_ostream &o);
367 
368   // runHeader - Emit all the __builtin prototypes used in arm_neon.h
369   void runHeader(raw_ostream &o);
370 
371   // runTests - Emit tests for all the Neon intrinsics.
372   void runTests(raw_ostream &o);
373 
374 private:
375   void emitIntrinsic(raw_ostream &OS, Record *R,
376                      StringMap<ClassKind> &EmittedMap);
377   void genBuiltinsDef(raw_ostream &OS);
378   void genOverloadTypeCheckCode(raw_ostream &OS,
379                                 StringMap<ClassKind> &A64IntrinsicMap,
380                                 bool isA64TypeCheck);
381   void genIntrinsicRangeCheckCode(raw_ostream &OS,
382                                   StringMap<ClassKind> &A64IntrinsicMap,
383                                   bool isA64RangeCheck);
384   void genTargetTest(raw_ostream &OS, StringMap<OpKind> &EmittedMap,
385                      bool isA64TestGen);
386 };
387 } // end anonymous namespace
388 
389 /// ParseTypes - break down a string such as "fQf" into a vector of StringRefs,
390 /// which each StringRef representing a single type declared in the string.
391 /// for "fQf" we would end up with 2 StringRefs, "f", and "Qf", representing
392 /// 2xfloat and 4xfloat respectively.
393 static void ParseTypes(Record *r, std::string &s,
394                        SmallVectorImpl<StringRef> &TV) {
395   const char *data = s.data();
396   int len = 0;
397 
398   for (unsigned i = 0, e = s.size(); i != e; ++i, ++len) {
399     if (data[len] == 'P' || data[len] == 'Q' || data[len] == 'U'
400                          || data[len] == 'H' || data[len] == 'S')
401       continue;
402 
403     switch (data[len]) {
404       case 'c':
405       case 's':
406       case 'i':
407       case 'l':
408       case 'k':
409       case 'h':
410       case 'f':
411       case 'd':
412         break;
413       default:
414         PrintFatalError(r->getLoc(),
415                       "Unexpected letter: " + std::string(data + len, 1));
416     }
417     TV.push_back(StringRef(data, len + 1));
418     data += len + 1;
419     len = -1;
420   }
421 }
422 
423 /// Widen - Convert a type code into the next wider type.  char -> short,
424 /// short -> int, etc.
425 static char Widen(const char t) {
426   switch (t) {
427     case 'c':
428       return 's';
429     case 's':
430       return 'i';
431     case 'i':
432       return 'l';
433     case 'l':
434       return 'k';
435     case 'h':
436       return 'f';
437     case 'f':
438       return 'd';
439     default:
440       PrintFatalError("unhandled type in widen!");
441   }
442 }
443 
444 /// Narrow - Convert a type code into the next smaller type.  short -> char,
445 /// float -> half float, etc.
446 static char Narrow(const char t) {
447   switch (t) {
448     case 's':
449       return 'c';
450     case 'i':
451       return 's';
452     case 'l':
453       return 'i';
454     case 'k':
455       return 'l';
456     case 'f':
457       return 'h';
458     case 'd':
459       return 'f';
460     default:
461       PrintFatalError("unhandled type in narrow!");
462   }
463 }
464 
465 static std::string GetNarrowTypestr(StringRef ty)
466 {
467   std::string s;
468   for (size_t i = 0, end = ty.size(); i < end; i++) {
469     switch (ty[i]) {
470       case 's':
471         s += 'c';
472         break;
473       case 'i':
474         s += 's';
475         break;
476       case 'l':
477         s += 'i';
478         break;
479       case 'k':
480         s += 'l';
481         break;
482       default:
483         s += ty[i];
484         break;
485     }
486   }
487 
488   return s;
489 }
490 
491 /// For a particular StringRef, return the base type code, and whether it has
492 /// the quad-vector, polynomial, or unsigned modifiers set.
493 static char ClassifyType(StringRef ty, bool &quad, bool &poly, bool &usgn) {
494   unsigned off = 0;
495   // ignore scalar.
496   if (ty[off] == 'S') {
497     ++off;
498   }
499   // remember quad.
500   if (ty[off] == 'Q' || ty[off] == 'H') {
501     quad = true;
502     ++off;
503   }
504 
505   // remember poly.
506   if (ty[off] == 'P') {
507     poly = true;
508     ++off;
509   }
510 
511   // remember unsigned.
512   if (ty[off] == 'U') {
513     usgn = true;
514     ++off;
515   }
516 
517   // base type to get the type string for.
518   return ty[off];
519 }
520 
521 /// ModType - Transform a type code and its modifiers based on a mod code. The
522 /// mod code definitions may be found at the top of arm_neon.td.
523 static char ModType(const char mod, char type, bool &quad, bool &poly,
524                     bool &usgn, bool &scal, bool &cnst, bool &pntr) {
525   switch (mod) {
526     case 't':
527       if (poly) {
528         poly = false;
529         usgn = true;
530       }
531       break;
532     case 'b':
533       scal = true;
534     case 'u':
535       usgn = true;
536       poly = false;
537       if (type == 'f')
538         type = 'i';
539       if (type == 'd')
540         type = 'l';
541       break;
542     case '$':
543       scal = true;
544     case 'x':
545       usgn = false;
546       poly = false;
547       if (type == 'f')
548         type = 'i';
549       if (type == 'd')
550         type = 'l';
551       break;
552     case 'o':
553       scal = true;
554       type = 'd';
555       usgn = false;
556       break;
557     case 'y':
558       scal = true;
559     case 'f':
560       if (type == 'h')
561         quad = true;
562       type = 'f';
563       usgn = false;
564       break;
565     case 'F':
566       type = 'd';
567       usgn = false;
568       break;
569     case 'g':
570       quad = false;
571       break;
572     case 'B':
573     case 'C':
574     case 'D':
575     case 'j':
576       quad = true;
577       break;
578     case 'w':
579       type = Widen(type);
580       quad = true;
581       break;
582     case 'n':
583       type = Widen(type);
584       break;
585     case 'i':
586       type = 'i';
587       scal = true;
588       break;
589     case 'l':
590       type = 'l';
591       scal = true;
592       usgn = true;
593       break;
594     case 'z':
595       type = Narrow(type);
596       scal = true;
597       break;
598     case 'r':
599       type = Widen(type);
600       scal = true;
601       break;
602     case 's':
603     case 'a':
604       scal = true;
605       break;
606     case 'k':
607       quad = true;
608       break;
609     case 'c':
610       cnst = true;
611     case 'p':
612       pntr = true;
613       scal = true;
614       break;
615     case 'h':
616       type = Narrow(type);
617       if (type == 'h')
618         quad = false;
619       break;
620     case 'q':
621       type = Narrow(type);
622       quad = true;
623       break;
624     case 'e':
625       type = Narrow(type);
626       usgn = true;
627       break;
628     case 'm':
629       type = Narrow(type);
630       quad = false;
631       break;
632     default:
633       break;
634   }
635   return type;
636 }
637 
638 static bool IsMultiVecProto(const char p) {
639   return ((p >= '2' && p <= '4') || (p >= 'B' && p <= 'D'));
640 }
641 
642 /// TypeString - for a modifier and type, generate the name of the typedef for
643 /// that type.  QUc -> uint8x8_t.
644 static std::string TypeString(const char mod, StringRef typestr) {
645   bool quad = false;
646   bool poly = false;
647   bool usgn = false;
648   bool scal = false;
649   bool cnst = false;
650   bool pntr = false;
651 
652   if (mod == 'v')
653     return "void";
654   if (mod == 'i')
655     return "int";
656 
657   // base type to get the type string for.
658   char type = ClassifyType(typestr, quad, poly, usgn);
659 
660   // Based on the modifying character, change the type and width if necessary.
661   type = ModType(mod, type, quad, poly, usgn, scal, cnst, pntr);
662 
663   SmallString<128> s;
664 
665   if (usgn)
666     s.push_back('u');
667 
668   switch (type) {
669     case 'c':
670       s += poly ? "poly8" : "int8";
671       if (scal)
672         break;
673       s += quad ? "x16" : "x8";
674       break;
675     case 's':
676       s += poly ? "poly16" : "int16";
677       if (scal)
678         break;
679       s += quad ? "x8" : "x4";
680       break;
681     case 'i':
682       s += "int32";
683       if (scal)
684         break;
685       s += quad ? "x4" : "x2";
686       break;
687     case 'l':
688       s += (poly && !usgn)? "poly64" : "int64";
689       if (scal)
690         break;
691       s += quad ? "x2" : "x1";
692       break;
693     case 'k':
694       s += "poly128";
695       break;
696     case 'h':
697       s += "float16";
698       if (scal)
699         break;
700       s += quad ? "x8" : "x4";
701       break;
702     case 'f':
703       s += "float32";
704       if (scal)
705         break;
706       s += quad ? "x4" : "x2";
707       break;
708     case 'd':
709       s += "float64";
710       if (scal)
711         break;
712       s += quad ? "x2" : "x1";
713       break;
714 
715     default:
716       PrintFatalError("unhandled type!");
717   }
718 
719   if (mod == '2' || mod == 'B')
720     s += "x2";
721   if (mod == '3' || mod == 'C')
722     s += "x3";
723   if (mod == '4' || mod == 'D')
724     s += "x4";
725 
726   // Append _t, finishing the type string typedef type.
727   s += "_t";
728 
729   if (cnst)
730     s += " const";
731 
732   if (pntr)
733     s += " *";
734 
735   return s.str();
736 }
737 
738 /// BuiltinTypeString - for a modifier and type, generate the clang
739 /// BuiltinsARM.def prototype code for the function.  See the top of clang's
740 /// Builtins.def for a description of the type strings.
741 static std::string BuiltinTypeString(const char mod, StringRef typestr,
742                                      ClassKind ck, bool ret) {
743   bool quad = false;
744   bool poly = false;
745   bool usgn = false;
746   bool scal = false;
747   bool cnst = false;
748   bool pntr = false;
749 
750   if (mod == 'v')
751     return "v"; // void
752   if (mod == 'i')
753     return "i"; // int
754 
755   // base type to get the type string for.
756   char type = ClassifyType(typestr, quad, poly, usgn);
757 
758   // Based on the modifying character, change the type and width if necessary.
759   type = ModType(mod, type, quad, poly, usgn, scal, cnst, pntr);
760 
761   usgn = usgn | poly | ((ck == ClassI || ck == ClassW) &&
762                          scal && type != 'f' && type != 'd');
763 
764   // All pointers are void* pointers.  Change type to 'v' now.
765   if (pntr) {
766     usgn = false;
767     poly = false;
768     type = 'v';
769   }
770   // Treat half-float ('h') types as unsigned short ('s') types.
771   if (type == 'h') {
772     type = 's';
773     usgn = true;
774   }
775 
776   if (scal) {
777     SmallString<128> s;
778 
779     if (usgn)
780       s.push_back('U');
781     else if (type == 'c')
782       s.push_back('S'); // make chars explicitly signed
783 
784     if (type == 'l') // 64-bit long
785       s += "LLi";
786     else if (type == 'k') // 128-bit long
787       s = "LLLi";
788     else
789       s.push_back(type);
790 
791     if (cnst)
792       s.push_back('C');
793     if (pntr)
794       s.push_back('*');
795     return s.str();
796   }
797 
798   // Since the return value must be one type, return a vector type of the
799   // appropriate width which we will bitcast.  An exception is made for
800   // returning structs of 2, 3, or 4 vectors which are returned in a sret-like
801   // fashion, storing them to a pointer arg.
802   if (ret) {
803     if (IsMultiVecProto(mod))
804       return "vv*"; // void result with void* first argument
805     if (mod == 'f' || (ck != ClassB && type == 'f'))
806       return quad ? "V4f" : "V2f";
807     if (mod == 'F' || (ck != ClassB && type == 'd'))
808       return quad ? "V2d" : "V1d";
809     if (ck != ClassB && type == 's')
810       return quad ? "V8s" : "V4s";
811     if (ck != ClassB && type == 'i')
812       return quad ? "V4i" : "V2i";
813     if (ck != ClassB && type == 'l')
814       return quad ? "V2LLi" : "V1LLi";
815 
816     return quad ? "V16Sc" : "V8Sc";
817   }
818 
819   // Non-return array types are passed as individual vectors.
820   if (mod == '2' || mod == 'B')
821     return quad ? "V16ScV16Sc" : "V8ScV8Sc";
822   if (mod == '3' || mod == 'C')
823     return quad ? "V16ScV16ScV16Sc" : "V8ScV8ScV8Sc";
824   if (mod == '4' || mod == 'D')
825     return quad ? "V16ScV16ScV16ScV16Sc" : "V8ScV8ScV8ScV8Sc";
826 
827   if (mod == 'f' || (ck != ClassB && type == 'f'))
828     return quad ? "V4f" : "V2f";
829   if (mod == 'F' || (ck != ClassB && type == 'd'))
830     return quad ? "V2d" : "V1d";
831   if (ck != ClassB && type == 's')
832     return quad ? "V8s" : "V4s";
833   if (ck != ClassB && type == 'i')
834     return quad ? "V4i" : "V2i";
835   if (ck != ClassB && type == 'l')
836     return quad ? "V2LLi" : "V1LLi";
837 
838   return quad ? "V16Sc" : "V8Sc";
839 }
840 
841 /// InstructionTypeCode - Computes the ARM argument character code and
842 /// quad status for a specific type string and ClassKind.
843 static void InstructionTypeCode(const StringRef &typeStr,
844                                 const ClassKind ck,
845                                 bool &quad,
846                                 std::string &typeCode) {
847   bool poly = false;
848   bool usgn = false;
849   char type = ClassifyType(typeStr, quad, poly, usgn);
850 
851   switch (type) {
852   case 'c':
853     switch (ck) {
854     case ClassS: typeCode = poly ? "p8" : usgn ? "u8" : "s8"; break;
855     case ClassI: typeCode = "i8"; break;
856     case ClassW: typeCode = "8"; break;
857     default: break;
858     }
859     break;
860   case 's':
861     switch (ck) {
862     case ClassS: typeCode = poly ? "p16" : usgn ? "u16" : "s16"; break;
863     case ClassI: typeCode = "i16"; break;
864     case ClassW: typeCode = "16"; break;
865     default: break;
866     }
867     break;
868   case 'i':
869     switch (ck) {
870     case ClassS: typeCode = usgn ? "u32" : "s32"; break;
871     case ClassI: typeCode = "i32"; break;
872     case ClassW: typeCode = "32"; break;
873     default: break;
874     }
875     break;
876   case 'l':
877     switch (ck) {
878     case ClassS: typeCode = poly ? "p64" : usgn ? "u64" : "s64"; break;
879     case ClassI: typeCode = "i64"; break;
880     case ClassW: typeCode = "64"; break;
881     default: break;
882     }
883     break;
884   case 'k':
885     assert(poly && "Unrecognized 128 bit integer.");
886     typeCode = "p128";
887     break;
888   case 'h':
889     switch (ck) {
890     case ClassS:
891     case ClassI: typeCode = "f16"; break;
892     case ClassW: typeCode = "16"; break;
893     default: break;
894     }
895     break;
896   case 'f':
897     switch (ck) {
898     case ClassS:
899     case ClassI: typeCode = "f32"; break;
900     case ClassW: typeCode = "32"; break;
901     default: break;
902     }
903     break;
904   case 'd':
905     switch (ck) {
906     case ClassS:
907     case ClassI:
908       typeCode += "f64";
909       break;
910     case ClassW:
911       PrintFatalError("unhandled type!");
912     default:
913       break;
914     }
915     break;
916   default:
917     PrintFatalError("unhandled type!");
918   }
919 }
920 
921 static char Insert_BHSD_Suffix(StringRef typestr){
922   unsigned off = 0;
923   if(typestr[off++] == 'S'){
924     while(typestr[off] == 'Q' || typestr[off] == 'H'||
925           typestr[off] == 'P' || typestr[off] == 'U')
926       ++off;
927     switch (typestr[off]){
928     default  : break;
929     case 'c' : return 'b';
930     case 's' : return 'h';
931     case 'i' :
932     case 'f' : return 's';
933     case 'l' :
934     case 'd' : return 'd';
935     }
936   }
937   return 0;
938 }
939 
940 static bool endsWith_xN(std::string const &name) {
941   if (name.length() > 3) {
942     if (name.compare(name.length() - 3, 3, "_x2") == 0 ||
943         name.compare(name.length() - 3, 3, "_x3") == 0 ||
944         name.compare(name.length() - 3, 3, "_x4") == 0)
945       return true;
946   }
947   return false;
948 }
949 
950 /// MangleName - Append a type or width suffix to a base neon function name,
951 /// and insert a 'q' in the appropriate location if type string starts with 'Q'.
952 /// E.g. turn "vst2_lane" into "vst2q_lane_f32", etc.
953 /// Insert proper 'b' 'h' 's' 'd' if prefix 'S' is used.
954 static std::string MangleName(const std::string &name, StringRef typestr,
955                               ClassKind ck) {
956   if (name == "vcvt_f32_f16" || name == "vcvt_f32_f64" ||
957       name == "vcvt_f64_f32")
958     return name;
959 
960   bool quad = false;
961   std::string typeCode = "";
962 
963   InstructionTypeCode(typestr, ck, quad, typeCode);
964 
965   std::string s = name;
966 
967   if (typeCode.size() > 0) {
968     // If the name is end with _xN (N = 2,3,4), insert the typeCode before _xN.
969     if (endsWith_xN(s))
970       s.insert(s.length() - 3, "_" + typeCode);
971     else
972       s += "_" + typeCode;
973   }
974 
975   if (ck == ClassB)
976     s += "_v";
977 
978   // Insert a 'q' before the first '_' character so that it ends up before
979   // _lane or _n on vector-scalar operations.
980   if (typestr.find("Q") != StringRef::npos) {
981       size_t pos = s.find('_');
982       s = s.insert(pos, "q");
983   }
984   char ins = Insert_BHSD_Suffix(typestr);
985   if(ins){
986     size_t pos = s.find('_');
987     s = s.insert(pos, &ins, 1);
988   }
989 
990   return s;
991 }
992 
993 static void PreprocessInstruction(const StringRef &Name,
994                                   const std::string &InstName,
995                                   std::string &Prefix,
996                                   bool &HasNPostfix,
997                                   bool &HasLanePostfix,
998                                   bool &HasDupPostfix,
999                                   bool &IsSpecialVCvt,
1000                                   size_t &TBNumber) {
1001   // All of our instruction name fields from arm_neon.td are of the form
1002   //   <instructionname>_...
1003   // Thus we grab our instruction name via computation of said Prefix.
1004   const size_t PrefixEnd = Name.find_first_of('_');
1005   // If InstName is passed in, we use that instead of our name Prefix.
1006   Prefix = InstName.size() == 0? Name.slice(0, PrefixEnd).str() : InstName;
1007 
1008   const StringRef Postfix = Name.slice(PrefixEnd, Name.size());
1009 
1010   HasNPostfix = Postfix.count("_n");
1011   HasLanePostfix = Postfix.count("_lane");
1012   HasDupPostfix = Postfix.count("_dup");
1013   IsSpecialVCvt = Postfix.size() != 0 && Name.count("vcvt");
1014 
1015   if (InstName.compare("vtbl") == 0 ||
1016       InstName.compare("vtbx") == 0) {
1017     // If we have a vtblN/vtbxN instruction, use the instruction's ASCII
1018     // encoding to get its true value.
1019     TBNumber = Name[Name.size()-1] - 48;
1020   }
1021 }
1022 
1023 /// GenerateRegisterCheckPatternsForLoadStores - Given a bunch of data we have
1024 /// extracted, generate a FileCheck pattern for a Load Or Store
1025 static void
1026 GenerateRegisterCheckPatternForLoadStores(const StringRef &NameRef,
1027                                           const std::string& OutTypeCode,
1028                                           const bool &IsQuad,
1029                                           const bool &HasDupPostfix,
1030                                           const bool &HasLanePostfix,
1031                                           const size_t Count,
1032                                           std::string &RegisterSuffix) {
1033   const bool IsLDSTOne = NameRef.count("vld1") || NameRef.count("vst1");
1034   // If N == 3 || N == 4 and we are dealing with a quad instruction, Clang
1035   // will output a series of v{ld,st}1s, so we have to handle it specially.
1036   if ((Count == 3 || Count == 4) && IsQuad) {
1037     RegisterSuffix += "{";
1038     for (size_t i = 0; i < Count; i++) {
1039       RegisterSuffix += "d{{[0-9]+}}";
1040       if (HasDupPostfix) {
1041         RegisterSuffix += "[]";
1042       }
1043       if (HasLanePostfix) {
1044         RegisterSuffix += "[{{[0-9]+}}]";
1045       }
1046       if (i < Count-1) {
1047         RegisterSuffix += ", ";
1048       }
1049     }
1050     RegisterSuffix += "}";
1051   } else {
1052 
1053     // Handle normal loads and stores.
1054     RegisterSuffix += "{";
1055     for (size_t i = 0; i < Count; i++) {
1056       RegisterSuffix += "d{{[0-9]+}}";
1057       if (HasDupPostfix) {
1058         RegisterSuffix += "[]";
1059       }
1060       if (HasLanePostfix) {
1061         RegisterSuffix += "[{{[0-9]+}}]";
1062       }
1063       if (IsQuad && !HasLanePostfix) {
1064         RegisterSuffix += ", d{{[0-9]+}}";
1065         if (HasDupPostfix) {
1066           RegisterSuffix += "[]";
1067         }
1068       }
1069       if (i < Count-1) {
1070         RegisterSuffix += ", ";
1071       }
1072     }
1073     RegisterSuffix += "}, [r{{[0-9]+}}";
1074 
1075     // We only include the alignment hint if we have a vld1.*64 or
1076     // a dup/lane instruction.
1077     if (IsLDSTOne) {
1078       if ((HasLanePostfix || HasDupPostfix) && OutTypeCode != "8") {
1079         RegisterSuffix += ":" + OutTypeCode;
1080       }
1081     }
1082 
1083     RegisterSuffix += "]";
1084   }
1085 }
1086 
1087 static bool HasNPostfixAndScalarArgs(const StringRef &NameRef,
1088                                      const bool &HasNPostfix) {
1089   return (NameRef.count("vmla") ||
1090           NameRef.count("vmlal") ||
1091           NameRef.count("vmlsl") ||
1092           NameRef.count("vmull") ||
1093           NameRef.count("vqdmlal") ||
1094           NameRef.count("vqdmlsl") ||
1095           NameRef.count("vqdmulh") ||
1096           NameRef.count("vqdmull") ||
1097           NameRef.count("vqrdmulh")) && HasNPostfix;
1098 }
1099 
1100 static bool IsFiveOperandLaneAccumulator(const StringRef &NameRef,
1101                                          const bool &HasLanePostfix) {
1102   return (NameRef.count("vmla") ||
1103           NameRef.count("vmls") ||
1104           NameRef.count("vmlal") ||
1105           NameRef.count("vmlsl") ||
1106           (NameRef.count("vmul") && NameRef.size() == 3)||
1107           NameRef.count("vqdmlal") ||
1108           NameRef.count("vqdmlsl") ||
1109           NameRef.count("vqdmulh") ||
1110           NameRef.count("vqrdmulh")) && HasLanePostfix;
1111 }
1112 
1113 static bool IsSpecialLaneMultiply(const StringRef &NameRef,
1114                                   const bool &HasLanePostfix,
1115                                   const bool &IsQuad) {
1116   const bool IsVMulOrMulh = (NameRef.count("vmul") || NameRef.count("mulh"))
1117                                && IsQuad;
1118   const bool IsVMull = NameRef.count("mull") && !IsQuad;
1119   return (IsVMulOrMulh || IsVMull) && HasLanePostfix;
1120 }
1121 
1122 static void NormalizeProtoForRegisterPatternCreation(const std::string &Name,
1123                                                      const std::string &Proto,
1124                                                      const bool &HasNPostfix,
1125                                                      const bool &IsQuad,
1126                                                      const bool &HasLanePostfix,
1127                                                      const bool &HasDupPostfix,
1128                                                      std::string &NormedProto) {
1129   // Handle generic case.
1130   const StringRef NameRef(Name);
1131   for (size_t i = 0, end = Proto.size(); i < end; i++) {
1132     switch (Proto[i]) {
1133     case 'u':
1134     case 'f':
1135     case 'F':
1136     case 'd':
1137     case 's':
1138     case 'x':
1139     case 't':
1140     case 'n':
1141       NormedProto += IsQuad? 'q' : 'd';
1142       break;
1143     case 'w':
1144     case 'k':
1145       NormedProto += 'q';
1146       break;
1147     case 'g':
1148     case 'j':
1149     case 'h':
1150     case 'e':
1151       NormedProto += 'd';
1152       break;
1153     case 'i':
1154       NormedProto += HasLanePostfix? 'a' : 'i';
1155       break;
1156     case 'a':
1157       if (HasLanePostfix) {
1158         NormedProto += 'a';
1159       } else if (HasNPostfixAndScalarArgs(NameRef, HasNPostfix)) {
1160         NormedProto += IsQuad? 'q' : 'd';
1161       } else {
1162         NormedProto += 'i';
1163       }
1164       break;
1165     }
1166   }
1167 
1168   // Handle Special Cases.
1169   const bool IsNotVExt = !NameRef.count("vext");
1170   const bool IsVPADAL = NameRef.count("vpadal");
1171   const bool Is5OpLaneAccum = IsFiveOperandLaneAccumulator(NameRef,
1172                                                            HasLanePostfix);
1173   const bool IsSpecialLaneMul = IsSpecialLaneMultiply(NameRef, HasLanePostfix,
1174                                                       IsQuad);
1175 
1176   if (IsSpecialLaneMul) {
1177     // If
1178     NormedProto[2] = NormedProto[3];
1179     NormedProto.erase(3);
1180   } else if (NormedProto.size() == 4 &&
1181              NormedProto[0] == NormedProto[1] &&
1182              IsNotVExt) {
1183     // If NormedProto.size() == 4 and the first two proto characters are the
1184     // same, ignore the first.
1185     NormedProto = NormedProto.substr(1, 3);
1186   } else if (Is5OpLaneAccum) {
1187     // If we have a 5 op lane accumulator operation, we take characters 1,2,4
1188     std::string tmp = NormedProto.substr(1,2);
1189     tmp += NormedProto[4];
1190     NormedProto = tmp;
1191   } else if (IsVPADAL) {
1192     // If we have VPADAL, ignore the first character.
1193     NormedProto = NormedProto.substr(0, 2);
1194   } else if (NameRef.count("vdup") && NormedProto.size() > 2) {
1195     // If our instruction is a dup instruction, keep only the first and
1196     // last characters.
1197     std::string tmp = "";
1198     tmp += NormedProto[0];
1199     tmp += NormedProto[NormedProto.size()-1];
1200     NormedProto = tmp;
1201   }
1202 }
1203 
1204 /// GenerateRegisterCheckPatterns - Given a bunch of data we have
1205 /// extracted, generate a FileCheck pattern to check that an
1206 /// instruction's arguments are correct.
1207 static void GenerateRegisterCheckPattern(const std::string &Name,
1208                                          const std::string &Proto,
1209                                          const std::string &OutTypeCode,
1210                                          const bool &HasNPostfix,
1211                                          const bool &IsQuad,
1212                                          const bool &HasLanePostfix,
1213                                          const bool &HasDupPostfix,
1214                                          const size_t &TBNumber,
1215                                          std::string &RegisterSuffix) {
1216 
1217   RegisterSuffix = "";
1218 
1219   const StringRef NameRef(Name);
1220 
1221   if ((NameRef.count("vdup") || NameRef.count("vmov")) && HasNPostfix) {
1222     return;
1223   }
1224 
1225   const bool IsLoadStore = NameRef.count("vld") || NameRef.count("vst");
1226   const bool IsTBXOrTBL = NameRef.count("vtbl") || NameRef.count("vtbx");
1227 
1228   if (IsLoadStore) {
1229     // Grab N value from  v{ld,st}N using its ascii representation.
1230     const size_t Count = NameRef[3] - 48;
1231 
1232     GenerateRegisterCheckPatternForLoadStores(NameRef, OutTypeCode, IsQuad,
1233                                               HasDupPostfix, HasLanePostfix,
1234                                               Count, RegisterSuffix);
1235   } else if (IsTBXOrTBL) {
1236     RegisterSuffix += "d{{[0-9]+}}, {";
1237     for (size_t i = 0; i < TBNumber-1; i++) {
1238       RegisterSuffix += "d{{[0-9]+}}, ";
1239     }
1240     RegisterSuffix += "d{{[0-9]+}}}, d{{[0-9]+}}";
1241   } else {
1242     // Handle a normal instruction.
1243     if (NameRef.count("vget") || NameRef.count("vset"))
1244       return;
1245 
1246     // We first normalize our proto, since we only need to emit 4
1247     // different types of checks, yet have more than 4 proto types
1248     // that map onto those 4 patterns.
1249     std::string NormalizedProto("");
1250     NormalizeProtoForRegisterPatternCreation(Name, Proto, HasNPostfix, IsQuad,
1251                                              HasLanePostfix, HasDupPostfix,
1252                                              NormalizedProto);
1253 
1254     for (size_t i = 0, end = NormalizedProto.size(); i < end; i++) {
1255       const char &c = NormalizedProto[i];
1256       switch (c) {
1257       case 'q':
1258         RegisterSuffix += "q{{[0-9]+}}, ";
1259         break;
1260 
1261       case 'd':
1262         RegisterSuffix += "d{{[0-9]+}}, ";
1263         break;
1264 
1265       case 'i':
1266         RegisterSuffix += "#{{[0-9]+}}, ";
1267         break;
1268 
1269       case 'a':
1270         RegisterSuffix += "d{{[0-9]+}}[{{[0-9]}}], ";
1271         break;
1272       }
1273     }
1274 
1275     // Remove extra ", ".
1276     RegisterSuffix = RegisterSuffix.substr(0, RegisterSuffix.size()-2);
1277   }
1278 }
1279 
1280 /// GenerateChecksForIntrinsic - Given a specific instruction name +
1281 /// typestr + class kind, generate the proper set of FileCheck
1282 /// Patterns to check for. We could just return a string, but instead
1283 /// use a vector since it provides us with the extra flexibility of
1284 /// emitting multiple checks, which comes in handy for certain cases
1285 /// like mla where we want to check for 2 different instructions.
1286 static void GenerateChecksForIntrinsic(const std::string &Name,
1287                                        const std::string &Proto,
1288                                        StringRef &OutTypeStr,
1289                                        StringRef &InTypeStr,
1290                                        ClassKind Ck,
1291                                        const std::string &InstName,
1292                                        bool IsHiddenLOp,
1293                                        std::vector<std::string>& Result) {
1294 
1295   // If Ck is a ClassNoTest instruction, just return so no test is
1296   // emitted.
1297   if(Ck == ClassNoTest)
1298     return;
1299 
1300   if (Name == "vcvt_f32_f16") {
1301     Result.push_back("vcvt.f32.f16");
1302     return;
1303   }
1304 
1305 
1306   // Now we preprocess our instruction given the data we have to get the
1307   // data that we need.
1308   // Create a StringRef for String Manipulation of our Name.
1309   const StringRef NameRef(Name);
1310   // Instruction Prefix.
1311   std::string Prefix;
1312   // The type code for our out type string.
1313   std::string OutTypeCode;
1314   // To handle our different cases, we need to check for different postfixes.
1315   // Is our instruction a quad instruction.
1316   bool IsQuad = false;
1317   // Our instruction is of the form <instructionname>_n.
1318   bool HasNPostfix = false;
1319   // Our instruction is of the form <instructionname>_lane.
1320   bool HasLanePostfix = false;
1321   // Our instruction is of the form <instructionname>_dup.
1322   bool HasDupPostfix  = false;
1323   // Our instruction is a vcvt instruction which requires special handling.
1324   bool IsSpecialVCvt = false;
1325   // If we have a vtbxN or vtblN instruction, this is set to N.
1326   size_t TBNumber = -1;
1327   // Register Suffix
1328   std::string RegisterSuffix;
1329 
1330   PreprocessInstruction(NameRef, InstName, Prefix,
1331                         HasNPostfix, HasLanePostfix, HasDupPostfix,
1332                         IsSpecialVCvt, TBNumber);
1333 
1334   InstructionTypeCode(OutTypeStr, Ck, IsQuad, OutTypeCode);
1335   GenerateRegisterCheckPattern(Name, Proto, OutTypeCode, HasNPostfix, IsQuad,
1336                                HasLanePostfix, HasDupPostfix, TBNumber,
1337                                RegisterSuffix);
1338 
1339   // In the following section, we handle a bunch of special cases. You can tell
1340   // a special case by the fact we are returning early.
1341 
1342   // If our instruction is a logical instruction without postfix or a
1343   // hidden LOp just return the current Prefix.
1344   if (Ck == ClassL || IsHiddenLOp) {
1345     Result.push_back(Prefix + " " + RegisterSuffix);
1346     return;
1347   }
1348 
1349   // If we have a vmov, due to the many different cases, some of which
1350   // vary within the different intrinsics generated for a single
1351   // instruction type, just output a vmov. (e.g. given an instruction
1352   // A, A.u32 might be vmov and A.u8 might be vmov.8).
1353   //
1354   // FIXME: Maybe something can be done about this. The two cases that we care
1355   // about are vmov as an LType and vmov as a WType.
1356   if (Prefix == "vmov") {
1357     Result.push_back(Prefix + " " + RegisterSuffix);
1358     return;
1359   }
1360 
1361   // In the following section, we handle special cases.
1362 
1363   if (OutTypeCode == "64") {
1364     // If we have a 64 bit vdup/vext and are handling an uint64x1_t
1365     // type, the intrinsic will be optimized away, so just return
1366     // nothing.  On the other hand if we are handling an uint64x2_t
1367     // (i.e. quad instruction), vdup/vmov instructions should be
1368     // emitted.
1369     if (Prefix == "vdup" || Prefix == "vext") {
1370       if (IsQuad) {
1371         Result.push_back("{{vmov|vdup}}");
1372       }
1373       return;
1374     }
1375 
1376     // v{st,ld}{2,3,4}_{u,s}64 emit v{st,ld}1.64 instructions with
1377     // multiple register operands.
1378     bool MultiLoadPrefix = Prefix == "vld2" || Prefix == "vld3"
1379                             || Prefix == "vld4";
1380     bool MultiStorePrefix = Prefix == "vst2" || Prefix == "vst3"
1381                             || Prefix == "vst4";
1382     if (MultiLoadPrefix || MultiStorePrefix) {
1383       Result.push_back(NameRef.slice(0, 3).str() + "1.64");
1384       return;
1385     }
1386 
1387     // v{st,ld}1_{lane,dup}_{u64,s64} use vldr/vstr/vmov/str instead of
1388     // emitting said instructions. So return a check for
1389     // vldr/vstr/vmov/str instead.
1390     if (HasLanePostfix || HasDupPostfix) {
1391       if (Prefix == "vst1") {
1392         Result.push_back("{{str|vstr|vmov}}");
1393         return;
1394       } else if (Prefix == "vld1") {
1395         Result.push_back("{{ldr|vldr|vmov}}");
1396         return;
1397       }
1398     }
1399   }
1400 
1401   // vzip.32/vuzp.32 are the same instruction as vtrn.32 and are
1402   // sometimes disassembled as vtrn.32. We use a regex to handle both
1403   // cases.
1404   if ((Prefix == "vzip" || Prefix == "vuzp") && OutTypeCode == "32") {
1405     Result.push_back("{{vtrn|" + Prefix + "}}.32 " + RegisterSuffix);
1406     return;
1407   }
1408 
1409   // Currently on most ARM processors, we do not use vmla/vmls for
1410   // quad floating point operations. Instead we output vmul + vadd. So
1411   // check if we have one of those instructions and just output a
1412   // check for vmul.
1413   if (OutTypeCode == "f32") {
1414     if (Prefix == "vmls") {
1415       Result.push_back("vmul." + OutTypeCode + " " + RegisterSuffix);
1416       Result.push_back("vsub." + OutTypeCode);
1417       return;
1418     } else if (Prefix == "vmla") {
1419       Result.push_back("vmul." + OutTypeCode + " " + RegisterSuffix);
1420       Result.push_back("vadd." + OutTypeCode);
1421       return;
1422     }
1423   }
1424 
1425   // If we have vcvt, get the input type from the instruction name
1426   // (which should be of the form instname_inputtype) and append it
1427   // before the output type.
1428   if (Prefix == "vcvt") {
1429     const std::string inTypeCode = NameRef.substr(NameRef.find_last_of("_")+1);
1430     Prefix += "." + inTypeCode;
1431   }
1432 
1433   // Append output type code to get our final mangled instruction.
1434   Prefix += "." + OutTypeCode;
1435 
1436   Result.push_back(Prefix + " " + RegisterSuffix);
1437 }
1438 
1439 /// UseMacro - Examine the prototype string to determine if the intrinsic
1440 /// should be defined as a preprocessor macro instead of an inline function.
1441 static bool UseMacro(const std::string &proto) {
1442   // If this builtin takes an immediate argument, we need to #define it rather
1443   // than use a standard declaration, so that SemaChecking can range check
1444   // the immediate passed by the user.
1445   if (proto.find('i') != std::string::npos)
1446     return true;
1447 
1448   // Pointer arguments need to use macros to avoid hiding aligned attributes
1449   // from the pointer type.
1450   if (proto.find('p') != std::string::npos ||
1451       proto.find('c') != std::string::npos)
1452     return true;
1453 
1454   return false;
1455 }
1456 
1457 /// MacroArgUsedDirectly - Return true if argument i for an intrinsic that is
1458 /// defined as a macro should be accessed directly instead of being first
1459 /// assigned to a local temporary.
1460 static bool MacroArgUsedDirectly(const std::string &proto, unsigned i) {
1461   // True for constant ints (i), pointers (p) and const pointers (c).
1462   return (proto[i] == 'i' || proto[i] == 'p' || proto[i] == 'c');
1463 }
1464 
1465 // Generate the string "(argtype a, argtype b, ...)"
1466 static std::string GenArgs(const std::string &proto, StringRef typestr,
1467                            const std::string &name) {
1468   bool define = UseMacro(proto);
1469   char arg = 'a';
1470 
1471   std::string s;
1472   s += "(";
1473 
1474   for (unsigned i = 1, e = proto.size(); i != e; ++i, ++arg) {
1475     if (define) {
1476       // Some macro arguments are used directly instead of being assigned
1477       // to local temporaries; prepend an underscore prefix to make their
1478       // names consistent with the local temporaries.
1479       if (MacroArgUsedDirectly(proto, i))
1480         s += "__";
1481     } else {
1482       s += TypeString(proto[i], typestr) + " __";
1483     }
1484     s.push_back(arg);
1485     if ((i + 1) < e)
1486       s += ", ";
1487   }
1488 
1489   s += ")";
1490   return s;
1491 }
1492 
1493 // Macro arguments are not type-checked like inline function arguments, so
1494 // assign them to local temporaries to get the right type checking.
1495 static std::string GenMacroLocals(const std::string &proto, StringRef typestr,
1496                                   const std::string &name ) {
1497   char arg = 'a';
1498   std::string s;
1499   bool generatedLocal = false;
1500 
1501   for (unsigned i = 1, e = proto.size(); i != e; ++i, ++arg) {
1502     // Do not create a temporary for an immediate argument.
1503     // That would defeat the whole point of using a macro!
1504     if (MacroArgUsedDirectly(proto, i))
1505       continue;
1506     generatedLocal = true;
1507     s += TypeString(proto[i], typestr) + " __";
1508     s.push_back(arg);
1509     s += " = (";
1510     s.push_back(arg);
1511     s += "); ";
1512   }
1513 
1514   if (generatedLocal)
1515     s += "\\\n  ";
1516   return s;
1517 }
1518 
1519 // Use the vmovl builtin to sign-extend or zero-extend a vector.
1520 static std::string Extend(StringRef typestr, const std::string &a, bool h=0) {
1521   std::string s, high;
1522   high = h ? "_high" : "";
1523   s = MangleName("vmovl" + high, typestr, ClassS);
1524   s += "(" + a + ")";
1525   return s;
1526 }
1527 
1528 // Get the high 64-bit part of a vector
1529 static std::string GetHigh(const std::string &a, StringRef typestr) {
1530   std::string s;
1531   s = MangleName("vget_high", typestr, ClassS);
1532   s += "(" + a + ")";
1533   return s;
1534 }
1535 
1536 // Gen operation with two operands and get high 64-bit for both of two operands.
1537 static std::string Gen2OpWith2High(StringRef typestr,
1538                                    const std::string &op,
1539                                    const std::string &a,
1540                                    const std::string &b) {
1541   std::string s;
1542   std::string Op1 = GetHigh(a, typestr);
1543   std::string Op2 = GetHigh(b, typestr);
1544   s = MangleName(op, typestr, ClassS);
1545   s += "(" + Op1 + ", " + Op2 + ");";
1546   return s;
1547 }
1548 
1549 // Gen operation with three operands and get high 64-bit of the latter
1550 // two operands.
1551 static std::string Gen3OpWith2High(StringRef typestr,
1552                                    const std::string &op,
1553                                    const std::string &a,
1554                                    const std::string &b,
1555                                    const std::string &c) {
1556   std::string s;
1557   std::string Op1 = GetHigh(b, typestr);
1558   std::string Op2 = GetHigh(c, typestr);
1559   s = MangleName(op, typestr, ClassS);
1560   s += "(" + a + ", " + Op1 + ", " + Op2 + ");";
1561   return s;
1562 }
1563 
1564 // Gen combine operation by putting a on low 64-bit, and b on high 64-bit.
1565 static std::string GenCombine(std::string typestr,
1566                               const std::string &a,
1567                               const std::string &b) {
1568   std::string s;
1569   s = MangleName("vcombine", typestr, ClassS);
1570   s += "(" + a + ", " + b + ")";
1571   return s;
1572 }
1573 
1574 static std::string Duplicate(unsigned nElts, StringRef typestr,
1575                              const std::string &a) {
1576   std::string s;
1577 
1578   s = "(" + TypeString('d', typestr) + "){ ";
1579   for (unsigned i = 0; i != nElts; ++i) {
1580     s += a;
1581     if ((i + 1) < nElts)
1582       s += ", ";
1583   }
1584   s += " }";
1585 
1586   return s;
1587 }
1588 
1589 static std::string SplatLane(unsigned nElts, const std::string &vec,
1590                              const std::string &lane) {
1591   std::string s = "__builtin_shufflevector(" + vec + ", " + vec;
1592   for (unsigned i = 0; i < nElts; ++i)
1593     s += ", " + lane;
1594   s += ")";
1595   return s;
1596 }
1597 
1598 static std::string RemoveHigh(const std::string &name) {
1599   std::string s = name;
1600   std::size_t found = s.find("_high_");
1601   if (found == std::string::npos)
1602     PrintFatalError("name should contain \"_high_\" for high intrinsics");
1603   s.replace(found, 5, "");
1604   return s;
1605 }
1606 
1607 static unsigned GetNumElements(StringRef typestr, bool &quad) {
1608   quad = false;
1609   bool dummy = false;
1610   char type = ClassifyType(typestr, quad, dummy, dummy);
1611   unsigned nElts = 0;
1612   switch (type) {
1613   case 'c': nElts = 8; break;
1614   case 's': nElts = 4; break;
1615   case 'i': nElts = 2; break;
1616   case 'l': nElts = 1; break;
1617   case 'k': nElts = 1; break;
1618   case 'h': nElts = 4; break;
1619   case 'f': nElts = 2; break;
1620   case 'd':
1621     nElts = 1;
1622     break;
1623   default:
1624     PrintFatalError("unhandled type!");
1625   }
1626   if (quad) nElts <<= 1;
1627   return nElts;
1628 }
1629 
1630 // Generate the definition for this intrinsic, e.g. "a + b" for OpAdd.
1631 //
1632 // Note that some intrinsic definitions around 'lane' are being implemented
1633 // with macros, because they all contain constant integer argument, and we
1634 // statically check the range of the lane index to meet the semantic
1635 // requirement of different intrinsics.
1636 //
1637 // For the intrinsics implemented with macro, if they contain another intrinsic
1638 // implemented with maco, we have to avoid using the same argument names for
1639 // the nested instrinsics. For example, macro vfms_lane is being implemented
1640 // with another macor vfma_lane, so we rename all arguments for vfms_lane by
1641 // adding a suffix '1'.
1642 
1643 static std::string GenOpString(const std::string &name, OpKind op,
1644                                const std::string &proto, StringRef typestr) {
1645   bool quad;
1646   unsigned nElts = GetNumElements(typestr, quad);
1647   bool define = UseMacro(proto);
1648 
1649   std::string ts = TypeString(proto[0], typestr);
1650   std::string s;
1651   if (!define) {
1652     s = "return ";
1653   }
1654 
1655   switch(op) {
1656   case OpAdd:
1657     s += "__a + __b;";
1658     break;
1659   case OpAddl:
1660     s += Extend(typestr, "__a") + " + " + Extend(typestr, "__b") + ";";
1661     break;
1662   case OpAddlHi:
1663     s += Extend(typestr, "__a", 1) + " + " + Extend(typestr, "__b", 1) + ";";
1664     break;
1665   case OpAddw:
1666     s += "__a + " + Extend(typestr, "__b") + ";";
1667     break;
1668   case OpAddwHi:
1669     s += "__a + " + Extend(typestr, "__b", 1) + ";";
1670     break;
1671   case OpSub:
1672     s += "__a - __b;";
1673     break;
1674   case OpSubl:
1675     s += Extend(typestr, "__a") + " - " + Extend(typestr, "__b") + ";";
1676     break;
1677   case OpSublHi:
1678     s += Extend(typestr, "__a", 1) + " - " + Extend(typestr, "__b", 1) + ";";
1679     break;
1680   case OpSubw:
1681     s += "__a - " + Extend(typestr, "__b") + ";";
1682     break;
1683   case OpSubwHi:
1684     s += "__a - " + Extend(typestr, "__b", 1) + ";";
1685     break;
1686   case OpMulN:
1687     s += "__a * " + Duplicate(nElts, typestr, "__b") + ";";
1688     break;
1689   case OpMulLane:
1690     s += "__a * " + SplatLane(nElts, "__b", "__c") + ";";
1691     break;
1692   case OpMulXLane:
1693     s += MangleName("vmulx", typestr, ClassS) + "(__a, " +
1694       SplatLane(nElts, "__b", "__c") + ");";
1695     break;
1696   case OpMul:
1697     s += "__a * __b;";
1698     break;
1699   case OpFMlaN:
1700     s += MangleName("vfma", typestr, ClassS);
1701     s += "(__a, __b, " + Duplicate(nElts,typestr, "__c") + ");";
1702     break;
1703   case OpFMlsN:
1704     s += MangleName("vfms", typestr, ClassS);
1705     s += "(__a, __b, " + Duplicate(nElts,typestr, "__c") + ");";
1706     break;
1707   case OpMullLane:
1708     s += MangleName("vmull", typestr, ClassS) + "(__a, " +
1709       SplatLane(nElts, "__b", "__c") + ");";
1710     break;
1711   case OpMullHiLane:
1712     s += MangleName("vmull", typestr, ClassS) + "(" +
1713       GetHigh("__a", typestr) + ", " + SplatLane(nElts, "__b", "__c") + ");";
1714     break;
1715   case OpMlaN:
1716     s += "__a + (__b * " + Duplicate(nElts, typestr, "__c") + ");";
1717     break;
1718   case OpMlaLane:
1719     s += "__a + (__b * " + SplatLane(nElts, "__c", "__d") + ");";
1720     break;
1721   case OpMla:
1722     s += "__a + (__b * __c);";
1723     break;
1724   case OpMlalN:
1725     s += "__a + " + MangleName("vmull", typestr, ClassS) + "(__b, " +
1726       Duplicate(nElts, typestr, "__c") + ");";
1727     break;
1728   case OpMlalLane:
1729     s += "__a + " + MangleName("vmull", typestr, ClassS) + "(__b, " +
1730       SplatLane(nElts, "__c", "__d") + ");";
1731     break;
1732   case OpMlalHiLane:
1733     s += "__a + " + MangleName("vmull", typestr, ClassS) + "(" +
1734       GetHigh("__b", typestr) + ", " + SplatLane(nElts, "__c", "__d") + ");";
1735     break;
1736   case OpMlal:
1737     s += "__a + " + MangleName("vmull", typestr, ClassS) + "(__b, __c);";
1738     break;
1739   case OpMullHi:
1740     s += Gen2OpWith2High(typestr, "vmull", "__a", "__b");
1741     break;
1742   case OpMullHiP64: {
1743     std::string Op1 = GetHigh("__a", typestr);
1744     std::string Op2 = GetHigh("__b", typestr);
1745     s += MangleName("vmull", typestr, ClassS);
1746     s += "((poly64_t)" + Op1 + ", (poly64_t)" + Op2 + ");";
1747     break;
1748   }
1749   case OpMullHiN:
1750     s += MangleName("vmull_n", typestr, ClassS);
1751     s += "(" + GetHigh("__a", typestr) + ", __b);";
1752     return s;
1753   case OpMlalHi:
1754     s += Gen3OpWith2High(typestr, "vmlal", "__a", "__b", "__c");
1755     break;
1756   case OpMlalHiN:
1757     s += MangleName("vmlal_n", typestr, ClassS);
1758     s += "(__a, " + GetHigh("__b", typestr) + ", __c);";
1759     return s;
1760   case OpMlsN:
1761     s += "__a - (__b * " + Duplicate(nElts, typestr, "__c") + ");";
1762     break;
1763   case OpMlsLane:
1764     s += "__a - (__b * " + SplatLane(nElts, "__c", "__d") + ");";
1765     break;
1766   case OpFMSLane:
1767     s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n  ";
1768     s += TypeString(proto[2], typestr) + " __b1 = __b; \\\n  ";
1769     s += TypeString(proto[3], typestr) + " __c1 = __c; \\\n  ";
1770     s += MangleName("vfma_lane", typestr, ClassS) + "(__a1, __b1, -__c1, __d);";
1771     break;
1772   case OpFMSLaneQ:
1773     s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n  ";
1774     s += TypeString(proto[2], typestr) + " __b1 = __b; \\\n  ";
1775     s += TypeString(proto[3], typestr) + " __c1 = __c; \\\n  ";
1776     s += MangleName("vfma_laneq", typestr, ClassS) + "(__a1, __b1, -__c1, __d);";
1777     break;
1778   case OpMls:
1779     s += "__a - (__b * __c);";
1780     break;
1781   case OpMlslN:
1782     s += "__a - " + MangleName("vmull", typestr, ClassS) + "(__b, " +
1783       Duplicate(nElts, typestr, "__c") + ");";
1784     break;
1785   case OpMlslLane:
1786     s += "__a - " + MangleName("vmull", typestr, ClassS) + "(__b, " +
1787       SplatLane(nElts, "__c", "__d") + ");";
1788     break;
1789   case OpMlslHiLane:
1790     s += "__a - " + MangleName("vmull", typestr, ClassS) + "(" +
1791       GetHigh("__b", typestr) + ", " + SplatLane(nElts, "__c", "__d") + ");";
1792     break;
1793   case OpMlsl:
1794     s += "__a - " + MangleName("vmull", typestr, ClassS) + "(__b, __c);";
1795     break;
1796   case OpMlslHi:
1797     s += Gen3OpWith2High(typestr, "vmlsl", "__a", "__b", "__c");
1798     break;
1799   case OpMlslHiN:
1800     s += MangleName("vmlsl_n", typestr, ClassS);
1801     s += "(__a, " + GetHigh("__b", typestr) + ", __c);";
1802     break;
1803   case OpQDMullLane:
1804     s += MangleName("vqdmull", typestr, ClassS) + "(__a, " +
1805       SplatLane(nElts, "__b", "__c") + ");";
1806     break;
1807   case OpQDMullHiLane:
1808     s += MangleName("vqdmull", typestr, ClassS) + "(" +
1809       GetHigh("__a", typestr) + ", " + SplatLane(nElts, "__b", "__c") + ");";
1810     break;
1811   case OpQDMlalLane:
1812     s += MangleName("vqdmlal", typestr, ClassS) + "(__a, __b, " +
1813       SplatLane(nElts, "__c", "__d") + ");";
1814     break;
1815   case OpQDMlalHiLane:
1816     s += MangleName("vqdmlal", typestr, ClassS) + "(__a, " +
1817       GetHigh("__b", typestr) + ", " + SplatLane(nElts, "__c", "__d") + ");";
1818     break;
1819   case OpQDMlslLane:
1820     s += MangleName("vqdmlsl", typestr, ClassS) + "(__a, __b, " +
1821       SplatLane(nElts, "__c", "__d") + ");";
1822     break;
1823   case OpQDMlslHiLane:
1824     s += MangleName("vqdmlsl", typestr, ClassS) + "(__a, " +
1825       GetHigh("__b", typestr) + ", " + SplatLane(nElts, "__c", "__d") + ");";
1826     break;
1827   case OpQDMulhLane:
1828     s += MangleName("vqdmulh", typestr, ClassS) + "(__a, " +
1829       SplatLane(nElts, "__b", "__c") + ");";
1830     break;
1831   case OpQRDMulhLane:
1832     s += MangleName("vqrdmulh", typestr, ClassS) + "(__a, " +
1833       SplatLane(nElts, "__b", "__c") + ");";
1834     break;
1835   case OpEq:
1836     s += "(" + ts + ")(__a == __b);";
1837     break;
1838   case OpGe:
1839     s += "(" + ts + ")(__a >= __b);";
1840     break;
1841   case OpLe:
1842     s += "(" + ts + ")(__a <= __b);";
1843     break;
1844   case OpGt:
1845     s += "(" + ts + ")(__a > __b);";
1846     break;
1847   case OpLt:
1848     s += "(" + ts + ")(__a < __b);";
1849     break;
1850   case OpNeg:
1851     s += " -__a;";
1852     break;
1853   case OpNot:
1854     s += " ~__a;";
1855     break;
1856   case OpAnd:
1857     s += "__a & __b;";
1858     break;
1859   case OpOr:
1860     s += "__a | __b;";
1861     break;
1862   case OpXor:
1863     s += "__a ^ __b;";
1864     break;
1865   case OpAndNot:
1866     s += "__a & ~__b;";
1867     break;
1868   case OpOrNot:
1869     s += "__a | ~__b;";
1870     break;
1871   case OpCast:
1872     s += "(" + ts + ")__a;";
1873     break;
1874   case OpConcat:
1875     s += "(" + ts + ")__builtin_shufflevector((int64x1_t)__a";
1876     s += ", (int64x1_t)__b, 0, 1);";
1877     break;
1878   case OpHi:
1879     // nElts is for the result vector, so the source is twice that number.
1880     s += "__builtin_shufflevector(__a, __a";
1881     for (unsigned i = nElts; i < nElts * 2; ++i)
1882       s += ", " + utostr(i);
1883     s+= ");";
1884     break;
1885   case OpLo:
1886     s += "__builtin_shufflevector(__a, __a";
1887     for (unsigned i = 0; i < nElts; ++i)
1888       s += ", " + utostr(i);
1889     s+= ");";
1890     break;
1891   case OpDup:
1892     s += Duplicate(nElts, typestr, "__a") + ";";
1893     break;
1894   case OpDupLane:
1895     s += SplatLane(nElts, "__a", "__b") + ";";
1896     break;
1897   case OpSelect:
1898     // ((0 & 1) | (~0 & 2))
1899     s += "(" + ts + ")";
1900     ts = TypeString(proto[1], typestr);
1901     s += "((__a & (" + ts + ")__b) | ";
1902     s += "(~__a & (" + ts + ")__c));";
1903     break;
1904   case OpRev16:
1905     s += "__builtin_shufflevector(__a, __a";
1906     for (unsigned i = 2; i <= nElts; i += 2)
1907       for (unsigned j = 0; j != 2; ++j)
1908         s += ", " + utostr(i - j - 1);
1909     s += ");";
1910     break;
1911   case OpRev32: {
1912     unsigned WordElts = nElts >> (1 + (int)quad);
1913     s += "__builtin_shufflevector(__a, __a";
1914     for (unsigned i = WordElts; i <= nElts; i += WordElts)
1915       for (unsigned j = 0; j != WordElts; ++j)
1916         s += ", " + utostr(i - j - 1);
1917     s += ");";
1918     break;
1919   }
1920   case OpRev64: {
1921     unsigned DblWordElts = nElts >> (int)quad;
1922     s += "__builtin_shufflevector(__a, __a";
1923     for (unsigned i = DblWordElts; i <= nElts; i += DblWordElts)
1924       for (unsigned j = 0; j != DblWordElts; ++j)
1925         s += ", " + utostr(i - j - 1);
1926     s += ");";
1927     break;
1928   }
1929   case OpXtnHi: {
1930     s = TypeString(proto[1], typestr) + " __a1 = " +
1931         MangleName("vmovn", typestr, ClassS) + "(__b);\n  " +
1932         "return __builtin_shufflevector(__a, __a1";
1933     for (unsigned i = 0; i < nElts * 4; ++i)
1934       s += ", " + utostr(i);
1935     s += ");";
1936     break;
1937   }
1938   case OpSqxtunHi: {
1939     s = TypeString(proto[1], typestr) + " __a1 = " +
1940         MangleName("vqmovun", typestr, ClassS) + "(__b);\n  " +
1941         "return __builtin_shufflevector(__a, __a1";
1942     for (unsigned i = 0; i < nElts * 4; ++i)
1943       s += ", " + utostr(i);
1944     s += ");";
1945     break;
1946   }
1947   case OpQxtnHi: {
1948     s = TypeString(proto[1], typestr) + " __a1 = " +
1949         MangleName("vqmovn", typestr, ClassS) + "(__b);\n  " +
1950         "return __builtin_shufflevector(__a, __a1";
1951     for (unsigned i = 0; i < nElts * 4; ++i)
1952       s += ", " + utostr(i);
1953     s += ");";
1954     break;
1955   }
1956   case OpFcvtnHi: {
1957     std::string FName = (nElts == 1) ? "vcvt_f32" : "vcvt_f16";
1958     s = TypeString(proto[1], typestr) + " __a1 = " +
1959         MangleName(FName, typestr, ClassS) + "(__b);\n  " +
1960         "return __builtin_shufflevector(__a, __a1";
1961     for (unsigned i = 0; i < nElts * 4; ++i)
1962       s += ", " + utostr(i);
1963     s += ");";
1964     break;
1965   }
1966   case OpFcvtlHi: {
1967     std::string FName = (nElts == 2) ? "vcvt_f64" : "vcvt_f32";
1968     s = TypeString('d', typestr) + " __a1 = " + GetHigh("__a", typestr) +
1969         ";\n  return " + MangleName(FName, typestr, ClassS) + "(__a1);";
1970     break;
1971   }
1972   case OpFcvtxnHi: {
1973     s = TypeString(proto[1], typestr) + " __a1 = " +
1974         MangleName("vcvtx_f32", typestr, ClassS) + "(__b);\n  " +
1975         "return __builtin_shufflevector(__a, __a1";
1976     for (unsigned i = 0; i < nElts * 4; ++i)
1977       s += ", " + utostr(i);
1978     s += ");";
1979     break;
1980   }
1981   case OpUzp1:
1982     s += "__builtin_shufflevector(__a, __b";
1983     for (unsigned i = 0; i < nElts; i++)
1984       s += ", " + utostr(2*i);
1985     s += ");";
1986     break;
1987   case OpUzp2:
1988     s += "__builtin_shufflevector(__a, __b";
1989     for (unsigned i = 0; i < nElts; i++)
1990       s += ", " + utostr(2*i+1);
1991     s += ");";
1992     break;
1993   case OpZip1:
1994     s += "__builtin_shufflevector(__a, __b";
1995     for (unsigned i = 0; i < (nElts/2); i++)
1996        s += ", " + utostr(i) + ", " + utostr(i+nElts);
1997     s += ");";
1998     break;
1999   case OpZip2:
2000     s += "__builtin_shufflevector(__a, __b";
2001     for (unsigned i = nElts/2; i < nElts; i++)
2002        s += ", " + utostr(i) + ", " + utostr(i+nElts);
2003     s += ");";
2004     break;
2005   case OpTrn1:
2006     s += "__builtin_shufflevector(__a, __b";
2007     for (unsigned i = 0; i < (nElts/2); i++)
2008        s += ", " + utostr(2*i) + ", " + utostr(2*i+nElts);
2009     s += ");";
2010     break;
2011   case OpTrn2:
2012     s += "__builtin_shufflevector(__a, __b";
2013     for (unsigned i = 0; i < (nElts/2); i++)
2014        s += ", " + utostr(2*i+1) + ", " + utostr(2*i+1+nElts);
2015     s += ");";
2016     break;
2017   case OpAbdl: {
2018     std::string abd = MangleName("vabd", typestr, ClassS) + "(__a, __b)";
2019     if (typestr[0] != 'U') {
2020       // vabd results are always unsigned and must be zero-extended.
2021       std::string utype = "U" + typestr.str();
2022       s += "(" + TypeString(proto[0], typestr) + ")";
2023       abd = "(" + TypeString('d', utype) + ")" + abd;
2024       s += Extend(utype, abd) + ";";
2025     } else {
2026       s += Extend(typestr, abd) + ";";
2027     }
2028     break;
2029   }
2030   case OpAbdlHi:
2031     s += Gen2OpWith2High(typestr, "vabdl", "__a", "__b");
2032     break;
2033   case OpAddhnHi: {
2034     std::string addhn = MangleName("vaddhn", typestr, ClassS) + "(__b, __c)";
2035     s += GenCombine(GetNarrowTypestr(typestr), "__a", addhn);
2036     s += ";";
2037     break;
2038   }
2039   case OpRAddhnHi: {
2040     std::string raddhn = MangleName("vraddhn", typestr, ClassS) + "(__b, __c)";
2041     s += GenCombine(GetNarrowTypestr(typestr), "__a", raddhn);
2042     s += ";";
2043     break;
2044   }
2045   case OpSubhnHi: {
2046     std::string subhn = MangleName("vsubhn", typestr, ClassS) + "(__b, __c)";
2047     s += GenCombine(GetNarrowTypestr(typestr), "__a", subhn);
2048     s += ";";
2049     break;
2050   }
2051   case OpRSubhnHi: {
2052     std::string rsubhn = MangleName("vrsubhn", typestr, ClassS) + "(__b, __c)";
2053     s += GenCombine(GetNarrowTypestr(typestr), "__a", rsubhn);
2054     s += ";";
2055     break;
2056   }
2057   case OpAba:
2058     s += "__a + " + MangleName("vabd", typestr, ClassS) + "(__b, __c);";
2059     break;
2060   case OpAbal:
2061     s += "__a + " + MangleName("vabdl", typestr, ClassS) + "(__b, __c);";
2062     break;
2063   case OpAbalHi:
2064     s += Gen3OpWith2High(typestr, "vabal", "__a", "__b", "__c");
2065     break;
2066   case OpQDMullHi:
2067     s += Gen2OpWith2High(typestr, "vqdmull", "__a", "__b");
2068     break;
2069   case OpQDMullHiN:
2070     s += MangleName("vqdmull_n", typestr, ClassS);
2071     s += "(" + GetHigh("__a", typestr) + ", __b);";
2072     return s;
2073   case OpQDMlalHi:
2074     s += Gen3OpWith2High(typestr, "vqdmlal", "__a", "__b", "__c");
2075     break;
2076   case OpQDMlalHiN:
2077     s += MangleName("vqdmlal_n", typestr, ClassS);
2078     s += "(__a, " + GetHigh("__b", typestr) + ", __c);";
2079     return s;
2080   case OpQDMlslHi:
2081     s += Gen3OpWith2High(typestr, "vqdmlsl", "__a", "__b", "__c");
2082     break;
2083   case OpQDMlslHiN:
2084     s += MangleName("vqdmlsl_n", typestr, ClassS);
2085     s += "(__a, " + GetHigh("__b", typestr) + ", __c);";
2086     return s;
2087   case OpDiv:
2088     s += "__a / __b;";
2089     break;
2090   case OpMovlHi: {
2091     s = TypeString(proto[1], typestr.drop_front()) + " __a1 = " +
2092         MangleName("vget_high", typestr, ClassS) + "(__a);\n  " + s;
2093     s += "(" + ts + ")" + MangleName("vshll_n", typestr, ClassS);
2094     s += "(__a1, 0);";
2095     break;
2096   }
2097   case OpLongHi: {
2098     // Another local variable __a1 is needed for calling a Macro,
2099     // or using __a will have naming conflict when Macro expanding.
2100     s += TypeString(proto[1], typestr.drop_front()) + " __a1 = " +
2101          MangleName("vget_high", typestr, ClassS) + "(__a); \\\n";
2102     s += "  (" + ts + ")" + MangleName(RemoveHigh(name), typestr, ClassS) +
2103          "(__a1, __b);";
2104     break;
2105   }
2106   case OpNarrowHi: {
2107     s += "(" + ts + ")" + MangleName("vcombine", typestr, ClassS) + "(__a, " +
2108          MangleName(RemoveHigh(name), typestr, ClassS) + "(__b, __c));";
2109     break;
2110   }
2111   case OpCopyLane: {
2112     s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n  ";
2113     s += TypeString(proto[3], typestr) + " __c1 = __c; \\\n  ";
2114     s += TypeString('s', typestr) + " __c2 = " +
2115          MangleName("vget_lane", typestr, ClassS) + "(__c1, __d); \\\n  " +
2116          MangleName("vset_lane", typestr, ClassS) + "(__c2, __a1, __b);";
2117     break;
2118   }
2119   case OpCopyQLane: {
2120     std::string typeCode = "";
2121     InstructionTypeCode(typestr, ClassS, quad, typeCode);
2122     s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n  ";
2123     s += TypeString(proto[3], typestr) + " __c1 = __c; \\\n  ";
2124     s += TypeString('s', typestr) + " __c2 = vget_lane_" + typeCode +
2125          "(__c1, __d); \\\n  vsetq_lane_" + typeCode + "(__c2, __a1, __b);";
2126     break;
2127   }
2128   case OpCopyLaneQ: {
2129     std::string typeCode = "";
2130     InstructionTypeCode(typestr, ClassS, quad, typeCode);
2131     s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n  ";
2132     s += TypeString(proto[3], typestr) + " __c1 = __c; \\\n  ";
2133     s += TypeString('s', typestr) + " __c2 = vgetq_lane_" + typeCode +
2134          "(__c1, __d); \\\n  vset_lane_" + typeCode + "(__c2, __a1, __b);";
2135     break;
2136   }
2137   case OpScalarMulLane: {
2138     std::string typeCode = "";
2139     InstructionTypeCode(typestr, ClassS, quad, typeCode);
2140     s += TypeString('s', typestr) + " __d1 = vget_lane_" + typeCode +
2141       "(__b, __c);\\\n  __a * __d1;";
2142     break;
2143   }
2144   case OpScalarMulLaneQ: {
2145     std::string typeCode = "";
2146     InstructionTypeCode(typestr, ClassS, quad, typeCode);
2147     s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n  ";
2148     s += TypeString(proto[2], typestr) + " __b1 = __b; \\\n  ";
2149     s += TypeString('s', typestr) + " __d1 = vgetq_lane_" + typeCode +
2150       "(__b1, __c);\\\n  __a1 * __d1;";
2151     break;
2152   }
2153   case OpScalarMulXLane: {
2154     bool dummy = false;
2155     char type = ClassifyType(typestr, dummy, dummy, dummy);
2156     if (type == 'f') type = 's';
2157     std::string typeCode = "";
2158     InstructionTypeCode(typestr, ClassS, quad, typeCode);
2159     s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n  ";
2160     s += TypeString(proto[2], typestr) + " __b1 = __b; \\\n  ";
2161     s += TypeString('s', typestr) + " __d1 = vget_lane_" + typeCode +
2162       "(__b1, __c);\\\n  vmulx" + type + "_" +
2163       typeCode +  "(__a1, __d1);";
2164     break;
2165   }
2166   case OpScalarMulXLaneQ: {
2167     bool dummy = false;
2168     char type = ClassifyType(typestr, dummy, dummy, dummy);
2169     if (type == 'f') type = 's';
2170     std::string typeCode = "";
2171     InstructionTypeCode(typestr, ClassS, quad, typeCode);
2172     s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n  ";
2173     s += TypeString(proto[2], typestr) + " __b1 = __b; \\\n  ";
2174     s += TypeString('s', typestr) + " __d1 = vgetq_lane_" +
2175       typeCode + "(__b1, __c);\\\n  vmulx" + type +
2176       "_" + typeCode +  "(__a1, __d1);";
2177     break;
2178   }
2179 
2180   case OpScalarVMulXLane: {
2181     bool dummy = false;
2182     char type = ClassifyType(typestr, dummy, dummy, dummy);
2183     if (type == 'f') type = 's';
2184     std::string typeCode = "";
2185     InstructionTypeCode(typestr, ClassS, quad, typeCode);
2186     s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n  ";
2187     s += TypeString(proto[2], typestr) + " __b1 = __b; \\\n  ";
2188     s += TypeString('s', typestr) + " __d1 = vget_lane_" +
2189       typeCode + "(__a1, 0);\\\n" +
2190       "  " + TypeString('s', typestr) + " __e1 = vget_lane_" +
2191       typeCode + "(__b1, __c);\\\n" +
2192       "  " + TypeString('s', typestr) + " __f1 = vmulx" + type + "_" +
2193       typeCode + "(__d1, __e1);\\\n" +
2194       "  " + TypeString('d', typestr) + " __g1;\\\n" +
2195       "  vset_lane_" + typeCode + "(__f1, __g1, __c);";
2196     break;
2197   }
2198 
2199   case OpScalarVMulXLaneQ: {
2200     bool dummy = false;
2201     char type = ClassifyType(typestr, dummy, dummy, dummy);
2202     if (type == 'f') type = 's';
2203     std::string typeCode = "";
2204     InstructionTypeCode(typestr, ClassS, quad, typeCode);
2205     s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n  ";
2206     s += TypeString(proto[2], typestr) + " __b1 = __b; \\\n  ";
2207     s += TypeString('s', typestr) + " __d1 = vget_lane_" +
2208       typeCode + "(__a1, 0);\\\n" +
2209       "  " + TypeString('s', typestr) + " __e1 = vgetq_lane_" +
2210       typeCode + "(__b1, __c);\\\n" +
2211       "  " + TypeString('s', typestr) + " __f1 = vmulx" + type + "_" +
2212       typeCode + "(__d1, __e1);\\\n" +
2213       "  " + TypeString('d', typestr) + " __g1;\\\n" +
2214       "  vset_lane_" + typeCode + "(__f1, __g1, 0);";
2215     break;
2216   }
2217   case OpScalarQDMullLane: {
2218     std::string typeCode = "";
2219     InstructionTypeCode(typestr, ClassS, quad, typeCode);
2220     s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n  ";
2221     s += TypeString(proto[2], typestr) + " __b1 = __b; \\\n  ";
2222     s += MangleName("vqdmull", typestr, ClassS) + "(__a1, " +
2223     "vget_lane_" + typeCode + "(__b1, __c));";
2224     break;
2225   }
2226   case OpScalarQDMullLaneQ: {
2227     std::string typeCode = "";
2228     InstructionTypeCode(typestr, ClassS, quad, typeCode);
2229     s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n  ";
2230     s += TypeString(proto[2], typestr) + " __b1 = __b; \\\n  ";
2231     s += MangleName("vqdmull", typestr, ClassS) + "(__a1, " +
2232     "vgetq_lane_" + typeCode + "(__b1, __c));";
2233     break;
2234   }
2235   case OpScalarQDMulHiLane: {
2236     std::string typeCode = "";
2237     InstructionTypeCode(typestr, ClassS, quad, typeCode);
2238     s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n  ";
2239     s += TypeString(proto[2], typestr) + " __b1 = __b; \\\n  ";
2240     s += MangleName("vqdmulh", typestr, ClassS) + "(__a1, " +
2241     "vget_lane_" + typeCode + "(__b1, __c));";
2242     break;
2243   }
2244   case OpScalarQDMulHiLaneQ: {
2245     std::string typeCode = "";
2246     InstructionTypeCode(typestr, ClassS, quad, typeCode);
2247     s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n  ";
2248     s += TypeString(proto[2], typestr) + " __b1 = __b; \\\n  ";
2249     s += MangleName("vqdmulh", typestr, ClassS) + "(__a1, " +
2250     "vgetq_lane_" + typeCode + "(__b1, __c));";
2251     break;
2252   }
2253   case OpScalarQRDMulHiLane: {
2254     std::string typeCode = "";
2255     InstructionTypeCode(typestr, ClassS, quad, typeCode);
2256     s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n  ";
2257     s += TypeString(proto[2], typestr) + " __b1 = __b; \\\n  ";
2258     s += MangleName("vqrdmulh", typestr, ClassS) + "(__a1, " +
2259     "vget_lane_" + typeCode + "(__b1, __c));";
2260     break;
2261   }
2262   case OpScalarQRDMulHiLaneQ: {
2263     std::string typeCode = "";
2264     InstructionTypeCode(typestr, ClassS, quad, typeCode);
2265     s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n  ";
2266     s += TypeString(proto[2], typestr) + " __b1 = __b; \\\n  ";
2267     s += MangleName("vqrdmulh", typestr, ClassS) + "(__a1, " +
2268     "vgetq_lane_" + typeCode + "(__b1, __c));";
2269     break;
2270   }
2271   case OpScalarGetLane:{
2272     std::string typeCode = "";
2273     InstructionTypeCode(typestr, ClassS, quad, typeCode);
2274     s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n  ";
2275 
2276     std::string intType = quad ? "int16x8_t" : "int16x4_t";
2277     std::string intName = quad ? "vgetq" : "vget";
2278 
2279     // reinterpret float16 vector as int16 vector
2280     s += intType + " __a2 = *(" + intType + " *)(&__a1);\\\n";
2281 
2282     s += "  int16_t __a3 = " + intName + "_lane_s16(__a2, __b);\\\n";
2283 
2284     // reinterpret int16 vector as float16 vector
2285     s += "  float16_t __a4 = *(float16_t *)(&__a3);\\\n";
2286     s += "  __a4;";
2287     break;
2288   }
2289   case OpScalarSetLane:{
2290     std::string typeCode = "";
2291     InstructionTypeCode(typestr, ClassS, quad, typeCode);
2292     s += TypeString(proto[1], typestr) + " __a1 = __a;\\\n  ";
2293 
2294     std::string origType = quad ? "float16x8_t" : "float16x4_t";
2295     std::string intType = quad ? "int16x8_t" : "int16x4_t";
2296     std::string intName = quad ? "vsetq" : "vset";
2297 
2298     // reinterpret float16_t as int16_t
2299     s += "int16_t __a2 = *(int16_t *)(&__a1);\\\n";
2300     // reinterpret float16 vector as int16 vector
2301     s += "  " + intType + " __b2 = *(" + intType + " *)(&__b);\\\n";
2302 
2303     s += "  " + intType + " __b3 = " + intName + "_lane_s16(__a2, __b2, __c);\\\n";
2304 
2305     // reinterpret int16 vector as float16 vector
2306     s += "  " + origType + " __b4 = *(" + origType + " *)(&__b3);\\\n";
2307     s += "__b4;";
2308     break;
2309   }
2310 
2311   default:
2312     PrintFatalError("unknown OpKind!");
2313   }
2314   return s;
2315 }
2316 
2317 static unsigned GetNeonEnum(const std::string &proto, StringRef typestr) {
2318   unsigned mod = proto[0];
2319 
2320   if (mod == 'v' || mod == 'f' || mod == 'F')
2321     mod = proto[1];
2322 
2323   bool quad = false;
2324   bool poly = false;
2325   bool usgn = false;
2326   bool scal = false;
2327   bool cnst = false;
2328   bool pntr = false;
2329 
2330   // Base type to get the type string for.
2331   char type = ClassifyType(typestr, quad, poly, usgn);
2332 
2333   // Based on the modifying character, change the type and width if necessary.
2334   type = ModType(mod, type, quad, poly, usgn, scal, cnst, pntr);
2335 
2336   NeonTypeFlags::EltType ET;
2337   switch (type) {
2338     case 'c':
2339       ET = poly ? NeonTypeFlags::Poly8 : NeonTypeFlags::Int8;
2340       break;
2341     case 's':
2342       ET = poly ? NeonTypeFlags::Poly16 : NeonTypeFlags::Int16;
2343       break;
2344     case 'i':
2345       ET = NeonTypeFlags::Int32;
2346       break;
2347     case 'l':
2348       ET = poly ? NeonTypeFlags::Poly64 : NeonTypeFlags::Int64;
2349       break;
2350     case 'k':
2351       ET = NeonTypeFlags::Poly128;
2352       break;
2353     case 'h':
2354       ET = NeonTypeFlags::Float16;
2355       break;
2356     case 'f':
2357       ET = NeonTypeFlags::Float32;
2358       break;
2359     case 'd':
2360       ET = NeonTypeFlags::Float64;
2361       break;
2362     default:
2363       PrintFatalError("unhandled type!");
2364   }
2365   NeonTypeFlags Flags(ET, usgn, quad && proto[1] != 'g');
2366   return Flags.getFlags();
2367 }
2368 
2369 // We don't check 'a' in this function, because for builtin function the
2370 // argument matching to 'a' uses a vector type splatted from a scalar type.
2371 static bool ProtoHasScalar(const std::string proto)
2372 {
2373   return (proto.find('s') != std::string::npos
2374           || proto.find('z') != std::string::npos
2375           || proto.find('r') != std::string::npos
2376           || proto.find('b') != std::string::npos
2377           || proto.find('$') != std::string::npos
2378           || proto.find('y') != std::string::npos
2379           || proto.find('o') != std::string::npos);
2380 }
2381 
2382 // Generate the definition for this intrinsic, e.g. __builtin_neon_cls(a)
2383 static std::string GenBuiltin(const std::string &name, const std::string &proto,
2384                               StringRef typestr, ClassKind ck) {
2385   std::string s;
2386 
2387   // If this builtin returns a struct 2, 3, or 4 vectors, pass it as an implicit
2388   // sret-like argument.
2389   bool sret = IsMultiVecProto(proto[0]);
2390 
2391   bool define = UseMacro(proto);
2392 
2393   // Check if the prototype has a scalar operand with the type of the vector
2394   // elements.  If not, bitcasting the args will take care of arg checking.
2395   // The actual signedness etc. will be taken care of with special enums.
2396   if (!ProtoHasScalar(proto))
2397     ck = ClassB;
2398 
2399   if (proto[0] != 'v') {
2400     std::string ts = TypeString(proto[0], typestr);
2401 
2402     if (define) {
2403       if (sret)
2404         s += ts + " r; ";
2405       else
2406         s += "(" + ts + ")";
2407     } else if (sret) {
2408       s += ts + " r; ";
2409     } else {
2410       s += "return (" + ts + ")";
2411     }
2412   }
2413 
2414   bool splat = proto.find('a') != std::string::npos;
2415 
2416   s += "__builtin_neon_";
2417   if (splat) {
2418     // Call the non-splat builtin: chop off the "_n" suffix from the name.
2419     std::string vname(name, 0, name.size()-2);
2420     s += MangleName(vname, typestr, ck);
2421   } else {
2422     s += MangleName(name, typestr, ck);
2423   }
2424   s += "(";
2425 
2426   // Pass the address of the return variable as the first argument to sret-like
2427   // builtins.
2428   if (sret)
2429     s += "&r, ";
2430 
2431   char arg = 'a';
2432   for (unsigned i = 1, e = proto.size(); i != e; ++i, ++arg) {
2433     std::string args = std::string(&arg, 1);
2434 
2435     // Use the local temporaries instead of the macro arguments.
2436     args = "__" + args;
2437 
2438     bool argQuad = false;
2439     bool argPoly = false;
2440     bool argUsgn = false;
2441     bool argScalar = false;
2442     bool dummy = false;
2443     char argType = ClassifyType(typestr, argQuad, argPoly, argUsgn);
2444     argType = ModType(proto[i], argType, argQuad, argPoly, argUsgn, argScalar,
2445                       dummy, dummy);
2446 
2447     // Handle multiple-vector values specially, emitting each subvector as an
2448     // argument to the __builtin.
2449     unsigned NumOfVec = 0;
2450     if (proto[i] >= '2' && proto[i] <= '4') {
2451       NumOfVec = proto[i] - '0';
2452     } else if (proto[i] >= 'B' && proto[i] <= 'D') {
2453       NumOfVec = proto[i] - 'A' + 1;
2454     }
2455 
2456     if (NumOfVec > 0) {
2457       // Check if an explicit cast is needed.
2458       if (argType != 'c' || argPoly || argUsgn)
2459         args = (argQuad ? "(int8x16_t)" : "(int8x8_t)") + args;
2460 
2461       for (unsigned vi = 0, ve = NumOfVec; vi != ve; ++vi) {
2462         s += args + ".val[" + utostr(vi) + "]";
2463         if ((vi + 1) < ve)
2464           s += ", ";
2465       }
2466       if ((i + 1) < e)
2467         s += ", ";
2468 
2469       continue;
2470     }
2471 
2472     if (splat && (i + 1) == e)
2473       args = Duplicate(GetNumElements(typestr, argQuad), typestr, args);
2474 
2475     // Check if an explicit cast is needed.
2476     if ((splat || !argScalar) &&
2477         ((ck == ClassB && argType != 'c') || argPoly || argUsgn)) {
2478       std::string argTypeStr = "c";
2479       if (ck != ClassB)
2480         argTypeStr = argType;
2481       if (argQuad)
2482         argTypeStr = "Q" + argTypeStr;
2483       args = "(" + TypeString('d', argTypeStr) + ")" + args;
2484     }
2485 
2486     s += args;
2487     if ((i + 1) < e)
2488       s += ", ";
2489   }
2490 
2491   // Extra constant integer to hold type class enum for this function, e.g. s8
2492   if (ck == ClassB)
2493     s += ", " + utostr(GetNeonEnum(proto, typestr));
2494 
2495   s += ");";
2496 
2497   if (proto[0] != 'v' && sret) {
2498     if (define)
2499       s += " r;";
2500     else
2501       s += " return r;";
2502   }
2503   return s;
2504 }
2505 
2506 static std::string GenBuiltinDef(const std::string &name,
2507                                  const std::string &proto,
2508                                  StringRef typestr, ClassKind ck) {
2509   std::string s("BUILTIN(__builtin_neon_");
2510 
2511   // If all types are the same size, bitcasting the args will take care
2512   // of arg checking.  The actual signedness etc. will be taken care of with
2513   // special enums.
2514   if (!ProtoHasScalar(proto))
2515     ck = ClassB;
2516 
2517   s += MangleName(name, typestr, ck);
2518   s += ", \"";
2519 
2520   for (unsigned i = 0, e = proto.size(); i != e; ++i)
2521     s += BuiltinTypeString(proto[i], typestr, ck, i == 0);
2522 
2523   // Extra constant integer to hold type class enum for this function, e.g. s8
2524   if (ck == ClassB)
2525     s += "i";
2526 
2527   s += "\", \"n\")";
2528   return s;
2529 }
2530 
2531 static std::string GenIntrinsic(const std::string &name,
2532                                 const std::string &proto,
2533                                 StringRef outTypeStr, StringRef inTypeStr,
2534                                 OpKind kind, ClassKind classKind) {
2535   assert(!proto.empty() && "");
2536   bool define = UseMacro(proto) && kind != OpUnavailable;
2537   std::string s;
2538 
2539   // static always inline + return type
2540   if (define)
2541     s += "#define ";
2542   else
2543     s += "__ai " + TypeString(proto[0], outTypeStr) + " ";
2544 
2545   // Function name with type suffix
2546   std::string mangledName = MangleName(name, outTypeStr, ClassS);
2547   if (outTypeStr != inTypeStr) {
2548     // If the input type is different (e.g., for vreinterpret), append a suffix
2549     // for the input type.  String off a "Q" (quad) prefix so that MangleName
2550     // does not insert another "q" in the name.
2551     unsigned typeStrOff = (inTypeStr[0] == 'Q' ? 1 : 0);
2552     StringRef inTypeNoQuad = inTypeStr.substr(typeStrOff);
2553     mangledName = MangleName(mangledName, inTypeNoQuad, ClassS);
2554   }
2555   s += mangledName;
2556 
2557   // Function arguments
2558   s += GenArgs(proto, inTypeStr, name);
2559 
2560   // Definition.
2561   if (define) {
2562     s += " __extension__ ({ \\\n  ";
2563     s += GenMacroLocals(proto, inTypeStr, name);
2564   } else if (kind == OpUnavailable) {
2565     s += " __attribute__((unavailable));\n";
2566     return s;
2567   } else
2568     s += " {\n  ";
2569 
2570   if (kind != OpNone)
2571     s += GenOpString(name, kind, proto, outTypeStr);
2572   else
2573     s += GenBuiltin(name, proto, outTypeStr, classKind);
2574   if (define)
2575     s += " })";
2576   else
2577     s += " }";
2578   s += "\n";
2579   return s;
2580 }
2581 
2582 /// run - Read the records in arm_neon.td and output arm_neon.h.  arm_neon.h
2583 /// is comprised of type definitions and function declarations.
2584 void NeonEmitter::run(raw_ostream &OS) {
2585   OS <<
2586     "/*===---- arm_neon.h - ARM Neon intrinsics ------------------------------"
2587     "---===\n"
2588     " *\n"
2589     " * Permission is hereby granted, free of charge, to any person obtaining "
2590     "a copy\n"
2591     " * of this software and associated documentation files (the \"Software\"),"
2592     " to deal\n"
2593     " * in the Software without restriction, including without limitation the "
2594     "rights\n"
2595     " * to use, copy, modify, merge, publish, distribute, sublicense, "
2596     "and/or sell\n"
2597     " * copies of the Software, and to permit persons to whom the Software is\n"
2598     " * furnished to do so, subject to the following conditions:\n"
2599     " *\n"
2600     " * The above copyright notice and this permission notice shall be "
2601     "included in\n"
2602     " * all copies or substantial portions of the Software.\n"
2603     " *\n"
2604     " * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, "
2605     "EXPRESS OR\n"
2606     " * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF "
2607     "MERCHANTABILITY,\n"
2608     " * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT "
2609     "SHALL THE\n"
2610     " * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR "
2611     "OTHER\n"
2612     " * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, "
2613     "ARISING FROM,\n"
2614     " * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER "
2615     "DEALINGS IN\n"
2616     " * THE SOFTWARE.\n"
2617     " *\n"
2618     " *===--------------------------------------------------------------------"
2619     "---===\n"
2620     " */\n\n";
2621 
2622   OS << "#ifndef __ARM_NEON_H\n";
2623   OS << "#define __ARM_NEON_H\n\n";
2624 
2625   OS << "#if !defined(__ARM_NEON)\n";
2626   OS << "#error \"NEON support not enabled\"\n";
2627   OS << "#endif\n\n";
2628 
2629   OS << "#include <stdint.h>\n\n";
2630 
2631   // Emit NEON-specific scalar typedefs.
2632   OS << "typedef float float32_t;\n";
2633   OS << "typedef __fp16 float16_t;\n";
2634 
2635   OS << "#ifdef __aarch64__\n";
2636   OS << "typedef double float64_t;\n";
2637   OS << "#endif\n\n";
2638 
2639   // For now, signedness of polynomial types depends on target
2640   OS << "#ifdef __aarch64__\n";
2641   OS << "typedef uint8_t poly8_t;\n";
2642   OS << "typedef uint16_t poly16_t;\n";
2643   OS << "typedef uint64_t poly64_t;\n";
2644   OS << "typedef __uint128_t poly128_t;\n";
2645   OS << "#else\n";
2646   OS << "typedef int8_t poly8_t;\n";
2647   OS << "typedef int16_t poly16_t;\n";
2648   OS << "#endif\n";
2649 
2650   // Emit Neon vector typedefs.
2651   std::string TypedefTypes(
2652       "cQcsQsiQilQlUcQUcUsQUsUiQUiUlQUlhQhfQfdQdPcQPcPsQPsPlQPl");
2653   SmallVector<StringRef, 24> TDTypeVec;
2654   ParseTypes(0, TypedefTypes, TDTypeVec);
2655 
2656   // Emit vector typedefs.
2657   bool isA64 = false;
2658   bool preinsert;
2659   bool postinsert;
2660   for (unsigned i = 0, e = TDTypeVec.size(); i != e; ++i) {
2661     bool dummy, quad = false, poly = false;
2662     char type = ClassifyType(TDTypeVec[i], quad, poly, dummy);
2663     preinsert = false;
2664     postinsert = false;
2665 
2666     if (type == 'd' || (type == 'l' && poly)) {
2667       preinsert = isA64? false: true;
2668       isA64 = true;
2669     } else {
2670       postinsert = isA64? true: false;
2671       isA64 = false;
2672     }
2673     if (postinsert)
2674       OS << "#endif\n";
2675     if (preinsert)
2676       OS << "#ifdef __aarch64__\n";
2677 
2678     if (poly)
2679       OS << "typedef __attribute__((neon_polyvector_type(";
2680     else
2681       OS << "typedef __attribute__((neon_vector_type(";
2682 
2683     unsigned nElts = GetNumElements(TDTypeVec[i], quad);
2684     OS << utostr(nElts) << "))) ";
2685     if (nElts < 10)
2686       OS << " ";
2687 
2688     OS << TypeString('s', TDTypeVec[i]);
2689     OS << " " << TypeString('d', TDTypeVec[i]) << ";\n";
2690 
2691   }
2692   postinsert = isA64? true: false;
2693   if (postinsert)
2694     OS << "#endif\n";
2695   OS << "\n";
2696 
2697   // Emit struct typedefs.
2698   isA64 = false;
2699   for (unsigned vi = 2; vi != 5; ++vi) {
2700     for (unsigned i = 0, e = TDTypeVec.size(); i != e; ++i) {
2701       bool dummy, quad = false, poly = false;
2702       char type = ClassifyType(TDTypeVec[i], quad, poly, dummy);
2703       preinsert = false;
2704       postinsert = false;
2705 
2706       if (type == 'd' || (type == 'l' && poly)) {
2707         preinsert = isA64? false: true;
2708         isA64 = true;
2709       } else {
2710         postinsert = isA64? true: false;
2711         isA64 = false;
2712       }
2713       if (postinsert)
2714         OS << "#endif\n";
2715       if (preinsert)
2716         OS << "#ifdef __aarch64__\n";
2717 
2718       std::string ts = TypeString('d', TDTypeVec[i]);
2719       std::string vs = TypeString('0' + vi, TDTypeVec[i]);
2720       OS << "typedef struct " << vs << " {\n";
2721       OS << "  " << ts << " val";
2722       OS << "[" << utostr(vi) << "]";
2723       OS << ";\n} ";
2724       OS << vs << ";\n";
2725       OS << "\n";
2726     }
2727   }
2728   postinsert = isA64? true: false;
2729   if (postinsert)
2730     OS << "#endif\n";
2731   OS << "\n";
2732 
2733   OS<<"#define __ai static inline __attribute__((__always_inline__, __nodebug__))\n\n";
2734 
2735   std::vector<Record*> RV = Records.getAllDerivedDefinitions("Inst");
2736 
2737   StringMap<ClassKind> EmittedMap;
2738 
2739   // Emit vmovl, vmull and vabd intrinsics first so they can be used by other
2740   // intrinsics.  (Some of the saturating multiply instructions are also
2741   // used to implement the corresponding "_lane" variants, but tablegen
2742   // sorts the records into alphabetical order so that the "_lane" variants
2743   // come after the intrinsics they use.)
2744   emitIntrinsic(OS, Records.getDef("VMOVL"), EmittedMap);
2745   emitIntrinsic(OS, Records.getDef("VMULL"), EmittedMap);
2746   emitIntrinsic(OS, Records.getDef("VABD"), EmittedMap);
2747   emitIntrinsic(OS, Records.getDef("VABDL"), EmittedMap);
2748 
2749   // ARM intrinsics must be emitted before AArch64 intrinsics to ensure
2750   // common intrinsics appear only once in the output stream.
2751   // The check for uniquiness is done in emitIntrinsic.
2752   // Emit ARM intrinsics.
2753   for (unsigned i = 0, e = RV.size(); i != e; ++i) {
2754     Record *R = RV[i];
2755 
2756     // Skip AArch64 intrinsics; they will be emitted at the end.
2757     bool isA64 = R->getValueAsBit("isA64");
2758     if (isA64)
2759       continue;
2760 
2761     if (R->getName() != "VMOVL" && R->getName() != "VMULL" &&
2762         R->getName() != "VABD")
2763       emitIntrinsic(OS, R, EmittedMap);
2764   }
2765 
2766   // Emit AArch64-specific intrinsics.
2767   OS << "#ifdef __aarch64__\n";
2768 
2769   emitIntrinsic(OS, Records.getDef("VMULL_P64"), EmittedMap);
2770   emitIntrinsic(OS, Records.getDef("VMOVL_HIGH"), EmittedMap);
2771   emitIntrinsic(OS, Records.getDef("VMULL_HIGH"), EmittedMap);
2772   emitIntrinsic(OS, Records.getDef("VABDL_HIGH"), EmittedMap);
2773 
2774   for (unsigned i = 0, e = RV.size(); i != e; ++i) {
2775     Record *R = RV[i];
2776 
2777     // Skip ARM intrinsics already included above.
2778     bool isA64 = R->getValueAsBit("isA64");
2779     if (!isA64)
2780       continue;
2781 
2782     // Skip crypto temporarily, and will emit them all together at the end.
2783     bool isCrypto = R->getValueAsBit("isCrypto");
2784     if (isCrypto)
2785       continue;
2786 
2787     emitIntrinsic(OS, R, EmittedMap);
2788   }
2789 
2790   OS << "#endif\n\n";
2791 
2792   // Now emit all the crypto intrinsics together
2793   OS << "#ifdef __ARM_FEATURE_CRYPTO\n";
2794 
2795   for (unsigned i = 0, e = RV.size(); i != e; ++i) {
2796     Record *R = RV[i];
2797 
2798     bool isCrypto = R->getValueAsBit("isCrypto");
2799     if (!isCrypto)
2800       continue;
2801 
2802     emitIntrinsic(OS, R, EmittedMap);
2803   }
2804 
2805 
2806   OS << "#endif\n\n";
2807 
2808   OS << "#undef __ai\n\n";
2809   OS << "#endif /* __ARM_NEON_H */\n";
2810 }
2811 
2812 /// emitIntrinsic - Write out the arm_neon.h header file definitions for the
2813 /// intrinsics specified by record R checking for intrinsic uniqueness.
2814 void NeonEmitter::emitIntrinsic(raw_ostream &OS, Record *R,
2815                                 StringMap<ClassKind> &EmittedMap) {
2816   std::string name = R->getValueAsString("Name");
2817   std::string Proto = R->getValueAsString("Prototype");
2818   std::string Types = R->getValueAsString("Types");
2819 
2820   SmallVector<StringRef, 16> TypeVec;
2821   ParseTypes(R, Types, TypeVec);
2822 
2823   OpKind kind = OpMap[R->getValueAsDef("Operand")->getName()];
2824 
2825   ClassKind classKind = ClassNone;
2826   if (R->getSuperClasses().size() >= 2)
2827     classKind = ClassMap[R->getSuperClasses()[1]];
2828   if (classKind == ClassNone && kind == OpNone)
2829     PrintFatalError(R->getLoc(), "Builtin has no class kind");
2830 
2831   for (unsigned ti = 0, te = TypeVec.size(); ti != te; ++ti) {
2832     if (kind == OpReinterpret) {
2833       bool outQuad = false;
2834       bool dummy = false;
2835       (void)ClassifyType(TypeVec[ti], outQuad, dummy, dummy);
2836       for (unsigned srcti = 0, srcte = TypeVec.size();
2837            srcti != srcte; ++srcti) {
2838         bool inQuad = false;
2839         (void)ClassifyType(TypeVec[srcti], inQuad, dummy, dummy);
2840         if (srcti == ti || inQuad != outQuad)
2841           continue;
2842         std::string s = GenIntrinsic(name, Proto, TypeVec[ti], TypeVec[srcti],
2843                                      OpCast, ClassS);
2844         if (EmittedMap.count(s))
2845           continue;
2846         EmittedMap[s] = ClassS;
2847         OS << s;
2848       }
2849     } else {
2850       std::string s =
2851           GenIntrinsic(name, Proto, TypeVec[ti], TypeVec[ti], kind, classKind);
2852       if (EmittedMap.count(s))
2853         continue;
2854       EmittedMap[s] = classKind;
2855       OS << s;
2856     }
2857   }
2858   OS << "\n";
2859 }
2860 
2861 static unsigned RangeFromType(const char mod, StringRef typestr) {
2862   // base type to get the type string for.
2863   bool quad = false, dummy = false;
2864   char type = ClassifyType(typestr, quad, dummy, dummy);
2865   type = ModType(mod, type, quad, dummy, dummy, dummy, dummy, dummy);
2866 
2867   switch (type) {
2868     case 'c':
2869       return (8 << (int)quad) - 1;
2870     case 'h':
2871     case 's':
2872       return (4 << (int)quad) - 1;
2873     case 'f':
2874     case 'i':
2875       return (2 << (int)quad) - 1;
2876     case 'd':
2877     case 'l':
2878       return (1 << (int)quad) - 1;
2879     case 'k':
2880       return 0;
2881     default:
2882       PrintFatalError("unhandled type!");
2883   }
2884 }
2885 
2886 static unsigned RangeScalarShiftImm(const char mod, StringRef typestr) {
2887   // base type to get the type string for.
2888   bool dummy = false;
2889   char type = ClassifyType(typestr, dummy, dummy, dummy);
2890   type = ModType(mod, type, dummy, dummy, dummy, dummy, dummy, dummy);
2891 
2892   switch (type) {
2893     case 'c':
2894       return 7;
2895     case 'h':
2896     case 's':
2897       return 15;
2898     case 'f':
2899     case 'i':
2900       return 31;
2901     case 'd':
2902     case 'l':
2903       return 63;
2904     case 'k':
2905       return 127;
2906     default:
2907       PrintFatalError("unhandled type!");
2908   }
2909 }
2910 
2911 /// Generate the ARM and AArch64 intrinsic range checking code for
2912 /// shift/lane immediates, checking for unique declarations.
2913 void
2914 NeonEmitter::genIntrinsicRangeCheckCode(raw_ostream &OS,
2915                                         StringMap<ClassKind> &A64IntrinsicMap,
2916                                         bool isA64RangeCheck) {
2917   std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst");
2918   StringMap<OpKind> EmittedMap;
2919 
2920   // Generate the intrinsic range checking code for shift/lane immediates.
2921   if (isA64RangeCheck)
2922     OS << "#ifdef GET_NEON_AARCH64_IMMEDIATE_CHECK\n";
2923   else
2924     OS << "#ifdef GET_NEON_IMMEDIATE_CHECK\n";
2925 
2926   for (unsigned i = 0, e = RV.size(); i != e; ++i) {
2927     Record *R = RV[i];
2928 
2929     OpKind k = OpMap[R->getValueAsDef("Operand")->getName()];
2930     if (k != OpNone)
2931       continue;
2932 
2933     std::string name = R->getValueAsString("Name");
2934     std::string Proto = R->getValueAsString("Prototype");
2935     std::string Types = R->getValueAsString("Types");
2936     std::string Rename = name + "@" + Proto;
2937 
2938     // Functions with 'a' (the splat code) in the type prototype should not get
2939     // their own builtin as they use the non-splat variant.
2940     if (Proto.find('a') != std::string::npos)
2941       continue;
2942 
2943     // Functions which do not have an immediate do not need to have range
2944     // checking code emitted.
2945     size_t immPos = Proto.find('i');
2946     if (immPos == std::string::npos)
2947       continue;
2948 
2949     SmallVector<StringRef, 16> TypeVec;
2950     ParseTypes(R, Types, TypeVec);
2951 
2952     if (R->getSuperClasses().size() < 2)
2953       PrintFatalError(R->getLoc(), "Builtin has no class kind");
2954 
2955     ClassKind ck = ClassMap[R->getSuperClasses()[1]];
2956     if (!ProtoHasScalar(Proto))
2957       ck = ClassB;
2958 
2959     // Do not include AArch64 range checks if not generating code for AArch64.
2960     bool isA64 = R->getValueAsBit("isA64");
2961     if (!isA64RangeCheck && isA64)
2962       continue;
2963 
2964     // Include ARM range checks in AArch64 but only if ARM intrinsics are not
2965     // redefined by AArch64 to handle new types.
2966     if (isA64RangeCheck && !isA64 && A64IntrinsicMap.count(Rename)) {
2967       ClassKind &A64CK = A64IntrinsicMap[Rename];
2968       if (A64CK == ck && ck != ClassNone)
2969         continue;
2970     }
2971 
2972     for (unsigned ti = 0, te = TypeVec.size(); ti != te; ++ti) {
2973       std::string namestr, shiftstr, rangestr;
2974 
2975       if (R->getValueAsBit("isVCVT_N")) {
2976         // VCVT between floating- and fixed-point values takes an immediate
2977         // in the range [1, 32] for f32, or [1, 64] for f64.
2978         ck = ClassB;
2979         if (name.find("32") != std::string::npos)
2980           rangestr = "l = 1; u = 31"; // upper bound = l + u
2981         else if (name.find("64") != std::string::npos)
2982           rangestr = "l = 1; u = 63";
2983         else
2984           PrintFatalError(R->getLoc(),
2985               "Fixed point convert name should contains \"32\" or \"64\"");
2986 
2987       } else if (R->getValueAsBit("isScalarShift")) {
2988         // Right shifts have an 'r' in the name, left shifts do not.  Convert
2989         // instructions have the same bounds and right shifts.
2990         if (name.find('r') != std::string::npos ||
2991             name.find("cvt") != std::string::npos)
2992           rangestr = "l = 1; ";
2993 
2994         unsigned upBound = RangeScalarShiftImm(Proto[immPos - 1], TypeVec[ti]);
2995         // Narrow shift has half the upper bound
2996         if (R->getValueAsBit("isScalarNarrowShift"))
2997           upBound /= 2;
2998 
2999         rangestr += "u = " + utostr(upBound);
3000       } else if (R->getValueAsBit("isShift")) {
3001         // Builtins which are overloaded by type will need to have their upper
3002         // bound computed at Sema time based on the type constant.
3003         shiftstr = ", true";
3004 
3005         // Right shifts have an 'r' in the name, left shifts do not.
3006         if (name.find('r') != std::string::npos)
3007           rangestr = "l = 1; ";
3008 
3009         rangestr += "u = RFT(TV" + shiftstr + ")";
3010       } else if (ck == ClassB) {
3011         // ClassB intrinsics have a type (and hence lane number) that is only
3012         // known at runtime.
3013         assert(immPos > 0 && "unexpected immediate operand");
3014         if (R->getValueAsBit("isLaneQ"))
3015           rangestr = "u = RFT(TV, false, true)";
3016         else
3017           rangestr = "u = RFT(TV, false, false)";
3018       } else {
3019         // The immediate generally refers to a lane in the preceding argument.
3020         assert(immPos > 0 && "unexpected immediate operand");
3021         rangestr =
3022             "u = " + utostr(RangeFromType(Proto[immPos - 1], TypeVec[ti]));
3023       }
3024       // Make sure cases appear only once by uniquing them in a string map.
3025       namestr = MangleName(name, TypeVec[ti], ck);
3026       if (EmittedMap.count(namestr))
3027         continue;
3028       EmittedMap[namestr] = OpNone;
3029 
3030       // Calculate the index of the immediate that should be range checked.
3031       unsigned immidx = 0;
3032 
3033       // Builtins that return a struct of multiple vectors have an extra
3034       // leading arg for the struct return.
3035       if (IsMultiVecProto(Proto[0]))
3036         ++immidx;
3037 
3038       // Add one to the index for each argument until we reach the immediate
3039       // to be checked.  Structs of vectors are passed as multiple arguments.
3040       for (unsigned ii = 1, ie = Proto.size(); ii != ie; ++ii) {
3041         switch (Proto[ii]) {
3042         default:
3043           immidx += 1;
3044           break;
3045         case '2':
3046         case 'B':
3047           immidx += 2;
3048           break;
3049         case '3':
3050         case 'C':
3051           immidx += 3;
3052           break;
3053         case '4':
3054         case 'D':
3055           immidx += 4;
3056           break;
3057         case 'i':
3058           ie = ii + 1;
3059           break;
3060         }
3061       }
3062       OS << "case NEON::BI__builtin_neon_";
3063       OS << MangleName(name, TypeVec[ti], ck) << ": i = " << immidx << "; "
3064          << rangestr << "; break;\n";
3065     }
3066   }
3067   OS << "#endif\n\n";
3068 }
3069 
3070 /// Generate the ARM and AArch64 overloaded type checking code for
3071 /// SemaChecking.cpp, checking for unique builtin declarations.
3072 void
3073 NeonEmitter::genOverloadTypeCheckCode(raw_ostream &OS,
3074                                       StringMap<ClassKind> &A64IntrinsicMap,
3075                                       bool isA64TypeCheck) {
3076   std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst");
3077 
3078   // Generate the overloaded type checking code for SemaChecking.cpp
3079   if (isA64TypeCheck)
3080     OS << "#ifdef GET_NEON_AARCH64_OVERLOAD_CHECK\n";
3081   else
3082     OS << "#ifdef GET_NEON_OVERLOAD_CHECK\n";
3083 
3084   for (unsigned i = 0, e = RV.size(); i != e; ++i) {
3085     Record *R = RV[i];
3086     OpKind k = OpMap[R->getValueAsDef("Operand")->getName()];
3087     if (k != OpNone)
3088       continue;
3089 
3090     std::string Proto = R->getValueAsString("Prototype");
3091     std::string Types = R->getValueAsString("Types");
3092     std::string name = R->getValueAsString("Name");
3093     std::string Rename = name + "@" + Proto;
3094 
3095     // Functions with 'a' (the splat code) in the type prototype should not get
3096     // their own builtin as they use the non-splat variant.
3097     if (Proto.find('a') != std::string::npos)
3098       continue;
3099 
3100     // Functions which have a scalar argument cannot be overloaded, no need to
3101     // check them if we are emitting the type checking code.
3102     if (ProtoHasScalar(Proto))
3103       continue;
3104 
3105     SmallVector<StringRef, 16> TypeVec;
3106     ParseTypes(R, Types, TypeVec);
3107 
3108     if (R->getSuperClasses().size() < 2)
3109       PrintFatalError(R->getLoc(), "Builtin has no class kind");
3110 
3111     // Do not include AArch64 type checks if not generating code for AArch64.
3112     bool isA64 = R->getValueAsBit("isA64");
3113     if (!isA64TypeCheck && isA64)
3114       continue;
3115 
3116     // Include ARM  type check in AArch64 but only if ARM intrinsics
3117     // are not redefined in AArch64 to handle new types, e.g. "vabd" is a SIntr
3118     // redefined in AArch64 to handle an additional 2 x f64 type.
3119     ClassKind ck = ClassMap[R->getSuperClasses()[1]];
3120     if (isA64TypeCheck && !isA64 && A64IntrinsicMap.count(Rename)) {
3121       ClassKind &A64CK = A64IntrinsicMap[Rename];
3122       if (A64CK == ck && ck != ClassNone)
3123         continue;
3124     }
3125 
3126     int si = -1, qi = -1;
3127     uint64_t mask = 0, qmask = 0;
3128     for (unsigned ti = 0, te = TypeVec.size(); ti != te; ++ti) {
3129       // Generate the switch case(s) for this builtin for the type validation.
3130       bool quad = false, poly = false, usgn = false;
3131       (void) ClassifyType(TypeVec[ti], quad, poly, usgn);
3132 
3133       if (quad) {
3134         qi = ti;
3135         qmask |= 1ULL << GetNeonEnum(Proto, TypeVec[ti]);
3136       } else {
3137         si = ti;
3138         mask |= 1ULL << GetNeonEnum(Proto, TypeVec[ti]);
3139       }
3140     }
3141 
3142     // Check if the builtin function has a pointer or const pointer argument.
3143     int PtrArgNum = -1;
3144     bool HasConstPtr = false;
3145     for (unsigned arg = 1, arge = Proto.size(); arg != arge; ++arg) {
3146       char ArgType = Proto[arg];
3147       if (ArgType == 'c') {
3148         HasConstPtr = true;
3149         PtrArgNum = arg - 1;
3150         break;
3151       }
3152       if (ArgType == 'p') {
3153         PtrArgNum = arg - 1;
3154         break;
3155       }
3156     }
3157     // For sret builtins, adjust the pointer argument index.
3158     if (PtrArgNum >= 0 && IsMultiVecProto(Proto[0]))
3159       PtrArgNum += 1;
3160 
3161     // Omit type checking for the pointer arguments of vld1_lane, vld1_dup,
3162     // and vst1_lane intrinsics.  Using a pointer to the vector element
3163     // type with one of those operations causes codegen to select an aligned
3164     // load/store instruction.  If you want an unaligned operation,
3165     // the pointer argument needs to have less alignment than element type,
3166     // so just accept any pointer type.
3167     if (name == "vld1_lane" || name == "vld1_dup" || name == "vst1_lane") {
3168       PtrArgNum = -1;
3169       HasConstPtr = false;
3170     }
3171 
3172     if (mask) {
3173       OS << "case NEON::BI__builtin_neon_";
3174       OS << MangleName(name, TypeVec[si], ClassB) << ": mask = "
3175          << "0x" << utohexstr(mask) << "ULL";
3176       if (PtrArgNum >= 0)
3177         OS << "; PtrArgNum = " << PtrArgNum;
3178       if (HasConstPtr)
3179         OS << "; HasConstPtr = true";
3180       OS << "; break;\n";
3181     }
3182     if (qmask) {
3183       OS << "case NEON::BI__builtin_neon_";
3184       OS << MangleName(name, TypeVec[qi], ClassB) << ": mask = "
3185          << "0x" << utohexstr(qmask) << "ULL";
3186       if (PtrArgNum >= 0)
3187         OS << "; PtrArgNum = " << PtrArgNum;
3188       if (HasConstPtr)
3189         OS << "; HasConstPtr = true";
3190       OS << "; break;\n";
3191     }
3192   }
3193   OS << "#endif\n\n";
3194 }
3195 
3196 /// genBuiltinsDef: Generate the BuiltinsARM.def and  BuiltinsAArch64.def
3197 /// declaration of builtins, checking for unique builtin declarations.
3198 void NeonEmitter::genBuiltinsDef(raw_ostream &OS) {
3199   std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst");
3200   StringMap<OpKind> EmittedMap;
3201 
3202   // Generate BuiltinsNEON.
3203   OS << "#ifdef GET_NEON_BUILTINS\n";
3204 
3205   for (unsigned i = 0, e = RV.size(); i != e; ++i) {
3206     Record *R = RV[i];
3207     OpKind k = OpMap[R->getValueAsDef("Operand")->getName()];
3208     if (k != OpNone)
3209       continue;
3210 
3211     std::string Proto = R->getValueAsString("Prototype");
3212     std::string name = R->getValueAsString("Name");
3213     std::string Rename = name + "@" + Proto;
3214 
3215     // Functions with 'a' (the splat code) in the type prototype should not get
3216     // their own builtin as they use the non-splat variant.
3217     if (Proto.find('a') != std::string::npos)
3218       continue;
3219 
3220     std::string Types = R->getValueAsString("Types");
3221     SmallVector<StringRef, 16> TypeVec;
3222     ParseTypes(R, Types, TypeVec);
3223 
3224     if (R->getSuperClasses().size() < 2)
3225       PrintFatalError(R->getLoc(), "Builtin has no class kind");
3226 
3227     ClassKind ck = ClassMap[R->getSuperClasses()[1]];
3228 
3229     for (unsigned ti = 0, te = TypeVec.size(); ti != te; ++ti) {
3230       // Generate the declaration for this builtin, ensuring
3231       // that each unique BUILTIN() macro appears only once in the output
3232       // stream.
3233       std::string bd = GenBuiltinDef(name, Proto, TypeVec[ti], ck);
3234       if (EmittedMap.count(bd))
3235         continue;
3236 
3237       EmittedMap[bd] = OpNone;
3238       OS << bd << "\n";
3239     }
3240   }
3241   OS << "#endif\n\n";
3242 }
3243 
3244 /// runHeader - Emit a file with sections defining:
3245 /// 1. the NEON section of BuiltinsARM.def and BuiltinsAArch64.def.
3246 /// 2. the SemaChecking code for the type overload checking.
3247 /// 3. the SemaChecking code for validation of intrinsic immediate arguments.
3248 void NeonEmitter::runHeader(raw_ostream &OS) {
3249   std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst");
3250 
3251   // build a map of AArch64 intriniscs to be used in uniqueness checks.
3252   StringMap<ClassKind> A64IntrinsicMap;
3253   for (unsigned i = 0, e = RV.size(); i != e; ++i) {
3254     Record *R = RV[i];
3255 
3256     bool isA64 = R->getValueAsBit("isA64");
3257     if (!isA64)
3258       continue;
3259 
3260     ClassKind CK = ClassNone;
3261     if (R->getSuperClasses().size() >= 2)
3262       CK = ClassMap[R->getSuperClasses()[1]];
3263 
3264     std::string Name = R->getValueAsString("Name");
3265     std::string Proto = R->getValueAsString("Prototype");
3266     std::string Rename = Name + "@" + Proto;
3267     if (A64IntrinsicMap.count(Rename))
3268       continue;
3269     A64IntrinsicMap[Rename] = CK;
3270   }
3271 
3272   // Generate shared BuiltinsXXX.def
3273   genBuiltinsDef(OS);
3274 
3275   // Generate ARM overloaded type checking code for SemaChecking.cpp
3276   genOverloadTypeCheckCode(OS, A64IntrinsicMap, false);
3277 
3278   // Generate AArch64 overloaded type checking code for SemaChecking.cpp
3279   genOverloadTypeCheckCode(OS, A64IntrinsicMap, true);
3280 
3281   // Generate ARM range checking code for shift/lane immediates.
3282   genIntrinsicRangeCheckCode(OS, A64IntrinsicMap, false);
3283 
3284   // Generate the AArch64 range checking code for shift/lane immediates.
3285   genIntrinsicRangeCheckCode(OS, A64IntrinsicMap, true);
3286 }
3287 
3288 /// GenTest - Write out a test for the intrinsic specified by the name and
3289 /// type strings, including the embedded patterns for FileCheck to match.
3290 static std::string GenTest(const std::string &name,
3291                            const std::string &proto,
3292                            StringRef outTypeStr, StringRef inTypeStr,
3293                            bool isShift, bool isHiddenLOp,
3294                            ClassKind ck, const std::string &InstName,
3295                            bool isA64,
3296                            std::string & testFuncProto) {
3297   assert(!proto.empty() && "");
3298   std::string s;
3299 
3300   // Function name with type suffix
3301   std::string mangledName = MangleName(name, outTypeStr, ClassS);
3302   if (outTypeStr != inTypeStr) {
3303     // If the input type is different (e.g., for vreinterpret), append a suffix
3304     // for the input type.  String off a "Q" (quad) prefix so that MangleName
3305     // does not insert another "q" in the name.
3306     unsigned typeStrOff = (inTypeStr[0] == 'Q' ? 1 : 0);
3307     StringRef inTypeNoQuad = inTypeStr.substr(typeStrOff);
3308     mangledName = MangleName(mangledName, inTypeNoQuad, ClassS);
3309   }
3310 
3311   // todo: GenerateChecksForIntrinsic does not generate CHECK
3312   // for aarch64 instructions yet
3313   std::vector<std::string> FileCheckPatterns;
3314   if (!isA64) {
3315     GenerateChecksForIntrinsic(name, proto, outTypeStr, inTypeStr, ck, InstName,
3316                                isHiddenLOp, FileCheckPatterns);
3317     s+= "// CHECK_ARM: test_" + mangledName + "\n";
3318   }
3319   s += "// CHECK_AARCH64: test_" + mangledName + "\n";
3320 
3321   // Emit the FileCheck patterns.
3322   // If for any reason we do not want to emit a check, mangledInst
3323   // will be the empty string.
3324   if (FileCheckPatterns.size()) {
3325     for (std::vector<std::string>::const_iterator i = FileCheckPatterns.begin(),
3326                                                   e = FileCheckPatterns.end();
3327          i != e;
3328          ++i) {
3329       s += "// CHECK_ARM: " + *i + "\n";
3330     }
3331   }
3332 
3333   // Emit the start of the test function.
3334 
3335   testFuncProto = TypeString(proto[0], outTypeStr) + " test_" + mangledName + "(";
3336   char arg = 'a';
3337   std::string comma;
3338   for (unsigned i = 1, e = proto.size(); i != e; ++i, ++arg) {
3339     // Do not create arguments for values that must be immediate constants.
3340     if (proto[i] == 'i')
3341       continue;
3342     testFuncProto += comma + TypeString(proto[i], inTypeStr) + " ";
3343     testFuncProto.push_back(arg);
3344     comma = ", ";
3345   }
3346   testFuncProto += ")";
3347 
3348   s+= testFuncProto;
3349   s+= " {\n  ";
3350 
3351   if (proto[0] != 'v')
3352     s += "return ";
3353   s += mangledName + "(";
3354   arg = 'a';
3355   for (unsigned i = 1, e = proto.size(); i != e; ++i, ++arg) {
3356     if (proto[i] == 'i') {
3357       // For immediate operands, test the maximum value.
3358       if (isShift)
3359         s += "1"; // FIXME
3360       else
3361         // The immediate generally refers to a lane in the preceding argument.
3362         s += utostr(RangeFromType(proto[i-1], inTypeStr));
3363     } else {
3364       s.push_back(arg);
3365     }
3366     if ((i + 1) < e)
3367       s += ", ";
3368   }
3369   s += ");\n}\n\n";
3370   return s;
3371 }
3372 
3373 /// Write out all intrinsic tests for the specified target, checking
3374 /// for intrinsic test uniqueness.
3375 void NeonEmitter::genTargetTest(raw_ostream &OS, StringMap<OpKind> &EmittedMap,
3376                                 bool isA64GenTest) {
3377   if (isA64GenTest)
3378     OS << "#ifdef __aarch64__\n";
3379 
3380   std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst");
3381   for (unsigned i = 0, e = RV.size(); i != e; ++i) {
3382     Record *R = RV[i];
3383     std::string name = R->getValueAsString("Name");
3384     std::string Proto = R->getValueAsString("Prototype");
3385     std::string Types = R->getValueAsString("Types");
3386     bool isShift = R->getValueAsBit("isShift");
3387     std::string InstName = R->getValueAsString("InstName");
3388     bool isHiddenLOp = R->getValueAsBit("isHiddenLInst");
3389     bool isA64 = R->getValueAsBit("isA64");
3390 
3391     // do not include AArch64 intrinsic test if not generating
3392     // code for AArch64
3393     if (!isA64GenTest && isA64)
3394       continue;
3395 
3396     SmallVector<StringRef, 16> TypeVec;
3397     ParseTypes(R, Types, TypeVec);
3398 
3399     ClassKind ck = ClassMap[R->getSuperClasses()[1]];
3400     OpKind kind = OpMap[R->getValueAsDef("Operand")->getName()];
3401     if (kind == OpUnavailable)
3402       continue;
3403     for (unsigned ti = 0, te = TypeVec.size(); ti != te; ++ti) {
3404       if (kind == OpReinterpret) {
3405         bool outQuad = false;
3406         bool dummy = false;
3407         (void)ClassifyType(TypeVec[ti], outQuad, dummy, dummy);
3408         for (unsigned srcti = 0, srcte = TypeVec.size();
3409              srcti != srcte; ++srcti) {
3410           bool inQuad = false;
3411           (void)ClassifyType(TypeVec[srcti], inQuad, dummy, dummy);
3412           if (srcti == ti || inQuad != outQuad)
3413             continue;
3414           std::string testFuncProto;
3415           std::string s = GenTest(name, Proto, TypeVec[ti], TypeVec[srcti],
3416                                   isShift, isHiddenLOp, ck, InstName, isA64,
3417                                   testFuncProto);
3418           if (EmittedMap.count(testFuncProto))
3419             continue;
3420           EmittedMap[testFuncProto] = kind;
3421           OS << s << "\n";
3422         }
3423       } else {
3424         std::string testFuncProto;
3425         std::string s = GenTest(name, Proto, TypeVec[ti], TypeVec[ti], isShift,
3426                                 isHiddenLOp, ck, InstName, isA64, testFuncProto);
3427         if (EmittedMap.count(testFuncProto))
3428           continue;
3429         EmittedMap[testFuncProto] = kind;
3430         OS << s << "\n";
3431       }
3432     }
3433   }
3434 
3435   if (isA64GenTest)
3436     OS << "#endif\n";
3437 }
3438 /// runTests - Write out a complete set of tests for all of the Neon
3439 /// intrinsics.
3440 void NeonEmitter::runTests(raw_ostream &OS) {
3441   OS << "// RUN: %clang_cc1 -triple thumbv7s-apple-darwin -target-abi "
3442         "apcs-gnu\\\n"
3443         "// RUN:  -target-cpu swift -ffreestanding -Os -S -o - %s\\\n"
3444         "// RUN:  | FileCheck %s -check-prefix=CHECK_ARM\n"
3445         "\n"
3446         "// RUN: %clang_cc1 -triple aarch64-none-linux-gnu \\\n"
3447         "// RUN -target-feature +neon  -ffreestanding -S -o - %s \\\n"
3448         "// RUN:  | FileCheck %s -check-prefix=CHECK_AARCH64\n"
3449         "\n"
3450         "// REQUIRES: long_tests\n"
3451         "\n"
3452         "#include <arm_neon.h>\n"
3453         "\n";
3454 
3455   // ARM tests must be emitted before AArch64 tests to ensure
3456   // tests for intrinsics that are common to ARM and AArch64
3457   // appear only once in the output stream.
3458   // The check for uniqueness is done in genTargetTest.
3459   StringMap<OpKind> EmittedMap;
3460 
3461   genTargetTest(OS, EmittedMap, false);
3462 
3463   genTargetTest(OS, EmittedMap, true);
3464 }
3465 
3466 namespace clang {
3467 void EmitNeon(RecordKeeper &Records, raw_ostream &OS) {
3468   NeonEmitter(Records).run(OS);
3469 }
3470 void EmitNeonSema(RecordKeeper &Records, raw_ostream &OS) {
3471   NeonEmitter(Records).runHeader(OS);
3472 }
3473 void EmitNeonTest(RecordKeeper &Records, raw_ostream &OS) {
3474   NeonEmitter(Records).runTests(OS);
3475 }
3476 } // End namespace clang
3477