added support for DSA libraries to compiler and made some optimisations.
provided an API for the editor to use.
This commit is contained in:
+53
-30
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user