fix(v5te): properly implement SMLAL<x><y>

This commit is contained in:
Rekai Nyangadzayi Musuka 2023-09-19 21:48:12 -05:00
parent 106820b444
commit 37b3fe3d10
1 changed files with 10 additions and 25 deletions

View File

@ -108,26 +108,21 @@ pub fn control(comptime InstrFn: type, comptime I: bool, comptime op: u6) InstrF
const rm = opcode & 0xF; const rm = opcode & 0xF;
const rs = opcode >> 8 & 0xF; const rs = opcode >> 8 & 0xF;
const rd_lo = opcode >> 12 & 0xF; const rdlo = opcode >> 12 & 0xF;
const rd_hi = opcode >> 16 & 0xF; const rdhi = opcode >> 16 & 0xF;
const left: i32 = @as(i16, @bitCast(@as(u16, @truncate(cpu.r[rm] >> 16 * X)))); const left: i64 = @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)))); const right: i64 = @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 product = left * right; 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); const accumulate = @as(i64, rdhi_val) << 32 | rdlo_val;
cpu.r[rd_hi] = blk: { const sum = product +% accumulate;
// 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 rdhi_val: i32 = @bitCast(cpu.r[rd_hi]); cpu.r[rdhi] = @bitCast(@as(i32, @truncate(sum >> 32)));
break :blk @bitCast(rdhi_val + offset_thing + @addWithOverflow(rdlo_val, product)[1]); cpu.r[rdlo] = @bitCast(@as(i32, @truncate(sum)));
};
}, },
0b01_1000, 0b01_1100 => { // SMLAW<y> 0b01_1000, 0b01_1100 => { // SMLAW<y>
const Y = op >> 2 & 1; 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 { inline fn msr(comptime R: bool, comptime imm: bool, cpu: *Arm32, opcode: u32) void {
const field_mask: u4 = @truncate(opcode >> 16 & 0xF); const field_mask: u4 = @truncate(opcode >> 16 & 0xF);
const rm_idx = opcode & 0xF; const rm_idx = opcode & 0xF;