diff --git a/lang/src/son/hbvm/regalloc.rs b/lang/src/son/hbvm/regalloc.rs index 452f3320e..c3551dbd1 100644 --- a/lang/src/son/hbvm/regalloc.rs +++ b/lang/src/son/hbvm/regalloc.rs @@ -9,7 +9,11 @@ use { PLoc, Sig, Types, }, alloc::{borrow::ToOwned, vec::Vec}, - core::{mem, ops::Range}, + core::{ + mem, + ops::{Range, RangeBounds}, + usize, + }, hbbytecode::{self as instrs}, }; @@ -37,9 +41,13 @@ impl HbvmBackend { self.emit(instrs::st(reg::RET_ADDR + tail as u8, reg::STACK_PTR, 0, 0)); } - res.node_to_reg[MEM as usize] = res.bundles.len() as u8 + 1; + if let Some(PLoc::Ref(..)) = tys.parama(sig.ret).0 { + res.node_to_reg[MEM as usize] = res.bundles.len() as u8 + 1; + res.bundles.push(Bundle::new(0)); + } let reg_offset = if tail { reg::RET + 12 } else { reg::RET_ADDR + 1 }; + let bundle_count = res.bundles.len() + (reg_offset as usize); res.node_to_reg.iter_mut().filter(|r| **r != 0).for_each(|r| { if *r == u8::MAX { @@ -52,6 +60,11 @@ impl HbvmBackend { } }); + debug_assert!(!res + .node_to_reg + .iter() + .any(|&a| a == reg::RET_ADDR || (reg::RET..reg_offset - 1).contains(&a))); + let atr = |allc: Nid| { let allc = strip_load(allc); debug_assert_eq!( @@ -298,11 +311,22 @@ impl HbvmBackend { self.ralloc = res; - let bundle_count = self.ralloc.bundles.len() + (reg_offset as usize); debug_assert!(bundle_count < reg::STACK_PTR as usize, "TODO: spill memory"); + debug_assert_eq!( + self.ralloc + .node_to_reg + .iter() + .filter(|&&r| r + > (bundle_count as u8 + + (tail && bundle_count > (reg::RET_ADDR) as usize) as u8)) + .copied() + .collect::>(), + vec![], + "{bundle_count}" + ); ( if tail { - bundle_count.saturating_sub((reg::RET_ADDR - 1) as _) + bundle_count.saturating_sub(reg::RET_ADDR as _) } else { self.ralloc.bundles.len() },