feat: implement QADD/QSUB
This commit is contained in:
@@ -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;
|
||||
}
|
||||
@@ -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}),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user