added support for DSA libraries to compiler and made some optimisations.

provided an API for the editor to use.
This commit is contained in:
2026-02-04 01:56:58 +00:00
parent f25db6c8fd
commit 14a04a524c
8 changed files with 212 additions and 360 deletions
+53 -30
View File
@@ -117,7 +117,13 @@ impl RegisterAllocator {
// Load from bpr + offset (offset is negative)
code.push(format!("\tsubi bpr {} {}", -(offset + 4), reg));
code.push(format!("\tldw {}, {}", reg, reg));
code.push(format!(
"\tldw {}, {} // bpr{}: {}",
reg,
reg,
offset - 4,
var_name
));
// Update location to register
self.variable_locations
@@ -164,43 +170,57 @@ impl RegisterAllocator {
match location {
Location::Register(dest_reg) => {
if dest_reg != source_reg {
code.push(format!("\tmov {}, {}", source_reg, dest_reg));
code.push(format!(
"\tmov {}, {} // var {}",
source_reg, dest_reg, var_name
));
}
}
Location::Stack(offset) => {
code.push(format!("\tstw {}, bpr, {}", source_reg, offset));
code.push(format!(
"\tstw {}, bpr, {} // var {}",
source_reg, offset, var_name
));
}
}
} else {
// Variable doesn't exist yet, we can just use the same reg.
self.variable_locations.insert(
var_name.to_string(),
Location::Register(source_reg.to_string()),
);
self.register_contents
.insert(source_reg.to_string(), var_name.to_string());
self.in_use.insert(source_reg.to_string(), true);
// self.variable_locations.insert(
// var_name.to_string(),
// Location::Register(source_reg.to_string()),
// );
// self.register_contents
// .insert(source_reg.to_string(), var_name.to_string());
// self.in_use.insert(source_reg.to_string(), true);
// this is not needed for now as if we're storing a var we already have a temp
// register allocated.
// if let Some(free_reg) = self.find_free_register() {
// if &free_reg != source_reg {
// code.push(format!("\tmov {}, {}", source_reg, free_reg));
// }
// self.variable_locations
// .insert(var_name.to_string(),
// Location::Register(free_reg.clone()));
// self.register_contents
// .insert(free_reg.clone(), var_name.to_string());
// self.in_use.insert(free_reg, true);
// } else {
// // No free registers - allocate on stack
// code.push(format!("\tstw {}, bpr, {}", source_reg, self.stack_offset));
// self.variable_locations
// .insert(var_name.to_string(), Location::Stack(self.stack_offset));
// self.stack_offset -= 4; // Move to next stack slot
// }
let source_reg = source_reg.to_string();
// if we can avoid a move, absolutely do that.
if self.available_registers.contains(&source_reg) {
self.variable_locations
.insert(var_name.to_string(), Location::Register(source_reg.clone()));
self.register_contents
.insert(source_reg.clone(), var_name.to_string());
self.in_use.insert(source_reg, true);
} else if let Some(free_reg) = self.find_free_register() {
code.push(format!("\tmov {}, {}", source_reg, free_reg));
self.variable_locations
.insert(var_name.to_string(), Location::Register(free_reg.clone()));
self.register_contents
.insert(free_reg.clone(), var_name.to_string());
self.in_use.insert(free_reg, true);
} else {
// No free registers - allocate on stack
// code.push(format!("\tstw {}, bpr, {}", source_reg, self.stack_offset));
// self.variable_locations
// .insert(var_name.to_string(), Location::Stack(self.stack_offset));
// self.stack_offset -= 4; // Move to next stack slot
//
todo!(
"we should spill other registers and keep this variable on the stack as it's more recent!"
);
}
}
code
@@ -213,7 +233,10 @@ impl RegisterAllocator {
if let Some(var_name) = self.register_contents.get(reg).cloned() {
// PUSH register to stack (spr decrements automatically)
code.push(format!("\tpush {}", reg));
code.push(format!(
"\tpush {} // bpr{}: {}",
reg, self.stack_offset, var_name
));
// Track that we pushed one word
self.stack_offset -= 4;