NEON support for _lane ops, and multiplies by scalar.
[oota-llvm.git] / utils / TableGen / NeonEmitter.cpp
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 //===----------------------------------------------------------------------===//
15
16 #include "NeonEmitter.h"
17 #include "llvm/ADT/SmallString.h"
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/ADT/StringExtras.h"
20 #include <string>
21
22 using namespace llvm;
23
24 static void ParseTypes(Record *r, std::string &s,
25                        SmallVectorImpl<StringRef> &TV) {
26   const char *data = s.data();
27   int len = 0;
28   
29   for (unsigned i = 0, e = s.size(); i != e; ++i, ++len) {
30     if (data[len] == 'P' || data[len] == 'Q' || data[len] == 'U')
31       continue;
32     
33     switch (data[len]) {
34       case 'c':
35       case 's':
36       case 'i':
37       case 'l':
38       case 'h':
39       case 'f':
40         break;
41       default:
42         throw TGError(r->getLoc(),
43                       "Unexpected letter: " + std::string(data + len, 1));
44         break;
45     }
46     TV.push_back(StringRef(data, len + 1));
47     data += len + 1;
48     len = -1;
49   }
50 }
51
52 static char Widen(const char t) {
53   switch (t) {
54     case 'c':
55       return 's';
56     case 's':
57       return 'i';
58     case 'i':
59       return 'l';
60     default: throw "unhandled type in widen!";
61   }
62   return '\0';
63 }
64
65 static char Narrow(const char t) {
66   switch (t) {
67     case 's':
68       return 'c';
69     case 'i':
70       return 's';
71     case 'l':
72       return 'i';
73     case 'f':
74       return 'h';
75     default: throw "unhandled type in widen!";
76   }
77   return '\0';
78 }
79
80 static char ClassifyType(StringRef ty, bool &quad, bool &poly, bool &usgn) {
81   unsigned off = 0;
82   
83   // remember quad.
84   if (ty[off] == 'Q') {
85     quad = true;
86     ++off;
87   }
88   
89   // remember poly.
90   if (ty[off] == 'P') {
91     poly = true;
92     ++off;
93   }
94   
95   // remember unsigned.
96   if (ty[off] == 'U') {
97     usgn = true;
98     ++off;
99   }
100   
101   // base type to get the type string for.
102   return ty[off];
103 }
104
105 static char ModType(const char mod, char type, bool &quad, bool &poly,
106                     bool &usgn, bool &scal, bool &cnst, bool &pntr) {
107   switch (mod) {
108     case 't':
109       if (poly) {
110         poly = false;
111         usgn = true;
112       }
113       break;
114     case 'u':
115       usgn = true;
116     case 'x':
117       poly = false;
118       if (type == 'f')
119         type = 'i';
120       break;
121     case 'f':
122       if (type == 'h')
123         quad = true;
124       type = 'f';
125       usgn = false;
126       break;
127     case 'w':
128       type = Widen(type);
129       quad = true;
130       break;
131     case 'n':
132       type = Widen(type);
133       break;
134     case 'l':
135       type = 'l';
136       scal = true;
137       usgn = true;
138       break;
139     case 's':
140     case 'a':
141       scal = true;
142       break;
143     case 'k':
144       quad = true;
145       break;
146     case 'c':
147       cnst = true;
148     case 'p':
149       usgn = false;
150       poly = false;
151       pntr = true;
152       scal = true;
153       break;
154     case 'h':
155       type = Narrow(type);
156       if (type == 'h')
157         quad = false;
158       break;
159     case 'e':
160       type = Narrow(type);
161       usgn = true;
162       break;
163     default:
164       break;
165   }
166   return type;
167 }
168
169 static std::string TypeString(const char mod, StringRef typestr,
170                               bool ret = false) {
171   bool quad = false;
172   bool poly = false;
173   bool usgn = false;
174   bool scal = false;
175   bool cnst = false;
176   bool pntr = false;
177   
178   if (mod == 'v')
179     return "void";
180   if (mod == 'i')
181     return "int";
182   
183   // base type to get the type string for.
184   char type = ClassifyType(typestr, quad, poly, usgn);
185   
186   // Based on the modifying character, change the type and width if necessary.
187   type = ModType(mod, type, quad, poly, usgn, scal, cnst, pntr);
188   
189   SmallString<128> s;
190   
191   if (ret)
192     s += "__neon_";
193   
194   if (usgn)
195     s.push_back('u');
196   
197   switch (type) {
198     case 'c':
199       s += poly ? "poly8" : "int8";
200       if (scal)
201         break;
202       s += quad ? "x16" : "x8";
203       break;
204     case 's':
205       s += poly ? "poly16" : "int16";
206       if (scal)
207         break;
208       s += quad ? "x8" : "x4";
209       break;
210     case 'i':
211       s += "int32";
212       if (scal)
213         break;
214       s += quad ? "x4" : "x2";
215       break;
216     case 'l':
217       s += "int64";
218       if (scal)
219         break;
220       s += quad ? "x2" : "x1";
221       break;
222     case 'h':
223       s += "float16";
224       if (scal)
225         break;
226       s += quad ? "x8" : "x4";
227       break;
228     case 'f':
229       s += "float32";
230       if (scal)
231         break;
232       s += quad ? "x4" : "x2";
233       break;
234     default:
235       throw "unhandled type!";
236       break;
237   }
238
239   if (mod == '2')
240     s += "x2";
241   if (mod == '3')
242     s += "x3";
243   if (mod == '4')
244     s += "x4";
245   
246   // Append _t, finishing the type string typedef type.
247   s += "_t";
248   
249   if (cnst)
250     s += " const";
251   
252   if (pntr)
253     s += " *";
254   
255   return s.str();
256 }
257
258 static std::string BuiltinTypeString(const char mod, StringRef typestr,
259                                      ClassKind ck, bool ret) {
260   bool quad = false;
261   bool poly = false;
262   bool usgn = false;
263   bool scal = false;
264   bool cnst = false;
265   bool pntr = false;
266   
267   if (mod == 'v')
268     return "v";
269   if (mod == 'i')
270     return "i";
271   
272   // base type to get the type string for.
273   char type = ClassifyType(typestr, quad, poly, usgn);
274   
275   // Based on the modifying character, change the type and width if necessary.
276   type = ModType(mod, type, quad, poly, usgn, scal, cnst, pntr);
277
278   if (pntr)
279     type = 'v';
280   
281   if (type == 'h') {
282     type = 's';
283     usgn = true;
284   }
285   usgn = usgn | poly | ((ck == ClassI || ck == ClassW) && scal && type != 'f');
286
287   if (scal) {
288     SmallString<128> s;
289
290     if (usgn)
291       s.push_back('U');
292     
293     if (type == 'l')
294       s += "LLi";
295     else
296       s.push_back(type);
297  
298     if (cnst)
299       s.push_back('C');
300     if (pntr)
301       s.push_back('*');
302     return s.str();
303   }
304
305   // Since the return value must be one type, return a vector type of the
306   // appropriate width which we will bitcast.
307   if (ret) {
308     if (mod == '2')
309       return quad ? "V32c" : "V16c";
310     if (mod == '3')
311       return quad ? "V48c" : "V24c";
312     if (mod == '4')
313       return quad ? "V64c" : "V32c";
314     if (mod == 'f' || (ck != ClassB && type == 'f'))
315       return quad ? "V4f" : "V2f";
316     if (ck != ClassB && type == 's')
317       return quad ? "V8s" : "V4s";
318     if (ck != ClassB && type == 'i')
319       return quad ? "V4i" : "V2i";
320     if (ck != ClassB && type == 'l')
321       return quad ? "V2LLi" : "V1LLi";
322     
323     return quad ? "V16c" : "V8c";
324   }    
325
326   // Non-return array types are passed as individual vectors.
327   if (mod == '2')
328     return quad ? "V16cV16c" : "V8cV8c";
329   if (mod == '3')
330     return quad ? "V16cV16cV16c" : "V8cV8cV8c";
331   if (mod == '4')
332     return quad ? "V16cV16cV16cV16c" : "V8cV8cV8cV8c";
333
334   if (mod == 'f' || (ck != ClassB && type == 'f'))
335     return quad ? "V4f" : "V2f";
336   if (ck != ClassB && type == 's')
337     return quad ? "V8s" : "V4s";
338   if (ck != ClassB && type == 'i')
339     return quad ? "V4i" : "V2i";
340   if (ck != ClassB && type == 'l')
341     return quad ? "V2LLi" : "V1LLi";
342   
343   return quad ? "V16c" : "V8c";
344 }
345
346 // Turn "vst2_lane" into "vst2q_lane_f32", etc.
347 static std::string MangleName(const std::string &name, StringRef typestr,
348                               ClassKind ck) {
349   if (name == "vcvt_f32_f16")
350     return name;
351   
352   bool quad = false;
353   bool poly = false;
354   bool usgn = false;
355   char type = ClassifyType(typestr, quad, poly, usgn);
356
357   std::string s = name;
358   
359   switch (type) {
360   case 'c':
361     switch (ck) {
362     case ClassS: s += poly ? "_p8" : usgn ? "_u8" : "_s8"; break;
363     case ClassI: s += "_i8"; break;
364     case ClassW: s += "_8"; break;
365     default: break;
366     }
367     break;
368   case 's':
369     switch (ck) {
370     case ClassS: s += poly ? "_p16" : usgn ? "_u16" : "_s16"; break;
371     case ClassI: s += "_i16"; break;
372     case ClassW: s += "_16"; break;
373     default: break;
374     }
375     break;
376   case 'i':
377     switch (ck) {
378     case ClassS: s += usgn ? "_u32" : "_s32"; break;
379     case ClassI: s += "_i32"; break;
380     case ClassW: s += "_32"; break;
381     default: break;
382     }
383     break;
384   case 'l':
385     switch (ck) {
386     case ClassS: s += usgn ? "_u64" : "_s64"; break;
387     case ClassI: s += "_i64"; break;
388     case ClassW: s += "_64"; break;
389     default: break;
390     }
391     break;
392   case 'h':
393     switch (ck) {
394     case ClassS:
395     case ClassI: s += "_f16"; break;
396     case ClassW: s += "_16"; break;
397     default: break;
398     }
399     break;
400   case 'f':
401     switch (ck) {
402     case ClassS:
403     case ClassI: s += "_f32"; break;
404     case ClassW: s += "_32"; break;
405     default: break;
406     }
407     break;
408   default:
409     throw "unhandled type!";
410     break;
411   }
412   if (ck == ClassB)
413     s += "_v";
414     
415   // Insert a 'q' before the first '_' character so that it ends up before 
416   // _lane or _n on vector-scalar operations.
417   if (quad) {
418     size_t pos = s.find('_');
419     s = s.insert(pos, "q");
420   }
421   return s;
422 }
423
424 // Generate the string "(argtype a, argtype b, ...)"
425 static std::string GenArgs(const std::string &proto, StringRef typestr) {
426   bool define = proto.find('i') != std::string::npos;
427   char arg = 'a';
428   
429   std::string s;
430   s += "(";
431   
432   for (unsigned i = 1, e = proto.size(); i != e; ++i, ++arg) {
433     if (!define) {
434       s += TypeString(proto[i], typestr);
435       s.push_back(' ');
436     }
437     s.push_back(arg);
438     if ((i + 1) < e)
439       s += ", ";
440   }
441   
442   s += ")";
443   return s;
444 }
445
446 static std::string Duplicate(StringRef typestr, const std::string &a) {
447   bool dummy, quad = false;
448   char type = ClassifyType(typestr, quad, dummy, dummy);
449   unsigned nElts = 0;
450   switch (type) {
451     case 'c': nElts = 8; break;
452     case 's': nElts = 4; break;
453     case 'i': nElts = 2; break;
454     case 'l': nElts = 1; break;
455     case 'h': nElts = 4; break;
456     case 'f': nElts = 2; break;
457   }
458   nElts <<= quad;
459
460   std::string s;
461   
462   s = "(__neon_" + TypeString('d', typestr) + "){ ";
463   for (unsigned i = 0; i != nElts; ++i) {
464     s += a;
465     if ((i + 1) < nElts)
466       s += ", ";
467   }
468   s += " }";
469   
470   return s;
471 }
472
473 // Generate the definition for this intrinsic, e.g. "a + b" for OpAdd.
474 // If structTypes is true, the NEON types are structs of vector types rather
475 // than vector types, and the call becomes "a.val + b.val"
476 static std::string GenOpString(OpKind op, const std::string &proto,
477                                StringRef typestr, bool structTypes = true) {
478   std::string ts = TypeString(proto[0], typestr);
479   std::string s = ts + " r; r";
480   
481   if (structTypes)
482     s += ".val";
483   
484   s += " = ";
485
486   std::string a, b, c;
487   if (proto.size() > 1)
488     a = (structTypes && proto[1] != 'l' && proto[1] != 's') ? "a.val" : "a";
489   b = structTypes ? "b.val" : "b";
490   c = structTypes ? "c.val" : "c";
491   
492   switch(op) {
493   case OpAdd:
494     s += a + " + " + b;
495     break;
496   case OpSub:
497     s += a + " - " + b;
498     break;
499   case OpMulN:
500     b = Duplicate(typestr, "b");
501   case OpMul:
502     s += a + " * " + b;
503     break;
504   case OpMlaN:
505     c = Duplicate(typestr, "c");
506   case OpMla:
507     s += a + " + ( " + b + " * " + c + " )";
508     break;
509   case OpMlsN:
510     c = Duplicate(typestr, "c");
511   case OpMls:
512     s += a + " - ( " + b + " * " + c + " )";
513     break;
514   case OpEq:
515     s += "(__neon_" + ts + ")(" + a + " == " + b + ")";
516     break;
517   case OpGe:
518     s += "(__neon_" + ts + ")(" + a + " >= " + b + ")";
519     break;
520   case OpLe:
521     s += "(__neon_" + ts + ")(" + a + " <= " + b + ")";
522     break;
523   case OpGt:
524     s += "(__neon_" + ts + ")(" + a + " > " + b + ")";
525     break;
526   case OpLt:
527     s += "(__neon_" + ts + ")(" + a + " < " + b + ")";
528     break;
529   case OpNeg:
530     s += " -" + a;
531     break;
532   case OpNot:
533     s += " ~" + a;
534     break;
535   case OpAnd:
536     s += a + " & " + b;
537     break;
538   case OpOr:
539     s += a + " | " + b;
540     break;
541   case OpXor:
542     s += a + " ^ " + b;
543     break;
544   case OpAndNot:
545     s += a + " & ~" + b;
546     break;
547   case OpOrNot:
548     s += a + " | ~" + b;
549     break;
550   case OpCast:
551     s += "(__neon_" + ts + ")" + a;
552     break;
553   case OpConcat:
554     s += "__builtin_shufflevector((__neon_int64x1_t)" + a;
555     s += ", (__neon_int64x1_t)" + b + ", 0, 1)";
556     break;
557   case OpHi:
558     s += "(__neon_int64x1_t)(((__neon_int64x2_t)" + a + ")[1])";
559     break;
560   case OpLo:
561     s += "(__neon_int64x1_t)(((__neon_int64x2_t)" + a + ")[0])";
562     break;
563   case OpDup:
564     s += Duplicate(typestr, a);
565     break;
566   default:
567     throw "unknown OpKind!";
568     break;
569   }
570   s += "; return r;";
571   return s;
572 }
573
574 static unsigned GetNeonEnum(const std::string &proto, StringRef typestr) {
575   unsigned mod = proto[0];
576   unsigned ret = 0;
577
578   if (mod == 'v' || mod == 'f')
579     mod = proto[1];
580
581   bool quad = false;
582   bool poly = false;
583   bool usgn = false;
584   bool scal = false;
585   bool cnst = false;
586   bool pntr = false;
587   
588   // base type to get the type string for.
589   char type = ClassifyType(typestr, quad, poly, usgn);
590   
591   // Based on the modifying character, change the type and width if necessary.
592   type = ModType(mod, type, quad, poly, usgn, scal, cnst, pntr);
593   
594   if (usgn)
595     ret |= 0x08;
596   if (quad)
597     ret |= 0x10;
598   
599   switch (type) {
600     case 'c': 
601       ret |= poly ? 5 : 0;
602       break;
603     case 's':
604       ret |= poly ? 6 : 1;
605       break;
606     case 'i':
607       ret |= 2;
608       break;
609     case 'l':
610       ret |= 3;
611       break;
612     case 'h':
613       ret |= 7;
614       break;
615     case 'f':
616       ret |= 4;
617       break;
618     default:
619       throw "unhandled type!";
620       break;
621   }
622   return ret;
623 }
624
625 // Generate the definition for this intrinsic, e.g. __builtin_neon_cls(a)
626 // If structTypes is true, the NEON types are structs of vector types rather
627 // than vector types, and the call becomes __builtin_neon_cls(a.val)
628 static std::string GenBuiltin(const std::string &name, const std::string &proto,
629                               StringRef typestr, ClassKind ck,
630                               bool structTypes = true) {
631   char arg = 'a';
632   std::string s;
633
634   bool unioning = (proto[0] == '2' || proto[0] == '3' || proto[0] == '4');
635   bool define = proto.find('i') != std::string::npos;
636
637   // If all types are the same size, bitcasting the args will take care 
638   // of arg checking.  The actual signedness etc. will be taken care of with
639   // special enums.
640   if (proto.find('s') == std::string::npos)
641     ck = ClassB;
642
643   if (proto[0] != 'v') {
644     std::string ts = TypeString(proto[0], typestr);
645     
646     if (define) {
647       if (proto[0] != 's')
648         s += "(" + ts + "){(__neon_" + ts + ")";
649     } else {
650       if (unioning) {
651         s += "union { ";
652         s += TypeString(proto[0], typestr, true) + " val; ";
653         s += TypeString(proto[0], typestr, false) + " s; ";
654         s += "} r;";
655       } else {
656         s += ts;
657       }
658       
659       s += " r; r";
660       if (structTypes && proto[0] != 's' && proto[0] != 'i' && proto[0] != 'l')
661         s += ".val";
662       
663       s += " = ";
664     }
665   }
666   
667   bool splat = proto.find('a') != std::string::npos;
668   
669   s += "__builtin_neon_";
670   if (splat) {
671     std::string vname(name, 0, name.size()-2);
672     s += MangleName(vname, typestr, ck);
673   } else {
674     s += MangleName(name, typestr, ck);
675   }
676   s += "(";
677   
678   for (unsigned i = 1, e = proto.size(); i != e; ++i, ++arg) {
679     // Handle multiple-vector values specially, emitting each subvector as an
680     // argument to the __builtin.
681     if (structTypes && (proto[i] == '2' || proto[i] == '3' || proto[i] == '4')){
682       for (unsigned vi = 0, ve = proto[i] - '0'; vi != ve; ++vi) {
683         s.push_back(arg);
684         s += ".val[" + utostr(vi) + "]";
685         if ((vi + 1) < ve)
686           s += ", ";
687       }
688       if ((i + 1) < e)
689         s += ", ";
690
691       continue;
692     }
693     
694     // Parenthesize the args from the macro.
695     if (define)
696       s.push_back('(');
697     
698     if (splat && (i + 1) == e) 
699       s += Duplicate(typestr, std::string(&arg, 1));
700     else
701       s.push_back(arg);
702
703     // Parenthesize the args from the macro.
704     if (define)
705       s.push_back(')');
706     
707     if (structTypes && proto[i] != 's' && proto[i] != 'i' && proto[i] != 'l' &&
708         proto[i] != 'p' && proto[i] != 'c' && proto[i] != 'a') {
709       s += ".val";
710     }
711     if ((i + 1) < e)
712       s += ", ";
713   }
714   
715   // Extra constant integer to hold type class enum for this function, e.g. s8
716   if (ck == ClassB)
717     s += ", " + utostr(GetNeonEnum(proto, typestr));
718   
719   if (define)
720     s += ")";
721   else
722     s += ");";
723
724   if (proto[0] != 'v') {
725     if (define) {
726       if (proto[0] != 's')
727         s += "}";
728     } else {
729       if (unioning)
730         s += " return r.s;";
731       else
732         s += " return r;";
733     }
734   }
735   return s;
736 }
737
738 static std::string GenBuiltinDef(const std::string &name, 
739                                  const std::string &proto,
740                                  StringRef typestr, ClassKind ck) {
741   std::string s("BUILTIN(__builtin_neon_");
742
743   // If all types are the same size, bitcasting the args will take care 
744   // of arg checking.  The actual signedness etc. will be taken care of with
745   // special enums.
746   if (proto.find('s') == std::string::npos)
747     ck = ClassB;
748   
749   s += MangleName(name, typestr, ck);
750   s += ", \"";
751   
752   for (unsigned i = 0, e = proto.size(); i != e; ++i)
753     s += BuiltinTypeString(proto[i], typestr, ck, i == 0);
754
755   // Extra constant integer to hold type class enum for this function, e.g. s8
756   if (ck == ClassB)
757     s += "i";
758   
759   s += "\", \"n\")";
760   return s;
761 }
762
763 void NeonEmitter::run(raw_ostream &OS) {
764   EmitSourceFileHeader("ARM NEON Header", OS);
765   
766   // FIXME: emit license into file?
767   
768   OS << "#ifndef __ARM_NEON_H\n";
769   OS << "#define __ARM_NEON_H\n\n";
770   
771   OS << "#ifndef __ARM_NEON__\n";
772   OS << "#error \"NEON support not enabled\"\n";
773   OS << "#endif\n\n";
774
775   OS << "#include <stdint.h>\n\n";
776
777   // Emit NEON-specific scalar typedefs.
778   // FIXME: probably need to do something better for polynomial types.
779   OS << "typedef float float32_t;\n";
780   OS << "typedef uint8_t poly8_t;\n";
781   OS << "typedef uint16_t poly16_t;\n";
782   OS << "typedef uint16_t float16_t;\n";
783
784   // Emit Neon vector typedefs.
785   std::string TypedefTypes("cQcsQsiQilQlUcQUcUsQUsUiQUiUlQUlhQhfQfPcQPcPsQPs");
786   SmallVector<StringRef, 24> TDTypeVec;
787   ParseTypes(0, TypedefTypes, TDTypeVec);
788
789   // Emit vector typedefs.
790   for (unsigned v = 1; v != 5; ++v) {
791     for (unsigned i = 0, e = TDTypeVec.size(); i != e; ++i) {
792       bool dummy, quad = false;
793       (void) ClassifyType(TDTypeVec[i], quad, dummy, dummy);
794       OS << "typedef __attribute__(( __vector_size__(";
795       
796       OS << utostr(8*v*(quad ? 2 : 1)) << ") )) ";
797       if (!quad)
798         OS << " ";
799       
800       OS << TypeString('s', TDTypeVec[i]);
801       OS << " __neon_";
802       
803       char t = (v == 1) ? 'd' : '0' + v;
804       OS << TypeString(t, TDTypeVec[i]) << ";\n";
805     }
806   }
807   OS << "\n";
808
809   // Emit struct typedefs.
810   for (unsigned vi = 1; vi != 5; ++vi) {
811     for (unsigned i = 0, e = TDTypeVec.size(); i != e; ++i) {
812       std::string ts = TypeString('d', TDTypeVec[i]);
813       std::string vs = (vi > 1) ? TypeString('0' + vi, TDTypeVec[i]) : ts;
814       OS << "typedef struct __" << vs << " {\n";
815       OS << "  __neon_" << ts << " val";
816       if (vi > 1)
817         OS << "[" << utostr(vi) << "]";
818       OS << ";\n} " << vs << ";\n\n";
819     }
820   }
821   
822   OS << "#define __ai static __attribute__((__always_inline__))\n\n";
823
824   std::vector<Record*> RV = Records.getAllDerivedDefinitions("Inst");
825   
826   // Unique the return+pattern types, and assign them.
827   for (unsigned i = 0, e = RV.size(); i != e; ++i) {
828     Record *R = RV[i];
829     std::string name = LowercaseString(R->getName());
830     std::string Proto = R->getValueAsString("Prototype");
831     std::string Types = R->getValueAsString("Types");
832     
833     SmallVector<StringRef, 16> TypeVec;
834     ParseTypes(R, Types, TypeVec);
835     
836     OpKind k = OpMap[R->getValueAsDef("Operand")->getName()];
837     
838     bool define = Proto.find('i') != std::string::npos;
839     
840     for (unsigned ti = 0, te = TypeVec.size(); ti != te; ++ti) {
841       assert(!Proto.empty() && "");
842       
843       // static always inline + return type
844       if (define)
845         OS << "#define";
846       else
847         OS << "__ai " << TypeString(Proto[0], TypeVec[ti]);
848       
849       // Function name with type suffix
850       OS << " " << MangleName(name, TypeVec[ti], ClassS);
851       
852       // Function arguments
853       OS << GenArgs(Proto, TypeVec[ti]);
854       
855       // Definition.
856       if (define)
857         OS << " ";
858       else
859         OS << " { ";
860       
861       if (k != OpNone) {
862         OS << GenOpString(k, Proto, TypeVec[ti]);
863       } else {
864         if (R->getSuperClasses().size() < 2)
865           throw TGError(R->getLoc(), "Builtin has no class kind");
866         
867         ClassKind ck = ClassMap[R->getSuperClasses()[1]];
868
869         if (ck == ClassNone)
870           throw TGError(R->getLoc(), "Builtin has no class kind");
871         OS << GenBuiltin(name, Proto, TypeVec[ti], ck);
872       }
873       if (!define)
874         OS << " }";
875       OS << "\n";
876     }
877     OS << "\n";
878   }
879   OS << "#undef __ai\n\n";
880   OS << "#endif /* __ARM_NEON_H */\n";
881 }
882
883 void NeonEmitter::runHeader(raw_ostream &OS) {
884   std::vector<Record*> RV = Records.getAllDerivedDefinitions("Inst");
885
886   StringMap<OpKind> EmittedMap;
887   
888   for (unsigned i = 0, e = RV.size(); i != e; ++i) {
889     Record *R = RV[i];
890
891     OpKind k = OpMap[R->getValueAsDef("Operand")->getName()];
892     if (k != OpNone)
893       continue;
894     
895     std::string name = LowercaseString(R->getName());
896     std::string Proto = R->getValueAsString("Prototype");
897     std::string Types = R->getValueAsString("Types");
898
899     if (Proto.find('a') != std::string::npos)
900       continue;
901       
902     SmallVector<StringRef, 16> TypeVec;
903     ParseTypes(R, Types, TypeVec);
904
905     if (R->getSuperClasses().size() < 2)
906       throw TGError(R->getLoc(), "Builtin has no class kind");
907     
908     ClassKind ck = ClassMap[R->getSuperClasses()[1]];
909     
910     for (unsigned ti = 0, te = TypeVec.size(); ti != te; ++ti) {
911       std::string bd = GenBuiltinDef(name, Proto, TypeVec[ti], ck);
912       if (EmittedMap.count(bd))
913         continue;
914       
915       EmittedMap[bd] = OpNone;
916       OS << bd << "\n";
917     }
918   }
919 }