Skip to content

Commit

Permalink
refactor(lih): optimize and clean lih generation;
Browse files Browse the repository at this point in the history
  • Loading branch information
5-pebbles committed Sep 10, 2024
1 parent 46fe4eb commit 7d12eb4
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 30 deletions.
63 changes: 35 additions & 28 deletions src/compilation/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,13 @@ impl IrGenerator {
self.push(Ir::Set(immediate))
}

pub fn zero(&mut self, register: IrRegister) -> &mut Self {
self.nor(
register,
Either::Immediate(Immediate::Constant(u6::new(0b111111))),
)
}

pub fn mov(&mut self, register: IrRegister, either: Either) -> &mut Self {
if matches!(either, Either::Register(ref value) if *value == register) {
return self;
Expand Down Expand Up @@ -246,57 +253,57 @@ impl IrGenerator {
}

pub fn lih(&mut self, condition: Conditional, address: AddressTuple) -> &mut Self {
// TODO optimize
let helper = free_register!(MEM_REGISTER).unwrap();

match condition.kind {
ConditionalKind::Eq | ConditionalKind::NotEq => {
if matches!(condition.left, Either::Register(left) if left == MEM_REGISTER) {
self.sub(MEM_REGISTER, condition.right)
self.xor(MEM_REGISTER, condition.right)
} else {
self.mov(MEM_REGISTER, condition.right)
.sub(MEM_REGISTER, condition.left)
.xor(MEM_REGISTER, condition.left)
};
}
_ => todo!(),
}

self.mov(helper, Either::Immediate(Immediate::Constant(u6::new(0))));

(0..6).into_iter().for_each(|_| {
self.or(helper, Either::Register(MEM_REGISTER))
.ror(MEM_REGISTER);
});
// If the value in MEM_REGISTER is zero then jump.

self.and(
helper,
Either::Immediate(Immediate::Constant(u6::new(0b000001))),
);
let helper = free_register!(MEM_REGISTER).unwrap();
self.zero(helper);
// Distribute the value until we have [0b000000 | 0b111111]
(0..6).into_iter().for_each(|_| {
self.or(helper, Either::Register(MEM_REGISTER))
.ror(MEM_REGISTER);
});

if condition.kind == ConditionalKind::NotEq {
self.not(helper).and(
helper,
Either::Immediate(Immediate::Constant(u6::new(0b000001))),
);
}
}
_ => todo!(),
// Flip if we are using one of the negated conditions.
if condition.kind == ConditionalKind::NotEq {
self.not(helper);
}

// At this point helper should contain zero if we are going to jump else one
self.rol(helper).or(MEM_REGISTER, Either::Register(helper));
// Mask into [0 | 3]
self.and(
helper,
Either::Immediate(Immediate::Constant(u6::new(0b000011))),
);

// Add that to our label and jump to the new address.
let label = unique_label();
self.add(
MEM_REGISTER,
helper,
Either::Immediate(Immediate::LabelP1(label.clone(), Span::new(0, 0))),
)
.pc(AddressTuple(
Either::Immediate(Immediate::LabelP0(label.clone(), Span::new(0, 0))),
Either::Register(helper),
));

if self.next_address & u12::new(0b111111) == u12::new(0b111111) {
// skip 6-bit overflow
// Adding a six bit tuple is complicated and expensive.
// Solution: skip the 6-bit overflow.
while self.next_address & u12::new(0b111111) > u12::new(0b111111 - 3) {
self.nop();
}

// If we added three to this label we will skip the last instruction otherwise we will jump to the target address
self.lab(label, Span::new(0, 0)).unwrap().pc(address)
}

Expand Down
2 changes: 0 additions & 2 deletions src/tests/logic_is_hard.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// I am about to fall asleep... zzz

use arbitrary_int::{u12, u6};

use crate::{compilation::compile_to_binary, emulation::InteractiveState, utils::tuple_as_u12};
Expand Down

0 comments on commit 7d12eb4

Please sign in to comment.