feat: stub coprocessor instructions

This commit is contained in:
Rekai Nyangadzayi Musuka 2023-07-25 21:44:30 -05:00
parent 96a3a45d9b
commit f31c4bdb65
2 changed files with 75 additions and 2 deletions

View File

@ -0,0 +1,50 @@
const std = @import("std");
const Bus = @import("../../../lib.zig").Bus;
const log = std.log.scoped(.coprocessor_handler);
pub fn dataTransfer(comptime InstrFn: type, comptime P: bool, comptime U: bool, comptime N: bool, comptime W: bool, comptime L: bool) InstrFn {
_ = L;
_ = W;
_ = N;
_ = U;
_ = P;
const Arm32 = @typeInfo(@typeInfo(InstrFn).Pointer.child).Fn.params[0].type.?;
return struct {
fn inner(cpu: Arm32, _: Bus, opcode: u32) void {
_ = cpu;
log.err("TODO: handle 0x{X:0>8} which is a coprocessor data transfer instr", .{opcode});
}
}.inner;
}
pub fn registerTransfer(comptime InstrFn: type, comptime opcode1: u3, comptime L: bool, comptime opcode2: u3) InstrFn {
_ = opcode2;
_ = L;
_ = opcode1;
const Arm32 = @typeInfo(@typeInfo(InstrFn).Pointer.child).Fn.params[0].type.?;
return struct {
fn inner(cpu: Arm32, _: Bus, opcode: u32) void {
_ = cpu;
log.err("TODO: handle 0x{X:0>8} which is a coprocessor register transfer instr", .{opcode});
}
}.inner;
}
pub fn dataProcessing(comptime InstrFn: type, comptime opcode1: u4, comptime opcode2: u3) InstrFn {
_ = opcode2;
_ = opcode1;
const Arm32 = @typeInfo(@typeInfo(InstrFn).Pointer.child).Fn.params[0].type.?;
return struct {
fn inner(cpu: Arm32, _: Bus, opcode: u32) void {
_ = cpu;
log.err("TODO: handle 0x{X:0>8} which is a coprocessor data processing instr", .{opcode});
}
}.inner;
}

View File

@ -18,6 +18,8 @@ pub const arm = struct {
const multiply = @import("cpu/arm/multiply.zig").multiply; const multiply = @import("cpu/arm/multiply.zig").multiply;
const multiplyLong = @import("cpu/arm/multiply.zig").multiplyLong; const multiplyLong = @import("cpu/arm/multiply.zig").multiplyLong;
const cop = @import("cpu/arm/coprocessor.zig");
/// Determine index into ARM InstrFn LUT /// Determine index into ARM InstrFn LUT
pub fn idx(opcode: u32) u12 { pub fn idx(opcode: u32) u12 {
// FIXME: omit these? // FIXME: omit these?
@ -92,8 +94,29 @@ pub const arm = struct {
const L = i >> 8 & 1 == 1; const L = i >> 8 & 1 == 1;
break :blk branch(InstrFn, L); break :blk branch(InstrFn, L);
}, },
0b10 => und, // COP Data Transfer 0b10 => blk: {
0b11 => if (i >> 8 & 1 == 1) swi(InstrFn) else und, // COP Data Operation + Register Transfer const P = i >> 8 & 1 == 1;
const U = i >> 7 & 1 == 1;
const N = i >> 6 & 1 == 1;
const W = i >> 5 & 1 == 1;
const L = i >> 4 & 1 == 1;
break :blk cop.dataTransfer(InstrFn, P, U, N, W, L);
},
0b11 => blk: {
if (i >> 8 & 1 == 1) break :blk swi(InstrFn);
const data_opcode1 = i >> 4 & 0xF; // bits 20 -> 23
const reg_opcode1 = i >> 5 & 0x7; // bits 21 -> 23
const opcode2 = i >> 1 & 0x7; // bits 5 -> 7
const L = i >> 4 & 1 == 1; // bit 20
// Bit 4 (index pos of 0) distinguishes between these classes of instructions
break :blk switch (i & 1 == 1) {
true => cop.registerTransfer(InstrFn, reg_opcode1, L, opcode2),
false => cop.dataProcessing(InstrFn, data_opcode1, opcode2),
};
},
}, },
}; };
} }