diff --git a/build.zig.zon b/build.zig.zon index 46b894b..83dc384 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -9,8 +9,8 @@ }, .dependencies = .{ .@"zba-util" = .{ - .url = "https://git.musuka.dev/paoda/zba-util/archive/78b944a98f18592512241f71ca2267ef951c82e1.tar.gz", - .hash = "12207da7e1f5d6180666db9575f84373055b230cb4259a4b6310562293338dc10b9d", + .url = "https://git.musuka.dev/paoda/zba-util/archive/7ebaf2854a2d31ef30691427681286e35130b1ae.tar.gz", + .hash = "12206ea1b29665cecb78bf2c269d1d0ed0a9b6f5f1dffe2aceaddd1cd8abc13a2f08", }, }, } diff --git a/src/arm/cpu/arm/half_signed_data_transfer.zig b/src/arm/cpu/arm/half_signed_data_transfer.zig index d71e60b..da4abe3 100644 --- a/src/arm/cpu/arm/half_signed_data_transfer.zig +++ b/src/arm/cpu/arm/half_signed_data_transfer.zig @@ -1,6 +1,7 @@ const std = @import("std"); const sext = @import("zba-util").sext; const rotr = @import("zba-util").rotr; +const alignAddr = @import("zba-util").alignAddr; const log = std.log.scoped(.half_and_signed_data_transfer); @@ -27,8 +28,10 @@ pub fn halfAndSignedDataTransfer(comptime InstrFn: type, comptime P: bool, compt switch (op) { 0b01 => { // LDRH - const value = cpu.read(u16, address); - result = rotr(u32, value, 8 * (address & 1)); + result = switch (Arm32.arch) { + .v4t => rotr(u32, cpu.read(u16, address), 8 * (address & 1)), + .v5te => cpu.read(u16, alignAddr(u16, address)), + }; }, 0b10 => { // LDRSB @@ -36,10 +39,17 @@ pub fn halfAndSignedDataTransfer(comptime InstrFn: type, comptime P: bool, compt }, 0b11 => { // LDRSH - const value = cpu.read(u16, address); + result = switch (Arm32.arch) { + .v4t => blk: { + const value = cpu.read(u16, address); - // FIXME: I shouldn't have to use @as(u8, ...) here - result = if (address & 1 == 1) sext(u32, u8, @as(u8, @truncate(value >> 8))) else sext(u32, u16, value); + break :blk switch (address & 1 == 1) { + true => sext(u32, u8, @as(u8, @truncate(value >> 8))), + false => sext(u32, u16, value), + }; + }, + .v5te => sext(u32, u16, cpu.read(u16, alignAddr(u16, address))), + }; }, 0b00 => unreachable, } diff --git a/src/arm/cpu/thumb/data_transfer.zig b/src/arm/cpu/thumb/data_transfer.zig index c6ed066..edab60b 100644 --- a/src/arm/cpu/thumb/data_transfer.zig +++ b/src/arm/cpu/thumb/data_transfer.zig @@ -1,5 +1,6 @@ const rotr = @import("zba-util").rotr; const sext = @import("zba-util").sext; +const alignAddr = @import("zba-util").alignAddr; pub fn fmt6(comptime InstrFn: type, comptime rd: u3) InstrFn { const Arm32 = @typeInfo(@typeInfo(@typeInfo(InstrFn).Pointer.child).Fn.params[0].type.?).Pointer.child; @@ -41,15 +42,24 @@ pub fn fmt78(comptime InstrFn: type, comptime op: u2, comptime T: bool) InstrFn }, 0b10 => { // LDRH - const value = cpu.read(u16, address); - cpu.r[rd] = rotr(u32, value, 8 * (address & 1)); + cpu.r[rd] = switch (Arm32.arch) { + .v4t => rotr(u32, cpu.read(u16, address), 8 * (address & 1)), + .v5te => cpu.read(u16, alignAddr(u16, address)), + }; }, 0b11 => { // LDRSH - const value = cpu.read(u16, address); + cpu.r[rd] = switch (Arm32.arch) { + .v4t => blk: { + const value = cpu.read(u16, address); - // FIXME: I shouldn't have to use @as(u8, ...) here - cpu.r[rd] = if (address & 1 == 1) sext(u32, u8, @as(u8, @truncate(value >> 8))) else sext(u32, u16, value); + break :blk switch (address & 1 == 1) { + true => sext(u32, u8, @as(u8, @truncate(value >> 8))), + false => sext(u32, u16, value), + }; + }, + .v5te => sext(u32, u16, cpu.read(u16, alignAddr(u16, address))), + }; }, } } else { @@ -128,8 +138,10 @@ pub fn fmt10(comptime InstrFn: type, comptime L: bool, comptime offset: u5) Inst if (L) { // LDRH - const value = cpu.read(u16, address); - cpu.r[rd] = rotr(u32, value, 8 * (address & 1)); + cpu.r[rd] = switch (Arm32.arch) { + .v4t => rotr(u32, cpu.read(u16, address), 8 * (address & 1)), + .v5te => cpu.read(u16, alignAddr(u16, address)), + }; } else { // STRH