Home | History | Annotate | Download | only in slang
      1 /*
      2  * Copyright 2010, The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <cstdio>
     18 #include <cstring>
     19 
     20 #include <string>
     21 
     22 #include "slang_rs_type_spec.h"
     23 
     24 enum {
     25 #define ENUM_PRIMITIVE_DATA_TYPE(x, name, bits) x,
     26 #define PRIMITIVE_DATA_TYPE_RANGE(x, y) \
     27     FirstPrimitiveType = x, \
     28     LastPrimitiveType = y,
     29   PRIMITIVE_DATA_TYPE_ENUMS
     30 #undef ENUM_PRIMITIVE_DATA_TYPE
     31 #undef PRIMITIVE_DATA_TYPE_RANGE
     32 
     33 #define ENUM_RS_MATRIX_DATA_TYPE(x, name, dim) x,
     34 #define RS_MATRIX_DATA_TYPE_RANGE(x, y)  \
     35     FirstRSMatrixType = x,  \
     36     LastRSMatrixType = y,
     37   RS_MATRIX_DATA_TYPE_ENUMS
     38 #undef ENUM_RS_MATRIX_DATA_TYPE
     39 #undef RS_MATRIX_DATA_TYPE_RANGE
     40 
     41 #define ENUM_RS_OBJECT_DATA_TYPE(x, name) x,
     42 #define RS_OBJECT_DATA_TYPE_RANGE(x, y) \
     43     FirstRSObjectType = x,  \
     44     LastRSObjectType = y,
     45   RS_OBJECT_DATA_TYPE_ENUMS
     46 #undef ENUM_RS_OBJECT_DATA_TYPE
     47 #undef RS_OBJECT_DATA_TYPE_RANGE
     48 };
     49 
     50 class RSDataTypeSpec {
     51  private:
     52   const char *mTypeName;        // e.g. Float32
     53   // FIXME: better name
     54   const char *mTypePragmaName;  // e.g. float
     55   size_t mBits;
     56 
     57  protected:
     58   enum {
     59     DT_PrimitiveClass,
     60     DT_RSMatrixClass,
     61     DT_RSObjectClass
     62   } mClass;
     63 
     64  public:
     65   RSDataTypeSpec(const char *TypeName,
     66                  const char *TypePragmaName,
     67                  size_t Bits)
     68       : mTypeName(TypeName),
     69         mTypePragmaName(TypePragmaName),
     70         mBits(Bits),
     71         mClass(DT_PrimitiveClass) {
     72     return;
     73   }
     74 
     75   inline const char *getTypeName() const { return mTypeName; }
     76   inline const char *getTypePragmaName() const { return mTypePragmaName; }
     77   inline size_t getSizeInBit() const { return mBits; }
     78   inline bool isRSMatrix() const { return (mClass == DT_RSMatrixClass); }
     79   inline bool isRSObject() const { return (mClass == DT_RSObjectClass); }
     80 };
     81 
     82 class RSMatrixDataTypeSpec : public RSDataTypeSpec {
     83  private:
     84   unsigned mDim;
     85   static float ignore;
     86 
     87  public:
     88   RSMatrixDataTypeSpec(const char *TypeName,
     89                        const char *TypePragmaName,
     90                        unsigned Dim)
     91       : RSDataTypeSpec(TypeName, TypePragmaName, Dim * Dim * sizeof(ignore)),
     92         mDim(Dim) {
     93     mClass = DT_RSMatrixClass;
     94     return;
     95   }
     96 
     97   inline unsigned getDim() const { return mDim; }
     98 };
     99 
    100 class RSObjectDataTypeSpec : public RSDataTypeSpec {
    101  public:
    102   RSObjectDataTypeSpec(const char *TypeName,
    103                        const char *TypePragmaName)
    104       : RSDataTypeSpec(TypeName, TypePragmaName, 32 /* opaque pointer */) {
    105     mClass = DT_RSObjectClass;
    106     return;
    107   }
    108 };
    109 
    110 /////////////////////////////////////////////////////////////////////////////
    111 
    112 // clang::BuiltinType::Kind -> RSDataTypeSpec
    113 class ClangBuiltinTypeMap {
    114   const char *mBuiltinTypeKind;
    115   const RSDataTypeSpec *mDataType;
    116 
    117  public:
    118   ClangBuiltinTypeMap(const char *BuiltinTypeKind,
    119                       const RSDataTypeSpec *DataType)
    120       : mBuiltinTypeKind(BuiltinTypeKind),
    121         mDataType(DataType) {
    122     return;
    123   }
    124 
    125   inline const char *getBuiltinTypeKind() const { return mBuiltinTypeKind; }
    126   inline const RSDataTypeSpec *getDataType() const { return mDataType; }
    127 };
    128 
    129 /////////////////////////////////////////////////////////////////////////////
    130 
    131 class RSDataElementSpec {
    132  private:
    133   const char *mElementName;
    134   const RSDataTypeSpec *mDataType;
    135   bool mIsNormal;
    136   unsigned mVectorSize;
    137 
    138  public:
    139   RSDataElementSpec(const char *ElementName,
    140                     const RSDataTypeSpec *DataType,
    141                     bool IsNormal,
    142                     unsigned VectorSize)
    143       : mElementName(ElementName),
    144         mDataType(DataType),
    145         mIsNormal(IsNormal),
    146         mVectorSize(VectorSize) {
    147     return;
    148   }
    149 
    150   inline const char *getElementName() const { return mElementName; }
    151   inline const RSDataTypeSpec *getDataType() const { return mDataType; }
    152   inline bool isNormal() const { return mIsNormal; }
    153   inline unsigned getVectorSize() const { return mVectorSize; }
    154 };
    155 
    156 /////////////////////////////////////////////////////////////////////////////
    157 
    158 // -gen-rs-data-type-enums
    159 //
    160 // ENUM_PRIMITIVE_DATA_TYPE(type, cname, bits)
    161 // ENUM_PRIMITIVE_DATA_TYPE_RANGE(begin_type, end_type)
    162 // ENUM_RS_MATRIX_DATA_TYPE(type, cname, bits)
    163 // ENUM_RS_MATRIX_DATA_TYPE_RANGE(begin_type, end_type)
    164 // ENUM_RS_OBJECT_DATA_TYPE(type, cname, bits)
    165 // ENUM_RS_OBJECT_DATA_TYPE_RANGE(begin_type, end_type)
    166 //
    167 // ENUM_RS_DATA_TYPE(type, cname, bits)
    168 // e.g., ENUM_RS_DATA_TYPE(Float32, "float", 256)
    169 static int GenRSDataTypeEnums(const RSDataTypeSpec *const DataTypes[],
    170                               unsigned NumDataTypes) {
    171   // Alias missing #define
    172 #define ALIAS_DEF(x, y) \
    173   printf("#ifndef " #x "\n");  \
    174   printf("#define " #x "(type, cname, bits) " #y "(type, cname, bits)\n");  \
    175   printf("#endif\n\n")
    176   ALIAS_DEF(ENUM_PRIMITIVE_DATA_TYPE, ENUM_RS_DATA_TYPE);
    177   ALIAS_DEF(ENUM_RS_MATRIX_DATA_TYPE, ENUM_RS_DATA_TYPE);
    178   ALIAS_DEF(ENUM_RS_OBJECT_DATA_TYPE, ENUM_RS_DATA_TYPE);
    179 #undef ALIAS_DEF
    180 
    181 #define ALIAS_DEF(x) \
    182   printf("#ifndef " #x "\n");  \
    183   printf("#define " #x "(begin_type, end_type)\n");  \
    184   printf("#endif\n\n")
    185   ALIAS_DEF(ENUM_PRIMITIVE_DATA_TYPE_RANGE);
    186   ALIAS_DEF(ENUM_RS_MATRIX_DATA_TYPE_RANGE);
    187   ALIAS_DEF(ENUM_RS_OBJECT_DATA_TYPE_RANGE);
    188 #undef ALIAS_DEF
    189 
    190 #define DEF(x) \
    191   printf(#x "(%s, \"%s\", %lu)\n",  \
    192          DataTypes[i]->getTypeName(), \
    193          DataTypes[i]->getTypePragmaName(), \
    194          (unsigned long) DataTypes[i]->getSizeInBit());  // NOLINT(runtime/int)
    195 #define DEF_RANGE(x, begin, end)  \
    196   printf(#x "(%s, %s)\n\n", \
    197          DataTypes[begin]->getTypeName(), \
    198          DataTypes[end]->getTypeName())
    199   for (unsigned i = FirstPrimitiveType; i <= LastPrimitiveType; i++)
    200     DEF(ENUM_PRIMITIVE_DATA_TYPE);
    201   DEF_RANGE(ENUM_PRIMITIVE_DATA_TYPE_RANGE,
    202             FirstPrimitiveType, LastPrimitiveType);
    203   for (unsigned i = FirstRSMatrixType; i <= LastRSMatrixType; i++)
    204     DEF(ENUM_RS_MATRIX_DATA_TYPE)
    205   DEF_RANGE(ENUM_RS_MATRIX_DATA_TYPE_RANGE,
    206             FirstRSMatrixType, LastRSMatrixType);
    207   for (unsigned i = FirstRSObjectType; i <= LastRSObjectType; i++)
    208     DEF(ENUM_RS_OBJECT_DATA_TYPE)
    209   DEF_RANGE(ENUM_RS_OBJECT_DATA_TYPE_RANGE,
    210             FirstRSObjectType, LastRSObjectType);
    211 #undef DEF
    212 #undef DEF_RANGE
    213 
    214 #define UNDEF(x)  \
    215   printf("#undef " #x "\n")
    216   UNDEF(ENUM_PRIMITIVE_DATA_TYPE);
    217   UNDEF(ENUM_RS_MATRIX_DATA_TYPE);
    218   UNDEF(ENUM_RS_OBJECT_DATA_TYPE);
    219   UNDEF(ENUM_PRIMITIVE_DATA_TYPE_RANGE);
    220   UNDEF(ENUM_RS_MATRIX_DATA_TYPE_RANGE);
    221   UNDEF(ENUM_RS_OBJECT_DATA_TYPE_RANGE);
    222   UNDEF(ENUM_RS_DATA_TYPE);
    223   return 0;
    224 }
    225 
    226 // -gen-clang-builtin-cnames
    227 //
    228 // ENUM_SUPPORT_BUILTIN_TYPE(builtin_type, type, cname)
    229 // e.g., ENUM_SUPPORT_BUILTIN_TYPE(clang::BuiltinType::Float, Float32, "float")
    230 static int GenClangBuiltinEnum(
    231     const ClangBuiltinTypeMap *const ClangBuilitinsMap[],
    232     unsigned NumClangBuilitins) {
    233   for (unsigned i = 0; i < NumClangBuilitins; i++)
    234     printf("ENUM_SUPPORT_BUILTIN_TYPE(%s, %s, \"%s\")\n",
    235            ClangBuilitinsMap[i]->getBuiltinTypeKind(),
    236            ClangBuilitinsMap[i]->getDataType()->getTypeName(),
    237            ClangBuilitinsMap[i]->getDataType()->getTypePragmaName());
    238   printf("#undef ENUM_SUPPORT_BUILTIN_TYPE\n");
    239   return 0;
    240 }
    241 
    242 // -gen-rs-matrix-type-enums
    243 //
    244 // ENUM_RS_MATRIX_TYPE(type, cname, dim)
    245 // e.g., ENUM_RS_MATRIX_TYPE(RSMatrix2x2, "rs_matrix2x2", 2)
    246 static int GenRSMatrixTypeEnums(const RSDataTypeSpec *const DataTypes[],
    247                                 unsigned NumDataTypes) {
    248   for (unsigned i = 0; i < NumDataTypes; i++)
    249     if (DataTypes[i]->isRSMatrix()) {
    250       const RSMatrixDataTypeSpec *const MatrixDataType =
    251           static_cast<const RSMatrixDataTypeSpec *const>(DataTypes[i]);
    252       printf("ENUM_RS_MATRIX_TYPE(%s, \"%s\", %u)\n",
    253              MatrixDataType->getTypeName(),
    254              MatrixDataType->getTypePragmaName(),
    255              MatrixDataType->getDim());
    256     }
    257   printf("#undef ENUM_RS_MATRIX_TYPE\n");
    258   return 0;
    259 }
    260 
    261 // -gen-rs-object-type-enums
    262 //
    263 // ENUM_RS_OBJECT_TYPE(type, cname)
    264 // e.g., ENUM_RS_OBJECT_TYPE(RSElement, "rs_element")
    265 static int GenRSObjectTypeEnums(const RSDataTypeSpec *const DataTypes[],
    266                                 unsigned NumDataTypes) {
    267   for (unsigned i = 0; i < NumDataTypes; i++)
    268     if (DataTypes[i]->isRSObject())
    269       printf("ENUM_RS_OBJECT_TYPE(%s, \"%s\")\n",
    270              DataTypes[i]->getTypeName(),
    271              DataTypes[i]->getTypePragmaName());
    272   printf("#undef ENUM_RS_OBJECT_TYPE\n");
    273   return 0;
    274 }
    275 
    276 // -gen-rs-data-element-enums
    277 //
    278 // ENUM_RS_DATA_ELEMENT(name, dt, dk, normailized, vsize)
    279 // e.g., ENUM_RS_DATA_ELEMENT("rs_pixel_rgba", PixelRGB, Unsigned8, true, 4)
    280 int GenRSDataElementEnums(const RSDataElementSpec *const DataElements[],
    281                           unsigned NumDataElements) {
    282   for (unsigned i = 0; i < NumDataElements; i++)
    283     printf("ENUM_RS_DATA_ELEMENT(\"%s\", %s, %s, %d)\n",
    284            DataElements[i]->getElementName(),
    285            DataElements[i]->getDataType()->getTypeName(),
    286            ((DataElements[i]->isNormal()) ? "true" : "false"),
    287            DataElements[i]->getVectorSize());
    288   printf("#undef ENUM_RS_DATA_ELEMENT\n");
    289   return 0;
    290 }
    291 
    292 int main(int argc, char **argv) {
    293   if (argc < 2) {
    294     fprintf(stderr, "usage: %s [gen type]\n", argv[0]);
    295     return 1;
    296   }
    297 
    298   RSDataTypeSpec *DataTypes[] = {
    299 #define ENUM_PRIMITIVE_DATA_TYPE(x, name, bits) \
    300   new RSDataTypeSpec(#x , name, bits),
    301 #define PRIMITIVE_DATA_TYPE_RANGE(x, y)
    302   PRIMITIVE_DATA_TYPE_ENUMS
    303 #undef ENUM_PRIMITIVE_DATA_TYPE
    304 #undef PRIMITIVE_DATA_TYPE_RANGE
    305 
    306 #define ENUM_RS_MATRIX_DATA_TYPE(x, name, dim) \
    307   new RSMatrixDataTypeSpec(#x , name, dim),
    308 #define RS_MATRIX_DATA_TYPE_RANGE(x, y)
    309   RS_MATRIX_DATA_TYPE_ENUMS
    310 #undef ENUM_RS_MATRIX_DATA_TYPE
    311 #undef RS_MATRIX_DATA_TYPE_RANGE
    312 
    313 #define ENUM_RS_OBJECT_DATA_TYPE(x, name)  \
    314   new RSObjectDataTypeSpec(#x, name),
    315 #define RS_OBJECT_DATA_TYPE_RANGE(x, y)
    316   RS_OBJECT_DATA_TYPE_ENUMS
    317 #undef ENUM_RS_OBJECT_DATA_TYPE
    318 #undef RS_OBJECT_DATA_TYPE_RANGE
    319   };
    320 
    321   unsigned NumDataTypes = sizeof(DataTypes) / sizeof(DataTypes[0]);
    322   /////////////////////////////////////////////////////////////////////////////
    323 
    324   ClangBuiltinTypeMap *ClangBuilitinsMap[] = {
    325     new ClangBuiltinTypeMap("clang::BuiltinType::Bool",   DataTypes[Boolean]),
    326     new ClangBuiltinTypeMap("clang::BuiltinType::Char_U", DataTypes[Unsigned8]),
    327     new ClangBuiltinTypeMap("clang::BuiltinType::UChar",  DataTypes[Unsigned8]),
    328     new ClangBuiltinTypeMap("clang::BuiltinType::Char16", DataTypes[Signed16]),
    329     new ClangBuiltinTypeMap("clang::BuiltinType::Char32", DataTypes[Signed32]),
    330     new ClangBuiltinTypeMap(
    331       "clang::BuiltinType::UShort", DataTypes[Unsigned16]),
    332     new ClangBuiltinTypeMap(
    333       "clang::BuiltinType::UInt", DataTypes[Unsigned32]),
    334     new ClangBuiltinTypeMap(
    335       "clang::BuiltinType::ULong",  DataTypes[Unsigned32]),
    336     new ClangBuiltinTypeMap(
    337       "clang::BuiltinType::ULongLong", DataTypes[Unsigned64]),
    338 
    339     new ClangBuiltinTypeMap("clang::BuiltinType::Char_S", DataTypes[Signed8]),
    340     new ClangBuiltinTypeMap("clang::BuiltinType::SChar",  DataTypes[Signed8]),
    341     new ClangBuiltinTypeMap("clang::BuiltinType::Short",  DataTypes[Signed16]),
    342     new ClangBuiltinTypeMap("clang::BuiltinType::Int",    DataTypes[Signed32]),
    343     new ClangBuiltinTypeMap("clang::BuiltinType::Long",   DataTypes[Signed64]),
    344     new ClangBuiltinTypeMap(
    345       "clang::BuiltinType::LongLong", DataTypes[Signed64]),
    346 
    347     new ClangBuiltinTypeMap("clang::BuiltinType::Float",  DataTypes[Float32]),
    348     new ClangBuiltinTypeMap("clang::BuiltinType::Double", DataTypes[Float64])
    349   };
    350 
    351   unsigned NumClangBuilitins =
    352       sizeof(ClangBuilitinsMap) / sizeof(ClangBuilitinsMap[0]);
    353 
    354   /////////////////////////////////////////////////////////////////////////////
    355 
    356   RSDataElementSpec *DataElements[] = {
    357     new RSDataElementSpec("rs_pixel_l",
    358                           DataTypes[Unsigned8],
    359                           /* IsNormal = */true, /* VectorSize = */1),
    360     new RSDataElementSpec("rs_pixel_a",
    361                           DataTypes[Unsigned8],
    362                           true, 1),
    363     new RSDataElementSpec("rs_pixel_la",
    364                           DataTypes[Unsigned8],
    365                           true, 2),
    366     new RSDataElementSpec("rs_pixel_rgb",
    367                           DataTypes[Unsigned8],
    368                           true, 3),
    369     new RSDataElementSpec("rs_pixel_rgba",
    370                           DataTypes[Unsigned8],
    371                           true, 4),
    372     new RSDataElementSpec("rs_pixel_rgb565",
    373                           DataTypes[Unsigned8],
    374                           true, 3),
    375     new RSDataElementSpec("rs_pixel_rgb5551",
    376                           DataTypes[Unsigned8],
    377                           true, 4),
    378     new RSDataElementSpec("rs_pixel_rgb4444",
    379                           DataTypes[Unsigned8],
    380                           true, 4),
    381   };
    382 
    383   unsigned NumDataElements = sizeof(DataElements) / sizeof(DataElements[0]);
    384   /////////////////////////////////////////////////////////////////////////////
    385   int Result = 1;
    386 
    387   if (::strcmp(argv[1], "-gen-rs-data-type-enums") == 0)
    388     Result = GenRSDataTypeEnums(DataTypes, NumDataTypes);
    389   else if (::strcmp(argv[1], "-gen-clang-builtin-enums") == 0)
    390     Result = GenClangBuiltinEnum(ClangBuilitinsMap, NumClangBuilitins);
    391   else if (::strcmp(argv[1], "-gen-rs-matrix-type-enums") == 0)
    392     Result = GenRSMatrixTypeEnums(DataTypes, NumDataTypes);
    393   else if (::strcmp(argv[1], "-gen-rs-object-type-enums") == 0)
    394     Result = GenRSObjectTypeEnums(DataTypes, NumDataTypes);
    395   else if (::strcmp(argv[1], "-gen-rs-data-element-enums") == 0)
    396     Result = GenRSDataElementEnums(DataElements, NumDataElements);
    397   else
    398     fprintf(stderr, "%s: Unknown table generation type '%s'\n",
    399                     argv[0], argv[1]);
    400 
    401 
    402   /////////////////////////////////////////////////////////////////////////////
    403   for (unsigned i = 0; i < NumDataTypes; i++)
    404     delete DataTypes[i];
    405   for (unsigned i = 0; i < NumClangBuilitins; i++)
    406     delete ClangBuilitinsMap[i];
    407   for (unsigned i = 0; i < NumDataElements; i++)
    408     delete DataElements[i];
    409 
    410   return Result;
    411 }
    412