aboutsummaryrefslogtreecommitdiff
path: root/spike_main
diff options
context:
space:
mode:
Diffstat (limited to 'spike_main')
-rw-r--r--spike_main/spike.cc63
1 files changed, 41 insertions, 22 deletions
diff --git a/spike_main/spike.cc b/spike_main/spike.cc
index cd8a6d8..5815761 100644
--- a/spike_main/spike.cc
+++ b/spike_main/spike.cc
@@ -123,31 +123,49 @@ bool sort_mem_region(const mem_cfg_t &a, const mem_cfg_t &b)
return (a.base < b.base);
}
-void merge_overlapping_memory_regions(std::vector<mem_cfg_t> &mems)
+static bool check_mem_overlap(const mem_cfg_t& L, const mem_cfg_t& R)
{
- // check the user specified memory regions and merge the overlapping or
- // eliminate the containing parts
- assert(!mems.empty());
+ const reg_t L_end = L.base + L.size - 1;
+ const reg_t R_end = R.base + R.size - 1;
+
+ return std::max(L.base, R.base) <= std::min(L_end, R_end);
+}
+
+static mem_cfg_t merge_mem_regions(const mem_cfg_t& L, const mem_cfg_t& R)
+{
+ // one can merge only intersecting regions
+ assert(check_mem_overlap(L, R));
+
+ const reg_t merged_base = std::min(L.base, R.base);
+ const reg_t merged_end_incl = std::max(L.base + L.size - 1, R.base + R.size - 1);
+ const reg_t merged_size = merged_end_incl - merged_base + 1;
+
+ return mem_cfg_t(merged_base, merged_size);
+}
+
+// check the user specified memory regions and merge the overlapping or
+// eliminate the containing parts
+static std::vector<mem_cfg_t>
+merge_overlapping_memory_regions(std::vector<mem_cfg_t> mems)
+{
+ if (mems.empty())
+ return {};
std::sort(mems.begin(), mems.end(), sort_mem_region);
- for (auto it = mems.begin() + 1; it != mems.end(); ) {
- reg_t start = prev(it)->base;
- reg_t end = prev(it)->base + prev(it)->size;
- reg_t start2 = it->base;
- reg_t end2 = it->base + it->size;
-
- //contains -> remove
- if (start2 >= start && end2 <= end) {
- it = mems.erase(it);
- //partial overlapped -> extend
- } else if (start2 >= start && start2 < end) {
- prev(it)->size = std::max(end, end2) - start;
- it = mems.erase(it);
- // no overlapping -> keep it
- } else {
- it++;
+
+ std::vector<mem_cfg_t> merged_mem;
+ merged_mem.push_back(mems.front());
+
+ for (auto mem_it = std::next(mems.begin()); mem_it != mems.end(); ++mem_it) {
+ const auto& mem_int = *mem_it;
+ if (!check_mem_overlap(merged_mem.back(), mem_int)) {
+ merged_mem.push_back(mem_int);
+ continue;
}
+ merged_mem.back() = merge_mem_regions(merged_mem.back(), mem_int);
}
+
+ return merged_mem;
}
static std::vector<mem_cfg_t> parse_mem_layout(const char* arg)
@@ -217,9 +235,10 @@ static std::vector<mem_cfg_t> parse_mem_layout(const char* arg)
arg = p + 1;
}
- merge_overlapping_memory_regions(res);
+ auto merged_mem = merge_overlapping_memory_regions(res);
- return res;
+ assert(!merged_mem.empty());
+ return merged_mem;
}
static std::vector<std::pair<reg_t, mem_t*>> make_mems(const std::vector<mem_cfg_t> &layout)