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 "Record.h" 20 #include "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 namespace llvm { 90 91 class NeonEmitter : public TableGenBackend { 92 RecordKeeper &Records; 93 StringMap<OpKind> OpMap; 94 DenseMap<Record*, ClassKind> ClassMap; 95 96 public: NeonEmitter(RecordKeeper & R)97 NeonEmitter(RecordKeeper &R) : Records(R) { 98 OpMap["OP_NONE"] = OpNone; 99 OpMap["OP_ADD"] = OpAdd; 100 OpMap["OP_ADDL"] = OpAddl; 101 OpMap["OP_ADDW"] = OpAddw; 102 OpMap["OP_SUB"] = OpSub; 103 OpMap["OP_SUBL"] = OpSubl; 104 OpMap["OP_SUBW"] = OpSubw; 105 OpMap["OP_MUL"] = OpMul; 106 OpMap["OP_MLA"] = OpMla; 107 OpMap["OP_MLAL"] = OpMlal; 108 OpMap["OP_MLS"] = OpMls; 109 OpMap["OP_MLSL"] = OpMlsl; 110 OpMap["OP_MUL_N"] = OpMulN; 111 OpMap["OP_MLA_N"] = OpMlaN; 112 OpMap["OP_MLS_N"] = OpMlsN; 113 OpMap["OP_MLAL_N"] = OpMlalN; 114 OpMap["OP_MLSL_N"] = OpMlslN; 115 OpMap["OP_MUL_LN"]= OpMulLane; 116 OpMap["OP_MULL_LN"] = OpMullLane; 117 OpMap["OP_MLA_LN"]= OpMlaLane; 118 OpMap["OP_MLS_LN"]= OpMlsLane; 119 OpMap["OP_MLAL_LN"] = OpMlalLane; 120 OpMap["OP_MLSL_LN"] = OpMlslLane; 121 OpMap["OP_QDMULL_LN"] = OpQDMullLane; 122 OpMap["OP_QDMLAL_LN"] = OpQDMlalLane; 123 OpMap["OP_QDMLSL_LN"] = OpQDMlslLane; 124 OpMap["OP_QDMULH_LN"] = OpQDMulhLane; 125 OpMap["OP_QRDMULH_LN"] = OpQRDMulhLane; 126 OpMap["OP_EQ"] = OpEq; 127 OpMap["OP_GE"] = OpGe; 128 OpMap["OP_LE"] = OpLe; 129 OpMap["OP_GT"] = OpGt; 130 OpMap["OP_LT"] = OpLt; 131 OpMap["OP_NEG"] = OpNeg; 132 OpMap["OP_NOT"] = OpNot; 133 OpMap["OP_AND"] = OpAnd; 134 OpMap["OP_OR"] = OpOr; 135 OpMap["OP_XOR"] = OpXor; 136 OpMap["OP_ANDN"] = OpAndNot; 137 OpMap["OP_ORN"] = OpOrNot; 138 OpMap["OP_CAST"] = OpCast; 139 OpMap["OP_CONC"] = OpConcat; 140 OpMap["OP_HI"] = OpHi; 141 OpMap["OP_LO"] = OpLo; 142 OpMap["OP_DUP"] = OpDup; 143 OpMap["OP_DUP_LN"] = OpDupLane; 144 OpMap["OP_SEL"] = OpSelect; 145 OpMap["OP_REV16"] = OpRev16; 146 OpMap["OP_REV32"] = OpRev32; 147 OpMap["OP_REV64"] = OpRev64; 148 OpMap["OP_REINT"] = OpReinterpret; 149 OpMap["OP_ABDL"] = OpAbdl; 150 OpMap["OP_ABA"] = OpAba; 151 OpMap["OP_ABAL"] = OpAbal; 152 153 Record *SI = R.getClass("SInst"); 154 Record *II = R.getClass("IInst"); 155 Record *WI = R.getClass("WInst"); 156 ClassMap[SI] = ClassS; 157 ClassMap[II] = ClassI; 158 ClassMap[WI] = ClassW; 159 } 160 161 // run - Emit arm_neon.h.inc 162 void run(raw_ostream &o); 163 164 // runHeader - Emit all the __builtin prototypes used in arm_neon.h 165 void runHeader(raw_ostream &o); 166 167 // runTests - Emit tests for all the Neon intrinsics. 168 void runTests(raw_ostream &o); 169 170 private: 171 void emitIntrinsic(raw_ostream &OS, Record *R); 172 }; 173 174 } // End llvm namespace 175 176 #endif 177