1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright (C) 2013 Rob Clark <robdclark@gmail.com> 3bf215546Sopenharmony_ci * Copyright (C) 2010-2011 Marcin Kościelnicki <koriakin@0x04.net> 4bf215546Sopenharmony_ci * Copyright (C) 2010 Luca Barbieri <luca@luca-barbieri.com> 5bf215546Sopenharmony_ci * Copyright (C) 2010 Marcin Slusarz <marcin.slusarz@gmail.com> 6bf215546Sopenharmony_ci * All Rights Reserved. 7bf215546Sopenharmony_ci * 8bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 9bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 10bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 11bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 13bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 16bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 17bf215546Sopenharmony_ci * Software. 18bf215546Sopenharmony_ci * 19bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 22bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 23bf215546Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 24bf215546Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 25bf215546Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE. 26bf215546Sopenharmony_ci */ 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci/* modified version of headergen which uses enums and inline fxns for 29bf215546Sopenharmony_ci * type safety.. based on original headergen 30bf215546Sopenharmony_ci */ 31bf215546Sopenharmony_ci 32bf215546Sopenharmony_ci#include "rnn.h" 33bf215546Sopenharmony_ci#include "util.h" 34bf215546Sopenharmony_ci#include <stdbool.h> 35bf215546Sopenharmony_ci#include <stdio.h> 36bf215546Sopenharmony_ci#include <stdlib.h> 37bf215546Sopenharmony_ci#include <inttypes.h> 38bf215546Sopenharmony_ci#include <time.h> 39bf215546Sopenharmony_ci#include <ctype.h> 40bf215546Sopenharmony_ci#include <unistd.h> 41bf215546Sopenharmony_ci#include <string.h> 42bf215546Sopenharmony_ci#include <sys/stat.h> 43bf215546Sopenharmony_ci#include <sys/wait.h> 44bf215546Sopenharmony_ci#include <assert.h> 45bf215546Sopenharmony_ci 46bf215546Sopenharmony_cistruct rnndelem **elems = NULL; 47bf215546Sopenharmony_ciint elemsnum = 0; 48bf215546Sopenharmony_ciint elemsmax = 0; 49bf215546Sopenharmony_ci 50bf215546Sopenharmony_cichar **offsetfns = NULL; 51bf215546Sopenharmony_ciint offsetfnsnum = 0; 52bf215546Sopenharmony_ciint offsetfnsmax = 0; 53bf215546Sopenharmony_ci 54bf215546Sopenharmony_ciint startcol = 64; 55bf215546Sopenharmony_ci 56bf215546Sopenharmony_cistruct fout { 57bf215546Sopenharmony_ci char *name; 58bf215546Sopenharmony_ci FILE *file; 59bf215546Sopenharmony_ci char *guard; 60bf215546Sopenharmony_ci}; 61bf215546Sopenharmony_ci 62bf215546Sopenharmony_cistruct fout *fouts = 0; 63bf215546Sopenharmony_ciint foutsnum = 0; 64bf215546Sopenharmony_ciint foutsmax = 0; 65bf215546Sopenharmony_ci 66bf215546Sopenharmony_cistatic bool no_asserts = false; 67bf215546Sopenharmony_ci 68bf215546Sopenharmony_cistatic void seekcol (FILE *f, int src, int dst) { 69bf215546Sopenharmony_ci if (dst <= src) 70bf215546Sopenharmony_ci fprintf (f, "\t"); 71bf215546Sopenharmony_ci else { 72bf215546Sopenharmony_ci int n = dst/8 - src/8; 73bf215546Sopenharmony_ci if (n) { 74bf215546Sopenharmony_ci while (n--) 75bf215546Sopenharmony_ci fprintf (f, "\t"); 76bf215546Sopenharmony_ci n = dst&7; 77bf215546Sopenharmony_ci } else 78bf215546Sopenharmony_ci n = dst-src; 79bf215546Sopenharmony_ci while (n--) 80bf215546Sopenharmony_ci fprintf (f, " "); 81bf215546Sopenharmony_ci } 82bf215546Sopenharmony_ci} 83bf215546Sopenharmony_ci 84bf215546Sopenharmony_cistatic FILE *findfout (char *file) { 85bf215546Sopenharmony_ci int i; 86bf215546Sopenharmony_ci for (i = 0; i < foutsnum; i++) 87bf215546Sopenharmony_ci if (!strcmp(fouts[i].name, file)) 88bf215546Sopenharmony_ci break; 89bf215546Sopenharmony_ci if (i == foutsnum) { 90bf215546Sopenharmony_ci fprintf (stderr, "AIII, didn't open file %s.\n", file); 91bf215546Sopenharmony_ci exit(1); 92bf215546Sopenharmony_ci } 93bf215546Sopenharmony_ci return fouts[i].file; 94bf215546Sopenharmony_ci} 95bf215546Sopenharmony_ci 96bf215546Sopenharmony_cistatic void printdef (char *name, char *suf, int type, uint64_t val, char *file) { 97bf215546Sopenharmony_ci FILE *dst = findfout(file); 98bf215546Sopenharmony_ci int len; 99bf215546Sopenharmony_ci if (suf) 100bf215546Sopenharmony_ci fprintf (dst, "#define %s__%s%n", name, suf, &len); 101bf215546Sopenharmony_ci else 102bf215546Sopenharmony_ci fprintf (dst, "#define %s%n", name, &len); 103bf215546Sopenharmony_ci if (type == 0 && val > 0xffffffffull) 104bf215546Sopenharmony_ci seekcol (dst, len, startcol-8); 105bf215546Sopenharmony_ci else 106bf215546Sopenharmony_ci seekcol (dst, len, startcol); 107bf215546Sopenharmony_ci switch (type) { 108bf215546Sopenharmony_ci case 0: 109bf215546Sopenharmony_ci if (val > 0xffffffffull) 110bf215546Sopenharmony_ci fprintf (dst, "0x%016"PRIx64"ULL\n", val); 111bf215546Sopenharmony_ci else 112bf215546Sopenharmony_ci fprintf (dst, "0x%08"PRIx64"\n", val); 113bf215546Sopenharmony_ci break; 114bf215546Sopenharmony_ci case 1: 115bf215546Sopenharmony_ci fprintf (dst, "%"PRIu64"\n", val); 116bf215546Sopenharmony_ci break; 117bf215546Sopenharmony_ci } 118bf215546Sopenharmony_ci} 119bf215546Sopenharmony_ci 120bf215546Sopenharmony_cistatic void printvalue (struct rnnvalue *val, int shift) { 121bf215546Sopenharmony_ci if (val->varinfo.dead) 122bf215546Sopenharmony_ci return; 123bf215546Sopenharmony_ci if (val->valvalid) 124bf215546Sopenharmony_ci printdef (val->fullname, 0, 0, val->value << shift, val->file); 125bf215546Sopenharmony_ci} 126bf215546Sopenharmony_ci 127bf215546Sopenharmony_cistatic void printbitfield (struct rnnbitfield *bf, int shift); 128bf215546Sopenharmony_ci 129bf215546Sopenharmony_cistatic void printtypeinfo (struct rnntypeinfo *ti, struct rnnbitfield *bf, 130bf215546Sopenharmony_ci char *prefix, char *file) { 131bf215546Sopenharmony_ci FILE *dst = findfout(file); 132bf215546Sopenharmony_ci enum rnnttype intype = ti->type; 133bf215546Sopenharmony_ci char *typename = NULL; 134bf215546Sopenharmony_ci uint32_t mask = typeinfo_mask(ti); 135bf215546Sopenharmony_ci uint32_t width = 1 + ti->high - ti->low; 136bf215546Sopenharmony_ci 137bf215546Sopenharmony_ci /* for fixed point, input type (arg to fxn) is float: */ 138bf215546Sopenharmony_ci if ((ti->type == RNN_TTYPE_FIXED) || (ti->type == RNN_TTYPE_UFIXED)) 139bf215546Sopenharmony_ci intype = RNN_TTYPE_FLOAT; 140bf215546Sopenharmony_ci 141bf215546Sopenharmony_ci /* for toplevel register (ie. not bitfield), only generate accessor 142bf215546Sopenharmony_ci * fxn for special cases (float, shr, min/max, etc): 143bf215546Sopenharmony_ci */ 144bf215546Sopenharmony_ci if (bf || ti->shr || ti->minvalid || ti->maxvalid || ti->alignvalid || 145bf215546Sopenharmony_ci ti->radixvalid || (intype == RNN_TTYPE_FLOAT)) { 146bf215546Sopenharmony_ci switch (intype) { 147bf215546Sopenharmony_ci case RNN_TTYPE_HEX: 148bf215546Sopenharmony_ci case RNN_TTYPE_UINT: 149bf215546Sopenharmony_ci case RNN_TTYPE_A3XX_REGID: 150bf215546Sopenharmony_ci typename = "uint32_t"; 151bf215546Sopenharmony_ci break; 152bf215546Sopenharmony_ci case RNN_TTYPE_INT: 153bf215546Sopenharmony_ci typename = "int32_t"; 154bf215546Sopenharmony_ci break; 155bf215546Sopenharmony_ci case RNN_TTYPE_FLOAT: 156bf215546Sopenharmony_ci typename = "float"; 157bf215546Sopenharmony_ci break; 158bf215546Sopenharmony_ci case RNN_TTYPE_ENUM: 159bf215546Sopenharmony_ci asprintf(&typename, "enum %s", ti->name); 160bf215546Sopenharmony_ci break; 161bf215546Sopenharmony_ci default: 162bf215546Sopenharmony_ci break; 163bf215546Sopenharmony_ci } 164bf215546Sopenharmony_ci } 165bf215546Sopenharmony_ci 166bf215546Sopenharmony_ci /* for boolean, just generate a #define flag.. rather than inline fxn */ 167bf215546Sopenharmony_ci if (bf && (intype == RNN_TTYPE_BOOLEAN)) { 168bf215546Sopenharmony_ci printdef(bf->fullname, 0, 0, mask, file); 169bf215546Sopenharmony_ci return; 170bf215546Sopenharmony_ci } 171bf215546Sopenharmony_ci 172bf215546Sopenharmony_ci if (typename) { 173bf215546Sopenharmony_ci printdef(prefix, "MASK", 0, mask, file); 174bf215546Sopenharmony_ci printdef(prefix, "SHIFT", 1, ti->low, file); 175bf215546Sopenharmony_ci 176bf215546Sopenharmony_ci fprintf(dst, "static inline uint32_t %s(%s val)\n", prefix, typename); 177bf215546Sopenharmony_ci fprintf(dst, "{\n"); 178bf215546Sopenharmony_ci 179bf215546Sopenharmony_ci if ((ti->minvalid || ti->maxvalid || ti->alignvalid) && !no_asserts) { 180bf215546Sopenharmony_ci fprintf(dst, "\tassert(1"); 181bf215546Sopenharmony_ci if (ti->minvalid) 182bf215546Sopenharmony_ci fprintf(dst, " && (val >= %"PRIu64")", ti->min); 183bf215546Sopenharmony_ci if (ti->maxvalid) 184bf215546Sopenharmony_ci fprintf(dst, " && (val <= %"PRIu64")", ti->max); 185bf215546Sopenharmony_ci if (ti->alignvalid) 186bf215546Sopenharmony_ci fprintf(dst, " && !(val %% %"PRIu64")", ti->align); 187bf215546Sopenharmony_ci fprintf(dst, ");\n"); 188bf215546Sopenharmony_ci } 189bf215546Sopenharmony_ci 190bf215546Sopenharmony_ci if (ti->shr && !no_asserts) { 191bf215546Sopenharmony_ci fprintf(dst, "\tassert(!(val & 0x%x));\n", (1 << ti->shr) - 1); 192bf215546Sopenharmony_ci } 193bf215546Sopenharmony_ci 194bf215546Sopenharmony_ci fprintf(dst, "\treturn (("); 195bf215546Sopenharmony_ci 196bf215546Sopenharmony_ci if (ti->type == RNN_TTYPE_FIXED) { 197bf215546Sopenharmony_ci fprintf(dst, "((int32_t)(val * %d.0))", (1 << ti->radix)); 198bf215546Sopenharmony_ci } else if (ti->type == RNN_TTYPE_UFIXED) { 199bf215546Sopenharmony_ci fprintf(dst, "((uint32_t)(val * %d.0))", (1 << ti->radix)); 200bf215546Sopenharmony_ci } else if (ti->type == RNN_TTYPE_FLOAT) { 201bf215546Sopenharmony_ci if (width == 32) 202bf215546Sopenharmony_ci fprintf(dst, "fui(val)"); 203bf215546Sopenharmony_ci else if (width == 16) 204bf215546Sopenharmony_ci fprintf(dst, "_mesa_float_to_half(val)"); 205bf215546Sopenharmony_ci else 206bf215546Sopenharmony_ci assert(!"invalid float size"); 207bf215546Sopenharmony_ci } else { 208bf215546Sopenharmony_ci fprintf(dst, "val"); 209bf215546Sopenharmony_ci } 210bf215546Sopenharmony_ci 211bf215546Sopenharmony_ci if (ti->shr) 212bf215546Sopenharmony_ci fprintf(dst, " >> %d", ti->shr); 213bf215546Sopenharmony_ci 214bf215546Sopenharmony_ci fprintf(dst, ") << %s__SHIFT) & %s__MASK;\n", prefix, prefix); 215bf215546Sopenharmony_ci fprintf(dst, "}\n"); 216bf215546Sopenharmony_ci 217bf215546Sopenharmony_ci if (intype == RNN_TTYPE_ENUM) 218bf215546Sopenharmony_ci free(typename); 219bf215546Sopenharmony_ci } 220bf215546Sopenharmony_ci 221bf215546Sopenharmony_ci int i; 222bf215546Sopenharmony_ci for (i = 0; i < ti->valsnum; i++) 223bf215546Sopenharmony_ci printvalue(ti->vals[i], ti->low); 224bf215546Sopenharmony_ci for (i = 0; i < ti->bitfieldsnum; i++) 225bf215546Sopenharmony_ci printbitfield(ti->bitfields[i], ti->low); 226bf215546Sopenharmony_ci} 227bf215546Sopenharmony_ci 228bf215546Sopenharmony_cistatic void printbitfield (struct rnnbitfield *bf, int shift) { 229bf215546Sopenharmony_ci if (bf->varinfo.dead) 230bf215546Sopenharmony_ci return; 231bf215546Sopenharmony_ci printtypeinfo (&bf->typeinfo, bf, bf->fullname, bf->file); 232bf215546Sopenharmony_ci} 233bf215546Sopenharmony_ci 234bf215546Sopenharmony_cistatic void printdelem (struct rnndelem *elem, uint64_t offset, const char *str) { 235bf215546Sopenharmony_ci int use_offset_fxn; 236bf215546Sopenharmony_ci char *offsetfn = NULL; 237bf215546Sopenharmony_ci 238bf215546Sopenharmony_ci if (elem->varinfo.dead) 239bf215546Sopenharmony_ci return; 240bf215546Sopenharmony_ci 241bf215546Sopenharmony_ci use_offset_fxn = elem->offsets || elem->doffset || elem->doffsets; 242bf215546Sopenharmony_ci assert((!!elem->offsets + !!elem->doffset + !!elem->doffsets) <= 1); 243bf215546Sopenharmony_ci 244bf215546Sopenharmony_ci if (use_offset_fxn) 245bf215546Sopenharmony_ci asprintf(&offsetfn, "__offset_%s", elem->name); 246bf215546Sopenharmony_ci 247bf215546Sopenharmony_ci if (elem->length != 1) { 248bf215546Sopenharmony_ci ADDARRAY(elems, elem); 249bf215546Sopenharmony_ci ADDARRAY(offsetfns, offsetfn); 250bf215546Sopenharmony_ci } 251bf215546Sopenharmony_ci 252bf215546Sopenharmony_ci if (elem->name) { 253bf215546Sopenharmony_ci char *regname; 254bf215546Sopenharmony_ci if (str) { 255bf215546Sopenharmony_ci asprintf(®name, "REG_%s_%s", elem->fullname, str); 256bf215546Sopenharmony_ci } else { 257bf215546Sopenharmony_ci asprintf(®name, "REG_%s", elem->fullname); 258bf215546Sopenharmony_ci } 259bf215546Sopenharmony_ci if (elemsnum) { 260bf215546Sopenharmony_ci int len; 261bf215546Sopenharmony_ci FILE *dst = findfout(elem->file); 262bf215546Sopenharmony_ci int i; 263bf215546Sopenharmony_ci 264bf215546Sopenharmony_ci if (use_offset_fxn) { 265bf215546Sopenharmony_ci fprintf(dst, "static inline uint32_t %s(", offsetfn); 266bf215546Sopenharmony_ci if (elem->index) 267bf215546Sopenharmony_ci fprintf(dst, "enum %s", elem->index->name); 268bf215546Sopenharmony_ci else 269bf215546Sopenharmony_ci fprintf(dst, "uint32_t"); 270bf215546Sopenharmony_ci fprintf(dst, " idx)\n"); 271bf215546Sopenharmony_ci fprintf(dst, "{\n"); 272bf215546Sopenharmony_ci if (elem->doffset) { 273bf215546Sopenharmony_ci fprintf(dst, "\treturn (%s) + (%#" PRIx64 "*idx);\n", elem->doffset, elem->stride); 274bf215546Sopenharmony_ci } else { 275bf215546Sopenharmony_ci int valuesnum = elem->doffsets ? elem->doffsetsnum : elem->offsetsnum; 276bf215546Sopenharmony_ci 277bf215546Sopenharmony_ci fprintf(dst, "\tswitch (idx) {\n"); 278bf215546Sopenharmony_ci for (i = 0; i < valuesnum; i++) { 279bf215546Sopenharmony_ci struct rnnvalue *val = NULL; 280bf215546Sopenharmony_ci fprintf(dst, "\t\tcase "); 281bf215546Sopenharmony_ci if (elem->index) { 282bf215546Sopenharmony_ci int j; 283bf215546Sopenharmony_ci for (j = 0; j < elem->index->valsnum; j++) { 284bf215546Sopenharmony_ci if (elem->index->vals[j]->value == i) { 285bf215546Sopenharmony_ci val = elem->index->vals[j]; 286bf215546Sopenharmony_ci break; 287bf215546Sopenharmony_ci } 288bf215546Sopenharmony_ci } 289bf215546Sopenharmony_ci } 290bf215546Sopenharmony_ci if (val) { 291bf215546Sopenharmony_ci fprintf(dst, "%s", val->name); 292bf215546Sopenharmony_ci } else { 293bf215546Sopenharmony_ci fprintf(dst, "%d", i); 294bf215546Sopenharmony_ci } 295bf215546Sopenharmony_ci if (elem->offsets) { 296bf215546Sopenharmony_ci fprintf(dst, ": return 0x%08"PRIx64";\n", elem->offsets[i]); 297bf215546Sopenharmony_ci } else { 298bf215546Sopenharmony_ci fprintf(dst, ": return (%s);\n", elem->doffsets[i]); 299bf215546Sopenharmony_ci } 300bf215546Sopenharmony_ci } 301bf215546Sopenharmony_ci fprintf(dst, "\t\tdefault: return INVALID_IDX(idx);\n"); 302bf215546Sopenharmony_ci fprintf(dst, "\t}\n"); 303bf215546Sopenharmony_ci } 304bf215546Sopenharmony_ci fprintf(dst, "}\n"); 305bf215546Sopenharmony_ci } 306bf215546Sopenharmony_ci fprintf (dst, "static inline uint32_t %s(", regname); 307bf215546Sopenharmony_ci for (i = 0; i < elemsnum; i++) { 308bf215546Sopenharmony_ci if (i) 309bf215546Sopenharmony_ci fprintf(dst, ", "); 310bf215546Sopenharmony_ci if (elems[i]->index) 311bf215546Sopenharmony_ci fprintf(dst, "enum %s ", elems[i]->index->name); 312bf215546Sopenharmony_ci else 313bf215546Sopenharmony_ci fprintf(dst, "uint32_t "); 314bf215546Sopenharmony_ci fprintf (dst, "i%d%n", i, &len); 315bf215546Sopenharmony_ci } 316bf215546Sopenharmony_ci fprintf (dst, ") { return "); 317bf215546Sopenharmony_ci fprintf (dst, "0x%08"PRIx64"", offset + elem->offset); 318bf215546Sopenharmony_ci for (i = 0; i < elemsnum; i++) { 319bf215546Sopenharmony_ci if (offsetfns[i]) 320bf215546Sopenharmony_ci fprintf(dst, " + %s(i%d)", offsetfns[i], i); 321bf215546Sopenharmony_ci else 322bf215546Sopenharmony_ci fprintf (dst, " + %#" PRIx64 "*i%d", elems[i]->stride, i); 323bf215546Sopenharmony_ci } 324bf215546Sopenharmony_ci fprintf (dst, "; }\n"); 325bf215546Sopenharmony_ci } else 326bf215546Sopenharmony_ci printdef (regname, 0, 0, offset + elem->offset, elem->file); 327bf215546Sopenharmony_ci 328bf215546Sopenharmony_ci free(regname); 329bf215546Sopenharmony_ci/* 330bf215546Sopenharmony_ci if (elem->stride) 331bf215546Sopenharmony_ci printdef (elem->fullname, "ESIZE", 0, elem->stride, elem->file); 332bf215546Sopenharmony_ci if (elem->length != 1) 333bf215546Sopenharmony_ci printdef (elem->fullname, "LEN", 0, elem->length, elem->file); 334bf215546Sopenharmony_ci*/ 335bf215546Sopenharmony_ci printtypeinfo (&elem->typeinfo, NULL, elem->fullname, elem->file); 336bf215546Sopenharmony_ci } 337bf215546Sopenharmony_ci fprintf (findfout(elem->file), "\n"); 338bf215546Sopenharmony_ci int j; 339bf215546Sopenharmony_ci for (j = 0; j < elem->subelemsnum; j++) { 340bf215546Sopenharmony_ci printdelem(elem->subelems[j], offset + elem->offset, elem->varinfo.prefixstr); 341bf215546Sopenharmony_ci } 342bf215546Sopenharmony_ci if (elem->length != 1) { 343bf215546Sopenharmony_ci elemsnum--; 344bf215546Sopenharmony_ci offsetfnsnum--; 345bf215546Sopenharmony_ci } 346bf215546Sopenharmony_ci free(offsetfn); 347bf215546Sopenharmony_ci} 348bf215546Sopenharmony_ci 349bf215546Sopenharmony_cistatic void print_file_info_(FILE *dst, struct stat* sb, struct tm* tm) 350bf215546Sopenharmony_ci{ 351bf215546Sopenharmony_ci char timestr[64]; 352bf215546Sopenharmony_ci strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S", tm); 353bf215546Sopenharmony_ci fprintf(dst, "(%7Lu bytes, from %s)\n", (unsigned long long)sb->st_size, timestr); 354bf215546Sopenharmony_ci} 355bf215546Sopenharmony_ci 356bf215546Sopenharmony_cistatic void print_file_info(FILE *dst, const char* file) 357bf215546Sopenharmony_ci{ 358bf215546Sopenharmony_ci struct stat sb; 359bf215546Sopenharmony_ci struct tm tm; 360bf215546Sopenharmony_ci stat(file, &sb); 361bf215546Sopenharmony_ci gmtime_r(&sb.st_mtime, &tm); 362bf215546Sopenharmony_ci print_file_info_(dst, &sb, &tm); 363bf215546Sopenharmony_ci} 364bf215546Sopenharmony_ci 365bf215546Sopenharmony_cistatic void printhead(struct fout f, struct rnndb *db) { 366bf215546Sopenharmony_ci int i, j; 367bf215546Sopenharmony_ci struct stat sb; 368bf215546Sopenharmony_ci struct tm tm; 369bf215546Sopenharmony_ci stat(f.name, &sb); 370bf215546Sopenharmony_ci gmtime_r(&sb.st_mtime, &tm); 371bf215546Sopenharmony_ci fprintf (f.file, "#ifndef %s\n", f.guard); 372bf215546Sopenharmony_ci fprintf (f.file, "#define %s\n", f.guard); 373bf215546Sopenharmony_ci fprintf (f.file, "\n"); 374bf215546Sopenharmony_ci fprintf(f.file, 375bf215546Sopenharmony_ci "/* Autogenerated file, DO NOT EDIT manually!\n" 376bf215546Sopenharmony_ci "\n" 377bf215546Sopenharmony_ci "This file was generated by the rules-ng-ng headergen tool in this git repository:\n" 378bf215546Sopenharmony_ci "http://github.com/freedreno/envytools/\n" 379bf215546Sopenharmony_ci "git clone https://github.com/freedreno/envytools.git\n" 380bf215546Sopenharmony_ci "\n" 381bf215546Sopenharmony_ci "The rules-ng-ng source files this header was generated from are:\n"); 382bf215546Sopenharmony_ci unsigned maxlen = 0; 383bf215546Sopenharmony_ci for(i = 0; i < db->filesnum; ++i) { 384bf215546Sopenharmony_ci unsigned len = strlen(db->files[i]); 385bf215546Sopenharmony_ci if(len > maxlen) 386bf215546Sopenharmony_ci maxlen = len; 387bf215546Sopenharmony_ci } 388bf215546Sopenharmony_ci for(i = 0; i < db->filesnum; ++i) { 389bf215546Sopenharmony_ci unsigned len = strlen(db->files[i]); 390bf215546Sopenharmony_ci fprintf(f.file, "- %s%*s ", db->files[i], maxlen - len, ""); 391bf215546Sopenharmony_ci print_file_info(f.file, db->files[i]); 392bf215546Sopenharmony_ci } 393bf215546Sopenharmony_ci fprintf(f.file, 394bf215546Sopenharmony_ci "\n" 395bf215546Sopenharmony_ci "Copyright (C) "); 396bf215546Sopenharmony_ci if(db->copyright.firstyear && db->copyright.firstyear < (1900 + tm.tm_year)) 397bf215546Sopenharmony_ci fprintf(f.file, "%u-", db->copyright.firstyear); 398bf215546Sopenharmony_ci fprintf(f.file, "%u", 1900 + tm.tm_year); 399bf215546Sopenharmony_ci if(db->copyright.authorsnum) { 400bf215546Sopenharmony_ci fprintf(f.file, " by the following authors:"); 401bf215546Sopenharmony_ci for(i = 0; i < db->copyright.authorsnum; ++i) { 402bf215546Sopenharmony_ci fprintf(f.file, "\n- "); 403bf215546Sopenharmony_ci if(db->copyright.authors[i]->name) 404bf215546Sopenharmony_ci fprintf(f.file, "%s", db->copyright.authors[i]->name); 405bf215546Sopenharmony_ci if(db->copyright.authors[i]->email) 406bf215546Sopenharmony_ci fprintf(f.file, " <%s>", db->copyright.authors[i]->email); 407bf215546Sopenharmony_ci if(db->copyright.authors[i]->nicknamesnum) { 408bf215546Sopenharmony_ci for(j = 0; j < db->copyright.authors[i]->nicknamesnum; ++j) { 409bf215546Sopenharmony_ci fprintf(f.file, "%s%s", (j ? ", " : " ("), db->copyright.authors[i]->nicknames[j]); 410bf215546Sopenharmony_ci } 411bf215546Sopenharmony_ci fprintf(f.file, ")"); 412bf215546Sopenharmony_ci } 413bf215546Sopenharmony_ci } 414bf215546Sopenharmony_ci } 415bf215546Sopenharmony_ci fprintf(f.file, "\n"); 416bf215546Sopenharmony_ci if(db->copyright.license) 417bf215546Sopenharmony_ci fprintf(f.file, "\n%s\n", db->copyright.license); 418bf215546Sopenharmony_ci fprintf(f.file, "*/\n\n\n"); 419bf215546Sopenharmony_ci} 420bf215546Sopenharmony_ci 421bf215546Sopenharmony_ciint main(int argc, char **argv) { 422bf215546Sopenharmony_ci char *file; 423bf215546Sopenharmony_ci struct rnndb *db; 424bf215546Sopenharmony_ci int i, j; 425bf215546Sopenharmony_ci 426bf215546Sopenharmony_ci if (argc < 2) { 427bf215546Sopenharmony_ci fprintf(stderr, "Usage:\n\theadergen database-file\n"); 428bf215546Sopenharmony_ci exit(1); 429bf215546Sopenharmony_ci } 430bf215546Sopenharmony_ci 431bf215546Sopenharmony_ci if ((argc >= 3) && !strcmp(argv[1], "--no-asserts")) { 432bf215546Sopenharmony_ci no_asserts = true; 433bf215546Sopenharmony_ci file = argv[2]; 434bf215546Sopenharmony_ci } else { 435bf215546Sopenharmony_ci file = argv[1]; 436bf215546Sopenharmony_ci } 437bf215546Sopenharmony_ci 438bf215546Sopenharmony_ci rnn_init(); 439bf215546Sopenharmony_ci db = rnn_newdb(); 440bf215546Sopenharmony_ci rnn_parsefile (db, file); 441bf215546Sopenharmony_ci rnn_prepdb (db); 442bf215546Sopenharmony_ci for(i = 0; i < db->filesnum; ++i) { 443bf215546Sopenharmony_ci char *dstname = malloc(strlen(db->files[i]) + 3); 444bf215546Sopenharmony_ci char *pretty; 445bf215546Sopenharmony_ci strcpy(dstname, db->files[i]); 446bf215546Sopenharmony_ci strcat(dstname, ".h"); 447bf215546Sopenharmony_ci struct fout f = { db->files[i], fopen(dstname, "w") }; 448bf215546Sopenharmony_ci if (!f.file) { 449bf215546Sopenharmony_ci perror(dstname); 450bf215546Sopenharmony_ci exit(1); 451bf215546Sopenharmony_ci } 452bf215546Sopenharmony_ci free(dstname); 453bf215546Sopenharmony_ci pretty = strrchr(f.name, '/'); 454bf215546Sopenharmony_ci if (pretty) 455bf215546Sopenharmony_ci pretty += 1; 456bf215546Sopenharmony_ci else 457bf215546Sopenharmony_ci pretty = f.name; 458bf215546Sopenharmony_ci f.guard = strdup(pretty); 459bf215546Sopenharmony_ci for (j = 0; j < strlen(f.guard); j++) 460bf215546Sopenharmony_ci if (isalnum(f.guard[j])) 461bf215546Sopenharmony_ci f.guard[j] = toupper(f.guard[j]); 462bf215546Sopenharmony_ci else 463bf215546Sopenharmony_ci f.guard[j] = '_'; 464bf215546Sopenharmony_ci ADDARRAY(fouts, f); 465bf215546Sopenharmony_ci printhead(f, db); 466bf215546Sopenharmony_ci } 467bf215546Sopenharmony_ci 468bf215546Sopenharmony_ci for (i = 0; i < db->enumsnum; i++) { 469bf215546Sopenharmony_ci FILE *dst = NULL; 470bf215546Sopenharmony_ci int j; 471bf215546Sopenharmony_ci for (j = 0; j < db->enums[i]->valsnum; j++) { 472bf215546Sopenharmony_ci if (!dst) { 473bf215546Sopenharmony_ci dst = findfout(db->enums[i]->vals[j]->file); 474bf215546Sopenharmony_ci fprintf(dst, "enum %s {\n", db->enums[i]->name); 475bf215546Sopenharmony_ci } 476bf215546Sopenharmony_ci if (0xffff0000 & db->enums[i]->vals[j]->value) 477bf215546Sopenharmony_ci fprintf(dst, "\t%s = 0x%08"PRIx64",\n", db->enums[i]->vals[j]->name, 478bf215546Sopenharmony_ci db->enums[i]->vals[j]->value); 479bf215546Sopenharmony_ci else 480bf215546Sopenharmony_ci fprintf(dst, "\t%s = %"PRIu64",\n", db->enums[i]->vals[j]->name, 481bf215546Sopenharmony_ci db->enums[i]->vals[j]->value); 482bf215546Sopenharmony_ci } 483bf215546Sopenharmony_ci if (dst) { 484bf215546Sopenharmony_ci fprintf(dst, "};\n\n"); 485bf215546Sopenharmony_ci } 486bf215546Sopenharmony_ci } 487bf215546Sopenharmony_ci for (i = 0; i < db->bitsetsnum; i++) { 488bf215546Sopenharmony_ci if (db->bitsets[i]->isinline) 489bf215546Sopenharmony_ci continue; 490bf215546Sopenharmony_ci int j; 491bf215546Sopenharmony_ci for (j = 0; j < db->bitsets[i]->bitfieldsnum; j++) 492bf215546Sopenharmony_ci printbitfield (db->bitsets[i]->bitfields[j], 0); 493bf215546Sopenharmony_ci } 494bf215546Sopenharmony_ci for (i = 0; i < db->domainsnum; i++) { 495bf215546Sopenharmony_ci if (db->domains[i]->size) 496bf215546Sopenharmony_ci printdef (db->domains[i]->fullname, "SIZE", 0, db->domains[i]->size, db->domains[i]->file); 497bf215546Sopenharmony_ci int j; 498bf215546Sopenharmony_ci for (j = 0; j < db->domains[i]->subelemsnum; j++) { 499bf215546Sopenharmony_ci printdelem(db->domains[i]->subelems[j], 0, NULL); 500bf215546Sopenharmony_ci } 501bf215546Sopenharmony_ci } 502bf215546Sopenharmony_ci for(i = 0; i < foutsnum; ++i) { 503bf215546Sopenharmony_ci fprintf (fouts[i].file, "\n#endif /* %s */\n", fouts[i].guard); 504bf215546Sopenharmony_ci } 505bf215546Sopenharmony_ci return db->estatus; 506bf215546Sopenharmony_ci} 507