diff --git a/src/arm/cpu/thumb/data_processing.zig b/src/arm/cpu/thumb/data_processing.zig index d0e4b63..36bb5ea 100644 --- a/src/arm/cpu/thumb/data_processing.zig +++ b/src/arm/cpu/thumb/data_processing.zig @@ -216,3 +216,13 @@ pub fn fmt13(comptime InstrFn: type, comptime S: bool) InstrFn { } }.inner; } + +pub fn bkpt(comptime InstrFn: type) InstrFn { + const Arm32 = @typeInfo(@typeInfo(@typeInfo(InstrFn).Pointer.child).Fn.params[0].type.?).Pointer.child; + + return struct { + fn inner(cpu: *Arm32, _: u16) void { + cpu.panic("TODO: handle THUMB BKPT", .{}); + } + }.inner; +} diff --git a/src/arm/v5te.zig b/src/arm/v5te.zig index 69a5bec..0b07b03 100644 --- a/src/arm/v5te.zig +++ b/src/arm/v5te.zig @@ -212,13 +212,18 @@ pub const thumb = struct { const rd = i >> 2 & 0x7; break :blk processing.fmt12(InstrFn, isSP, rd); }, - 0b011 => if (i >> 4 & 1 == 1) blk: { - const L = i >> 5 & 1 == 1; - const R = i >> 2 & 1 == 1; - break :blk block_transfer.fmt14(InstrFn, L, R); - } else blk: { - const S = i >> 1 & 1 == 1; - break :blk processing.fmt13(InstrFn, S); + 0b011 => switch (@as(u2, @truncate(i >> 3 & 0x3))) { + 0b10 => blk: { + // PUSH / POP + const L = i >> 5 & 1 == 1; + const R = i >> 2 & 1 == 1; + break :blk block_transfer.fmt14(InstrFn, L, R); + }, + 0b11 => processing.bkpt(InstrFn), + else => blk: { + const S = i >> 1 & 1 == 1; + break :blk processing.fmt13(InstrFn, S); + }, }, 0b100 => blk: { const L = i >> 5 & 1 == 1;