diff --git a/include/Instruction.h b/include/Instruction.h index 1955349..469c23e 100644 --- a/include/Instruction.h +++ b/include/Instruction.h @@ -577,6 +577,75 @@ template struct ReadMem : public Instruction { private: }; +// Division operation for the VM + +// c(0) = c(0) / c(i), handles division by zero +template struct Div : public Instruction { + Div(std::size_t i) : _i(i) {} + + auto execute(VM* vm) -> InstructionResult override { + VM::P::print_dbg("Div " + std::to_string(_i)); + auto& registers = vm->registers(); + + // Check if the divisor is zero + if (is_vm_type(registers[_i])) { + int divisor = vm_type_get(registers[_i]); + if (divisor == 0) { + return err("Division by zero error in register reg(" + std::to_string(_i) + ")"); + } + + // Perform integer division + auto res = divide(registers[0], registers[_i]); + if (res.ok()) { + registers[0] = res.result(); + vm->inc_pc(); + return true; + } + return res.error_value(); + } + return err("Expected int type in register reg(" + std::to_string(_i) + ") for division"); + } + +private: + std::size_t _i; +}; + +// c(0) = c(0) * c(i) +template struct Mult : public Instruction { + Mult(std::size_t i) : _i(i) { + } + + auto execute(VM* vm) -> InstructionResult override { + VM::P::print_dbg("Mult " + std::to_string(_i)); + auto& registers = vm->registers(); + + auto res = multiply(registers[0], registers[_i]); + if (res.ok()) { + registers[0] = res.result(); + vm->inc_pc(); + return true; + } + return res.error_value(); + } + +private: + std::size_t _i; + + static auto multiply(const VMType& lhs, const VMType& rhs) -> ResultOr { + if (is_vm_type(lhs) && is_vm_type(rhs)) { + return vm_type_get(lhs) * vm_type_get(rhs); + } + if (is_vm_type(lhs) && is_vm_type(rhs)) { + return vm_type_get(lhs) * vm_type_get(rhs); + } + if (is_vm_type(lhs) && is_vm_type(rhs)) { + return vm_type_get(lhs) * vm_type_get(rhs); + } + return err("Multiplication unsupported for given VMTypes"); + } +}; + + template using InstructionType = std::variant, CLoad, INDLoad, SLoad, Store, INDStore, Add, CAdd, INDAdd,