freedreno/rnn: warnings cleanup
[mesa.git] / src / freedreno / rnn / rnn.c
1 /*
2 * Copyright (C) 2010-2011 Marcin Koƛcielnicki <koriakin@0x04.net>
3 * Copyright (C) 2010 Luca Barbieri <luca@luca-barbieri.com>
4 * Copyright (C) 2010 Francisco Jerez <currojerez@riseup.net>
5 * Copyright (C) 2010 Martin Peres <martin.peres@ensi-bourges.fr>
6 * Copyright (C) 2010 Marcin Slusarz <marcin.slusarz@gmail.com>
7 * All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice (including the next
17 * paragraph) shall be included in all copies or substantial portions of the
18 * Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
24 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
26 * OTHER DEALINGS IN THE SOFTWARE.
27 */
28
29 /* workaround libxml2 silliness: */
30 #pragma GCC diagnostic ignored "-Wpointer-sign"
31
32 #include <libxml/xmlversion.h>
33 #include <libxml/parser.h>
34 #include <libxml/xpath.h>
35 #include <libxml/xmlreader.h>
36 #include <stdint.h>
37 #include <string.h>
38 #include <limits.h>
39 #include <ctype.h>
40 #include <stdio.h>
41 #include "rnn.h"
42 #include "rnn_path.h"
43 #include "util.h"
44
45 static char *catstr (char *a, char *b) {
46 if (!a)
47 return b;
48 return aprintf("%s_%s", a, b);
49 }
50
51 static int strdiff (const char *a, const char *b) {
52 if (!a && !b)
53 return 0;
54 if (!a || !b)
55 return 1;
56 return strcmp (a, b);
57 }
58
59 void rnn_init(void) {
60 LIBXML_TEST_VERSION
61 xmlInitParser();
62 }
63
64 struct rnndb *rnn_newdb(void) {
65 struct rnndb *db = calloc(sizeof *db, 1);
66 return db;
67 }
68
69 static char *getcontent (xmlNode *attr) {
70 xmlNode *chain = attr->children;
71 size_t size = 0;
72 char *content, *p;
73 while (chain) {
74 if (chain->type == XML_TEXT_NODE)
75 size += strlen(chain->content);
76 chain = chain->next;
77 }
78 p = content = malloc(size + 1);
79 chain = attr->children;
80 while (chain) {
81 if (chain->type == XML_TEXT_NODE) {
82 char* sp = chain->content;
83 if(p == content) {
84 while(isspace(*sp))
85 ++sp;
86 }
87 size_t len = strlen(sp);
88 memcpy(p, sp, len);
89 p += len;
90 }
91 chain = chain->next;
92 }
93 while(p != content && isspace(p[-1]))
94 --p;
95 *p = 0;
96 return content;
97 }
98
99 static char *getattrib (struct rnndb *db, char *file, int line, xmlAttr *attr) {
100 xmlNode *chain = attr->children;
101 while (chain) {
102 if (chain->type != XML_TEXT_NODE) {
103 fprintf (stderr, "%s:%d: unknown attribute child \"%s\" in attribute \"%s\"\n", file, line, chain->name, attr->name);
104 db->estatus = 1;
105 } else {
106 return chain->content;
107 }
108 chain = chain->next;
109 }
110 return "";
111 }
112
113 static int getboolattrib (struct rnndb *db, char *file, int line, xmlAttr *attr) {
114 char *c = getattrib(db, file, line, attr);
115 if (!strcmp(c, "yes") || !strcmp(c, "1"))
116 return 1;
117 if (!strcmp(c, "no") || !strcmp(c, "0"))
118 return 0;
119 fprintf (stderr, "%s:%d: invalid boolean value \"%s\" in attribute \"%s\"\n", file, line, c, attr->name);
120 db->estatus = 1;
121 return 0;
122 }
123
124 static uint64_t getnum(struct rnndb *db, char *file, int line, xmlAttr *attr, char *c)
125 {
126 char *cc;
127 uint64_t res;
128 if (strchr(c, 'x') || strchr(c, 'X'))
129 res = strtoull(c, &cc, 16);
130 else
131 res = strtoull(c, &cc, 10);
132 if (*cc) {
133 fprintf (stderr, "%s:%d: invalid numeric value \"%s\" in attribute \"%s\"\n", file, line, c, attr->name);
134 db->estatus = 1;
135 }
136 return res;
137 }
138
139 static uint64_t getnumattrib (struct rnndb *db, char *file, int line, xmlAttr *attr) {
140 char *c = getattrib(db, file, line, attr);
141 return getnum(db, file, line, attr, c);
142 }
143
144 static int trytop (struct rnndb *db, char *file, xmlNode *node);
145
146 static int trydoc (struct rnndb *db, char *file, xmlNode *node) {
147 if (!strcmp(node->name, "brief")) {
148 return 1;
149 } else if (!strcmp(node->name, "doc")) {
150 return 1;
151 }
152 return 0;
153 }
154
155 static struct rnnvalue *parsevalue(struct rnndb *db, char *file, xmlNode *node);
156 static struct rnnbitfield *parsebitfield(struct rnndb *db, char *file, xmlNode *node);
157
158 static int trytypetag (struct rnndb *db, char *file, xmlNode *node, struct rnntypeinfo *ti) {
159 if (!strcmp(node->name, "value")) {
160 struct rnnvalue *val = parsevalue(db, file, node);
161 if (val)
162 ADDARRAY(ti->vals, val);
163 return 1;
164 } else if (!strcmp(node->name, "bitfield")) {
165 struct rnnbitfield *bf = parsebitfield(db, file, node);
166 if (bf)
167 ADDARRAY(ti->bitfields, bf);
168 return 1;
169 }
170 return 0;
171 }
172 static int trytypeattr (struct rnndb *db, char *file, xmlNode *node, xmlAttr *attr, struct rnntypeinfo *ti) {
173 if (!strcmp(attr->name, "shr")) {
174 ti->shr = getnumattrib(db, file, node->line, attr);
175 return 1;
176 } else if (!strcmp(attr->name, "min")) {
177 ti->min = getnumattrib(db, file, node->line, attr);
178 ti->minvalid = 1;
179 return 1;
180 } else if (!strcmp(attr->name, "max")) {
181 ti->max = getnumattrib(db, file, node->line, attr);
182 ti->maxvalid = 1;
183 return 1;
184 } else if (!strcmp(attr->name, "align")) {
185 ti->align = getnumattrib(db, file, node->line, attr);
186 ti->alignvalid = 1;
187 return 1;
188 } else if (!strcmp(attr->name, "type")) {
189 ti->name = strdup(getattrib(db, file, node->line, attr));;
190 return 1;
191 } else if (!strcmp(attr->name, "radix")) {
192 ti->radix = getnumattrib(db, file, node->line, attr);
193 ti->radixvalid = 1;
194 return 1;
195 } else if (!strcmp(attr->name, "pos")) {
196 ti->high = ti->low = getnumattrib(db, file, node->line, attr);
197 return 1;
198 } else if (!strcmp(attr->name, "low")) {
199 ti->low = getnumattrib(db, file, node->line, attr);
200 return 1;
201 } else if (!strcmp(attr->name, "high")) {
202 ti->high = getnumattrib(db, file, node->line, attr);
203 return 1;
204 } else if (!strcmp(attr->name, "addvariant")) {
205 ti->addvariant = getboolattrib(db, file, node->line, attr);
206 }
207 return 0;
208 }
209
210 static struct rnnvalue *parsevalue(struct rnndb *db, char *file, xmlNode *node) {
211 struct rnnvalue *val = calloc(sizeof *val, 1);
212 val->file = file;
213 xmlAttr *attr = node->properties;
214 while (attr) {
215 if (!strcmp(attr->name, "name")) {
216 val->name = strdup(getattrib(db, file, node->line, attr));
217 } else if (!strcmp(attr->name, "value")) {
218 val->value = getnumattrib(db, file, node->line, attr);
219 val->valvalid = 1;
220 } else if (!strcmp(attr->name, "varset")) {
221 val->varinfo.varsetstr = strdup(getattrib(db, file, node->line, attr));
222 } else if (!strcmp(attr->name, "variants")) {
223 val->varinfo.variantsstr = strdup(getattrib(db, file, node->line, attr));
224 } else {
225 fprintf (stderr, "%s:%d: wrong attribute \"%s\" for value\n", file, node->line, attr->name);
226 db->estatus = 1;
227 }
228 attr = attr->next;
229 }
230 xmlNode *chain = node->children;
231 while (chain) {
232 if (chain->type != XML_ELEMENT_NODE) {
233 } else if (!trytop(db, file, chain) && !trydoc(db, file, chain)) {
234 fprintf (stderr, "%s:%d: wrong tag in %s: <%s>\n", file, chain->line, node->name, chain->name);
235 db->estatus = 1;
236 }
237 chain = chain->next;
238 }
239 if (!val->name) {
240 fprintf (stderr, "%s:%d: nameless value\n", file, node->line);
241 db->estatus = 1;
242 return 0;
243 } else {
244 return val;
245 }
246 }
247
248 static void parsespectype(struct rnndb *db, char *file, xmlNode *node) {
249 struct rnnspectype *res = calloc (sizeof *res, 1);
250 res->file = file;
251 xmlAttr *attr = node->properties;
252 int i;
253 while (attr) {
254 if (!strcmp(attr->name, "name")) {
255 res->name = strdup(getattrib(db, file, node->line, attr));
256 } else if (!trytypeattr(db, file, node, attr, &res->typeinfo)) {
257 fprintf (stderr, "%s:%d: wrong attribute \"%s\" for spectype\n", file, node->line, attr->name);
258 db->estatus = 1;
259 }
260 attr = attr->next;
261 }
262 if (!res->name) {
263 fprintf (stderr, "%s:%d: nameless spectype\n", file, node->line);
264 db->estatus = 1;
265 return;
266 }
267 for (i = 0; i < db->spectypesnum; i++)
268 if (!strcmp(db->spectypes[i]->name, res->name)) {
269 fprintf (stderr, "%s:%d: duplicated spectype name %s\n", file, node->line, res->name);
270 db->estatus = 1;
271 return;
272 }
273 ADDARRAY(db->spectypes, res);
274 xmlNode *chain = node->children;
275 while (chain) {
276 if (chain->type != XML_ELEMENT_NODE) {
277 } else if (!trytypetag(db, file, chain, &res->typeinfo) && !trytop(db, file, chain) && !trydoc(db, file, chain)) {
278 fprintf (stderr, "%s:%d: wrong tag in spectype: <%s>\n", file, chain->line, chain->name);
279 db->estatus = 1;
280 }
281 chain = chain->next;
282 }
283 }
284
285 static void parseenum(struct rnndb *db, char *file, xmlNode *node) {
286 xmlAttr *attr = node->properties;
287 char *name = 0;
288 int isinline = 0;
289 int bare = 0;
290 char *prefixstr = 0;
291 char *varsetstr = 0;
292 char *variantsstr = 0;
293 int i;
294 while (attr) {
295 if (!strcmp(attr->name, "name")) {
296 name = getattrib(db, file, node->line, attr);
297 } else if (!strcmp(attr->name, "bare")) {
298 bare = getboolattrib(db, file, node->line, attr);
299 } else if (!strcmp(attr->name, "inline")) {
300 isinline = getboolattrib(db, file, node->line, attr);
301 } else if (!strcmp(attr->name, "prefix")) {
302 prefixstr = strdup(getattrib(db, file, node->line, attr));
303 } else if (!strcmp(attr->name, "varset")) {
304 varsetstr = strdup(getattrib(db, file, node->line, attr));
305 } else if (!strcmp(attr->name, "variants")) {
306 variantsstr = strdup(getattrib(db, file, node->line, attr));
307 } else {
308 fprintf (stderr, "%s:%d: wrong attribute \"%s\" for enum\n", file, node->line, attr->name);
309 db->estatus = 1;
310 }
311 attr = attr->next;
312 }
313 if (!name) {
314 fprintf (stderr, "%s:%d: nameless enum\n", file, node->line);
315 db->estatus = 1;
316 return;
317 }
318 struct rnnenum *cur = 0;
319 for (i = 0; i < db->enumsnum; i++)
320 if (!strcmp(db->enums[i]->name, name)) {
321 cur = db->enums[i];
322 break;
323 }
324 if (cur) {
325 if (strdiff(cur->varinfo.prefixstr, prefixstr) ||
326 strdiff(cur->varinfo.varsetstr, varsetstr) ||
327 strdiff(cur->varinfo.variantsstr, variantsstr) ||
328 cur->isinline != isinline || cur->bare != bare) {
329 fprintf (stderr, "%s:%d: merge fail for enum %s\n", file, node->line, node->name);
330 db->estatus = 1;
331 }
332 } else {
333 cur = calloc(sizeof *cur, 1);
334 cur->name = strdup(name);
335 cur->isinline = isinline;
336 cur->bare = bare;
337 cur->varinfo.prefixstr = prefixstr;
338 cur->varinfo.varsetstr = varsetstr;
339 cur->varinfo.variantsstr = variantsstr;
340 cur->file = file;
341 ADDARRAY(db->enums, cur);
342 }
343 xmlNode *chain = node->children;
344 while (chain) {
345 if (chain->type != XML_ELEMENT_NODE) {
346 } else if (!strcmp(chain->name, "value")) {
347 struct rnnvalue *val = parsevalue(db, file, chain);
348 if (val)
349 ADDARRAY(cur->vals, val);
350 } else if (!trytop(db, file, chain) && !trydoc(db, file, chain)) {
351 fprintf (stderr, "%s:%d: wrong tag in enum: <%s>\n", file, chain->line, chain->name);
352 db->estatus = 1;
353 }
354 chain = chain->next;
355 }
356 }
357
358 static struct rnnbitfield *parsebitfield(struct rnndb *db, char *file, xmlNode *node) {
359 struct rnnbitfield *bf = calloc(sizeof *bf, 1);
360 bf->file = file;
361 xmlAttr *attr = node->properties;
362 bf->typeinfo.low = bf->typeinfo.high = -1;
363 while (attr) {
364 if (!strcmp(attr->name, "name")) {
365 bf->name = strdup(getattrib(db, file, node->line, attr));
366 } else if (!strcmp(attr->name, "varset")) {
367 bf->varinfo.varsetstr = strdup(getattrib(db, file, node->line, attr));
368 } else if (!strcmp(attr->name, "variants")) {
369 bf->varinfo.variantsstr = strdup(getattrib(db, file, node->line, attr));
370 } else if (!trytypeattr(db, file, node, attr, &bf->typeinfo)) {
371 fprintf (stderr, "%s:%d: wrong attribute \"%s\" for bitfield\n", file, node->line, attr->name);
372 db->estatus = 1;
373 }
374 attr = attr->next;
375 }
376 xmlNode *chain = node->children;
377 while (chain) {
378 if (chain->type != XML_ELEMENT_NODE) {
379 } else if (!trytypetag(db, file, chain, &bf->typeinfo) && !trytop(db, file, chain) && !trydoc(db, file, chain)) {
380 fprintf (stderr, "%s:%d: wrong tag in %s: <%s>\n", file, chain->line, node->name, chain->name);
381 db->estatus = 1;
382 }
383 chain = chain->next;
384 }
385 if (!bf->name) {
386 fprintf (stderr, "%s:%d: nameless bitfield\n", file, node->line);
387 db->estatus = 1;
388 return 0;
389 } else if (bf->typeinfo.low < 0|| bf->typeinfo.high < 0 || bf->typeinfo.high < bf->typeinfo.low) {
390 fprintf (stderr, "%s:%d: bitfield has wrong placement\n", file, node->line);
391 db->estatus = 1;
392 return 0;
393 } else {
394 return bf;
395 }
396 }
397
398 static void parsebitset(struct rnndb *db, char *file, xmlNode *node) {
399 xmlAttr *attr = node->properties;
400 char *name = 0;
401 int isinline = 0;
402 int bare = 0;
403 char *prefixstr = 0;
404 char *varsetstr = 0;
405 char *variantsstr = 0;
406 int i;
407 while (attr) {
408 if (!strcmp(attr->name, "name")) {
409 name = getattrib(db, file, node->line, attr);
410 } else if (!strcmp(attr->name, "bare")) {
411 bare = getboolattrib(db, file, node->line, attr);
412 } else if (!strcmp(attr->name, "inline")) {
413 isinline = getboolattrib(db, file, node->line, attr);
414 } else if (!strcmp(attr->name, "prefix")) {
415 prefixstr = strdup(getattrib(db, file, node->line, attr));
416 } else if (!strcmp(attr->name, "varset")) {
417 varsetstr = strdup(getattrib(db, file, node->line, attr));
418 } else if (!strcmp(attr->name, "variants")) {
419 variantsstr = strdup(getattrib(db, file, node->line, attr));
420 } else {
421 fprintf (stderr, "%s:%d: wrong attribute \"%s\" for bitset\n", file, node->line, attr->name);
422 db->estatus = 1;
423 }
424 attr = attr->next;
425 }
426 if (!name) {
427 fprintf (stderr, "%s:%d: nameless bitset\n", file, node->line);
428 db->estatus = 1;
429 return;
430 }
431 struct rnnbitset *cur = 0;
432 for (i = 0; i < db->bitsetsnum; i++)
433 if (!strcmp(db->bitsets[i]->name, name)) {
434 cur = db->bitsets[i];
435 break;
436 }
437 if (cur) {
438 if (strdiff(cur->varinfo.prefixstr, prefixstr) ||
439 strdiff(cur->varinfo.varsetstr, varsetstr) ||
440 strdiff(cur->varinfo.variantsstr, variantsstr) ||
441 cur->isinline != isinline || cur->bare != bare) {
442 fprintf (stderr, "%s:%d: merge fail for bitset %s\n", file, node->line, node->name);
443 db->estatus = 1;
444 }
445 } else {
446 cur = calloc(sizeof *cur, 1);
447 cur->name = strdup(name);
448 cur->isinline = isinline;
449 cur->bare = bare;
450 cur->varinfo.prefixstr = prefixstr;
451 cur->varinfo.varsetstr = varsetstr;
452 cur->varinfo.variantsstr = variantsstr;
453 cur->file = file;
454 ADDARRAY(db->bitsets, cur);
455 }
456 xmlNode *chain = node->children;
457 while (chain) {
458 if (chain->type != XML_ELEMENT_NODE) {
459 } else if (!strcmp(chain->name, "bitfield")) {
460 struct rnnbitfield *bf = parsebitfield(db, file, chain);
461 if (bf)
462 ADDARRAY(cur->bitfields, bf);
463 } else if (!trytop(db, file, chain) && !trydoc(db, file, chain)) {
464 fprintf (stderr, "%s:%d: wrong tag in bitset: <%s>\n", file, chain->line, chain->name);
465 db->estatus = 1;
466 }
467 chain = chain->next;
468 }
469 }
470
471 static struct rnndelem *trydelem(struct rnndb *db, char *file, xmlNode *node) {
472 if (!strcmp(node->name, "use-group")) {
473 struct rnndelem *res = calloc(sizeof *res, 1);
474 res->file = file;
475 res->type = RNN_ETYPE_USE_GROUP;
476 xmlAttr *attr = node->properties;
477 while (attr) {
478 if (!strcmp(attr->name, "name")) {
479 res->name = strdup(getattrib(db, file, node->line, attr));
480 } else {
481 fprintf (stderr, "%s:%d: wrong attribute \"%s\" for %s\n", file, node->line, attr->name, node->name);
482 db->estatus = 1;
483 }
484 attr = attr->next;
485 }
486 if (!res->name) {
487 fprintf (stderr, "%s:%d: nameless use-group\n", file, node->line);
488 db->estatus = 1;
489 return 0;
490 }
491 return res;
492 } else if (!strcmp(node->name, "stripe") || !strcmp(node->name, "array")) {
493 struct rnndelem *res = calloc(sizeof *res, 1);
494 res->type = (strcmp(node->name, "stripe")?RNN_ETYPE_ARRAY:RNN_ETYPE_STRIPE);
495 res->length = 1;
496 res->file = file;
497 xmlAttr *attr = node->properties;
498 while (attr) {
499 if (!strcmp(attr->name, "name")) {
500 res->name = strdup(getattrib(db, file, node->line, attr));
501 } else if (!strcmp(attr->name, "offset")) {
502 res->offset = getnumattrib(db, file, node->line, attr);
503 } else if (!strcmp(attr->name, "offsets")) {
504 char *str = strdup(getattrib(db, file, node->line, attr));
505 char *tok, *save, *tmp = str;
506 while ((tok = strtok_r(str, ",", &save))) {
507 uint64_t offset = getnum(db, file, node->line, attr, tok);
508 ADDARRAY(res->offsets, offset);
509 str = NULL;
510 }
511 if (str)
512 fprintf(stderr, "%s:%d: invalid offsets: %s\n", file, node->line, str);
513 free(tmp);
514 } else if (!strcmp(attr->name, "doffset")) {
515 /* dynamic runtime determined offset: */
516 res->doffset = strdup(getattrib(db, file, node->line, attr));
517 } else if (!strcmp(attr->name, "doffsets")) {
518 /* dynamic runtime determined offsets: */
519 char *str = strdup(getattrib(db, file, node->line, attr));
520 char *tok, *save, *tmp = str;
521 while ((tok = strtok_r(str, ",", &save))) {
522 char *doffset = strdup(tok);
523 ADDARRAY(res->doffsets, doffset);
524 str = NULL;
525 }
526 if (str)
527 fprintf(stderr, "%s:%d: invalid offsets: %s\n", file, node->line, str);
528 free(tmp);
529 } else if (!strcmp(attr->name, "length")) {
530 res->length = getnumattrib(db, file, node->line, attr);
531 } else if (!strcmp(attr->name, "stride")) {
532 res->stride = getnumattrib(db, file, node->line, attr);
533 } else if (!strcmp(attr->name, "prefix")) {
534 res->varinfo.prefixstr = strdup(getattrib(db, file, node->line, attr));
535 } else if (!strcmp(attr->name, "varset")) {
536 res->varinfo.varsetstr = strdup(getattrib(db, file, node->line, attr));
537 } else if (!strcmp(attr->name, "variants")) {
538 res->varinfo.variantsstr = strdup(getattrib(db, file, node->line, attr));
539 } else if (!strcmp(attr->name, "index")) {
540 const char *enumname = getattrib(db, file, node->line, attr);
541 res->index = rnn_findenum(db, enumname);
542 if (!res->index) {
543 fprintf(stderr, "%s:%d: invalid enum name \"%s\"\n", file, node->line, enumname);
544 db->estatus = 1;
545 }
546 } else {
547 fprintf (stderr, "%s:%d: wrong attribute \"%s\" for %s\n", file, node->line, attr->name, node->name);
548 db->estatus = 1;
549 }
550 attr = attr->next;
551 }
552 xmlNode *chain = node->children;
553 while (chain) {
554 struct rnndelem *delem;
555 if (chain->type != XML_ELEMENT_NODE) {
556 } else if ((delem = trydelem(db, file, chain))) {
557 ADDARRAY(res->subelems, delem);
558 } else if (!trytop(db, file, chain) && !trydoc(db, file, chain)) {
559 fprintf (stderr, "%s:%d: wrong tag in %s: <%s>\n", file, chain->line, node->name, chain->name);
560 db->estatus = 1;
561 }
562 chain = chain->next;
563 }
564
565 /* Sanity checking */
566 if (res->type == RNN_ETYPE_ARRAY && res->stride == 0) {
567 fprintf(stderr, "%s: Array %s's stride is undefined. Aborting.\n", file, res->name);
568 exit(-1);
569 }
570 return res;
571
572 }
573 int width;
574 if (!strcmp(node->name, "reg8"))
575 width = 8;
576 else if (!strcmp(node->name, "reg16"))
577 width = 16;
578 else if (!strcmp(node->name, "reg32"))
579 width = 32;
580 else if (!strcmp(node->name, "reg64"))
581 width = 64;
582 else
583 return 0;
584 struct rnndelem *res = calloc(sizeof *res, 1);
585 res->file = file;
586 res->type = RNN_ETYPE_REG;
587 res->width = width;
588 res->length = 1;
589 res->access = RNN_ACCESS_RW;
590 xmlAttr *attr = node->properties;
591 res->typeinfo.low = 0;
592 res->typeinfo.high = width - 1;
593 while (attr) {
594 if (!strcmp(attr->name, "name")) {
595 res->name = strdup(getattrib(db, file, node->line, attr));
596 } else if (!strcmp(attr->name, "offset")) {
597 res->offset = getnumattrib(db, file, node->line, attr);
598 } else if (!strcmp(attr->name, "length")) {
599 res->length = getnumattrib(db, file, node->line, attr);
600 } else if (!strcmp(attr->name, "stride")) {
601 res->stride = getnumattrib(db, file, node->line, attr);
602 } else if (!strcmp(attr->name, "varset")) {
603 res->varinfo.varsetstr = strdup(getattrib(db, file, node->line, attr));
604 } else if (!strcmp(attr->name, "variants")) {
605 res->varinfo.variantsstr = strdup(getattrib(db, file, node->line, attr));
606 } else if (!strcmp(attr->name, "access")) {
607 char *str = getattrib(db, file, node->line, attr);
608 if (!strcmp(str, "r"))
609 res->access = RNN_ACCESS_R;
610 else if (!strcmp(str, "w"))
611 res->access = RNN_ACCESS_W;
612 else if (!strcmp(str, "rw"))
613 res->access = RNN_ACCESS_RW;
614 else
615 fprintf (stderr, "%s:%d: wrong access type \"%s\" for register\n", file, node->line, str);
616 } else if (!trytypeattr(db, file, node, attr, &res->typeinfo)) {
617 fprintf (stderr, "%s:%d: wrong attribute \"%s\" for register\n", file, node->line, attr->name);
618 db->estatus = 1;
619 }
620 attr = attr->next;
621 }
622 xmlNode *chain = node->children;
623 while (chain) {
624 if (chain->type != XML_ELEMENT_NODE) {
625 } else if (!trytypetag(db, file, chain, &res->typeinfo) && !trytop(db, file, chain) && !trydoc(db, file, chain)) {
626 fprintf (stderr, "%s:%d: wrong tag in %s: <%s>\n", file, chain->line, node->name, chain->name);
627 db->estatus = 1;
628 }
629 chain = chain->next;
630 }
631 if (!res->name) {
632 fprintf (stderr, "%s:%d: nameless register\n", file, node->line);
633 db->estatus = 1;
634 return 0;
635 } else {
636 }
637 return res;
638 }
639
640 static void parsegroup(struct rnndb *db, char *file, xmlNode *node) {
641 xmlAttr *attr = node->properties;
642 char *name = 0;
643 int i;
644 while (attr) {
645 if (!strcmp(attr->name, "name")) {
646 name = getattrib(db, file, node->line, attr);
647 } else {
648 fprintf (stderr, "%s:%d: wrong attribute \"%s\" for group\n", file, node->line, attr->name);
649 db->estatus = 1;
650 }
651 attr = attr->next;
652 }
653 if (!name) {
654 fprintf (stderr, "%s:%d: nameless group\n", file, node->line);
655 db->estatus = 1;
656 return;
657 }
658 struct rnngroup *cur = 0;
659 for (i = 0; i < db->groupsnum; i++)
660 if (!strcmp(db->groups[i]->name, name)) {
661 cur = db->groups[i];
662 break;
663 }
664 if (!cur) {
665 cur = calloc(sizeof *cur, 1);
666 cur->name = strdup(name);
667 ADDARRAY(db->groups, cur);
668 }
669 xmlNode *chain = node->children;
670 while (chain) {
671 struct rnndelem *delem;
672 if (chain->type != XML_ELEMENT_NODE) {
673 } else if ((delem = trydelem(db, file, chain))) {
674 ADDARRAY(cur->subelems, delem);
675 } else if (!trytop(db, file, chain) && !trydoc(db, file, chain)) {
676 fprintf (stderr, "%s:%d: wrong tag in group: <%s>\n", file, chain->line, chain->name);
677 db->estatus = 1;
678 }
679 chain = chain->next;
680 }
681 }
682
683 static void parsedomain(struct rnndb *db, char *file, xmlNode *node) {
684 xmlAttr *attr = node->properties;
685 char *name = 0;
686 uint64_t size = 0; int width = 8;
687 int bare = 0;
688 char *prefixstr = 0;
689 char *varsetstr = 0;
690 char *variantsstr = 0;
691 int i;
692 while (attr) {
693 if (!strcmp(attr->name, "name")) {
694 name = getattrib(db, file, node->line, attr);
695 } else if (!strcmp(attr->name, "bare")) {
696 bare = getboolattrib(db, file, node->line, attr);
697 } else if (!strcmp(attr->name, "size")) {
698 size = getnumattrib(db, file, node->line, attr);
699 } else if (!strcmp(attr->name, "width")) {
700 width = getnumattrib(db, file, node->line, attr);
701 } else if (!strcmp(attr->name, "prefix")) {
702 prefixstr = strdup(getattrib(db, file, node->line, attr));
703 } else if (!strcmp(attr->name, "varset")) {
704 varsetstr = strdup(getattrib(db, file, node->line, attr));
705 } else if (!strcmp(attr->name, "variants")) {
706 variantsstr = strdup(getattrib(db, file, node->line, attr));
707 } else {
708 fprintf (stderr, "%s:%d: wrong attribute \"%s\" for domain\n", file, node->line, attr->name);
709 db->estatus = 1;
710 }
711 attr = attr->next;
712 }
713 if (!name) {
714 fprintf (stderr, "%s:%d: nameless domain\n", file, node->line);
715 db->estatus = 1;
716 return;
717 }
718 struct rnndomain *cur = 0;
719 for (i = 0; i < db->domainsnum; i++)
720 if (!strcmp(db->domains[i]->name, name)) {
721 cur = db->domains[i];
722 break;
723 }
724 if (cur) {
725 if (strdiff(cur->varinfo.prefixstr, prefixstr) ||
726 strdiff(cur->varinfo.varsetstr, varsetstr) ||
727 strdiff(cur->varinfo.variantsstr, variantsstr) ||
728 cur->width != width ||
729 cur->bare != bare ||
730 (size && cur->size && size != cur->size)) {
731 fprintf (stderr, "%s:%d: merge fail for domain %s\n", file, node->line, node->name);
732 db->estatus = 1;
733 } else {
734 if (size)
735 cur->size = size;
736 }
737 } else {
738 cur = calloc(sizeof *cur, 1);
739 cur->name = strdup(name);
740 cur->bare = bare;
741 cur->width = width;
742 cur->size = size;
743 cur->varinfo.prefixstr = prefixstr;
744 cur->varinfo.varsetstr = varsetstr;
745 cur->varinfo.variantsstr = variantsstr;
746 cur->file = file;
747 ADDARRAY(db->domains, cur);
748 }
749 xmlNode *chain = node->children;
750 while (chain) {
751 struct rnndelem *delem;
752 if (chain->type != XML_ELEMENT_NODE) {
753 } else if ((delem = trydelem(db, file, chain))) {
754 ADDARRAY(cur->subelems, delem);
755 } else if (!trytop(db, file, chain) && !trydoc(db, file, chain)) {
756 fprintf (stderr, "%s:%d: wrong tag in domain: <%s>\n", file, chain->line, chain->name);
757 db->estatus = 1;
758 }
759 chain = chain->next;
760 }
761 }
762
763 static void parsecopyright(struct rnndb *db, char *file, xmlNode *node) {
764 struct rnncopyright* copyright = &db->copyright;
765 xmlAttr *attr = node->properties;
766 while (attr) {
767 if (!strcmp(attr->name, "year")) {
768 unsigned firstyear = getnumattrib(db, file, node->line, attr);
769 if(!copyright->firstyear || firstyear < copyright->firstyear)
770 copyright->firstyear = firstyear;
771 } else {
772 fprintf (stderr, "%s:%d: wrong attribute \"%s\" for copyright\n", file, node->line, attr->name);
773 db->estatus = 1;
774 }
775 attr = attr->next;
776 }
777 xmlNode *chain = node->children;
778 while (chain) {
779 if (chain->type != XML_ELEMENT_NODE) {
780 } else if (!strcmp(chain->name, "license"))
781 if(copyright->license) {
782 if(strcmp(copyright->license, node->content)) {
783 fprintf(stderr, "fatal error: multiple different licenses specified!\n");
784 abort(); /* TODO: do something better here, but headergen, xml2html, etc. should not produce anything in this case */
785 }
786 } else
787 copyright->license = getcontent(chain);
788 else if (!strcmp(chain->name, "author")) {
789 struct rnnauthor* author = calloc(sizeof *author, 1);
790 xmlAttr* authorattr = chain->properties;
791 xmlNode *authorchild = chain->children;
792 author->contributions = getcontent(chain);
793 while (authorattr) {
794 if (!strcmp(authorattr->name, "name"))
795 author->name = strdup(getattrib(db, file, chain->line, authorattr));
796 else if (!strcmp(authorattr->name, "email"))
797 author->email = strdup(getattrib(db, file, chain->line, authorattr));
798 else {
799 fprintf (stderr, "%s:%d: wrong attribute \"%s\" for author\n", file, chain->line, authorattr->name);
800 db->estatus = 1;
801 }
802 authorattr = authorattr->next;
803 }
804 while(authorchild) {
805 if (authorchild->type != XML_ELEMENT_NODE) {
806 } else if (!strcmp(authorchild->name, "nick")) {
807 xmlAttr* nickattr = authorchild->properties;
808 char* nickname = 0;
809 while(nickattr) {
810 if (!strcmp(nickattr->name, "name"))
811 nickname = strdup(getattrib(db, file, authorchild->line, nickattr));
812 else {
813 fprintf (stderr, "%s:%d: wrong attribute \"%s\" for nick\n", file, authorchild->line, nickattr->name);
814 db->estatus = 1;
815 }
816 nickattr = nickattr->next;
817 }
818 if(!nickname) {
819 fprintf (stderr, "%s:%d: missing \"name\" attribute for nick\n", file, authorchild->line);
820 db->estatus = 1;
821 } else
822 ADDARRAY(author->nicknames, nickname);
823 } else {
824 fprintf (stderr, "%s:%d: wrong tag in author: <%s>\n", file, authorchild->line, authorchild->name);
825 db->estatus = 1;
826 }
827 authorchild = authorchild->next;
828 }
829 ADDARRAY(copyright->authors, author);
830 } else {
831 fprintf (stderr, "%s:%d: wrong tag in copyright: <%s>\n", file, chain->line, chain->name);
832 db->estatus = 1;
833 }
834 chain = chain->next;
835 }
836 }
837
838 static int trytop (struct rnndb *db, char *file, xmlNode *node) {
839 if (!strcmp(node->name, "enum")) {
840 parseenum(db, file, node);
841 return 1;
842 } else if (!strcmp(node->name, "bitset")) {
843 parsebitset(db, file, node);
844 return 1;
845 } else if (!strcmp(node->name, "group")) {
846 parsegroup(db, file, node);
847 return 1;
848 } else if (!strcmp(node->name, "domain")) {
849 parsedomain(db, file, node);
850 return 1;
851 } else if (!strcmp(node->name, "spectype")) {
852 parsespectype(db, file, node);
853 return 1;
854 } else if (!strcmp(node->name, "import")) {
855 xmlAttr *attr = node->properties;
856 char *subfile = 0;
857 while (attr) {
858 if (!strcmp(attr->name, "file")) {
859 subfile = getattrib(db, file, node->line, attr);
860 } else {
861 fprintf (stderr, "%s:%d: wrong attribute \"%s\" for import\n", file, node->line, attr->name);
862 db->estatus = 1;
863 }
864 attr = attr->next;
865 }
866 if (!subfile) {
867 fprintf (stderr, "%s:%d: missing \"file\" attribute for import\n", file, node->line);
868 db->estatus = 1;
869 } else {
870 rnn_parsefile(db, subfile);
871 }
872 return 1;
873 } else if (!strcmp(node->name, "copyright")) {
874 parsecopyright(db, file, node);
875 return 1;
876 }
877 return 0;
878 }
879
880 void rnn_parsefile (struct rnndb *db, char *file_orig) {
881 int i;
882 char *fname;
883 const char *rnn_path = getenv("RNN_PATH");
884
885 if (!rnn_path)
886 rnn_path = RNN_DEF_PATH;
887
888 FILE *file = find_in_path(file_orig, rnn_path, &fname);
889 if (!file) {
890 fprintf (stderr, "%s: couldn't find database file. Please set the env var RNN_PATH.\n", file_orig);
891 db->estatus = 1;
892 return;
893 }
894 fclose(file);
895
896 for (i = 0; i < db->filesnum; i++)
897 if (!strcmp(db->files[i], fname))
898 return;
899
900 ADDARRAY(db->files, fname);
901 xmlDocPtr doc = xmlParseFile(fname);
902 if (!doc) {
903 fprintf (stderr, "%s: couldn't open database file. Please set the env var RNN_PATH.\n", fname);
904 db->estatus = 1;
905 return;
906 }
907 xmlNode *root = doc->children;
908 while (root) {
909 if (root->type != XML_ELEMENT_NODE) {
910 } else if (strcmp(root->name, "database")) {
911 fprintf (stderr, "%s:%d: wrong top-level tag <%s>\n", fname, root->line, root->name);
912 db->estatus = 1;
913 } else {
914 xmlNode *chain = root->children;
915 while (chain) {
916 if (chain->type != XML_ELEMENT_NODE) {
917 } else if (!trytop(db, fname, chain) && !trydoc(db, fname, chain)) {
918 fprintf (stderr, "%s:%d: wrong tag in database: <%s>\n", fname, chain->line, chain->name);
919 db->estatus = 1;
920 }
921 chain = chain->next;
922 }
923 }
924 root = root->next;
925 }
926 xmlFreeDoc(doc);
927 }
928
929 static struct rnnvalue *copyvalue (struct rnnvalue *val, char *file) {
930 struct rnnvalue *res = calloc (sizeof *res, 1);
931 res->name = val->name;
932 res->valvalid = val->valvalid;
933 res->value = val->value;
934 res->varinfo = val->varinfo;
935 res->file = file;
936 return res;
937 }
938
939 static struct rnnbitfield *copybitfield (struct rnnbitfield *bf, char *file);
940
941
942 static void copytypeinfo (struct rnntypeinfo *dst, struct rnntypeinfo *src, char *file) {
943 int i;
944 dst->name = src->name;
945 dst->shr = src->shr;
946 dst->low = src->low;
947 dst->high = src->high;
948 dst->min = src->min;
949 dst->max = src->max;
950 dst->align = src->align;
951 dst->addvariant = src->addvariant;
952 for (i = 0; i < src->valsnum; i++)
953 ADDARRAY(dst->vals, copyvalue(src->vals[i], file));
954 for (i = 0; i < src->bitfieldsnum; i++)
955 ADDARRAY(dst->bitfields, copybitfield(src->bitfields[i], file));
956 }
957
958 static struct rnnbitfield *copybitfield (struct rnnbitfield *bf, char *file) {
959 struct rnnbitfield *res = calloc (sizeof *res, 1);
960 res->name = bf->name;
961 res->varinfo = bf->varinfo;
962 res->file = file;
963 copytypeinfo(&res->typeinfo, &bf->typeinfo, file);
964 return res;
965 }
966
967 static struct rnndelem *copydelem (struct rnndelem *elem, char *file) {
968 struct rnndelem *res = calloc (sizeof *res, 1);
969 res->type = elem->type;
970 res->name = elem->name;
971 res->width = elem->width;
972 res->access = elem->access;
973 res->offset = elem->offset;
974 res->length = elem->length;
975 res->stride = elem->stride;
976 res->varinfo = elem->varinfo;
977 res->file = file;
978 copytypeinfo(&res->typeinfo, &elem->typeinfo, file);
979 int i;
980 for (i = 0; i < elem->subelemsnum; i++)
981 ADDARRAY(res->subelems, copydelem(elem->subelems[i], file));
982 for (i = 0; i < elem->offsetsnum; i++)
983 ADDARRAY(res->offsets, elem->offsets[i]);
984 return res;
985 }
986
987 static struct rnnvarset *copyvarset (struct rnnvarset *varset) {
988 struct rnnvarset *res = calloc(sizeof *res, 1);
989 res->venum = varset->venum;
990 res->variants = calloc(sizeof *res->variants, res->venum->valsnum);
991 int i;
992 for (i = 0; i < res->venum->valsnum; i++)
993 res->variants[i] = varset->variants[i];
994 return res;
995 }
996
997 static void prepenum(struct rnndb *db, struct rnnenum *en);
998
999 static int findvidx (struct rnndb *db, struct rnnenum *en, char *name) {
1000 int i;
1001 for (i = 0; i < en->valsnum; i++)
1002 if (!strcmp(en->vals[i]->name, name))
1003 return i;
1004 fprintf (stderr, "Cannot find variant %s in enum %s!\n", name, en->name);
1005 db->estatus = 1;
1006 return -1;
1007 }
1008
1009 static void prepvarinfo (struct rnndb *db, char *what, struct rnnvarinfo *vi, struct rnnvarinfo *parent) {
1010 if (parent)
1011 vi->prefenum = parent->prefenum;
1012 if (vi->prefixstr) {
1013 if (!strcmp(vi->prefixstr, "none"))
1014 vi->prefenum = 0;
1015 else
1016 vi->prefenum = rnn_findenum(db, vi->prefixstr); // XXX
1017 }
1018 int i;
1019 if (parent)
1020 for (i = 0; i < parent->varsetsnum; i++)
1021 ADDARRAY(vi->varsets, copyvarset(parent->varsets[i]));
1022 struct rnnenum *varset = vi->prefenum;
1023 if (!varset && !vi->varsetstr && parent)
1024 vi->varsetstr = parent->varsetstr;
1025 if (vi->varsetstr)
1026 varset = rnn_findenum(db, vi->varsetstr);
1027 if (vi->variantsstr) {
1028 char *vars = vi->variantsstr;
1029 if (!varset) {
1030 fprintf (stderr, "%s: tried to use variants without active varset!\n", what);
1031 db->estatus = 1;
1032 return;
1033 }
1034 struct rnnvarset *vs = 0;
1035 int nvars = varset->valsnum;
1036 for (i = 0; i < vi->varsetsnum; i++)
1037 if (vi->varsets[i]->venum == varset) {
1038 vs = vi->varsets[i];
1039 break;
1040 }
1041 if (!vs) {
1042 vs = calloc (sizeof *vs, 1);
1043 vs->venum = varset;
1044 vs->variants = calloc(sizeof *vs->variants, nvars);
1045 for (i = 0; i < nvars; i++)
1046 vs->variants[i] = 1;
1047 ADDARRAY(vi->varsets, vs);
1048 }
1049 while (1) {
1050 while (*vars == ' ') vars++;
1051 if (*vars == 0)
1052 break;
1053 char *split = vars;
1054 while (*split != ':' && *split != '-' && *split != ' ' && *split != 0)
1055 split++;
1056 char *first = 0;
1057 if (split != vars)
1058 first = strndup(vars, split-vars);
1059 if (*split == ' ' || *split == 0) {
1060 int idx = findvidx(db, varset, first);
1061 if (idx != -1)
1062 vs->variants[idx] |= 2;
1063 vars = split;
1064 } else {
1065 char *end = split+1;
1066 while (*end != ' ' && *end != 0)
1067 end++;
1068 char *second = 0;
1069 if (end != split+1)
1070 second = strndup(split+1, end-split-1);
1071 int idx1 = 0;
1072 if (first)
1073 idx1 = findvidx(db, varset, first);
1074 int idx2 = nvars;
1075 if (second) {
1076 idx2 = findvidx(db, varset, second);
1077 if (*split == '-')
1078 idx2++;
1079 }
1080 if (idx1 != -1 && idx2 != -1)
1081 for (i = idx1; i < idx2; i++)
1082 vs->variants[i] |= 2;
1083 vars = end;
1084 free(second);
1085 }
1086 free(first);
1087 }
1088 vi->dead = 1;
1089 for (i = 0; i < nvars; i++) {
1090 vs->variants[i] = (vs->variants[i] == 3);
1091 if (vs->variants[i])
1092 vi->dead = 0;
1093 }
1094 }
1095 if (vi->dead)
1096 return;
1097 if (vi->prefenum) {
1098 struct rnnvarset *vs = 0;
1099 for (i = 0; i < vi->varsetsnum; i++)
1100 if (vi->varsets[i]->venum == vi->prefenum) {
1101 vs = vi->varsets[i];
1102 break;
1103 }
1104 if (vs) {
1105 for (i = 0; i < vi->prefenum->valsnum; i++)
1106 if (vs->variants[i]) {
1107 vi->prefix = vi->prefenum->vals[i]->name;
1108 return;
1109 }
1110 } else {
1111 vi->prefix = vi->prefenum->vals[0]->name;
1112 }
1113 }
1114 }
1115
1116 static void prepvalue(struct rnndb *db, struct rnnvalue *val, char *prefix, struct rnnvarinfo *parvi) {
1117 val->fullname = catstr(prefix, val->name);
1118 prepvarinfo (db, val->fullname, &val->varinfo, parvi);
1119 if (val->varinfo.dead)
1120 return;
1121 if (val->varinfo.prefix)
1122 val->fullname = catstr(val->varinfo.prefix, val->fullname);
1123 }
1124
1125 static void prepbitfield(struct rnndb *db, struct rnnbitfield *bf, char *prefix, struct rnnvarinfo *parvi);
1126
1127 static void preptypeinfo(struct rnndb *db, struct rnntypeinfo *ti, char *prefix, struct rnnvarinfo *vi, char *file) {
1128 int i;
1129 if (ti->name) {
1130 struct rnnenum *en = rnn_findenum (db, ti->name);
1131 struct rnnbitset *bs = rnn_findbitset (db, ti->name);
1132 struct rnnspectype *st = rnn_findspectype (db, ti->name);
1133 if (en) {
1134 if (en->isinline) {
1135 ti->type = RNN_TTYPE_INLINE_ENUM;
1136 int j;
1137 for (j = 0; j < en->valsnum; j++)
1138 ADDARRAY(ti->vals, copyvalue(en->vals[j], file));
1139 } else {
1140 ti->type = RNN_TTYPE_ENUM;
1141 ti->eenum = en;
1142 }
1143 } else if (bs) {
1144 if (bs->isinline) {
1145 ti->type = RNN_TTYPE_INLINE_BITSET;
1146 int j;
1147 for (j = 0; j < bs->bitfieldsnum; j++)
1148 ADDARRAY(ti->bitfields, copybitfield(bs->bitfields[j], file));
1149 } else {
1150 ti->type = RNN_TTYPE_BITSET;
1151 ti->ebitset = bs;
1152 }
1153 } else if (st) {
1154 ti->type = RNN_TTYPE_SPECTYPE;
1155 ti->spectype = st;
1156 } else if (!strcmp(ti->name, "hex")) {
1157 ti->type = RNN_TTYPE_HEX;
1158 } else if (!strcmp(ti->name, "float")) {
1159 ti->type = RNN_TTYPE_FLOAT;
1160 } else if (!strcmp(ti->name, "uint")) {
1161 ti->type = RNN_TTYPE_UINT;
1162 } else if (!strcmp(ti->name, "int")) {
1163 ti->type = RNN_TTYPE_INT;
1164 } else if (!strcmp(ti->name, "boolean")) {
1165 ti->type = RNN_TTYPE_BOOLEAN;
1166 } else if (!strcmp(ti->name, "bitfield")) {
1167 ti->type = RNN_TTYPE_INLINE_BITSET;
1168 } else if (!strcmp(ti->name, "enum")) {
1169 ti->type = RNN_TTYPE_INLINE_ENUM;
1170 } else if (!strcmp(ti->name, "fixed")) {
1171 ti->type = RNN_TTYPE_FIXED;
1172 } else if (!strcmp(ti->name, "ufixed")) {
1173 ti->type = RNN_TTYPE_UFIXED;
1174 } else if (!strcmp(ti->name, "a3xx_regid")) {
1175 ti->type = RNN_TTYPE_A3XX_REGID;
1176 } else if (!strcmp(ti->name, "waddress") || !strcmp(ti->name, "address")) {
1177 ti->type = RNN_TTYPE_HEX;
1178 } else {
1179 ti->type = RNN_TTYPE_HEX;
1180 fprintf (stderr, "%s: unknown type %s\n", prefix, ti->name);
1181 db->estatus = 1;
1182 }
1183 } else if (ti->bitfieldsnum) {
1184 ti->name = "bitfield";
1185 ti->type = RNN_TTYPE_INLINE_BITSET;
1186 } else if (ti->valsnum) {
1187 ti->name = "enum";
1188 ti->type = RNN_TTYPE_INLINE_ENUM;
1189 } else if (ti->low == 0 && ti->high == 0) {
1190 ti->name = "boolean";
1191 ti->type = RNN_TTYPE_BOOLEAN;
1192 } else {
1193 ti->name = "hex";
1194 ti->type = RNN_TTYPE_HEX;
1195 }
1196 if (ti->addvariant && ti->type != RNN_TTYPE_ENUM) {
1197 fprintf (stderr, "%s: addvariant specified on non-enum type %s\n", prefix, ti->name);
1198 db->estatus = 1;
1199 }
1200 for (i = 0; i < ti->bitfieldsnum; i++)
1201 prepbitfield(db, ti->bitfields[i], prefix, vi);
1202 for (i = 0; i < ti->valsnum; i++)
1203 prepvalue(db, ti->vals[i], prefix, vi);
1204 }
1205
1206 static void prepbitfield(struct rnndb *db, struct rnnbitfield *bf, char *prefix, struct rnnvarinfo *parvi) {
1207 bf->fullname = catstr(prefix, bf->name);
1208 prepvarinfo (db, bf->fullname, &bf->varinfo, parvi);
1209 if (bf->varinfo.dead)
1210 return;
1211 preptypeinfo(db, &bf->typeinfo, bf->fullname, &bf->varinfo, bf->file);
1212 if (bf->varinfo.prefix)
1213 bf->fullname = catstr(bf->varinfo.prefix, bf->fullname);
1214 }
1215
1216 static void prepdelem(struct rnndb *db, struct rnndelem *elem, char *prefix, struct rnnvarinfo *parvi, int width) {
1217 if (elem->type == RNN_ETYPE_USE_GROUP) {
1218 int i;
1219 struct rnngroup *gr = 0;
1220 for (i = 0; i < db->groupsnum; i++)
1221 if (!strcmp(db->groups[i]->name, elem->name)) {
1222 gr = db->groups[i];
1223 break;
1224 }
1225 if (gr) {
1226 for (i = 0; i < gr->subelemsnum; i++)
1227 ADDARRAY(elem->subelems, copydelem(gr->subelems[i], elem->file));
1228 } else {
1229 fprintf (stderr, "group %s not found!\n", elem->name);
1230 db->estatus = 1;
1231 }
1232 elem->type = RNN_ETYPE_STRIPE;
1233 elem->length = 1;
1234 elem->name = 0;
1235 }
1236 if (elem->name)
1237 elem->fullname = catstr(prefix, elem->name);
1238 prepvarinfo (db, elem->fullname?elem->fullname:prefix, &elem->varinfo, parvi);
1239 if (elem->varinfo.dead)
1240 return;
1241 if (elem->length != 1 && !elem->stride) {
1242 if (elem->type != RNN_ETYPE_REG) {
1243 fprintf (stderr, "%s has non-1 length, but no stride!\n", elem->fullname);
1244 db->estatus = 1;
1245 } else {
1246 elem->stride = elem->width/width;
1247 }
1248 }
1249 preptypeinfo(db, &elem->typeinfo, elem->name?elem->fullname:prefix, &elem->varinfo, elem->file);
1250
1251 int i;
1252 for (i = 0; i < elem->subelemsnum; i++)
1253 prepdelem(db, elem->subelems[i], elem->name?elem->fullname:prefix, &elem->varinfo, width);
1254 if (elem->varinfo.prefix && elem->name)
1255 elem->fullname = catstr(elem->varinfo.prefix, elem->fullname);
1256 }
1257
1258 static void prepdomain(struct rnndb *db, struct rnndomain *dom) {
1259 prepvarinfo (db, dom->name, &dom->varinfo, 0);
1260 int i;
1261 for (i = 0; i < dom->subelemsnum; i++)
1262 prepdelem(db, dom->subelems[i], dom->bare?0:dom->name, &dom->varinfo, dom->width);
1263 dom->fullname = catstr(dom->varinfo.prefix, dom->name);
1264 }
1265
1266 static void prepenum(struct rnndb *db, struct rnnenum *en) {
1267 if (en->prepared)
1268 return;
1269 prepvarinfo (db, en->name, &en->varinfo, 0);
1270 int i;
1271 if (en->isinline)
1272 return;
1273 for (i = 0; i < en->valsnum; i++)
1274 prepvalue(db, en->vals[i], en->bare?0:en->name, &en->varinfo);
1275 en->fullname = catstr(en->varinfo.prefix, en->name);
1276 en->prepared = 1;
1277 }
1278
1279 static void prepbitset(struct rnndb *db, struct rnnbitset *bs) {
1280 prepvarinfo (db, bs->name, &bs->varinfo, 0);
1281 int i;
1282 if (bs->isinline)
1283 return;
1284 for (i = 0; i < bs->bitfieldsnum; i++)
1285 prepbitfield(db, bs->bitfields[i], bs->bare?0:bs->name, &bs->varinfo);
1286 bs->fullname = catstr(bs->varinfo.prefix, bs->name);
1287 }
1288
1289 static void prepspectype(struct rnndb *db, struct rnnspectype *st) {
1290 preptypeinfo(db, &st->typeinfo, st->name, 0, st->file); // XXX doesn't exactly make sense...
1291 }
1292
1293 void rnn_prepdb (struct rnndb *db) {
1294 int i;
1295 for (i = 0; i < db->enumsnum; i++)
1296 prepenum(db, db->enums[i]);
1297 for (i = 0; i < db->bitsetsnum; i++)
1298 prepbitset(db, db->bitsets[i]);
1299 for (i = 0; i < db->domainsnum; i++)
1300 prepdomain(db, db->domains[i]);
1301 for (i = 0; i < db->spectypesnum; i++)
1302 prepspectype(db, db->spectypes[i]);
1303 }
1304
1305 struct rnnenum *rnn_findenum (struct rnndb *db, const char *name) {
1306 int i;
1307 for (i = 0; i < db->enumsnum; i++)
1308 if (!strcmp(db->enums[i]->name, name))
1309 return db->enums[i];
1310 return 0;
1311 }
1312
1313 struct rnnbitset *rnn_findbitset (struct rnndb *db, const char *name) {
1314 int i;
1315 for (i = 0; i < db->bitsetsnum; i++)
1316 if (!strcmp(db->bitsets[i]->name, name))
1317 return db->bitsets[i];
1318 return 0;
1319 }
1320
1321 struct rnndomain *rnn_finddomain (struct rnndb *db, const char *name) {
1322 int i;
1323 for (i = 0; i < db->domainsnum; i++)
1324 if (!strcmp(db->domains[i]->name, name))
1325 return db->domains[i];
1326 return 0;
1327 }
1328
1329 struct rnnspectype *rnn_findspectype (struct rnndb *db, const char *name) {
1330 int i;
1331 for (i = 0; i < db->spectypesnum; i++)
1332 if (!strcmp(db->spectypes[i]->name, name))
1333 return db->spectypes[i];
1334 return 0;
1335 }