summaryrefslogtreecommitdiff
path: root/utils/regtools/lib/soc_desc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/regtools/lib/soc_desc.cpp')
-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));