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