Home | History | Annotate | Download | only in TableGen
      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