summaryrefslogtreecommitdiff
path: root/utils/regtools/lib
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2016-02-06 15:01:24 +0000
committerAmaury Pouly <amaury.pouly@gmail.com>2016-02-06 15:12:55 +0000
commit0f701a64bee43e79f95970ae9c0ec43ea7fcdf17 (patch)
treec8ac6b5516eac120797eb6a06f633919e9f48f9b /utils/regtools/lib
parent16c915ec1826dcef2e58ecc055a3f5dfcefb235a (diff)
downloadrockbox-0f701a64bee43e79f95970ae9c0ec43ea7fcdf17.tar.gz
rockbox-0f701a64bee43e79f95970ae9c0ec43ea7fcdf17.zip
regtools: update v2 specification, library and tools
A v2 register description file can now include register variants and instances addresses can now be a list (previously it could only be a stride or a formula). Update the library to deal with that. The convert option of swiss_knife was updated and one incompatible change was introduce: if a v1 device has several addresses, those are converted to a single v2 instance with list (instead of several single instances). This should have been the behaviour from the start. Swiss_knife can now also convert regdumps, in which case it needs to be given both the dump and register description file. Also introduce two register descriptions files (vsoc1000 and vsoc2000) which give more complicated examples of v2 register description files. Change-Id: Id9415b8363269ffaf9216abfc6dd1bd1adbfcf8d
Diffstat (limited to 'utils/regtools/lib')
-rw-r--r--utils/regtools/lib/soc_desc.cpp473
1 files changed, 442 insertions, 31 deletions
diff --git a/utils/regtools/lib/soc_desc.cpp b/utils/regtools/lib/soc_desc.cpp
index 4e0e46f00e..e6c58d4814 100644
--- a/utils/regtools/lib/soc_desc.cpp
+++ b/utils/regtools/lib/soc_desc.cpp
@@ -308,13 +308,28 @@ bool parse_field_elem(xmlNode *node, field_t& field, error_context_t& ctx)
308 return ret; 308 return ret;
309} 309}
310 310
311bool parse_variant_elem(xmlNode *node, variant_t& variant, error_context_t& ctx)
312{
313 bool ret = true;
314 bool has_type = false, has_offset = false;
315 BEGIN_NODE_MATCH(node->children)
316 MATCH_UNIQUE_TEXT_NODE("type", variant.type, has_type, parse_name_elem, ctx)
317 MATCH_UNIQUE_TEXT_NODE("offset", variant.offset, has_offset, parse_unsigned_elem, ctx)
318 END_NODE_MATCH()
319 CHECK_HAS(node, "type", has_type, ctx)
320 CHECK_HAS(node, "offset", has_offset, ctx)
321 return ret;
322}
323
311bool parse_register_elem(xmlNode *node, register_t& reg, error_context_t& ctx) 324bool parse_register_elem(xmlNode *node, register_t& reg, error_context_t& ctx)
312{ 325{
313 bool ret = true; 326 bool ret = true;
314 bool has_width = false; 327 bool has_width = false, has_desc = false;
315 BEGIN_NODE_MATCH(node->children) 328 BEGIN_NODE_MATCH(node->children)
329 MATCH_UNIQUE_TEXT_NODE("desc", reg.desc, has_desc, parse_text_elem, ctx)
316 MATCH_UNIQUE_TEXT_NODE("width", reg.width, has_width, parse_unsigned_elem, ctx) 330 MATCH_UNIQUE_TEXT_NODE("width", reg.width, has_width, parse_unsigned_elem, ctx)
317 MATCH_ELEM_NODE("field", reg.field, parse_field_elem, ctx) 331 MATCH_ELEM_NODE("field", reg.field, parse_field_elem, ctx)
332 MATCH_ELEM_NODE("variant", reg.variant, parse_variant_elem, ctx)
318 END_NODE_MATCH() 333 END_NODE_MATCH()
319 if(!has_width) 334 if(!has_width)
320 reg.width = 32; 335 reg.width = 32;
@@ -344,21 +359,37 @@ bool parse_range_elem(xmlNode *node, range_t& range, error_context_t& ctx)
344 MATCH_UNIQUE_TEXT_NODE("stride", range.stride, has_stride, parse_unsigned_elem, ctx) 359 MATCH_UNIQUE_TEXT_NODE("stride", range.stride, has_stride, parse_unsigned_elem, ctx)
345 MATCH_UNIQUE_ELEM_NODE("formula", range, has_formula_attr, parse_formula_elem, ctx) 360 MATCH_UNIQUE_ELEM_NODE("formula", range, has_formula_attr, parse_formula_elem, ctx)
346 MATCH_UNIQUE_TEXT_NODE("formula", range.formula, has_formula, parse_text_elem, ctx) 361 MATCH_UNIQUE_TEXT_NODE("formula", range.formula, has_formula, parse_text_elem, ctx)
362 MATCH_TEXT_NODE("address", range.list, parse_unsigned_elem, ctx)
347 END_NODE_MATCH() 363 END_NODE_MATCH()
348 CHECK_HAS(node, "first", has_first, ctx) 364 CHECK_HAS(node, "first", has_first, ctx)
349 CHECK_HAS(node, "count", has_count, ctx) 365 if(range.list.size() == 0)
350 if(!has_base && !has_formula) 366 {
351 ret = ret && parse_missing_error(node, "base> or <formula", ctx); 367 CHECK_HAS(node, "count", has_count, ctx)
352 if(has_base && has_formula) 368 if(!has_base && !has_formula)
353 return parse_conflict_error(node, "base", "formula", ctx); 369 ret = ret && parse_missing_error(node, "base> or <formula", ctx);
354 if(has_base) 370 if(has_base && has_formula)
355 CHECK_HAS(node, "stride", has_stride, ctx) 371 return parse_conflict_error(node, "base", "formula", ctx);
356 if(has_stride && !has_base) 372 if(has_base)
357 ret = ret && parse_conflict_error(node, "stride", "formula", ctx); 373 CHECK_HAS(node, "stride", has_stride, ctx)
358 if(has_stride) 374 if(has_stride && !has_base)
359 range.type = range_t::STRIDE; 375 ret = ret && parse_conflict_error(node, "stride", "formula", ctx);
376 if(has_stride)
377 range.type = range_t::STRIDE;
378 else
379 range.type = range_t::FORMULA;
380 }
360 else 381 else
361 range.type = range_t::FORMULA; 382 {
383 if(has_base)
384 ret = ret && parse_conflict_error(node, "base", "addr", ctx);
385 if(has_count)
386 ret = ret && parse_conflict_error(node, "count", "addr", ctx);
387 if(has_formula)
388 ret = ret && parse_conflict_error(node, "formula", "addr", ctx);
389 if(has_stride)
390 ret = ret && parse_conflict_error(node, "stride", "addr", ctx);
391 range.type = range_t::LIST;
392 }
362 return ret; 393 return ret;
363} 394}
364 395
@@ -400,7 +431,6 @@ bool parse_node_elem(xmlNode *node_, node_t& node, error_context_t& ctx)
400 MATCH_ELEM_NODE("instance", node.instance, parse_instance_elem, ctx) 431 MATCH_ELEM_NODE("instance", node.instance, parse_instance_elem, ctx)
401 END_NODE_MATCH() 432 END_NODE_MATCH()
402 CHECK_HAS(node_, "name", has_name, ctx) 433 CHECK_HAS(node_, "name", has_name, ctx)
403 CHECK_HAS(node_, "instance", !node.instance.empty(), ctx)
404 if(has_register) 434 if(has_register)
405 node.register_.push_back(reg); 435 node.register_.push_back(reg);
406 return ret; 436 return ret;
@@ -466,6 +496,93 @@ bool parse_xml(const std::string& filename, soc_t& soc,
466} 496}
467 497
468/** 498/**
499 * Normalizer
500 */
501
502namespace
503{
504
505struct soc_sorter
506{
507 /* returns the first (lowest) address of an instance */
508 soc_addr_t first_addr(const instance_t& inst) const
509 {
510 if(inst.type == instance_t::SINGLE)
511 return inst.addr;
512 if(inst.range.type == range_t::STRIDE)
513 return inst.range.base;
514 soc_word_t res;
515 std::map< std::string, soc_word_t > vars;
516 vars[inst.range.variable] = inst.range.first;
517 error_context_t ctx;
518 if(!evaluate_formula(inst.range.formula, vars, res, "", ctx))
519 return 0xffffffff;
520 return res;
521 }
522
523 /* sort instances by first address */
524 bool operator()(const instance_t& a, const instance_t& b) const
525 {
526 return first_addr(a) < first_addr(b);
527 }
528
529 /* sort nodes by first address of first instance (which is the lowest of
530 * any instance if instances are sorted) */
531 bool operator()(const node_t& a, const node_t& b) const
532 {
533 /* borderline cases: no instances is lower than with instances */
534 if(a.instance.size() == 0)
535 return b.instance.size() > 0;
536 if(b.instance.size() == 0)
537 return false;
538 return first_addr(a.instance[0]) < first_addr(b.instance[0]);
539 }
540
541 /* sort fields by decreasing position */
542 bool operator()(const field_t& a, const field_t& b) const
543 {
544 return a.pos > b.pos;
545 }
546
547 /* sort enum values by value */
548 bool operator()(const enum_t& a, const enum_t& b) const
549 {
550 return a.value < b.value;
551 }
552};
553
554void normalize(field_t& field)
555{
556 std::sort(field.enum_.begin(), field.enum_.end(), soc_sorter());
557}
558
559void normalize(register_t& reg)
560{
561 for(size_t i = 0; i < reg.field.size(); i++)
562 normalize(reg.field[i]);
563 std::sort(reg.field.begin(), reg.field.end(), soc_sorter());
564}
565
566void normalize(node_t& node)
567{
568 for(size_t i = 0; i < node.register_.size(); i++)
569 normalize(node.register_[i]);
570 for(size_t i = 0; i < node.node.size(); i++)
571 normalize(node.node[i]);
572 std::sort(node.node.begin(), node.node.end(), soc_sorter());
573 std::sort(node.instance.begin(), node.instance.end(), soc_sorter());
574}
575
576}
577
578void normalize(soc_t& soc)
579{
580 for(size_t i = 0; i < soc.node.size(); i++)
581 normalize(soc.node[i]);
582 std::sort(soc.node.begin(), soc.node.end(), soc_sorter());
583}
584
585/**
469 * Producer 586 * Producer
470 */ 587 */
471 588
@@ -488,17 +605,20 @@ int produce_range(xmlTextWriterPtr writer, const range_t& range, error_context_t
488 SAFE(xmlTextWriterStartElement(writer, BAD_CAST "range")); 605 SAFE(xmlTextWriterStartElement(writer, BAD_CAST "range"));
489 /* <first/> */ 606 /* <first/> */
490 SAFE(xmlTextWriterWriteFormatElement(writer, BAD_CAST "first", "%lu", range.first)); 607 SAFE(xmlTextWriterWriteFormatElement(writer, BAD_CAST "first", "%lu", range.first));
491 /* <count/> */
492 SAFE(xmlTextWriterWriteFormatElement(writer, BAD_CAST "count", "%lu", range.count));
493 /* <base/><stride/> */
494 if(range.type == range_t::STRIDE) 608 if(range.type == range_t::STRIDE)
495 { 609 {
610 /* <count/> */
611 SAFE(xmlTextWriterWriteFormatElement(writer, BAD_CAST "count", "%lu", range.count));
612 /* <base/> */
496 SAFE(xmlTextWriterWriteFormatElement(writer, BAD_CAST "base", "0x%x", range.base)); 613 SAFE(xmlTextWriterWriteFormatElement(writer, BAD_CAST "base", "0x%x", range.base));
614 /* <stride/> */
497 SAFE(xmlTextWriterWriteFormatElement(writer, BAD_CAST "stride", "0x%x", range.stride)); 615 SAFE(xmlTextWriterWriteFormatElement(writer, BAD_CAST "stride", "0x%x", range.stride));
498 } 616 }
499 /* <formula> */ 617 /* <formula> */
500 else if(range.type == range_t::FORMULA) 618 else if(range.type == range_t::FORMULA)
501 { 619 {
620 /* <count/> */
621 SAFE(xmlTextWriterWriteFormatElement(writer, BAD_CAST "count", "%lu", range.count));
502 /* <formula> */ 622 /* <formula> */
503 SAFE(xmlTextWriterStartElement(writer, BAD_CAST "formula")); 623 SAFE(xmlTextWriterStartElement(writer, BAD_CAST "formula"));
504 /* variable */ 624 /* variable */
@@ -508,6 +628,11 @@ int produce_range(xmlTextWriterPtr writer, const range_t& range, error_context_t
508 /* </formula> */ 628 /* </formula> */
509 SAFE(xmlTextWriterEndElement(writer)); 629 SAFE(xmlTextWriterEndElement(writer));
510 } 630 }
631 else if(range.type == range_t::LIST)
632 {
633 for(size_t i = 0; i < range.list.size(); i++)
634 SAFE(xmlTextWriterWriteFormatElement(writer, BAD_CAST "address", "0x%x", range.list[i]));
635 }
511 /* </range> */ 636 /* </range> */
512 SAFE(xmlTextWriterEndElement(writer)); 637 SAFE(xmlTextWriterEndElement(writer));
513 638
@@ -575,6 +700,19 @@ int produce_field(xmlTextWriterPtr writer, const field_t& field, error_context_t
575 return 0; 700 return 0;
576} 701}
577 702
703int produce_variant(xmlTextWriterPtr writer, const variant_t& variant, error_context_t& ctx)
704{
705 /* <variant> */
706 SAFE(xmlTextWriterStartElement(writer, BAD_CAST "variant"));
707 /* <name/> */
708 SAFE(xmlTextWriterWriteElement(writer, BAD_CAST "type", BAD_CAST variant.type.c_str()));
709 /* <position/> */
710 SAFE(xmlTextWriterWriteFormatElement(writer, BAD_CAST "offset", "%lu", (unsigned long)variant.offset));
711 /* </variant> */
712 SAFE(xmlTextWriterEndElement(writer));
713 return 0;
714}
715
578int produce_register(xmlTextWriterPtr writer, const register_t& reg, error_context_t& ctx) 716int produce_register(xmlTextWriterPtr writer, const register_t& reg, error_context_t& ctx)
579{ 717{
580 /* <register> */ 718 /* <register> */
@@ -582,9 +720,15 @@ int produce_register(xmlTextWriterPtr writer, const register_t& reg, error_conte
582 /* <width/> */ 720 /* <width/> */
583 if(reg.width != 32) 721 if(reg.width != 32)
584 SAFE(xmlTextWriterWriteFormatElement(writer, BAD_CAST "width", "%lu", reg.width)); 722 SAFE(xmlTextWriterWriteFormatElement(writer, BAD_CAST "width", "%lu", reg.width));
723 /* <desc/> */
724 if(!reg.desc.empty())
725 SAFE(xmlTextWriterWriteElement(writer, BAD_CAST "desc", BAD_CAST reg.desc.c_str()));
585 /* fields */ 726 /* fields */
586 for(size_t i = 0; i < reg.field.size(); i++) 727 for(size_t i = 0; i < reg.field.size(); i++)
587 SAFE(produce_field(writer, reg.field[i], ctx)); 728 SAFE(produce_field(writer, reg.field[i], ctx));
729 /* variants */
730 for(size_t i = 0; i < reg.variant.size(); i++)
731 SAFE(produce_variant(writer, reg.variant[i], ctx));
588 /* </register> */ 732 /* </register> */
589 SAFE(xmlTextWriterEndElement(writer)); 733 SAFE(xmlTextWriterEndElement(writer));
590 return 0; 734 return 0;
@@ -671,6 +815,24 @@ Lerr:
671} 815}
672 816
673/** 817/**
818 * utils
819 */
820
821namespace
822{
823
824template< typename T >
825soc_id_t gen_fresh_id(const std::vector< T >& list)
826{
827 soc_id_t id = 0;
828 for(size_t i = 0; i < list.size(); i++)
829 id = std::max(id, list[i].id);
830 return id + 1;
831}
832
833}
834
835/**
674 * soc_ref_t 836 * soc_ref_t
675 */ 837 */
676 838
@@ -707,6 +869,11 @@ node_inst_t soc_ref_t::root_inst() const
707 return node_inst_t(*this); 869 return node_inst_t(*this);
708} 870}
709 871
872void soc_ref_t::reset()
873{
874 m_soc = 0;
875}
876
710/** 877/**
711 * node_ref_t */ 878 * node_ref_t */
712 879
@@ -733,6 +900,11 @@ bool node_ref_t::is_root() const
733 return m_path.empty(); 900 return m_path.empty();
734} 901}
735 902
903void node_ref_t::reset()
904{
905 m_soc.reset();
906}
907
736namespace 908namespace
737{ 909{
738 910
@@ -789,14 +961,20 @@ soc_ref_t node_ref_t::soc() const
789 return m_soc; 961 return m_soc;
790} 962}
791 963
792node_ref_t node_ref_t::parent() const 964node_ref_t node_ref_t::parent(unsigned level) const
793{ 965{
966 if(level > depth())
967 return node_ref_t();
794 std::vector< soc_id_t > path = m_path; 968 std::vector< soc_id_t > path = m_path;
795 if(!path.empty()) 969 path.resize(depth() - level);
796 path.pop_back();
797 return node_ref_t(m_soc, path); 970 return node_ref_t(m_soc, path);
798} 971}
799 972
973unsigned node_ref_t::depth() const
974{
975 return m_path.size();
976}
977
800register_ref_t node_ref_t::reg() const 978register_ref_t node_ref_t::reg() const
801{ 979{
802 node_t *n = get(); 980 node_t *n = get();
@@ -808,6 +986,18 @@ register_ref_t node_ref_t::reg() const
808 return register_ref_t(*this); 986 return register_ref_t(*this);
809} 987}
810 988
989register_ref_t node_ref_t::create_reg(size_t width) const
990{
991 node_t *n = get();
992 if(n == 0)
993 return register_ref_t();
994 if(!n->register_.empty())
995 return register_ref_t();
996 n->register_.resize(1);
997 n->register_[0].width = width;
998 return register_ref_t(*this);
999}
1000
811node_ref_t node_ref_t::child(const std::string& name) const 1001node_ref_t node_ref_t::child(const std::string& name) const
812{ 1002{
813 /* check the node exists */ 1003 /* check the node exists */
@@ -867,6 +1057,41 @@ bool node_ref_t::operator==(const node_ref_t& ref) const
867 return m_soc == ref.m_soc && m_path == ref.m_path; 1057 return m_soc == ref.m_soc && m_path == ref.m_path;
868} 1058}
869 1059
1060void node_ref_t::remove()
1061{
1062 if(is_root())
1063 {
1064 soc_t *s = soc().get();
1065 if(s)
1066 s->node.clear();
1067 }
1068 else
1069 {
1070 std::vector< node_t > *list = get_children(parent());
1071 if(list == 0)
1072 return;
1073 for(size_t i = 0; i < list->size(); i++)
1074 if((*list)[i].id == m_path.back())
1075 {
1076 list->erase(list->begin() + i);
1077 return;
1078 }
1079 }
1080}
1081
1082node_ref_t node_ref_t::create() const
1083{
1084 std::vector< node_t > *list = get_children(*this);
1085 if(list == 0)
1086 return node_ref_t();
1087 node_t n;
1088 n.id = gen_fresh_id(*list);
1089 list->push_back(n);
1090 std::vector< soc_id_t > path = m_path;
1091 path.push_back(n.id);
1092 return node_ref_t(soc(), path);
1093}
1094
870/** 1095/**
871 * register_ref_t 1096 * register_ref_t
872 */ 1097 */
@@ -885,6 +1110,11 @@ bool register_ref_t::valid() const
885 return get() != 0; 1110 return get() != 0;
886} 1111}
887 1112
1113void register_ref_t::reset()
1114{
1115 m_node.reset();
1116}
1117
888register_t *register_ref_t::get() const 1118register_t *register_ref_t::get() const
889{ 1119{
890 node_t *n = m_node.get(); 1120 node_t *n = m_node.get();
@@ -909,6 +1139,17 @@ std::vector< field_ref_t > register_ref_t::fields() const
909 return fields; 1139 return fields;
910} 1140}
911 1141
1142std::vector< variant_ref_t > register_ref_t::variants() const
1143{
1144 std::vector< variant_ref_t > variants;
1145 register_t *r = get();
1146 if(r == 0)
1147 return variants;
1148 for(size_t i = 0; i < r->variant.size(); i++)
1149 variants.push_back(variant_ref_t(*this, r->variant[i].id));
1150 return variants;
1151}
1152
912field_ref_t register_ref_t::field(const std::string& name) const 1153field_ref_t register_ref_t::field(const std::string& name) const
913{ 1154{
914 register_t *r = get(); 1155 register_t *r = get();
@@ -920,6 +1161,46 @@ field_ref_t register_ref_t::field(const std::string& name) const
920 return field_ref_t(); 1161 return field_ref_t();
921} 1162}
922 1163
1164variant_ref_t register_ref_t::variant(const std::string& type) const
1165{
1166 register_t *r = get();
1167 if(r == 0)
1168 return variant_ref_t();
1169 for(size_t i = 0; i < r->variant.size(); i++)
1170 if(r->variant[i].type == type)
1171 return variant_ref_t(*this, r->variant[i].id);
1172 return variant_ref_t();
1173}
1174
1175void register_ref_t::remove()
1176{
1177 node_t *n = node().get();
1178 if(n)
1179 n->register_.clear();
1180}
1181
1182field_ref_t register_ref_t::create_field() const
1183{
1184 register_t *r = get();
1185 if(r == 0)
1186 return field_ref_t();
1187 field_t f;
1188 f.id = gen_fresh_id(r->field);
1189 r->field.push_back(f);
1190 return field_ref_t(*this, f.id);
1191}
1192
1193variant_ref_t register_ref_t::create_variant() const
1194{
1195 register_t *r = get();
1196 if(r == 0)
1197 return variant_ref_t();
1198 variant_t v;
1199 v.id = gen_fresh_id(r->variant);
1200 r->variant.push_back(v);
1201 return variant_ref_t(*this, v.id);
1202}
1203
923/** 1204/**
924 * field_ref_t 1205 * field_ref_t
925 */ 1206 */
@@ -938,6 +1219,11 @@ bool field_ref_t::valid() const
938 return get() != 0; 1219 return get() != 0;
939} 1220}
940 1221
1222void field_ref_t::reset()
1223{
1224 m_reg.reset();
1225}
1226
941field_t *field_ref_t::get() const 1227field_t *field_ref_t::get() const
942{ 1228{
943 register_t *reg = m_reg.get(); 1229 register_t *reg = m_reg.get();
@@ -949,11 +1235,123 @@ field_t *field_ref_t::get() const
949 return 0; 1235 return 0;
950} 1236}
951 1237
1238std::vector< enum_ref_t > field_ref_t::enums() const
1239{
1240 std::vector< enum_ref_t > enums;
1241 field_t *f = get();
1242 if(f == 0)
1243 return enums;
1244 for(size_t i = 0; i < f->enum_.size(); i++)
1245 enums.push_back(enum_ref_t(*this, f->enum_[i].id));
1246 return enums;
1247}
1248
952register_ref_t field_ref_t::reg() const 1249register_ref_t field_ref_t::reg() const
953{ 1250{
954 return m_reg; 1251 return m_reg;
955} 1252}
956 1253
1254enum_ref_t field_ref_t::create_enum() const
1255{
1256 field_t *f = get();
1257 if(f == 0)
1258 return enum_ref_t();
1259 enum_t e;
1260 e.id = gen_fresh_id(f->enum_);
1261 f->enum_.push_back(e);
1262 return enum_ref_t(*this, e.id);
1263}
1264
1265/**
1266 * enum_ref_t
1267 */
1268
1269enum_ref_t::enum_ref_t(field_ref_t field, soc_id_t id)
1270 :m_field(field), m_id(id)
1271{
1272}
1273
1274enum_ref_t::enum_ref_t()
1275{
1276}
1277
1278bool enum_ref_t::valid() const
1279{
1280 return get() != 0;
1281}
1282
1283void enum_ref_t::reset()
1284{
1285 m_field.reset();
1286}
1287
1288enum_t *enum_ref_t::get() const
1289{
1290 field_t *field = m_field.get();
1291 if(field == 0)
1292 return 0;
1293 for(size_t i = 0; i < field->enum_.size(); i++)
1294 if(field->enum_[i].id == m_id)
1295 return &field->enum_[i];
1296 return 0;
1297}
1298
1299field_ref_t enum_ref_t::field() const
1300{
1301 return m_field;
1302}
1303
1304/**
1305 * variant_ref_t
1306 */
1307
1308variant_ref_t::variant_ref_t(register_ref_t reg, soc_id_t id)
1309 :m_reg(reg), m_id(id)
1310{
1311}
1312
1313variant_ref_t::variant_ref_t()
1314{
1315}
1316
1317bool variant_ref_t::valid() const
1318{
1319 return get() != 0;
1320}
1321
1322void variant_ref_t::reset()
1323{
1324 m_reg.reset();
1325}
1326
1327variant_t *variant_ref_t::get() const
1328{
1329 register_t *reg = m_reg.get();
1330 if(reg == 0)
1331 return 0;
1332 for(size_t i = 0; i < reg->variant.size(); i++)
1333 if(reg->variant[i].id == m_id)
1334 return &reg->variant[i];
1335 return 0;
1336}
1337
1338register_ref_t variant_ref_t::reg() const
1339{
1340 return m_reg;
1341}
1342
1343std::string variant_ref_t::type() const
1344{
1345 variant_t *v = get();
1346 return v ? v->type : std::string();
1347}
1348
1349soc_word_t variant_ref_t::offset() const
1350{
1351 variant_t *v = get();
1352 return v ? v->offset : 0;
1353}
1354
957/** 1355/**
958 * node_inst_t 1356 * node_inst_t
959 */ 1357 */
@@ -965,8 +1363,8 @@ const size_t INST_NO_INDEX = std::numeric_limits<std::size_t>::max();
965 1363
966bool get_inst_addr(range_t& range, size_t index, soc_addr_t& addr) 1364bool get_inst_addr(range_t& range, size_t index, soc_addr_t& addr)
967{ 1365{
968 if(index < range.first || index >= range.first + range.count) 1366 if(index < range.first || index >= range.first + range.size())
969 return false; 1367 return false;
970 switch(range.type) 1368 switch(range.type)
971 { 1369 {
972 case range_t::STRIDE: 1370 case range_t::STRIDE:
@@ -983,6 +1381,9 @@ bool get_inst_addr(range_t& range, size_t index, soc_addr_t& addr)
983 addr += res; 1381 addr += res;
984 return true; 1382 return true;
985 } 1383 }
1384 case range_t::LIST:
1385 addr += range.list[index - range.first];
1386 return true;
986 default: 1387 default:
987 return false; 1388 return false;
988 } 1389 }
@@ -1030,6 +1431,11 @@ bool node_inst_t::valid() const
1030 return is_root() || get() != 0; 1431 return is_root() || get() != 0;
1031} 1432}
1032 1433
1434void node_inst_t::reset()
1435{
1436 m_node.reset();
1437}
1438
1033node_ref_t node_inst_t::node() const 1439node_ref_t node_inst_t::node() const
1034{ 1440{
1035 return m_node; 1441 return m_node;
@@ -1045,15 +1451,20 @@ bool node_inst_t::is_root() const
1045 return m_node.is_root(); 1451 return m_node.is_root();
1046} 1452}
1047 1453
1048node_inst_t node_inst_t::parent() const 1454node_inst_t node_inst_t::parent(unsigned level) const
1049{ 1455{
1456 if(level > depth())
1457 return node_inst_t();
1050 std::vector< soc_id_t > ids = m_id_path; 1458 std::vector< soc_id_t > ids = m_id_path;
1051 std::vector< size_t > indexes = m_index_path; 1459 std::vector< size_t > indexes = m_index_path;
1052 if(!ids.empty()) 1460 ids.resize(depth() - level);
1053 ids.pop_back(); 1461 indexes.resize(depth() - level);
1054 if(!indexes.empty()) 1462 return node_inst_t(m_node.parent(level), ids, indexes);
1055 indexes.pop_back(); 1463}
1056 return node_inst_t(m_node.parent(), ids, indexes); 1464
1465unsigned node_inst_t::depth() const
1466{
1467 return m_id_path.size();
1057} 1468}
1058 1469
1059instance_t *node_inst_t::get() const 1470instance_t *node_inst_t::get() const
@@ -1069,7 +1480,7 @@ instance_t *node_inst_t::get() const
1069 1480
1070soc_addr_t node_inst_t::addr() const 1481soc_addr_t node_inst_t::addr() const
1071{ 1482{
1072 if(is_root()) 1483 if(!valid() || is_root())
1073 return 0; 1484 return 0;
1074 soc_addr_t addr = parent().addr(); 1485 soc_addr_t addr = parent().addr();
1075 if(!get_inst_addr(get(), m_index_path.back(), addr)) 1486 if(!get_inst_addr(get(), m_index_path.back(), addr))
@@ -1100,7 +1511,7 @@ node_inst_t node_inst_t::child(const std::string& name, size_t index) const
1100 std::vector< soc_id_t > ids = m_id_path; 1511 std::vector< soc_id_t > ids = m_id_path;
1101 std::vector< size_t > indexes = m_index_path; 1512 std::vector< size_t > indexes = m_index_path;
1102 ids.push_back(node.instance[j].id); 1513 ids.push_back(node.instance[j].id);
1103 ids.push_back(index); 1514 indexes.push_back(index);
1104 return node_inst_t(child_node, ids, indexes); 1515 return node_inst_t(child_node, ids, indexes);
1105 } 1516 }
1106 child_node.m_path.pop_back(); 1517 child_node.m_path.pop_back();
@@ -1133,7 +1544,7 @@ std::vector< node_inst_t > node_inst_t::children() const
1133 i_path.pop_back(); 1544 i_path.pop_back();
1134 break; 1545 break;
1135 case instance_t::RANGE: 1546 case instance_t::RANGE:
1136 for(size_t i = 0; i < inst.range.count; i++) 1547 for(size_t i = 0; i < inst.range.size(); i++)
1137 { 1548 {
1138 i_path.push_back(inst.range.first + i); 1549 i_path.push_back(inst.range.first + i);
1139 list.push_back(node_inst_t(child_node, n_path, i_path)); 1550 list.push_back(node_inst_t(child_node, n_path, i_path));