chore: tmp
This commit is contained in:
parent
cbd535f6c9
commit
1d4b5d4024
|
@ -3,6 +3,8 @@ pub fn blockDataTransfer(comptime InstrFn: type, comptime P: bool, comptime U: b
|
||||||
|
|
||||||
return struct {
|
return struct {
|
||||||
fn inner(cpu: *Arm32, opcode: u32) void {
|
fn inner(cpu: *Arm32, opcode: u32) void {
|
||||||
|
if (opcode == @byteSwap(0x030020E9)) @breakpoint();
|
||||||
|
|
||||||
const rn: u4 = @truncate(opcode >> 16 & 0xF);
|
const rn: u4 = @truncate(opcode >> 16 & 0xF);
|
||||||
const rlist: u16 = @intCast(opcode & 0xFFFF);
|
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;
|
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: {
|
const new_base_addr: u32 = if (U) blk: {
|
||||||
break :blk base_addr + 4 * reg_count;
|
break :blk base_addr + 4 * reg_count;
|
||||||
} else blk: {
|
} 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)
|
// 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
|
// Armv4: Store OLD Base if Rb is FIRST entry in Rlist, otherwise store NEW base
|
||||||
// Armv5: Always store OLD Base
|
// Armv5: Always store OLD Base
|
||||||
|
|
||||||
if (W and !L) {
|
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 mask = @as(u16, 1) << rn;
|
const is_first = @popCount(rlist & (mask - 1)) == 0;
|
||||||
const is_first = @popCount(rlist & (mask - 1)) == 0;
|
|
||||||
|
|
||||||
cpu.r[rn] = switch (Arm32.arch) {
|
cpu.r[rn] = switch (Arm32.arch) {
|
||||||
.v4t => if (is_first) base_addr else new_base_addr,
|
.v4t => if (is_first) base_addr else new_base_addr,
|
||||||
.v5te => base_addr,
|
.v5te => base_addr,
|
||||||
};
|
};
|
||||||
} else cpu.r[rn] = new_base_addr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// What happens when W is set and Rn is in the rlist? (LDM)
|
// 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
|
// ARMv5: writeback if Rn is "the ONLY register" or NOT the LAST register
|
||||||
|
|
||||||
if (W and L) {
|
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;
|
cpu.r[rn] = new_base_addr;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue