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
24enum {
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
50class 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
82class 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
100class 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
113class 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
131class 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)
169static 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")
230static 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)
246static 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")
265static 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)
280int 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
292int 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