diff --git a/src/arm/cpu/arm/psr_transfer.zig b/src/arm/cpu/arm/psr_transfer.zig index 0f1ae47..3280987 100644 --- a/src/arm/cpu/arm/psr_transfer.zig +++ b/src/arm/cpu/arm/psr_transfer.zig @@ -108,26 +108,21 @@ pub fn control(comptime InstrFn: type, comptime I: bool, comptime op: u6) InstrF const rm = opcode & 0xF; const rs = opcode >> 8 & 0xF; - const rd_lo = opcode >> 12 & 0xF; - const rd_hi = opcode >> 16 & 0xF; + const rdlo = opcode >> 12 & 0xF; + const rdhi = opcode >> 16 & 0xF; - const left: i32 = @as(i16, @bitCast(@as(u16, @truncate(cpu.r[rm] >> 16 * X)))); - const right: i32 = @as(i16, @bitCast(@as(u16, @truncate(cpu.r[rs] >> 16 * Y)))); - - // TODO: de-clutter this lmao - const rdlo_val: i32 = @bitCast(cpu.r[rd_lo]); + const left: i64 = @as(i16, @bitCast(@as(u16, @truncate(cpu.r[rm] >> 16 * X)))); + const right: i64 = @as(i16, @bitCast(@as(u16, @truncate(cpu.r[rs] >> 16 * Y)))); const product = left * right; - // WHY DOESN'T THIS WORK???????? + const rdhi_val: i32 = @bitCast(cpu.r[rdhi]); + const rdlo_val: i32 = @bitCast(cpu.r[rdlo]); - cpu.r[rd_lo] = @bitCast(rdlo_val + product); - cpu.r[rd_hi] = blk: { - // FIXME: I think this has to do with correcting sign values? - const offset_thing: i32 = @bitCast(if (product < 0) 0xFFFF_FFFF else @as(u32, 0)); + const accumulate = @as(i64, rdhi_val) << 32 | rdlo_val; + const sum = product +% accumulate; - const rdhi_val: i32 = @bitCast(cpu.r[rd_hi]); - break :blk @bitCast(rdhi_val + offset_thing + @addWithOverflow(rdlo_val, product)[1]); - }; + cpu.r[rdhi] = @bitCast(@as(i32, @truncate(sum >> 32))); + cpu.r[rdlo] = @bitCast(@as(i32, @truncate(sum))); }, 0b01_1000, 0b01_1100 => { // SMLAW const Y = op >> 2 & 1; @@ -178,16 +173,6 @@ pub fn control(comptime InstrFn: type, comptime I: bool, comptime op: u6) InstrF } } - // TODO: make generic on any integer? - inline fn carryFrom(left: i32, right: i32) u1 { - const _left: u32 = @bitCast(left); - const _right: u32 = @bitCast(right); - - const sum = @as(u64, _left) + @as(u64, _right); - - return @intCast(sum >> 32 & 1); - } - inline fn msr(comptime R: bool, comptime imm: bool, cpu: *Arm32, opcode: u32) void { const field_mask: u4 = @truncate(opcode >> 16 & 0xF); const rm_idx = opcode & 0xF;