feat: implement QADD/QSUB

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

View File

@ -444,6 +444,8 @@ pub const PSR = extern union {
t: Bit(u32, 5), t: Bit(u32, 5),
f: Bit(u32, 6), f: Bit(u32, 6),
i: Bit(u32, 7), i: Bit(u32, 7),
q: Bit(u32, 27), // ARMv5TE only
v: Bit(u32, 28), v: Bit(u32, 28),
c: Bit(u32, 29), c: Bit(u32, 29),
z: Bit(u32, 30), z: Bit(u32, 30),

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; const R = op >> 5 & 1 == 1;
msr(R, false, cpu, opcode); 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}),
} }
} }

View File

@ -20,7 +20,6 @@ pub const arm = struct {
const multiply = @import("cpu/arm/multiply.zig").multiply; const multiply = @import("cpu/arm/multiply.zig").multiply;
const cop = @import("cpu/arm/coprocessor.zig"); const cop = @import("cpu/arm/coprocessor.zig");
const clz = @import("cpu/arm/misc_instructions.zig").clz;
/// Determine index into ARM InstrFn LUT /// Determine index into ARM InstrFn LUT
pub fn idx(opcode: u32) u12 { pub fn idx(opcode: u32) u12 {
@ -43,8 +42,6 @@ pub const arm = struct {
handler.* = switch (@as(u2, i >> 10)) { handler.* = switch (@as(u2, i >> 10)) {
0b00 => if (i == 0x121) blk: { // 12 bits 0b00 => if (i == 0x121) blk: { // 12 bits
break :blk branchExchange(InstrFn); break :blk branchExchange(InstrFn);
} else if (i == 0x161) blk: { // 12 bits
break :blk clz(InstrFn);
} else if (i & 0xFBF == 0x109) blk: { // 11 bits } else if (i & 0xFBF == 0x109) blk: { // 11 bits
const B = i >> 6 & 1 == 1; const B = i >> 6 & 1 == 1;
break :blk swap(InstrFn, B); break :blk swap(InstrFn, B);