chore(v4t,v5te): don't give SWP/SWPB its own separate handler
This commit is contained in:
		| @@ -38,10 +38,28 @@ pub fn halfAndSignedDataTransfer(comptime InstrFn: type, comptime P: bool, compt | ||||
|                         // 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); | ||||
|                     }, | ||||
|                     0b00 => unreachable, // SWP / SWPB dealt with in single_data_swap.zig | ||||
|                     0b00 => unreachable, | ||||
|                 } | ||||
|             } else { | ||||
|                 switch (op) { | ||||
|                     0b00 => { | ||||
|                         const B = I; | ||||
|                         const swap_addr = cpu.r[rn]; | ||||
|  | ||||
|                         if (B) { | ||||
|                             // SWPB | ||||
|                             const value = cpu.read(u8, swap_addr); | ||||
|                             cpu.write(u8, swap_addr, @as(u8, @truncate(cpu.r[rm]))); | ||||
|  | ||||
|                             cpu.r[rd] = value; | ||||
|                         } else { | ||||
|                             // SWP | ||||
|                             const value = rotr(u32, cpu.read(u32, swap_addr), 8 * (swap_addr & 0x3)); | ||||
|                             cpu.write(u32, swap_addr, cpu.r[rm]); | ||||
|  | ||||
|                             cpu.r[rd] = value; | ||||
|                         } | ||||
|                     }, | ||||
|                     0b01 => { | ||||
|                         // STRH | ||||
|  | ||||
| @@ -76,7 +94,6 @@ pub fn halfAndSignedDataTransfer(comptime InstrFn: type, comptime P: bool, compt | ||||
|                         cpu.write(u32, address, cpu.r[rd]); | ||||
|                         cpu.write(u32, address + 4, cpu.r[rd + 1]); | ||||
|                     }, | ||||
|                     else => unreachable, | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|   | ||||
| @@ -1,29 +0,0 @@ | ||||
| const rotr = @import("zba-util").rotr; | ||||
|  | ||||
| pub fn singleDataSwap(comptime InstrFn: type, comptime B: bool) InstrFn { | ||||
|     const Arm32 = @typeInfo(@typeInfo(@typeInfo(InstrFn).Pointer.child).Fn.params[0].type.?).Pointer.child; | ||||
|  | ||||
|     return struct { | ||||
|         fn inner(cpu: *Arm32, opcode: u32) void { | ||||
|             const rn = opcode >> 16 & 0xF; | ||||
|             const rd = opcode >> 12 & 0xF; | ||||
|             const rm = opcode & 0xF; | ||||
|  | ||||
|             const address = cpu.r[rn]; | ||||
|  | ||||
|             if (B) { | ||||
|                 // SWPB | ||||
|                 const value = cpu.read(u8, address); | ||||
|  | ||||
|                 // FIXME: I shouldn't have to use @as(u8, ...) here | ||||
|                 cpu.write(u8, address, @as(u8, @truncate(cpu.r[rm]))); | ||||
|                 cpu.r[rd] = value; | ||||
|             } else { | ||||
|                 // SWP | ||||
|                 const value = rotr(u32, cpu.read(u32, address), 8 * (address & 0x3)); | ||||
|                 cpu.write(u32, address, cpu.r[rm]); | ||||
|                 cpu.r[rd] = value; | ||||
|             } | ||||
|         } | ||||
|     }.inner; | ||||
| } | ||||
| @@ -6,18 +6,19 @@ pub const arm = struct { | ||||
|  | ||||
|     const processing = @import("cpu/arm/data_processing.zig").dataProcessing; | ||||
|     const transfer = @import("cpu/arm/single_data_transfer.zig").singleDataTransfer; | ||||
|     const halfSignedTransfer = @import("cpu/arm/half_signed_data_transfer.zig").halfAndSignedDataTransfer; | ||||
|     const blockTransfer = @import("cpu/arm/block_data_transfer.zig").blockDataTransfer; | ||||
|     const branch = @import("cpu/arm/branch.zig").branch; | ||||
|     const branchExchange = @import("cpu/arm/branch.zig").branchAndExchange; | ||||
|     const swi = @import("cpu/arm/software_interrupt.zig").armSoftwareInterrupt; | ||||
|     const swap = @import("cpu/arm/single_data_swap.zig").singleDataSwap; | ||||
|  | ||||
|     // Control Instruction Extension Space | ||||
|     const control = @import("cpu/arm/psr_transfer.zig").control; | ||||
|     /// Load Store Instruction Extention Space | ||||
|     const loadStoreExt = @import("cpu/arm/half_signed_data_transfer.zig").halfAndSignedDataTransfer; | ||||
|  | ||||
|     /// Control Instruction Extension Space | ||||
|     const controlExt = @import("cpu/arm/psr_transfer.zig").control; | ||||
|  | ||||
|     /// Arithmetic Instruction Extension Space | ||||
|     const multiply = @import("cpu/arm/multiply.zig").multiply; | ||||
|     const multiplyExt = @import("cpu/arm/multiply.zig").multiply; | ||||
|  | ||||
|     /// Determine index into ARM InstrFn LUT | ||||
|     pub fn idx(opcode: u32) u12 { | ||||
| @@ -38,33 +39,30 @@ pub const arm = struct { | ||||
|  | ||||
|             for (&table, 0..) |*handler, i| { | ||||
|                 handler.* = switch (@as(u2, i >> 10)) { | ||||
|                     0b00 => if (i == 0x121) blk: { | ||||
|                     0b00 => if (i == 0x121) blk: { // 12 bits | ||||
|                         break :blk branchExchange(InstrFn); | ||||
|                     } else if (i & 0xFBF == 0x109) blk: { | ||||
|                         const B = i >> 6 & 1 == 1; | ||||
|                         break :blk swap(InstrFn, B); | ||||
|                     } else if (i & 0xF0F == 0x009) blk: { | ||||
|                     } else if (i & 0xF0F == 0x009) blk: { // 8 bits | ||||
|                         const L = i >> 7 & 1 == 1; | ||||
|                         const U = i >> 6 & 1 == 1; | ||||
|                         const A = i >> 5 & 1 == 1; | ||||
|                         const S = i >> 4 & 1 == 1; | ||||
|                         break :blk multiply(InstrFn, L, U, A, S); | ||||
|                     } else if (i & 0xE49 == 0x009 or i & 0xE49 == 0x049) blk: { | ||||
|                         break :blk multiplyExt(InstrFn, L, U, A, S); | ||||
|                     } else if (i & 0xE49 == 0x009 or i & 0xE49 == 0x049) blk: { // 6 bits | ||||
|                         const P = i >> 8 & 1 == 1; | ||||
|                         const U = i >> 7 & 1 == 1; | ||||
|                         const I = i >> 6 & 1 == 1; | ||||
|                         const W = i >> 5 & 1 == 1; | ||||
|                         const L = i >> 4 & 1 == 1; | ||||
|                         break :blk halfSignedTransfer(InstrFn, P, U, I, W, L); | ||||
|                     } else if (i & 0xD90 == 0x100) blk: { | ||||
|                         break :blk loadStoreExt(InstrFn, P, U, I, W, L); | ||||
|                     } else if (i & 0xD90 == 0x100) blk: { // 5 bits | ||||
|                         const I = i >> 9 & 1 == 1; | ||||
|                         const op = ((i >> 5) & 0x3) << 4 | (i & 0xF); | ||||
|                         break :blk control(InstrFn, I, op); | ||||
|                         break :blk controlExt(InstrFn, I, op); | ||||
|                     } else blk: { | ||||
|                         const I = i >> 9 & 1 == 1; | ||||
|                         const S = i >> 4 & 1 == 1; | ||||
|                         const instrKind = i >> 5 & 0xF; | ||||
|                         break :blk processing(InstrFn, I, S, instrKind); | ||||
|                         const instr_kind = i >> 5 & 0xF; | ||||
|                         break :blk processing(InstrFn, I, S, instr_kind); | ||||
|                     }, | ||||
|                     0b01 => if (i >> 9 & 1 == 1 and i & 1 == 1) und else blk: { | ||||
|                         const I = i >> 9 & 1 == 1; | ||||
|   | ||||
| @@ -6,18 +6,19 @@ pub const arm = struct { | ||||
|  | ||||
|     const processing = @import("cpu/arm/data_processing.zig").dataProcessing; | ||||
|     const transfer = @import("cpu/arm/single_data_transfer.zig").singleDataTransfer; | ||||
|     const halfSignedTransfer = @import("cpu/arm/half_signed_data_transfer.zig").halfAndSignedDataTransfer; | ||||
|     const blockTransfer = @import("cpu/arm/block_data_transfer.zig").blockDataTransfer; | ||||
|     const branch = @import("cpu/arm/branch.zig").branch; | ||||
|     const branchExchange = @import("cpu/arm/branch.zig").branchAndExchange; | ||||
|     const swi = @import("cpu/arm/software_interrupt.zig").armSoftwareInterrupt; | ||||
|     const swap = @import("cpu/arm/single_data_swap.zig").singleDataSwap; | ||||
|  | ||||
|     // Control Instruction Extension Space | ||||
|     const control = @import("cpu/arm/psr_transfer.zig").control; | ||||
|     /// Load Store Instruction Extention Space | ||||
|     const loadStoreExt = @import("cpu/arm/half_signed_data_transfer.zig").halfAndSignedDataTransfer; | ||||
|  | ||||
|     // Arithmetic Instruction Extension Space | ||||
|     const multiply = @import("cpu/arm/multiply.zig").multiply; | ||||
|     /// Control Instruction Extension Space | ||||
|     const controlExt = @import("cpu/arm/psr_transfer.zig").control; | ||||
|  | ||||
|     /// Arithmetic Instruction Extension Space | ||||
|     const multiplyExt = @import("cpu/arm/multiply.zig").multiply; | ||||
|  | ||||
|     const cop = @import("cpu/arm/coprocessor.zig"); | ||||
|  | ||||
| @@ -42,31 +43,28 @@ pub const arm = struct { | ||||
|                 handler.* = switch (@as(u2, i >> 10)) { | ||||
|                     0b00 => if (i == 0x121) blk: { // 12 bits | ||||
|                         break :blk branchExchange(InstrFn); | ||||
|                     } else if (i & 0xFBF == 0x109) blk: { // 11 bits | ||||
|                         const B = i >> 6 & 1 == 1; | ||||
|                         break :blk swap(InstrFn, B); | ||||
|                     } else if (i & 0xF0F == 0x009) blk: { // 8 bits | ||||
|                         const L = i >> 7 & 1 == 1; | ||||
|                         const U = i >> 6 & 1 == 1; | ||||
|                         const A = i >> 5 & 1 == 1; | ||||
|                         const S = i >> 4 & 1 == 1; | ||||
|                         break :blk multiply(InstrFn, L, U, A, S); | ||||
|                         break :blk multiplyExt(InstrFn, L, U, A, S); | ||||
|                     } else if (i & 0xE49 == 0x009 or i & 0xE49 == 0x049) blk: { // 6 bits | ||||
|                         const P = i >> 8 & 1 == 1; | ||||
|                         const U = i >> 7 & 1 == 1; | ||||
|                         const I = i >> 6 & 1 == 1; | ||||
|                         const W = i >> 5 & 1 == 1; | ||||
|                         const L = i >> 4 & 1 == 1; | ||||
|                         break :blk halfSignedTransfer(InstrFn, P, U, I, W, L); | ||||
|                         break :blk loadStoreExt(InstrFn, P, U, I, W, L); | ||||
|                     } else if (i & 0xD90 == 0x100) blk: { // 6 bits | ||||
|                         const I = i >> 9 & 1 == 1; | ||||
|                         const op = ((i >> 5) & 0x3) << 4 | (i & 0xF); | ||||
|                         break :blk control(InstrFn, I, op); | ||||
|                         break :blk controlExt(InstrFn, I, op); | ||||
|                     } else blk: { | ||||
|                         const I = i >> 9 & 1 == 1; | ||||
|                         const S = i >> 4 & 1 == 1; | ||||
|                         const instrKind = i >> 5 & 0xF; | ||||
|                         break :blk processing(InstrFn, I, S, instrKind); | ||||
|                         const instr_kind = i >> 5 & 0xF; | ||||
|                         break :blk processing(InstrFn, I, S, instr_kind); | ||||
|                     }, | ||||
|                     0b01 => if (i >> 9 & 1 == 1 and i & 1 == 1) und else blk: { | ||||
|                         const I = i >> 9 & 1 == 1; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user