fix(v5te): properly implement qadd/qsub qdadd/qdsub

This commit is contained in:
Rekai Nyangadzayi Musuka 2023-09-19 21:08:29 -05:00
parent a3eefa6432
commit 106820b444
1 changed files with 19 additions and 15 deletions

View File

@ -49,34 +49,38 @@ pub fn control(comptime InstrFn: type, comptime I: bool, comptime op: u6) InstrF
cpu.pipe.reload(cpu); cpu.pipe.reload(cpu);
}, },
0b00_0101, 0b01_0101 => { // QADD / QSUB 0b00_0101, 0b01_0101, 0b10_0101, 0b11_0101 => { // QADD / QDADD / QSUB / QDSUB
const U = op >> 4 & 1 == 1; const U = op >> 4 & 1 == 1;
const D = op >> 5 & 1 == 1;
const rm = opcode & 0xF; const rm = opcode & 0xF;
const rd = opcode >> 12 & 0xF; const rd = opcode >> 12 & 0xF;
const rn = opcode >> 16 & 0xF; const rn = opcode >> 16 & 0xF;
const left: i32 = @bitCast(cpu.r[rm]); const left: i32 = @bitCast(cpu.r[rm]);
const right: i32 = @bitCast(cpu.r[rn]); const right: i32 = blk: {
if (!D) break :blk @bitCast(cpu.r[rn]);
cpu.r[rd] = @bitCast(if (U) left -| right else left +| right); const ret = @mulWithOverflow(@as(i32, @bitCast(cpu.r[rn])), 2);
var product: i32 = ret[0];
if (cpu.r[rd] == 0x8000_0000 or cpu.r[rd] == 0x7FFF_FFFF) cpu.cpsr.q.set(); if (ret[1] == 0b1) {
}, product = if (product < 0) std.math.maxInt(i32) else std.math.minInt(i32);
0b10_0101, 0b11_0101 => { // QDADD / QDSUB cpu.cpsr.q.set();
const U = op >> 4 & 1 == 1; }
const rm = opcode & 0xF; break :blk product;
const rd = opcode >> 8 & 0xF; };
const rn = opcode >> 16 & 0xF;
const product = @as(i32, @bitCast(cpu.r[rn])) *| 2; const ret = if (U) @subWithOverflow(left, right) else @addWithOverflow(left, right);
if (product == 0x7FFF_FFFF) cpu.cpsr.q.set(); var result: i32 = ret[0];
const left: i32 = @bitCast(cpu.r[rm]); if (ret[1] == 0b1) {
result = if (result < 0) std.math.maxInt(i32) else std.math.minInt(i32);
cpu.cpsr.q.set();
}
cpu.r[rd] = @bitCast(if (U) left -| product else left +| product); cpu.r[rd] = @bitCast(result);
if (cpu.r[rd] == 0x8000_0000 or cpu.r[rd] == 0x7FFF_FFFF) cpu.cpsr.q.set();
}, },
0b01_0111 => cpu.panic("TODO: handle BKPT", .{}), 0b01_0111 => cpu.panic("TODO: handle BKPT", .{}),
0b00_1000, 0b00_1010, 0b00_1100, 0b00_1110 => { // SMLA<x><y> 0b00_1000, 0b00_1010, 0b00_1100, 0b00_1110 => { // SMLA<x><y>