89 lines
2.5 KiB
Rust
89 lines
2.5 KiB
Rust
use crate::constants_table::ConstantsTable;
|
|
use crate::ir::assemble::InstructionsBuilder;
|
|
use crate::ir::ir_expression::IrExpression;
|
|
use crate::ir::ir_variable::IrVrVariableDescriptor;
|
|
use crate::ir::register_allocation::VrUser;
|
|
use dvm_lib::instruction::{Instruction, Location};
|
|
use std::collections::HashSet;
|
|
use std::fmt::{Display, Formatter};
|
|
|
|
pub enum IrBinaryOperator {
|
|
Multiply,
|
|
Divide,
|
|
Add,
|
|
Subtract,
|
|
}
|
|
|
|
pub struct IrBinaryOperation {
|
|
left: Box<IrExpression>,
|
|
right: Box<IrExpression>,
|
|
op: IrBinaryOperator,
|
|
}
|
|
|
|
impl IrBinaryOperation {
|
|
pub fn new(left: IrExpression, right: IrExpression, op: IrBinaryOperator) -> Self {
|
|
Self {
|
|
left: left.into(),
|
|
right: right.into(),
|
|
op,
|
|
}
|
|
}
|
|
|
|
pub fn assemble_assign(
|
|
&self,
|
|
builder: &mut InstructionsBuilder,
|
|
constants_table: &mut ConstantsTable,
|
|
destination: Location,
|
|
) {
|
|
let instruction = match &self.op {
|
|
IrBinaryOperator::Multiply => Instruction::Multiply(
|
|
self.left.multiply_operand(),
|
|
self.right.multiply_operand(),
|
|
destination,
|
|
),
|
|
IrBinaryOperator::Divide => {
|
|
todo!()
|
|
}
|
|
IrBinaryOperator::Add => Instruction::Add(
|
|
self.left.add_operand(constants_table),
|
|
self.right.add_operand(constants_table),
|
|
destination,
|
|
),
|
|
IrBinaryOperator::Subtract => Instruction::Subtract(
|
|
self.left.subtract_operand(),
|
|
self.right.subtract_operand(),
|
|
destination,
|
|
),
|
|
};
|
|
builder.push(instruction);
|
|
}
|
|
}
|
|
|
|
impl Display for IrBinaryOperation {
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
match &self.op {
|
|
IrBinaryOperator::Multiply => {
|
|
write!(f, "{} * {}", self.left, self.right)
|
|
}
|
|
IrBinaryOperator::Divide => {
|
|
write!(f, "{} / {}", self.left, self.right)
|
|
}
|
|
IrBinaryOperator::Add => {
|
|
write!(f, "{} + {}", self.left, self.right)
|
|
}
|
|
IrBinaryOperator::Subtract => {
|
|
write!(f, "{} - {}", self.left, self.right)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
impl VrUser for IrBinaryOperation {
|
|
fn vr_uses(&self) -> HashSet<IrVrVariableDescriptor> {
|
|
[self.left.as_ref(), self.right.as_ref()]
|
|
.iter()
|
|
.flat_map(|e| e.vr_uses())
|
|
.collect()
|
|
}
|
|
}
|