diff options
author | Parshintsev Anatoly <anatoly.parshintsev@syntacore.com> | 2023-01-09 19:23:43 +0300 |
---|---|---|
committer | Andrew Waterman <andrew@sifive.com> | 2023-01-10 15:44:16 -0800 |
commit | ca1a5fd8f0280cca41ed54cb98c21514a882dacd (patch) | |
tree | 54f1ed0177fdfc2284ceb9e3d24b7806af36ba78 /spike_main | |
parent | 28eb7aa8bece565adac4245815c80ba3fc65fc8a (diff) | |
download | riscv-isa-sim-ca1a5fd8f0280cca41ed54cb98c21514a882dacd.zip riscv-isa-sim-ca1a5fd8f0280cca41ed54cb98c21514a882dacd.tar.gz riscv-isa-sim-ca1a5fd8f0280cca41ed54cb98c21514a882dacd.tar.bz2 |
improve merge_mem_regions to handle memory region covering the whole 64-bit address space
Diffstat (limited to 'spike_main')
-rw-r--r-- | spike_main/spike.cc | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/spike_main/spike.cc b/spike_main/spike.cc index b3cffae..8386a49 100644 --- a/spike_main/spike.cc +++ b/spike_main/spike.cc @@ -131,6 +131,18 @@ static bool check_mem_overlap(const mem_cfg_t& L, const mem_cfg_t& R) return std::max(L.get_base(), R.get_base()) <= std::min(L.get_inclusive_end(), R.get_inclusive_end()); } +static bool check_if_merge_covers_64bit_space(const mem_cfg_t& L, + const mem_cfg_t& R) +{ + if (!check_mem_overlap(L, R)) + return false; + + auto start = std::min(L.get_base(), R.get_base()); + auto end = std::max(L.get_inclusive_end(), R.get_inclusive_end()); + + return (start == 0ull) && (end == std::numeric_limits<uint64_t>::max()); +} + static mem_cfg_t merge_mem_regions(const mem_cfg_t& L, const mem_cfg_t& R) { // one can merge only intersecting regions @@ -162,6 +174,18 @@ merge_overlapping_memory_regions(std::vector<mem_cfg_t> mems) merged_mem.push_back(mem_int); continue; } + // there is a weird corner case preventing two memory regions from being + // merged: if the resulting size of a region is 2^64 bytes - currently, + // such regions are not representable by mem_cfg_t class (because the + // actual size field is effectively a 64 bit value) + // so we create two smaller memory regions that total for 2^64 bytes as + // a workaround + if (check_if_merge_covers_64bit_space(merged_mem.back(), mem_int)) { + merged_mem.clear(); + merged_mem.push_back(mem_cfg_t(0ull, 0ull - PGSIZE)); + merged_mem.push_back(mem_cfg_t(0ull - PGSIZE, PGSIZE)); + break; + } merged_mem.back() = merge_mem_regions(merged_mem.back(), mem_int); } |