summaryrefslogtreecommitdiff
path: root/src/abstract_hardware_model.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/abstract_hardware_model.cc')
-rw-r--r--src/abstract_hardware_model.cc63
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()) &&