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