feat: stub coprocessor instructions
This commit is contained in:
parent
96a3a45d9b
commit
f31c4bdb65
|
@ -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;
|
||||||
|
}
|
|
@ -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),
|
||||||
|
};
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue