feat: implement QADD/QSUB

This commit is contained in:
2023-09-07 03:36:17 -05:00
parent 177f9b55a9
commit 819eace2a7
4 changed files with 32 additions and 21 deletions

View File

@@ -1,17 +0,0 @@
const sext = @import("zba-util").sext;
pub fn clz(comptime InstrFn: type) InstrFn {
const Arm32 = @typeInfo(@typeInfo(@typeInfo(InstrFn).Pointer.child).Fn.params[0].type.?).Pointer.child;
return struct {
pub fn inner(cpu: *Arm32, opcode: u32) void {
const rd = opcode >> 12 & 0xF;
const rm = opcode & 0xF;
if (rd == 0xF) cpu.panic("CLZ: UNPREDICTABLE behaviour when rd == 15", .{});
if (rm == 0xF) cpu.panic("CLZ: UNPREDICTABLE behaviour when rm == 15", .{});
cpu.r[rd] = @clz(cpu.r[rm]);
}
}.inner;
}

View File

@@ -29,7 +29,36 @@ pub fn control(comptime InstrFn: type, comptime I: bool, comptime op: u6) InstrF
const R = op >> 5 & 1 == 1;
msr(R, false, cpu, opcode);
},
else => cpu.panic("unhandled instruction: 0x{X:0>8}", .{opcode}),
0b01_0001 => cpu.panic("TODO: implement v5TE BX", .{}),
0b11_0001 => { // CLZ
const rd = opcode >> 12 & 0xF;
const rm = opcode & 0xF;
if (rd == 0xF) cpu.panic("CLZ: UNPREDICTABLE behaviour when rd == 15", .{});
if (rm == 0xF) cpu.panic("CLZ: UNPREDICTABLE behaviour when rm == 15", .{});
cpu.r[rd] = @clz(cpu.r[rm]);
},
0b01_0011 => cpu.panic("TODO: implement v5TE BLX", .{}),
0b00_0101, 0b01_0101 => {
const U = op >> 4 & 1 == 1; // A for Add? is there a convention?
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]);
cpu.r[rd] = @bitCast(if (U) left -| right else left +| right);
if (cpu.r[rd] == if (U) 0x8000_0000 else 0x7FFF_FFFF) cpu.cpsr.q.set();
},
0b10_0101 => cpu.panic("TODO: implement QDADD", .{}),
0b11_0101 => cpu.panic("TODO: implement QDSUB", .{}),
0b01_0111 => cpu.panic("TODO: handle BKPT", .{}),
else => std.log.debug("unhandled instruction: 0x{X:0>8}", .{opcode}),
}
}