Finished LOAD, ADD, HUL and DIV implementation

This commit is contained in:
Anthony Foxclaw 2020-02-06 17:40:43 -05:00
parent d1340fe9fc
commit 223ce4c1bd
4 changed files with 66 additions and 38 deletions

View file

@ -1,3 +1,5 @@
use crate::instruction::Opcode::LOAD;
#[derive(Debug, PartialEq)]
pub enum Opcode {
HLT,
@ -5,28 +7,30 @@ pub enum Opcode {
LOAD,
ADD,
MUL,
DIV
DIV,
}
impl From<u8> for Opcode {
fn from(vm: u8) -> Self {
match vm {
0 => Opcode::HLT,
_ => Opcode::IGL
1 => Opcode::LOAD,
2 => Opcode::ADD,
3 => Opcode::MUL,
4 => Opcode::DIV
_ => Opcode::IGL,
}
}
}
#[derive(Debug, PartialEq)]
pub struct Instruction {
opcode: Opcode
opcode: Opcode,
}
impl Instruction {
pub fn new(opcode: Opcode) -> Self {
Instruction {
opcode
}
Instruction { opcode }
}
}
@ -45,4 +49,4 @@ mod instruction_tests {
let inst = Instruction::new(Opcode::HLT);
assert_eq!(inst.opcode, Opcode::HLT);
}
}
}

View file

@ -1,2 +1,2 @@
mod instruction;
mod vm;
mod instruction;

View file

@ -1,5 +1,3 @@
fn main() {
println!("Hello, world!");
}

View file

@ -3,7 +3,8 @@ use crate::instruction::Opcode;
pub struct VM {
registers: [i32; 32],
pc: usize,
program: Vec<u8>
program: Vec<u8>,
remainder: u32,
}
impl VM {
@ -11,7 +12,8 @@ impl VM {
VM {
registers: [0; 32],
pc: 0,
program: vec![]
program: vec![],
remainder: 0,
}
}
@ -28,36 +30,57 @@ impl VM {
}
fn next_16_bits(&mut self) -> u16 {
let result = ((self.program[self.pc] as u16) << 8) | self.program[self.pc + 1] as u16;
self.pc += 2;
result
}
pub fn run(&mut self) {
loop {
if self.pc >= self.program.len() {
break;
let mut is_done = false;
while !is_done {
is_done = self.execute_instruction()
}
}
pub fn run_once(&mut self) {
self.execute_instruction();
}
fn execute_instruction(&mut self) -> bool {
if self.pc >= self.program.len() {
return false;
}
match self.decode_opcode() {
Opcode::LOAD => {
let reg = self.next_8_bits() as usize;
let num = self.next_16_bits() as u32;
self.registers[reg] = num as i32;
}
match self.decode_opcode() {
Opcode::LOAD => {
let reg = self.next_8_bits() as usize;
let num = self.next_16_bits() as u32;
self.registers[reg] = num as i32;
}
Opcode::HLT => {
println!("HLT encountered");
return;
}
Opcode::IGL => {
println!("Unrecognized opcode found! Terminating!");
return;
}
Opcode::ADD => {}
Opcode::MUL => {}
Opcode::DIV => {}
Opcode::HLT => {
println!("HLT encountered");
return false;
}
Opcode::IGL => {
println!("Unrecognized opcode found! Terminating!");
}
Opcode::ADD => {
let reg1 = self.registers[self.next_8_bits() as usize];
let reg2 = self.registers[self.next_8_bits() as usize];
self.registers[self.next_8_bits() as usize] = reg1 + reg2;
}
Opcode::MUL => {
let reg1 = self.registers[self.next_8_bits() as usize];
let reg2 = self.registers[self.next_8_bits() as usize];
self.registers[self.next_8_bits() as usize] = reg1 * reg2;
}
Opcode::DIV => {
let reg1 = self.registers[self.next_8_bits() as usize];
let reg2 = self.registers[self.next_8_bits() as usize];
self.registers[self.next_8_bits() as usize] = reg1 / reg2;
self.remainder = (reg1 % reg2) as u32;
}
}
true
}
}
@ -74,18 +97,21 @@ mod vm_tests {
#[test]
fn test_opcode_hlt() {
let mut test_vm = VM::new();
let test_bytes = vec![0,0,0,0];
let test_bytes = vec![0, 0, 0, 0];
test_vm.program = test_bytes;
test_vm.run();
test_vm.run_once();
assert_eq!(test_vm.pc, 1);
}
#[test]
fn test_opcode_igl() {
let mut test_vm = VM::new();
let test_bytes = vec![200,0,0,0];
let test_bytes = vec![200, 0, 0, 0];
test_vm.program = test_bytes;
test_vm.run();
test_vm.run_once();
assert_eq!(test_vm.pc, 1);
}
}
#[test]
fn test_load_opcode() {}
}