fix(v5te): properly implement SMLAL<x><y>
This commit is contained in:
parent
106820b444
commit
37b3fe3d10
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue