blob: 7a703feb18b568ea58f7f9fc5b5bc26b6b50c3b1 [file] [log] [blame]
Peter Collingbourne51d77772011-10-06 13:03:08 +00001//===- NeonEmitter.h - 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#ifndef NEON_EMITTER_H
17#define NEON_EMITTER_H
18
19#include "llvm/TableGen/Record.h"
20#include "llvm/TableGen/TableGenBackend.h"
21#include "llvm/ADT/DenseMap.h"
22#include "llvm/ADT/StringMap.h"
23
24enum OpKind {
25 OpNone,
Jim Grosbach667381b2012-05-09 18:17:30 +000026 OpUnavailable,
Peter Collingbourne51d77772011-10-06 13:03:08 +000027 OpAdd,
28 OpAddl,
29 OpAddw,
30 OpSub,
31 OpSubl,
32 OpSubw,
33 OpMul,
34 OpMla,
35 OpMlal,
36 OpMls,
37 OpMlsl,
38 OpMulN,
39 OpMlaN,
40 OpMlsN,
41 OpMlalN,
42 OpMlslN,
43 OpMulLane,
44 OpMullLane,
45 OpMlaLane,
46 OpMlsLane,
47 OpMlalLane,
48 OpMlslLane,
49 OpQDMullLane,
50 OpQDMlalLane,
51 OpQDMlslLane,
52 OpQDMulhLane,
53 OpQRDMulhLane,
54 OpEq,
55 OpGe,
56 OpLe,
57 OpGt,
58 OpLt,
59 OpNeg,
60 OpNot,
61 OpAnd,
62 OpOr,
63 OpXor,
64 OpAndNot,
65 OpOrNot,
66 OpCast,
67 OpConcat,
68 OpDup,
69 OpDupLane,
70 OpHi,
71 OpLo,
72 OpSelect,
73 OpRev16,
74 OpRev32,
75 OpRev64,
76 OpReinterpret,
77 OpAbdl,
78 OpAba,
79 OpAbal
80};
81
82enum ClassKind {
83 ClassNone,
84 ClassI, // generic integer instruction, e.g., "i8" suffix
85 ClassS, // signed/unsigned/poly, e.g., "s8", "u8" or "p8" suffix
86 ClassW, // width-specific instruction, e.g., "8" suffix
87 ClassB // bitcast arguments with enum argument to specify type
88};
89
Bob Wilsonda95f732011-11-08 01:16:11 +000090/// NeonTypeFlags - Flags to identify the types for overloaded Neon
91/// builtins. These must be kept in sync with the flags in
92/// include/clang/Basic/TargetBuiltins.h.
93class NeonTypeFlags {
94 enum {
95 EltTypeMask = 0xf,
96 UnsignedFlag = 0x10,
97 QuadFlag = 0x20
98 };
99 uint32_t Flags;
100
101public:
102 enum EltType {
103 Int8,
104 Int16,
105 Int32,
106 Int64,
107 Poly8,
108 Poly16,
109 Float16,
110 Float32
111 };
112
113 NeonTypeFlags(unsigned F) : Flags(F) {}
114 NeonTypeFlags(EltType ET, bool IsUnsigned, bool IsQuad) : Flags(ET) {
115 if (IsUnsigned)
116 Flags |= UnsignedFlag;
117 if (IsQuad)
118 Flags |= QuadFlag;
119 }
120
121 uint32_t getFlags() const { return Flags; }
122};
123
Peter Collingbourne51d77772011-10-06 13:03:08 +0000124namespace llvm {
125
126 class NeonEmitter : public TableGenBackend {
127 RecordKeeper &Records;
128 StringMap<OpKind> OpMap;
129 DenseMap<Record*, ClassKind> ClassMap;
130
131 public:
132 NeonEmitter(RecordKeeper &R) : Records(R) {
133 OpMap["OP_NONE"] = OpNone;
Jim Grosbach667381b2012-05-09 18:17:30 +0000134 OpMap["OP_UNAVAILABLE"] = OpUnavailable;
Peter Collingbourne51d77772011-10-06 13:03:08 +0000135 OpMap["OP_ADD"] = OpAdd;
136 OpMap["OP_ADDL"] = OpAddl;
137 OpMap["OP_ADDW"] = OpAddw;
138 OpMap["OP_SUB"] = OpSub;
139 OpMap["OP_SUBL"] = OpSubl;
140 OpMap["OP_SUBW"] = OpSubw;
141 OpMap["OP_MUL"] = OpMul;
142 OpMap["OP_MLA"] = OpMla;
143 OpMap["OP_MLAL"] = OpMlal;
144 OpMap["OP_MLS"] = OpMls;
145 OpMap["OP_MLSL"] = OpMlsl;
146 OpMap["OP_MUL_N"] = OpMulN;
147 OpMap["OP_MLA_N"] = OpMlaN;
148 OpMap["OP_MLS_N"] = OpMlsN;
149 OpMap["OP_MLAL_N"] = OpMlalN;
150 OpMap["OP_MLSL_N"] = OpMlslN;
151 OpMap["OP_MUL_LN"]= OpMulLane;
152 OpMap["OP_MULL_LN"] = OpMullLane;
153 OpMap["OP_MLA_LN"]= OpMlaLane;
154 OpMap["OP_MLS_LN"]= OpMlsLane;
155 OpMap["OP_MLAL_LN"] = OpMlalLane;
156 OpMap["OP_MLSL_LN"] = OpMlslLane;
157 OpMap["OP_QDMULL_LN"] = OpQDMullLane;
158 OpMap["OP_QDMLAL_LN"] = OpQDMlalLane;
159 OpMap["OP_QDMLSL_LN"] = OpQDMlslLane;
160 OpMap["OP_QDMULH_LN"] = OpQDMulhLane;
161 OpMap["OP_QRDMULH_LN"] = OpQRDMulhLane;
162 OpMap["OP_EQ"] = OpEq;
163 OpMap["OP_GE"] = OpGe;
164 OpMap["OP_LE"] = OpLe;
165 OpMap["OP_GT"] = OpGt;
166 OpMap["OP_LT"] = OpLt;
167 OpMap["OP_NEG"] = OpNeg;
168 OpMap["OP_NOT"] = OpNot;
169 OpMap["OP_AND"] = OpAnd;
170 OpMap["OP_OR"] = OpOr;
171 OpMap["OP_XOR"] = OpXor;
172 OpMap["OP_ANDN"] = OpAndNot;
173 OpMap["OP_ORN"] = OpOrNot;
174 OpMap["OP_CAST"] = OpCast;
175 OpMap["OP_CONC"] = OpConcat;
176 OpMap["OP_HI"] = OpHi;
177 OpMap["OP_LO"] = OpLo;
178 OpMap["OP_DUP"] = OpDup;
179 OpMap["OP_DUP_LN"] = OpDupLane;
180 OpMap["OP_SEL"] = OpSelect;
181 OpMap["OP_REV16"] = OpRev16;
182 OpMap["OP_REV32"] = OpRev32;
183 OpMap["OP_REV64"] = OpRev64;
184 OpMap["OP_REINT"] = OpReinterpret;
185 OpMap["OP_ABDL"] = OpAbdl;
186 OpMap["OP_ABA"] = OpAba;
187 OpMap["OP_ABAL"] = OpAbal;
188
189 Record *SI = R.getClass("SInst");
190 Record *II = R.getClass("IInst");
191 Record *WI = R.getClass("WInst");
192 ClassMap[SI] = ClassS;
193 ClassMap[II] = ClassI;
194 ClassMap[WI] = ClassW;
195 }
196
197 // run - Emit arm_neon.h.inc
198 void run(raw_ostream &o);
199
200 // runHeader - Emit all the __builtin prototypes used in arm_neon.h
201 void runHeader(raw_ostream &o);
202
203 // runTests - Emit tests for all the Neon intrinsics.
204 void runTests(raw_ostream &o);
205
206 private:
207 void emitIntrinsic(raw_ostream &OS, Record *R);
208 };
209
210} // End llvm namespace
211
212#endif