chore: tmp

This commit is contained in:
Rekai Nyangadzayi Musuka 2023-09-24 01:43:47 -05:00
parent cbd535f6c9
commit 1d4b5d4024
1 changed files with 36 additions and 12 deletions

View File

@ -3,6 +3,8 @@ pub fn blockDataTransfer(comptime InstrFn: type, comptime P: bool, comptime U: b
return struct {
fn inner(cpu: *Arm32, opcode: u32) void {
if (opcode == @byteSwap(0x030020E9)) @breakpoint();
const rn: u4 = @truncate(opcode >> 16 & 0xF);
const rlist: u16 = @intCast(opcode & 0xFFFF);
@ -20,8 +22,6 @@ pub fn blockDataTransfer(comptime InstrFn: type, comptime P: bool, comptime U: b
break :blk base_addr - (4 * reg_count) + if (!P) 4 else 0;
};
// FIXME : why 4 * reg_count?
const new_base_addr: u32 = if (U) blk: {
break :blk base_addr + 4 * reg_count;
} else blk: {
@ -77,23 +77,47 @@ pub fn blockDataTransfer(comptime InstrFn: type, comptime P: bool, comptime U: b
}
}
{
const cond = @as(u2, @intFromBool(P)) << 1 | @intFromBool(U);
const end_address: u32 = switch (cond) {
0b00 => base_addr, // Decrement After
0b10 => base_addr - 4, // Increment Before
0b01 => base_addr + (4 * reg_count) - 4, // Increment After
0b11 => base_addr + (4 * reg_count), // Increment Before
};
const actual_addr = address - 4;
if (actual_addr != end_address) {
cpu.panic(
\\P = {}, U = {}, S = {}, W = {}, L = {}
\\base_addr = 0x{X:0>8}
\\start_addr = 0x{X:0>8}
\\expected_end_address = 0x{X:0>8} actual_end_address = 0x{X:0>8}
\\rlist = 0b{b:0>16}, first_in_list = r{}
, .{ P, U, S, W, L, base_addr, start_addr, end_address, actual_addr, rlist, first_in_list });
}
}
// What happens when W is set and Rn is in the rlist? (STM)
//
// Armv4: Store OLD Base if Rb is FIRST entry in Rlist, otherwise store NEW base
// Armv5: Always store OLD Base
if (W and !L) {
const rn_in_rlist = rlist >> rn & 1 == 1;
if (rlist >> rn & 1 == 0) { // rn is not in rlist
cpu.r[rn] = new_base_addr;
return;
}
if (rn_in_rlist) {
const mask = @as(u16, 1) << rn;
const is_first = @popCount(rlist & (mask - 1)) == 0;
const mask = @as(u16, 1) << rn;
const is_first = @popCount(rlist & (mask - 1)) == 0;
cpu.r[rn] = switch (Arm32.arch) {
.v4t => if (is_first) base_addr else new_base_addr,
.v5te => base_addr,
};
} else cpu.r[rn] = new_base_addr;
cpu.r[rn] = switch (Arm32.arch) {
.v4t => if (is_first) base_addr else new_base_addr,
.v5te => base_addr,
};
}
// What happens when W is set and Rn is in the rlist? (LDM)
@ -102,7 +126,7 @@ pub fn blockDataTransfer(comptime InstrFn: type, comptime P: bool, comptime U: b
// ARMv5: writeback if Rn is "the ONLY register" or NOT the LAST register
if (W and L) {
if (rlist >> rn & 1 == 0) {
if (rlist >> rn & 1 == 0) { // rn is not in rlist
cpu.r[rn] = new_base_addr;
return;
}