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