chore: use bitfield library
This commit is contained in:
117
src/cpu.zig
117
src/cpu.zig
@@ -1,7 +1,11 @@
|
||||
const std = @import("std");
|
||||
const util = @import("util.zig");
|
||||
const bitfield = @import("util/bitfield.zig");
|
||||
|
||||
const Bus = @import("bus.zig").Bus;
|
||||
const Scheduler = @import("scheduler.zig").Scheduler;
|
||||
const Bitfield = bitfield.Bitfield;
|
||||
const Bit = bitfield.Bit;
|
||||
|
||||
const comptimeDataProcessing = @import("cpu/data_processing.zig").comptimeDataProcessing;
|
||||
const comptimeSingleDataTransfer = @import("cpu/single_data_transfer.zig").comptimeSingleDataTransfer;
|
||||
@@ -21,7 +25,7 @@ pub const Arm7tdmi = struct {
|
||||
.r = [_]u32{0x00} ** 16,
|
||||
.sch = scheduler,
|
||||
.bus = bus,
|
||||
.cpsr = .{ .inner = 0x0000_00DF },
|
||||
.cpsr = .{ .val = 0x0000_00DF },
|
||||
};
|
||||
}
|
||||
|
||||
@@ -52,20 +56,20 @@ fn armIdx(opcode: u32) u12 {
|
||||
fn checkCond(cpsr: *const CPSR, opcode: u32) bool {
|
||||
// TODO: Should I implement an enum?
|
||||
return switch (@truncate(u4, opcode >> 28)) {
|
||||
0x0 => cpsr.z(), // EQ - Equal
|
||||
0x1 => !cpsr.z(), // NEQ - Not equal
|
||||
0x2 => cpsr.c(), // CS - Unsigned higher or same
|
||||
0x3 => !cpsr.c(), // CC - Unsigned lower
|
||||
0x4 => cpsr.n(), // MI - Negative
|
||||
0x5 => !cpsr.n(), // PL - Positive or zero
|
||||
0x6 => cpsr.v(), // VS - Overflow
|
||||
0x7 => !cpsr.v(), // VC - No overflow
|
||||
0x8 => cpsr.c() and !cpsr.z(), // HI - unsigned higher
|
||||
0x9 => !cpsr.c() and cpsr.z(), // LS - unsigned lower or same
|
||||
0xA => cpsr.n() == cpsr.v(), // GE - Greater or equal
|
||||
0xB => cpsr.n() != cpsr.v(), // LT - Less than
|
||||
0xC => !cpsr.z() and (cpsr.n() == cpsr.z()), // GT - Greater than
|
||||
0xD => cpsr.z() or (cpsr.n() != cpsr.v()), // LE - Less than or equal
|
||||
0x0 => cpsr.z.read(), // EQ - Equal
|
||||
0x1 => !cpsr.z.read(), // NEQ - Not equal
|
||||
0x2 => cpsr.c.read(), // CS - Unsigned higher or same
|
||||
0x3 => !cpsr.c.read(), // CC - Unsigned lower
|
||||
0x4 => cpsr.n.read(), // MI - Negative
|
||||
0x5 => !cpsr.n.read(), // PL - Positive or zero
|
||||
0x6 => cpsr.v.read(), // VS - Overflow
|
||||
0x7 => !cpsr.v.read(), // VC - No overflow
|
||||
0x8 => cpsr.c.read() and !cpsr.z.read(), // HI - unsigned higher
|
||||
0x9 => !cpsr.c.read() and cpsr.z.read(), // LS - unsigned lower or same
|
||||
0xA => cpsr.n.read() == cpsr.v.read(), // GE - Greater or equal
|
||||
0xB => cpsr.n.read() != cpsr.v.read(), // LT - Less than
|
||||
0xC => !cpsr.z.read() and (cpsr.n.read() == cpsr.z.read()), // GT - Greater than
|
||||
0xD => cpsr.z.read() or (cpsr.n.read() != cpsr.v.read()), // LE - Less than or equal
|
||||
0xE => true, // AL - Always
|
||||
0xF => std.debug.panic("0xF is a reserved condition field", .{}),
|
||||
};
|
||||
@@ -117,79 +121,16 @@ fn populate() [0x1000]InstrFn {
|
||||
};
|
||||
}
|
||||
|
||||
const CPSR = struct {
|
||||
inner: u32,
|
||||
|
||||
pub fn n(self: *const @This()) bool {
|
||||
return self.inner >> 31 & 1 == 1;
|
||||
}
|
||||
|
||||
pub fn setN(self: *@This(), set: bool) void {
|
||||
self.setBit(31, set);
|
||||
}
|
||||
|
||||
pub fn z(self: *const @This()) bool {
|
||||
return self.inner >> 30 & 1 == 1;
|
||||
}
|
||||
|
||||
pub fn setZ(self: *@This(), set: bool) void {
|
||||
self.setBit(30, set);
|
||||
}
|
||||
|
||||
pub fn c(self: *const @This()) bool {
|
||||
return self.inner >> 29 & 1 == 1;
|
||||
}
|
||||
|
||||
pub fn setC(self: *@This(), set: bool) void {
|
||||
self.setBit(29, set);
|
||||
}
|
||||
|
||||
pub fn v(self: *const @This()) bool {
|
||||
return self.inner >> 28 & 1 == 1;
|
||||
}
|
||||
|
||||
pub fn setV(self: *@This(), set: bool) void {
|
||||
self.setBit(28, set);
|
||||
}
|
||||
|
||||
pub fn i(self: *const @This()) bool {
|
||||
return self.inner >> 7 & 1 == 1;
|
||||
}
|
||||
|
||||
pub fn setI(self: *@This(), set: bool) void {
|
||||
self.setBit(7, set);
|
||||
}
|
||||
|
||||
pub fn f(self: *const @This()) bool {
|
||||
return self.inner >> 6 & 1 == 1;
|
||||
}
|
||||
|
||||
pub fn setF(self: *@This(), set: bool) void {
|
||||
self.setBit(6, set);
|
||||
}
|
||||
|
||||
pub fn t(self: *const @This()) bool {
|
||||
return self.inner >> 5 & 1 == 1;
|
||||
}
|
||||
|
||||
pub fn setT(self: *@This(), set: bool) void {
|
||||
self.setBit(5, set);
|
||||
}
|
||||
|
||||
pub fn mode(self: *const @This()) Mode {
|
||||
return self.inner & 0x1F;
|
||||
}
|
||||
|
||||
pub fn setMode(_: *@This(), _: Mode) void {
|
||||
std.debug.panic("TODO: Implement set_mode for CPSR", .{});
|
||||
}
|
||||
|
||||
fn setBit(self: *@This(), comptime bit: usize, set: bool) void {
|
||||
const set_val = @as(u32, @boolToInt(set)) << bit;
|
||||
const mask = ~(@as(u32, 1) << bit);
|
||||
|
||||
self.inner = (self.inner & mask) | set_val;
|
||||
}
|
||||
const CPSR = extern union {
|
||||
mode: Bitfield(u32, 0, 5),
|
||||
t: Bit(u32, 5),
|
||||
f: Bit(u32, 6),
|
||||
i: Bit(u32, 7),
|
||||
v: Bit(u32, 28),
|
||||
c: Bit(u32, 29),
|
||||
z: Bit(u32, 30),
|
||||
n: Bit(u32, 31),
|
||||
val: u32,
|
||||
};
|
||||
|
||||
const Mode = enum(u5) {
|
||||
|
Reference in New Issue
Block a user