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 enum {
     51 #define ENUM_RS_DATA_KIND(x) x,
     52   RS_DATA_KIND_ENUMS
     53 #undef ENUM_RS_DATA_KIND
     54 };
     55 
     56 class RSDataTypeSpec {
     57  private:
     58   const char *mTypeName;        // e.g. Float32
     59   // FIXME: better name
     60   const char *mTypePragmaName;  // e.g. float
     61   size_t mBits;
     62 
     63  protected:
     64   enum {
     65     DT_PrimitiveClass,
     66     DT_RSMatrixClass,
     67     DT_RSObjectClass
     68   } mClass;
     69 
     70  public:
     71   RSDataTypeSpec(const char *TypeName,
     72                  const char *TypePragmaName,
     73                  size_t Bits)
     74       : mTypeName(TypeName),
     75         mTypePragmaName(TypePragmaName),
     76         mBits(Bits),
     77         mClass(DT_PrimitiveClass) {
     78     return;
     79   }
     80 
     81   inline const char *getTypeName() const { return mTypeName; }
     82   inline const char *getTypePragmaName() const { return mTypePragmaName; }
     83   inline size_t getSizeInBit() const { return mBits; }
     84   inline bool isRSMatrix() const { return (mClass == DT_RSMatrixClass); }
     85   inline bool isRSObject() const { return (mClass == DT_RSObjectClass); }
     86 };
     87 
     88 class RSMatrixDataTypeSpec : public RSDataTypeSpec {
     89  private:
     90   unsigned mDim;
     91   static float ignore;
     92 
     93  public:
     94   RSMatrixDataTypeSpec(const char *TypeName,
     95                        const char *TypePragmaName,
     96                        unsigned Dim)
     97       : RSDataTypeSpec(TypeName, TypePragmaName, Dim * Dim * sizeof(ignore)),
     98         mDim(Dim) {
     99     mClass = DT_RSMatrixClass;
    100     return;
    101   }
    102 
    103   inline unsigned getDim() const { return mDim; }
    104 };
    105 
    106 class RSObjectDataTypeSpec : public RSDataTypeSpec {
    107  public:
    108   RSObjectDataTypeSpec(const char *TypeName,
    109                        const char *TypePragmaName)
    110       : RSDataTypeSpec(TypeName, TypePragmaName, 32 /* opaque pointer */) {
    111     mClass = DT_RSObjectClass;
    112     return;
    113   }
    114 };
    115 
    116 /////////////////////////////////////////////////////////////////////////////
    117 
    118 // clang::BuiltinType::Kind -> RSDataTypeSpec
    119 class ClangBuiltinTypeMap {
    120   const char *mBuiltinTypeKind;
    121   const RSDataTypeSpec *mDataType;
    122 
    123  public:
    124   ClangBuiltinTypeMap(const char *BuiltinTypeKind,
    125                       const RSDataTypeSpec *DataType)
    126       : mBuiltinTypeKind(BuiltinTypeKind),
    127         mDataType(DataType) {
    128     return;
    129   }
    130 
    131   inline const char *getBuiltinTypeKind() const { return mBuiltinTypeKind; }
    132   inline const RSDataTypeSpec *getDataType() const { return mDataType; }
    133 };
    134 
    135 /////////////////////////////////////////////////////////////////////////////
    136 
    137 class RSDataKindSpec {
    138  private:
    139   const char *mKindName;
    140 
    141  public:
    142   explicit RSDataKindSpec(const char *KindName) : mKindName(KindName) {
    143     return;
    144   }
    145 
    146   inline const char *getKindName() const { return mKindName; }
    147 };
    148 
    149 /////////////////////////////////////////////////////////////////////////////
    150 
    151 class RSDataElementSpec {
    152  private:
    153   const char *mElementName;
    154   const RSDataKindSpec *mDataKind;
    155   const RSDataTypeSpec *mDataType;
    156   bool mIsNormal;
    157   unsigned mVectorSize;
    158 
    159  public:
    160   RSDataElementSpec(const char *ElementName,
    161                     const RSDataKindSpec *DataKind,
    162                     const RSDataTypeSpec *DataType,
    163                     bool IsNormal,
    164                     unsigned VectorSize)
    165       : mElementName(ElementName),
    166         mDataKind(DataKind),
    167         mDataType(DataType),
    168         mIsNormal(IsNormal),
    169         mVectorSize(VectorSize) {
    170     return;
    171   }
    172 
    173   inline const char *getElementName() const { return mElementName; }
    174   inline const RSDataKindSpec *getDataKind() const { return mDataKind; }
    175   inline const RSDataTypeSpec *getDataType() const { return mDataType; }
    176   inline bool isNormal() const { return mIsNormal; }
    177   inline unsigned getVectorSize() const { return mVectorSize; }
    178 };
    179 
    180 /////////////////////////////////////////////////////////////////////////////
    181 
    182 // -gen-rs-data-type-enums
    183 //
    184 // ENUM_PRIMITIVE_DATA_TYPE(type, cname, bits)
    185 // ENUM_PRIMITIVE_DATA_TYPE_RANGE(begin_type, end_type)
    186 // ENUM_RS_MATRIX_DATA_TYPE(type, cname, bits)
    187 // ENUM_RS_MATRIX_DATA_TYPE_RANGE(begin_type, end_type)
    188 // ENUM_RS_OBJECT_DATA_TYPE(type, cname, bits)
    189 // ENUM_RS_OBJECT_DATA_TYPE_RANGE(begin_type, end_type)
    190 //
    191 // ENUM_RS_DATA_TYPE(type, cname, bits)
    192 // e.g., ENUM_RS_DATA_TYPE(Float32, "float", 256)
    193 static int GenRSDataTypeEnums(const RSDataTypeSpec *const DataTypes[],
    194                               unsigned NumDataTypes) {
    195   // Alias missing #define
    196 #define ALIAS_DEF(x, y) \
    197   printf("#ifndef " #x "\n");  \
    198   printf("#define " #x "(type, cname, bits) " #y "(type, cname, bits)\n");  \
    199   printf("#endif\n\n")
    200   ALIAS_DEF(ENUM_PRIMITIVE_DATA_TYPE, ENUM_RS_DATA_TYPE);
    201   ALIAS_DEF(ENUM_RS_MATRIX_DATA_TYPE, ENUM_RS_DATA_TYPE);
    202   ALIAS_DEF(ENUM_RS_OBJECT_DATA_TYPE, ENUM_RS_DATA_TYPE);
    203 #undef ALIAS_DEF
    204 
    205 #define ALIAS_DEF(x) \
    206   printf("#ifndef " #x "\n");  \
    207   printf("#define " #x "(begin_type, end_type)\n");  \
    208   printf("#endif\n\n")
    209   ALIAS_DEF(ENUM_PRIMITIVE_DATA_TYPE_RANGE);
    210   ALIAS_DEF(ENUM_RS_MATRIX_DATA_TYPE_RANGE);
    211   ALIAS_DEF(ENUM_RS_OBJECT_DATA_TYPE_RANGE);
    212 #undef ALIAS_DEF
    213 
    214 #define DEF(x) \
    215   printf(#x "(%s, \"%s\", %lu)\n",  \
    216          DataTypes[i]->getTypeName(), \
    217          DataTypes[i]->getTypePragmaName(), \
    218          (unsigned long) DataTypes[i]->getSizeInBit());  // NOLINT(runtime/int)
    219 #define DEF_RANGE(x, begin, end)  \
    220   printf(#x "(%s, %s)\n\n", \
    221          DataTypes[begin]->getTypeName(), \
    222          DataTypes[end]->getTypeName())
    223   for (unsigned i = FirstPrimitiveType; i <= LastPrimitiveType; i++)
    224     DEF(ENUM_PRIMITIVE_DATA_TYPE);
    225   DEF_RANGE(ENUM_PRIMITIVE_DATA_TYPE_RANGE,
    226             FirstPrimitiveType, LastPrimitiveType);
    227   for (unsigned i = FirstRSMatrixType; i <= LastRSMatrixType; i++)
    228     DEF(ENUM_RS_MATRIX_DATA_TYPE)
    229   DEF_RANGE(ENUM_RS_MATRIX_DATA_TYPE_RANGE,
    230             FirstRSMatrixType, LastRSMatrixType);
    231   for (unsigned i = FirstRSObjectType; i <= LastRSObjectType; i++)
    232     DEF(ENUM_RS_OBJECT_DATA_TYPE)
    233   DEF_RANGE(ENUM_RS_OBJECT_DATA_TYPE_RANGE,
    234             FirstRSObjectType, LastRSObjectType);
    235 #undef DEF
    236 #undef DEF_RANGE
    237 
    238 #define UNDEF(x)  \
    239   printf("#undef " #x "\n")
    240   UNDEF(ENUM_PRIMITIVE_DATA_TYPE);
    241   UNDEF(ENUM_RS_MATRIX_DATA_TYPE);
    242   UNDEF(ENUM_RS_OBJECT_DATA_TYPE);
    243   UNDEF(ENUM_PRIMITIVE_DATA_TYPE_RANGE);
    244   UNDEF(ENUM_RS_MATRIX_DATA_TYPE_RANGE);
    245   UNDEF(ENUM_RS_OBJECT_DATA_TYPE_RANGE);
    246   UNDEF(ENUM_RS_DATA_TYPE);
    247   return 0;
    248 }
    249 
    250 // -gen-clang-builtin-cnames
    251 //
    252 // ENUM_SUPPORT_BUILTIN_TYPE(builtin_type, type, cname)
    253 // e.g., ENUM_SUPPORT_BUILTIN_TYPE(clang::BuiltinType::Float, Float32, "float")
    254 static int GenClangBuiltinEnum(
    255     const ClangBuiltinTypeMap *const ClangBuilitinsMap[],
    256     unsigned NumClangBuilitins) {
    257   for (unsigned i = 0; i < NumClangBuilitins; i++)
    258     printf("ENUM_SUPPORT_BUILTIN_TYPE(%s, %s, \"%s\")\n",
    259            ClangBuilitinsMap[i]->getBuiltinTypeKind(),
    260            ClangBuilitinsMap[i]->getDataType()->getTypeName(),
    261            ClangBuilitinsMap[i]->getDataType()->getTypePragmaName());
    262   printf("#undef ENUM_SUPPORT_BUILTIN_TYPE\n");
    263   return 0;
    264 }
    265 
    266 // -gen-rs-matrix-type-enums
    267 //
    268 // ENUM_RS_MATRIX_TYPE(type, cname, dim)
    269 // e.g., ENUM_RS_MATRIX_TYPE(RSMatrix2x2, "rs_matrix2x2", 2)
    270 static int GenRSMatrixTypeEnums(const RSDataTypeSpec *const DataTypes[],
    271                                 unsigned NumDataTypes) {
    272   for (unsigned i = 0; i < NumDataTypes; i++)
    273     if (DataTypes[i]->isRSMatrix()) {
    274       const RSMatrixDataTypeSpec *const MatrixDataType =
    275           static_cast<const RSMatrixDataTypeSpec *const>(DataTypes[i]);
    276       printf("ENUM_RS_MATRIX_TYPE(%s, \"%s\", %u)\n",
    277              MatrixDataType->getTypeName(),
    278              MatrixDataType->getTypePragmaName(),
    279              MatrixDataType->getDim());
    280     }
    281   printf("#undef ENUM_RS_MATRIX_TYPE\n");
    282   return 0;
    283 }
    284 
    285 // -gen-rs-object-type-enums
    286 //
    287 // ENUM_RS_OBJECT_TYPE(type, cname)
    288 // e.g., ENUM_RS_OBJECT_TYPE(RSElement, "rs_element")
    289 static int GenRSObjectTypeEnums(const RSDataTypeSpec *const DataTypes[],
    290                                 unsigned NumDataTypes) {
    291   for (unsigned i = 0; i < NumDataTypes; i++)
    292     if (DataTypes[i]->isRSObject())
    293       printf("ENUM_RS_OBJECT_TYPE(%s, \"%s\")\n",
    294              DataTypes[i]->getTypeName(),
    295              DataTypes[i]->getTypePragmaName());
    296   printf("#undef ENUM_RS_OBJECT_TYPE\n");
    297   return 0;
    298 }
    299 
    300 // -gen-rs-data-kind-enums
    301 //
    302 // ENUM_RS_DATA_KIND(kind)
    303 // e.g., ENUM_RS_DATA_KIND(PixelRGB)
    304 int GenRSDataKindEnums(const RSDataKindSpec *const DataKinds[],
    305                        unsigned NumDataKinds) {
    306   for (unsigned i = 0; i < NumDataKinds; i++)
    307     printf("ENUM_RS_DATA_KIND(%s)\n", DataKinds[i]->getKindName());
    308   printf("#undef ENUM_RS_DATA_KIND\n");
    309   return 0;
    310 }
    311 
    312 // -gen-rs-data-element-enums
    313 //
    314 // ENUM_RS_DATA_ELEMENT(name, dt, dk, normailized, vsize)
    315 // e.g., ENUM_RS_DATA_ELEMENT("rs_pixel_rgba", PixelRGB, Unsigned8, true, 4)
    316 int GenRSDataElementEnums(const RSDataElementSpec *const DataElements[],
    317                           unsigned NumDataElements) {
    318   for (unsigned i = 0; i < NumDataElements; i++)
    319     printf("ENUM_RS_DATA_ELEMENT(\"%s\", %s, %s, %s, %d)\n",
    320            DataElements[i]->getElementName(),
    321            DataElements[i]->getDataKind()->getKindName(),
    322            DataElements[i]->getDataType()->getTypeName(),
    323            ((DataElements[i]->isNormal()) ? "true" : "false"),
    324            DataElements[i]->getVectorSize());
    325   printf("#undef ENUM_RS_DATA_ELEMENT\n");
    326   return 0;
    327 }
    328 
    329 int main(int argc, char **argv) {
    330   if (argc < 2) {
    331     fprintf(stderr, "usage: %s [gen type]\n", argv[0]);
    332     return 1;
    333   }
    334 
    335   RSDataTypeSpec *DataTypes[] = {
    336 #define ENUM_PRIMITIVE_DATA_TYPE(x, name, bits) \
    337   new RSDataTypeSpec(#x , name, bits),
    338 #define PRIMITIVE_DATA_TYPE_RANGE(x, y)
    339   PRIMITIVE_DATA_TYPE_ENUMS
    340 #undef ENUM_PRIMITIVE_DATA_TYPE
    341 #undef PRIMITIVE_DATA_TYPE_RANGE
    342 
    343 #define ENUM_RS_MATRIX_DATA_TYPE(x, name, dim) \
    344   new RSMatrixDataTypeSpec(#x , name, dim),
    345 #define RS_MATRIX_DATA_TYPE_RANGE(x, y)
    346   RS_MATRIX_DATA_TYPE_ENUMS
    347 #undef ENUM_RS_MATRIX_DATA_TYPE
    348 #undef RS_MATRIX_DATA_TYPE_RANGE
    349 
    350 #define ENUM_RS_OBJECT_DATA_TYPE(x, name)  \
    351   new RSObjectDataTypeSpec(#x, name),
    352 #define RS_OBJECT_DATA_TYPE_RANGE(x, y)
    353   RS_OBJECT_DATA_TYPE_ENUMS
    354 #undef ENUM_RS_OBJECT_DATA_TYPE
    355 #undef RS_OBJECT_DATA_TYPE_RANGE
    356   };
    357 
    358   unsigned NumDataTypes = sizeof(DataTypes) / sizeof(DataTypes[0]);
    359   /////////////////////////////////////////////////////////////////////////////
    360 
    361   ClangBuiltinTypeMap *ClangBuilitinsMap[] = {
    362     new ClangBuiltinTypeMap("clang::BuiltinType::Bool",   DataTypes[Boolean]),
    363     new ClangBuiltinTypeMap("clang::BuiltinType::Char_U", DataTypes[Unsigned8]),
    364     new ClangBuiltinTypeMap("clang::BuiltinType::UChar",  DataTypes[Unsigned8]),
    365     new ClangBuiltinTypeMap("clang::BuiltinType::Char16", DataTypes[Signed16]),
    366     new ClangBuiltinTypeMap("clang::BuiltinType::Char32", DataTypes[Signed32]),
    367     new ClangBuiltinTypeMap(
    368       "clang::BuiltinType::UShort", DataTypes[Unsigned16]),
    369     new ClangBuiltinTypeMap(
    370       "clang::BuiltinType::UInt", DataTypes[Unsigned32]),
    371     new ClangBuiltinTypeMap(
    372       "clang::BuiltinType::ULong",  DataTypes[Unsigned32]),
    373     new ClangBuiltinTypeMap(
    374       "clang::BuiltinType::ULongLong", DataTypes[Unsigned64]),
    375 
    376     new ClangBuiltinTypeMap("clang::BuiltinType::Char_S", DataTypes[Signed8]),
    377     new ClangBuiltinTypeMap("clang::BuiltinType::SChar",  DataTypes[Signed8]),
    378     new ClangBuiltinTypeMap("clang::BuiltinType::Short",  DataTypes[Signed16]),
    379     new ClangBuiltinTypeMap("clang::BuiltinType::Int",    DataTypes[Signed32]),
    380     new ClangBuiltinTypeMap("clang::BuiltinType::Long",   DataTypes[Signed64]),
    381     new ClangBuiltinTypeMap(
    382       "clang::BuiltinType::LongLong", DataTypes[Signed64]),
    383 
    384     new ClangBuiltinTypeMap("clang::BuiltinType::Float",  DataTypes[Float32]),
    385     new ClangBuiltinTypeMap("clang::BuiltinType::Double", DataTypes[Float64])
    386   };
    387 
    388   unsigned NumClangBuilitins =
    389       sizeof(ClangBuilitinsMap) / sizeof(ClangBuilitinsMap[0]);
    390 
    391   /////////////////////////////////////////////////////////////////////////////
    392 
    393   RSDataKindSpec *DataKinds[] = {
    394 #define ENUM_RS_DATA_KIND(x)  \
    395     new RSDataKindSpec(#x),
    396     RS_DATA_KIND_ENUMS
    397 #undef ENUM_RS_DATA_KIND
    398   };
    399 
    400   unsigned NumDataKinds = sizeof(DataKinds) / sizeof(DataKinds[0]);
    401   /////////////////////////////////////////////////////////////////////////////
    402 
    403   RSDataElementSpec *DataElements[] = {
    404     new RSDataElementSpec("rs_pixel_l",
    405                           DataKinds[PixelL],
    406                           DataTypes[Unsigned8],
    407                           /* IsNormal = */true, /* VectorSize = */1),
    408     new RSDataElementSpec("rs_pixel_a",
    409                           DataKinds[PixelA],
    410                           DataTypes[Unsigned8],
    411                           true, 1),
    412     new RSDataElementSpec("rs_pixel_la",
    413                           DataKinds[PixelLA],
    414                           DataTypes[Unsigned8],
    415                           true, 2),
    416     new RSDataElementSpec("rs_pixel_rgb",
    417                           DataKinds[PixelRGB],
    418                           DataTypes[Unsigned8],
    419                           true, 3),
    420     new RSDataElementSpec("rs_pixel_rgba",
    421                           DataKinds[PixelRGB],
    422                           DataTypes[Unsigned8],
    423                           true, 4),
    424     new RSDataElementSpec("rs_pixel_rgb565",
    425                           DataKinds[PixelRGB],
    426                           DataTypes[Unsigned8],
    427                           true, 3),
    428     new RSDataElementSpec("rs_pixel_rgb5551",
    429                           DataKinds[PixelRGBA],
    430                           DataTypes[Unsigned8],
    431                           true, 4),
    432     new RSDataElementSpec("rs_pixel_rgb4444",
    433                           DataKinds[PixelRGBA],
    434                           DataTypes[Unsigned8],
    435                           true, 4),
    436   };
    437 
    438   unsigned NumDataElements = sizeof(DataElements) / sizeof(DataElements[0]);
    439   /////////////////////////////////////////////////////////////////////////////
    440   int Result = 1;
    441 
    442   if (::strcmp(argv[1], "-gen-rs-data-type-enums") == 0)
    443     Result = GenRSDataTypeEnums(DataTypes, NumDataTypes);
    444   else if (::strcmp(argv[1], "-gen-clang-builtin-enums") == 0)
    445     Result = GenClangBuiltinEnum(ClangBuilitinsMap, NumClangBuilitins);
    446   else if (::strcmp(argv[1], "-gen-rs-matrix-type-enums") == 0)
    447     Result = GenRSMatrixTypeEnums(DataTypes, NumDataTypes);
    448   else if (::strcmp(argv[1], "-gen-rs-object-type-enums") == 0)
    449     Result = GenRSObjectTypeEnums(DataTypes, NumDataTypes);
    450   else if (::strcmp(argv[1], "-gen-rs-data-kind-enums") == 0)
    451     Result = GenRSDataKindEnums(DataKinds, NumDataKinds);
    452   else if (::strcmp(argv[1], "-gen-rs-data-element-enums") == 0)
    453     Result = GenRSDataElementEnums(DataElements, NumDataElements);
    454   else
    455     fprintf(stderr, "%s: Unknown table generation type '%s'\n",
    456                     argv[0], argv[1]);
    457 
    458 
    459   /////////////////////////////////////////////////////////////////////////////
    460   for (unsigned i = 0; i < NumDataTypes; i++)
    461     delete DataTypes[i];
    462   for (unsigned i = 0; i < NumClangBuilitins; i++)
    463     delete ClangBuilitinsMap[i];
    464   for (unsigned i = 0; i < NumDataKinds; i++)
    465     delete DataKinds[i];
    466   for (unsigned i = 0; i < NumDataElements; i++)
    467     delete DataElements[i];
    468 
    469   return Result;
    470 }
    471