feat(cpu): implement ARM multiply instructions
This commit is contained in:
parent
6c008ce950
commit
a459d4b433
|
@ -17,6 +17,7 @@ const blockDataTransfer = @import("cpu/arm/block_data_transfer.zig").blockDataTr
|
||||||
const branch = @import("cpu/arm/branch.zig").branch;
|
const branch = @import("cpu/arm/branch.zig").branch;
|
||||||
const branchAndExchange = @import("cpu/arm/branch.zig").branchAndExchange;
|
const branchAndExchange = @import("cpu/arm/branch.zig").branchAndExchange;
|
||||||
const softwareInterrupt = @import("cpu/arm/software_interrupt.zig").softwareInterrupt;
|
const softwareInterrupt = @import("cpu/arm/software_interrupt.zig").softwareInterrupt;
|
||||||
|
const multiply = @import("cpu/arm/multiply.zig").multiply;
|
||||||
|
|
||||||
// THUMB Instruction Groups
|
// THUMB Instruction Groups
|
||||||
const format1 = @import("cpu/thumb/format1.zig").format1;
|
const format1 = @import("cpu/thumb/format1.zig").format1;
|
||||||
|
@ -448,6 +449,13 @@ fn armPopulate() [0x1000]ArmInstrFn {
|
||||||
lut[i] = psrTransfer(I, R, kind);
|
lut[i] = psrTransfer(I, R, kind);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (i >> 6 & 0x3F == 0b000000 and i & 0xF == 0b1001) {
|
||||||
|
const A = i >> 5 & 1 == 1;
|
||||||
|
const S = i >> 4 & 1 == 1;
|
||||||
|
|
||||||
|
lut[i] = multiply(A, S);
|
||||||
|
}
|
||||||
|
|
||||||
if (i == 0x121) {
|
if (i == 0x121) {
|
||||||
lut[i] = branchAndExchange;
|
lut[i] = branchAndExchange;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const Bus = @import("../../Bus.zig");
|
||||||
|
const Arm7tdmi = @import("../../cpu.zig").Arm7tdmi;
|
||||||
|
const InstrFn = @import("../../cpu.zig").ArmInstrFn;
|
||||||
|
|
||||||
|
pub fn multiply(comptime A: bool, comptime S: bool) InstrFn {
|
||||||
|
return struct {
|
||||||
|
fn inner(cpu: *Arm7tdmi, _: *Bus, opcode: u32) void {
|
||||||
|
const rd = opcode >> 16 & 0xF;
|
||||||
|
const rn = opcode >> 12 & 0xF;
|
||||||
|
const rs = opcode >> 8 & 0xF;
|
||||||
|
const rm = opcode & 0xF;
|
||||||
|
|
||||||
|
const result = cpu.r[rm] * cpu.r[rs] + if (A) cpu.r[rn] else 0;
|
||||||
|
cpu.r[rd] = result;
|
||||||
|
|
||||||
|
if (S) {
|
||||||
|
cpu.cpsr.n.write(result >> 31 & 1 == 1);
|
||||||
|
cpu.cpsr.z.write(result == 0);
|
||||||
|
// V is unaffected, C is *actually* undefined in ARMv4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.inner;
|
||||||
|
}
|
|
@ -92,7 +92,10 @@ pub fn format4(comptime op: u4) InstrFn {
|
||||||
// MUL
|
// MUL
|
||||||
const result = cpu.r[rs] * cpu.r[rd];
|
const result = cpu.r[rs] * cpu.r[rd];
|
||||||
cpu.r[rd] = result;
|
cpu.r[rd] = result;
|
||||||
std.debug.panic("[CPU|THUMB|MUL] TODO: Set flags on ALU MUL", .{});
|
|
||||||
|
cpu.cpsr.n.write(result >> 31 & 1 == 1);
|
||||||
|
cpu.cpsr.z.write(result == 0);
|
||||||
|
// V is unaffected, assuming similar behaviour to ARMv4 MUL C is undefined
|
||||||
},
|
},
|
||||||
0xE => {
|
0xE => {
|
||||||
// BIC
|
// BIC
|
||||||
|
|
Loading…
Reference in New Issue