diff options
Diffstat (limited to 'src/abstract_hardware_model.cc')
| -rw-r--r-- | src/abstract_hardware_model.cc | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/src/abstract_hardware_model.cc b/src/abstract_hardware_model.cc index deebfd6..9262a92 100644 --- a/src/abstract_hardware_model.cc +++ b/src/abstract_hardware_model.cc @@ -1440,6 +1440,69 @@ const simt_mask_t &simt_splits_table::get_active_mask(unsigned num) { return m_splits_table[num].m_active_mask; } +// SIMD lane partitioning: secondary split access and targeted operations + +bool simt_splits_table::get_secondary_split_info(unsigned *pc, unsigned *rpc, + unsigned *split_id, + simt_mask_t *mask) const { + if (m_fifo_queue.size() < 2) return false; + auto it = m_fifo_queue.begin(); + ++it; // second entry + unsigned sec_entry = it->m_st_entry; + auto st_it = m_splits_table.find(sec_entry); + if (st_it == m_splits_table.end() || !st_it->second.m_valid) return false; + if (st_it->second.m_blocked || st_it->second.m_virtual) return false; + *pc = st_it->second.m_pc; + *rpc = st_it->second.m_recvg_pc; + *split_id = sec_entry; + *mask = st_it->second.m_active_mask; + return true; +} + +bool simt_splits_table::is_split_valid(unsigned split_id) const { + auto it = m_splits_table.find(split_id); + return it != m_splits_table.end() && it->second.m_valid; +} + +void simt_splits_table::get_split_info(unsigned split_id, unsigned *pc, + simt_mask_t *mask) const { + auto it = m_splits_table.find(split_id); + assert(it != m_splits_table.end() && it->second.m_valid); + *pc = it->second.m_pc; + *mask = it->second.m_active_mask; +} + +void simt_splits_table::update_pc_for_split(unsigned split_id, + address_type new_pc) { + assert(m_splits_table.find(split_id) != m_splits_table.end()); + assert(m_splits_table[split_id].m_valid); + m_splits_table[split_id].m_pc = new_pc; +} + +bool simt_splits_table::move_split_to_front(unsigned split_id) { + if (m_fifo_queue.empty()) return false; + if (m_fifo_queue.front().m_st_entry == split_id) { + m_active_split = split_id; + return true; // already at front + } + // Find and remove from current position + fifo_entry target; + bool found = false; + for (auto it = m_fifo_queue.begin(); it != m_fifo_queue.end(); ++it) { + if (it->m_st_entry == (int)split_id) { + target = *it; + m_fifo_queue.erase(it); + found = true; + break; + } + } + if (!found) return false; + // Insert at front and make active + m_fifo_queue.push_front(target); + m_active_split = split_id; + return true; +} + void simt_splits_table::get_pdom_splits_entry_info(unsigned num, unsigned *pc, unsigned *rpc) { assert((m_splits_table.find(num) != m_splits_table.end()) && |
