fix(v5te): properly implement qadd/qsub qdadd/qdsub
This commit is contained in:
parent
a3eefa6432
commit
106820b444
|
@ -49,34 +49,38 @@ pub fn control(comptime InstrFn: type, comptime I: bool, comptime op: u6) InstrF
|
|||
|
||||
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 D = op >> 5 & 1 == 1;
|
||||
|
||||
const rm = opcode & 0xF;
|
||||
const rd = opcode >> 12 & 0xF;
|
||||
const rn = opcode >> 16 & 0xF;
|
||||
|
||||
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();
|
||||
},
|
||||
0b10_0101, 0b11_0101 => { // QDADD / QDSUB
|
||||
const U = op >> 4 & 1 == 1;
|
||||
if (ret[1] == 0b1) {
|
||||
product = if (product < 0) std.math.maxInt(i32) else std.math.minInt(i32);
|
||||
cpu.cpsr.q.set();
|
||||
}
|
||||
|
||||
const rm = opcode & 0xF;
|
||||
const rd = opcode >> 8 & 0xF;
|
||||
const rn = opcode >> 16 & 0xF;
|
||||
break :blk product;
|
||||
};
|
||||
|
||||
const product = @as(i32, @bitCast(cpu.r[rn])) *| 2;
|
||||
if (product == 0x7FFF_FFFF) cpu.cpsr.q.set();
|
||||
const ret = if (U) @subWithOverflow(left, right) else @addWithOverflow(left, right);
|
||||
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);
|
||||
if (cpu.r[rd] == 0x8000_0000 or cpu.r[rd] == 0x7FFF_FFFF) cpu.cpsr.q.set();
|
||||
cpu.r[rd] = @bitCast(result);
|
||||
},
|
||||
0b01_0111 => cpu.panic("TODO: handle BKPT", .{}),
|
||||
0b00_1000, 0b00_1010, 0b00_1100, 0b00_1110 => { // SMLA<x><y>
|
||||
|
|
Loading…
Reference in New Issue