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 "util.h" 43 44#include "util/u_debug.h" 45 46static char *catstr (char *a, char *b) { 47 if (!a) 48 return b; 49 return aprintf("%s_%s", a, b); 50} 51 52static 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 60static void rnn_err(struct rnndb *db, const char *format, ...) _util_printf_format(2, 3); 61 62static 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 71void rnn_init(void) { 72 LIBXML_TEST_VERSION 73 xmlInitParser(); 74} 75 76struct rnndb *rnn_newdb(void) { 77 struct rnndb *db = calloc(sizeof *db, 1); 78 return db; 79} 80 81static 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 111static 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 124static 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 134static 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 148static 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 153static int trytop (struct rnndb *db, char *file, xmlNode *node); 154 155static 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 164static struct rnnvalue *parsevalue(struct rnndb *db, char *file, xmlNode *node); 165static struct rnnbitfield *parsebitfield(struct rnndb *db, char *file, xmlNode *node); 166 167static 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} 181static 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 220static 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 255static 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 288static 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 357static 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 393static 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 462static 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 625static 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 665static 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 741static 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 810static 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 850static 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 868static 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 916void 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 960static 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 970static struct rnnbitfield *copybitfield (struct rnnbitfield *bf, char *file); 971 972 973static 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 989static 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 998static 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 1018static 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 1028static void prepenum(struct rnndb *db, struct rnnenum *en); 1029 1030static 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 1039static 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 1145static 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 1154static void prepbitfield(struct rnndb *db, struct rnnbitfield *bf, char *prefix, struct rnnvarinfo *parvi); 1155 1156static 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 1233static 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 1243static 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 1283static 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 1291static 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 1304static 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 1314static 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 1318void 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 1330struct 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 1338struct 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 1346struct 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 1354struct 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