mirror of
https://github.com/FranLMSP/rultra64.git
synced 2026-01-01 07:51:34 -05:00
MULT instructions
This commit is contained in:
50
src/cpu.rs
50
src/cpu.rs
@@ -100,6 +100,16 @@ impl CPU {
|
||||
let (rs, rt) = params_rs_rt(opcode);
|
||||
self.ddiv(rs, rt);
|
||||
},
|
||||
// MULT | MULTU
|
||||
0b000_0001_1000 | 0b000_0001_1001 => {
|
||||
let (rs, rt) = params_rs_rt(opcode);
|
||||
self.mult(rs, rt);
|
||||
},
|
||||
// DMULT | DMULTU
|
||||
0b000_0001_1100 | 0b000_0001_1101 => {
|
||||
let (rs, rt) = params_rs_rt(opcode);
|
||||
self.dmult(rs, rt);
|
||||
},
|
||||
// AND
|
||||
0b000_0010_0100 => {
|
||||
let (rd, rs, rt) = params_rd_rs_rt(opcode);
|
||||
@@ -242,6 +252,22 @@ impl CPU {
|
||||
self.registers.set_hi(remainder);
|
||||
}
|
||||
|
||||
pub fn mult(&mut self, rs: usize, rt: usize) {
|
||||
let s = (self.registers.get_by_number(rs) as i32) as i64;
|
||||
let t = (self.registers.get_by_number(rt) as i32) as i64;
|
||||
let result = s * t;
|
||||
self.registers.set_lo(result & 0x000000FFFFFF);
|
||||
self.registers.set_hi(result >> 32);
|
||||
}
|
||||
|
||||
pub fn dmult(&mut self, rs: usize, rt: usize) {
|
||||
let s = self.registers.get_by_number(rs) as i128;
|
||||
let t = self.registers.get_by_number(rt) as i128;
|
||||
let result = s * t;
|
||||
self.registers.set_lo((result & 0xFFFFFFFFFFFF) as i64);
|
||||
self.registers.set_hi((result >> 64) as i64);
|
||||
}
|
||||
|
||||
pub fn and(&mut self, rd: usize, rs: usize, rt: usize) {
|
||||
let result = self.registers.get_by_number(rs) & self.registers.get_by_number(rt);
|
||||
self.registers.set_by_number(rd, result);
|
||||
@@ -454,6 +480,30 @@ mod cpu_instructions_tests {
|
||||
assert_eq!(cpu.registers.get_hi(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mult() {
|
||||
let mut cpu = CPU::new();
|
||||
let reg_s = 15;
|
||||
let reg_t = 20;
|
||||
cpu.registers.set_by_number(reg_s, 20);
|
||||
cpu.registers.set_by_number(reg_t, 20);
|
||||
cpu.mult(reg_s, reg_t);
|
||||
assert_eq!(cpu.registers.get_lo(), 400);
|
||||
assert_eq!(cpu.registers.get_hi(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dmult() {
|
||||
let mut cpu = CPU::new();
|
||||
let reg_s = 15;
|
||||
let reg_t = 20;
|
||||
cpu.registers.set_by_number(reg_s, 20);
|
||||
cpu.registers.set_by_number(reg_t, 20);
|
||||
cpu.dmult(reg_s, reg_t);
|
||||
assert_eq!(cpu.registers.get_lo(), 400);
|
||||
assert_eq!(cpu.registers.get_hi(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_and() {
|
||||
let mut cpu = CPU::new();
|
||||
|
||||
@@ -29,7 +29,7 @@ pub struct CPURegisters {
|
||||
program_counter: Generic<i64>,
|
||||
hi: Generic<i64>,
|
||||
lo: Generic<i64>,
|
||||
load_link: bool,
|
||||
// load_link: bool,
|
||||
}
|
||||
|
||||
impl CPURegisters {
|
||||
@@ -72,7 +72,7 @@ impl CPURegisters {
|
||||
program_counter: Generic(0xBFC00000),
|
||||
hi: Generic(0_i64),
|
||||
lo: Generic(0_i64),
|
||||
load_link: false,
|
||||
// load_link: false,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user