chore: refactor instruction exec code
This commit is contained in:
		
							
								
								
									
										29
									
								
								src/cpu.zig
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								src/cpu.zig
									
									
									
									
									
								
							@@ -9,9 +9,10 @@ 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;
 | 
			
		||||
const comptimeHalfSignedDataTransfer = @import("cpu/half_signed_data_transfer.zig").comptimeHalfSignedDataTransfer;
 | 
			
		||||
const dataProcessing = @import("cpu/data_processing.zig").dataProcessing;
 | 
			
		||||
const singleDataTransfer = @import("cpu/single_data_transfer.zig").singleDataTransfer;
 | 
			
		||||
const halfAndSignedDataTransfer = @import("cpu/half_signed_data_transfer.zig").halfAndSignedDataTransfer;
 | 
			
		||||
const branch = @import("cpu/branch.zig").branch;
 | 
			
		||||
 | 
			
		||||
pub const InstrFn = fn (*Arm7tdmi, *Bus, u32) void;
 | 
			
		||||
const arm_lut: [0x1000]InstrFn = populate();
 | 
			
		||||
@@ -58,7 +59,7 @@ pub const Arm7tdmi = struct {
 | 
			
		||||
        return word;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn fakePC(self: *const @This()) u32 {
 | 
			
		||||
    pub fn fakePC(self: *const @This()) u32 {
 | 
			
		||||
        return self.r[15] + 4;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -128,7 +129,7 @@ fn populate() [0x1000]InstrFn {
 | 
			
		||||
                const S = i >> 4 & 1 == 1;
 | 
			
		||||
                const instrKind = i >> 5 & 0xF;
 | 
			
		||||
 | 
			
		||||
                lut[i] = comptimeDataProcessing(I, S, instrKind);
 | 
			
		||||
                lut[i] = dataProcessing(I, S, instrKind);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (i >> 9 & 0x7 == 0b000 and i >> 3 & 1 == 1 and i & 1 == 1) {
 | 
			
		||||
@@ -138,7 +139,7 @@ fn populate() [0x1000]InstrFn {
 | 
			
		||||
                const W = i >> 5 & 1 == 1;
 | 
			
		||||
                const L = i >> 4 & 1 == 1;
 | 
			
		||||
 | 
			
		||||
                lut[i] = comptimeHalfSignedDataTransfer(P, U, I, W, L);
 | 
			
		||||
                lut[i] = halfAndSignedDataTransfer(P, U, I, W, L);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (i >> 10 & 0x3 == 0b01) {
 | 
			
		||||
@@ -149,12 +150,12 @@ fn populate() [0x1000]InstrFn {
 | 
			
		||||
                const W = i >> 5 & 1 == 1;
 | 
			
		||||
                const L = i >> 4 & 1 == 1;
 | 
			
		||||
 | 
			
		||||
                lut[i] = comptimeSingleDataTransfer(I, P, U, B, W, L);
 | 
			
		||||
                lut[i] = singleDataTransfer(I, P, U, B, W, L);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (i >> 9 & 0x7 == 0b101) {
 | 
			
		||||
                const L = i >> 8 & 1 == 1;
 | 
			
		||||
                lut[i] = comptimeBranch(L);
 | 
			
		||||
                lut[i] = branch(L);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -188,15 +189,3 @@ fn undefinedInstruction(_: *Arm7tdmi, _: *Bus, opcode: u32) void {
 | 
			
		||||
    const id = armIdx(opcode);
 | 
			
		||||
    std.debug.panic("[CPU] {{0x{X:}}} 0x{X:} is an illegal opcode", .{ id, opcode });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn comptimeBranch(comptime L: bool) InstrFn {
 | 
			
		||||
    return struct {
 | 
			
		||||
        fn branch(cpu: *Arm7tdmi, _: *Bus, opcode: u32) void {
 | 
			
		||||
            if (L) {
 | 
			
		||||
                cpu.r[14] = cpu.r[15] - 4;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            cpu.r[15] = cpu.fakePC() +% util.u32SignExtend(24, opcode << 2);
 | 
			
		||||
        }
 | 
			
		||||
    }.branch;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										19
									
								
								src/cpu/branch.zig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/cpu/branch.zig
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
const arm = @import("../cpu.zig");
 | 
			
		||||
const util = @import("../util.zig");
 | 
			
		||||
 | 
			
		||||
const Bus = @import("../bus.zig").Bus;
 | 
			
		||||
 | 
			
		||||
const Arm7tdmi = arm.Arm7tdmi;
 | 
			
		||||
const InstrFn = arm.InstrFn;
 | 
			
		||||
 | 
			
		||||
pub fn branch(comptime L: bool) InstrFn {
 | 
			
		||||
    return struct {
 | 
			
		||||
        fn inner(cpu: *Arm7tdmi, _: *Bus, opcode: u32) void {
 | 
			
		||||
            if (L) {
 | 
			
		||||
                cpu.r[14] = cpu.r[15] - 4;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            cpu.r[15] = cpu.fakePC() +% util.u32SignExtend(24, opcode << 2);
 | 
			
		||||
        }
 | 
			
		||||
    }.inner;
 | 
			
		||||
}
 | 
			
		||||
@@ -6,9 +6,9 @@ const Bus = @import("../bus.zig").Bus;
 | 
			
		||||
const Arm7tdmi = arm.Arm7tdmi;
 | 
			
		||||
const InstrFn = arm.InstrFn;
 | 
			
		||||
 | 
			
		||||
pub fn comptimeDataProcessing(comptime I: bool, comptime S: bool, comptime instrKind: u4) InstrFn {
 | 
			
		||||
pub fn dataProcessing(comptime I: bool, comptime S: bool, comptime instrKind: u4) InstrFn {
 | 
			
		||||
    return struct {
 | 
			
		||||
        fn dataProcessing(cpu: *Arm7tdmi, _: *Bus, opcode: u32) void {
 | 
			
		||||
        fn inner(cpu: *Arm7tdmi, _: *Bus, opcode: u32) void {
 | 
			
		||||
            const rd = opcode >> 12 & 0xF;
 | 
			
		||||
            const op1 = opcode >> 16 & 0xF;
 | 
			
		||||
 | 
			
		||||
@@ -68,5 +68,5 @@ pub fn comptimeDataProcessing(comptime I: bool, comptime S: bool, comptime instr
 | 
			
		||||
                else => std.debug.panic("[CPU] TODO: implement data processing type {}", .{instrKind}),
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }.dataProcessing;
 | 
			
		||||
    }.inner;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -6,9 +6,9 @@ const Bus = @import("../bus.zig").Bus;
 | 
			
		||||
const Arm7tdmi = arm.Arm7tdmi;
 | 
			
		||||
const InstrFn = arm.InstrFn;
 | 
			
		||||
 | 
			
		||||
pub fn comptimeHalfSignedDataTransfer(comptime P: bool, comptime U: bool, comptime I: bool, comptime W: bool, comptime L: bool) InstrFn {
 | 
			
		||||
pub fn halfAndSignedDataTransfer(comptime P: bool, comptime U: bool, comptime I: bool, comptime W: bool, comptime L: bool) InstrFn {
 | 
			
		||||
    return struct {
 | 
			
		||||
        fn halfSignedDataTransfer(cpu: *Arm7tdmi, bus: *Bus, opcode: u32) void {
 | 
			
		||||
        fn inner(cpu: *Arm7tdmi, bus: *Bus, opcode: u32) void {
 | 
			
		||||
            const rn = opcode >> 16 & 0xF;
 | 
			
		||||
            const rd = opcode >> 12 & 0xF;
 | 
			
		||||
            const rm = opcode & 0xF;
 | 
			
		||||
@@ -59,5 +59,5 @@ pub fn comptimeHalfSignedDataTransfer(comptime P: bool, comptime U: bool, compti
 | 
			
		||||
            address = modified_base;
 | 
			
		||||
            if (W and P or !P) cpu.r[rn] = address;
 | 
			
		||||
        }
 | 
			
		||||
    }.halfSignedDataTransfer;
 | 
			
		||||
    }.inner;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -8,9 +8,9 @@ const Arm7tdmi = arm.Arm7tdmi;
 | 
			
		||||
const InstrFn = arm.InstrFn;
 | 
			
		||||
const CPSR = arm.CPSR;
 | 
			
		||||
 | 
			
		||||
pub fn comptimeSingleDataTransfer(comptime I: bool, comptime P: bool, comptime U: bool, comptime B: bool, comptime W: bool, comptime L: bool) InstrFn {
 | 
			
		||||
pub fn singleDataTransfer(comptime I: bool, comptime P: bool, comptime U: bool, comptime B: bool, comptime W: bool, comptime L: bool) InstrFn {
 | 
			
		||||
    return struct {
 | 
			
		||||
        fn singleDataTransfer(cpu: *Arm7tdmi, bus: *Bus, opcode: u32) void {
 | 
			
		||||
        fn inner(cpu: *Arm7tdmi, bus: *Bus, opcode: u32) void {
 | 
			
		||||
            const rn = opcode >> 16 & 0xF;
 | 
			
		||||
            const rd = opcode >> 12 & 0xF;
 | 
			
		||||
 | 
			
		||||
@@ -46,7 +46,7 @@ pub fn comptimeSingleDataTransfer(comptime I: bool, comptime P: bool, comptime U
 | 
			
		||||
 | 
			
		||||
            // TODO: W-bit forces non-privledged mode for the transfer
 | 
			
		||||
        }
 | 
			
		||||
    }.singleDataTransfer;
 | 
			
		||||
    }.inner;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn registerOffset(cpu: *Arm7tdmi, opcode: u32) u32 {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user