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