feat: implement QADD/QSUB
This commit is contained in:
parent
177f9b55a9
commit
819eace2a7
|
@ -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),
|
||||||
|
|
|
@ -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;
|
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}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue