Compare commits

..

1 Commits

Author SHA1 Message Date
Rekai Nyangadzayi Musuka 9cee377fc5 chore: update dependencies 2023-07-10 22:06:02 -05:00
14 changed files with 38 additions and 57 deletions

View File

@ -3,7 +3,7 @@
.version = "0.1.0", .version = "0.1.0",
.dependencies = .{ .dependencies = .{
.@"zba-util" = .{ .@"zba-util" = .{
.url = "https://git.musuka.dev/paoda/zba-util/archive/322c798e384a0d24cc84ffcfa2e4a3ca807798a0.tar.gz", .url = "https://git.musuka.dev/paoda/zba-util/archive/8b09efb522c2fa4bb34e754697cb1c47b32b1274.tar.gz",
.hash = "12209ce0e729460b997706e47a53a32f1842672cd120189e612f4871731780a30ed0", .hash = "12209ce0e729460b997706e47a53a32f1842672cd120189e612f4871731780a30ed0",
}, },
}, },

View File

@ -58,7 +58,6 @@ pub fn Arm32(comptime arch: Architecture) type {
return self.stage[0] != null and self.stage[1] != null; return self.stage[0] != null and self.stage[1] != null;
} }
// TODO: Why does this not return T?
pub fn step(self: *@This(), cpu: *Self, comptime T: type) ?u32 { pub fn step(self: *@This(), cpu: *Self, comptime T: type) ?u32 {
comptime std.debug.assert(T == u32 or T == u16); comptime std.debug.assert(T == u32 or T == u16);
@ -175,7 +174,7 @@ pub fn Arm32(comptime arch: Architecture) type {
} }
pub fn setCpsr(self: *Self, value: u32) void { pub fn setCpsr(self: *Self, value: u32) void {
if (value & 0x1F != self.cpsr.raw & 0x1F) self.changeModeFromIdx(@truncate(value & 0x1F)); if (value & 0x1F != self.cpsr.raw & 0x1F) self.changeModeFromIdx(@as(u5, @truncate(value & 0x1F)));
self.cpsr.raw = value; self.cpsr.raw = value;
} }
@ -268,12 +267,12 @@ pub fn Arm32(comptime arch: Architecture) type {
} }
if (self.cpsr.t.read()) { if (self.cpsr.t.read()) {
const opcode: u16 = @truncate(self.pipe.step(self, u16) orelse return); const opcode = @as(u16, @truncate(self.pipe.step(self, u16) orelse return));
thumb.lut[thumb.idx(opcode)](self, self.bus, opcode); thumb.lut[thumb.idx(opcode)](self, self.bus, opcode);
} else { } else {
const opcode = self.pipe.step(self, u32) orelse return; const opcode = self.pipe.step(self, u32) orelse return;
if (self.cpsr.check(@truncate(opcode >> 28))) { if (self.cpsr.check(@as(u4, @truncate(opcode >> 28)))) {
arm.lut[arm.idx(opcode)](self, self.bus, opcode); arm.lut[arm.idx(opcode)](self, self.bus, opcode);
} }
} }
@ -392,7 +391,7 @@ pub const PSR = extern union {
} }
pub inline fn check(self: @This(), cond: u4) bool { pub inline fn check(self: @This(), cond: u4) bool {
const flags: u4 = @truncate(self.raw >> 28); const flags = @as(u4, @truncate(self.raw >> 28));
return condition_lut[cond] & (@as(u16, 1) << flags) != 0; return condition_lut[cond] & (@as(u16, 1) << flags) != 0;
} }

View File

@ -5,7 +5,7 @@ pub fn blockDataTransfer(comptime InstrFn: type, comptime P: bool, comptime U: b
return struct { return struct {
fn inner(cpu: Arm32, bus: Bus, opcode: u32) void { fn inner(cpu: Arm32, bus: Bus, opcode: u32) void {
const rn: u4 = @truncate(opcode >> 16 & 0xF); const rn = @as(u4, @truncate(opcode >> 16 & 0xF));
const rlist = opcode & 0xFFFF; const rlist = opcode & 0xFFFF;
const r15 = rlist >> 15 & 1 == 1; const r15 = rlist >> 15 & 1 == 1;
@ -15,7 +15,7 @@ pub fn blockDataTransfer(comptime InstrFn: type, comptime P: bool, comptime U: b
var write_to_base = true; var write_to_base = true;
while (i < 16) : (i += 1) { while (i < 16) : (i += 1) {
const r: u4 = @truncate(15 - i); const r = @as(u4, @truncate(15 - i));
if (rlist >> r & 1 == 1) { if (rlist >> r & 1 == 1) {
first = r; first = r;
count += 1; count += 1;

View File

@ -8,7 +8,7 @@ pub fn dataProcessing(comptime InstrFn: type, comptime I: bool, comptime S: bool
return struct { return struct {
fn inner(cpu: Arm32, _: Bus, opcode: u32) void { fn inner(cpu: Arm32, _: Bus, opcode: u32) void {
const rd: u4 = @truncate(opcode >> 12 & 0xF); const rd = @as(u4, @truncate(opcode >> 12 & 0xF));
const rn = opcode >> 16 & 0xF; const rn = opcode >> 16 & 0xF;
const old_carry = @intFromBool(cpu.cpsr.c.read()); const old_carry = @intFromBool(cpu.cpsr.c.read());
@ -17,7 +17,7 @@ pub fn dataProcessing(comptime InstrFn: type, comptime I: bool, comptime S: bool
if (!I and opcode >> 4 & 1 == 1) cpu.r[15] += 4; if (!I and opcode >> 4 & 1 == 1) cpu.r[15] += 4;
const op1 = cpu.r[rn]; const op1 = cpu.r[rn];
const amount: u8 = @truncate((opcode >> 8 & 0xF) << 1); const amount = @as(u8, @truncate((opcode >> 8 & 0xF) << 1));
const op2 = if (I) ror(S, &cpu.cpsr, opcode & 0xFF, amount) else exec(S, cpu, opcode); const op2 = if (I) ror(S, &cpu.cpsr, opcode & 0xFF, amount) else exec(S, cpu, opcode);
// Undo special condition from above // Undo special condition from above
@ -164,7 +164,9 @@ pub fn dataProcessing(comptime InstrFn: type, comptime I: bool, comptime S: bool
pub fn sbc(left: u32, right: u32, old_carry: u1) u32 { pub fn sbc(left: u32, right: u32, old_carry: u1) u32 {
// TODO: Make your own version (thanks peach.bot) // TODO: Make your own version (thanks peach.bot)
const subtrahend = @as(u64, right) -% old_carry +% 1; const subtrahend = @as(u64, right) -% old_carry +% 1;
return @truncate(left -% subtrahend); const ret = @as(u32, @truncate(left -% subtrahend));
return ret;
} }
pub fn add(overflow: *u1, left: u32, right: u32) u32 { pub fn add(overflow: *u1, left: u32, right: u32) u32 {

View File

@ -34,8 +34,6 @@ pub fn halfAndSignedDataTransfer(comptime InstrFn: type, comptime P: bool, compt
0b11 => { 0b11 => {
// LDRSH // LDRSH
const value = bus.read(u16, address); const value = bus.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); result = if (address & 1 == 1) sext(u32, u8, @as(u8, @truncate(value >> 8))) else sext(u32, u16, value);
}, },
0b00 => unreachable, // SWP 0b00 => unreachable, // SWP
@ -43,8 +41,6 @@ pub fn halfAndSignedDataTransfer(comptime InstrFn: type, comptime P: bool, compt
} else { } else {
if (opcode >> 5 & 0x01 == 0x01) { if (opcode >> 5 & 0x01 == 0x01) {
// STRH // STRH
// FIXME: I shouldn't have to use @as(u8, ...) here
bus.write(u16, address, @as(u16, @truncate(cpu.r[rd]))); bus.write(u16, address, @as(u16, @truncate(cpu.r[rd])));
} else unreachable; // SWP } else unreachable; // SWP
} }

View File

@ -11,7 +11,7 @@ pub fn multiply(comptime InstrFn: type, comptime A: bool, comptime S: bool) Inst
const rm = opcode & 0xF; const rm = opcode & 0xF;
const temp: u64 = @as(u64, cpu.r[rm]) * @as(u64, cpu.r[rs]) + if (A) cpu.r[rn] else 0; const temp: u64 = @as(u64, cpu.r[rm]) * @as(u64, cpu.r[rs]) + if (A) cpu.r[rn] else 0;
const result: u32 = @truncate(temp); const result = @as(u32, @truncate(temp));
cpu.r[rd] = result; cpu.r[rd] = result;
if (S) { if (S) {
@ -36,17 +36,17 @@ pub fn multiplyLong(comptime InstrFn: type, comptime U: bool, comptime A: bool,
if (U) { if (U) {
// Signed (WHY IS IT U THEN?) // Signed (WHY IS IT U THEN?)
var result: i64 = @as(i64, @as(i32, @bitCast(cpu.r[rm]))) * @as(i64, @as(i32, @bitCast(cpu.r[rs]))); var result: i64 = @as(i64, @as(i32, @bitCast(cpu.r[rm]))) * @as(i64, @as(i32, @bitCast(cpu.r[rs])));
if (A) result +%= @bitCast(@as(u64, cpu.r[rd_hi]) << 32 | @as(u64, cpu.r[rd_lo])); if (A) result +%= @as(i64, @bitCast(@as(u64, cpu.r[rd_hi]) << 32 | @as(u64, cpu.r[rd_lo])));
cpu.r[rd_hi] = @bitCast(@as(i32, @truncate(result >> 32))); cpu.r[rd_hi] = @as(u32, @bitCast(@as(i32, @truncate(result >> 32))));
cpu.r[rd_lo] = @bitCast(@as(i32, @truncate(result))); cpu.r[rd_lo] = @as(u32, @bitCast(@as(i32, @truncate(result))));
} else { } else {
// Unsigned // Unsigned
var result: u64 = @as(u64, cpu.r[rm]) * @as(u64, cpu.r[rs]); var result: u64 = @as(u64, cpu.r[rm]) * @as(u64, cpu.r[rs]);
if (A) result +%= @as(u64, cpu.r[rd_hi]) << 32 | @as(u64, cpu.r[rd_lo]); if (A) result +%= @as(u64, cpu.r[rd_hi]) << 32 | @as(u64, cpu.r[rd_lo]);
cpu.r[rd_hi] = @truncate(result >> 32); cpu.r[rd_hi] = @as(u32, @truncate(result >> 32));
cpu.r[rd_lo] = @truncate(result); cpu.r[rd_lo] = @as(u32, @truncate(result));
} }
if (S) { if (S) {

View File

@ -22,7 +22,7 @@ pub fn psrTransfer(comptime InstrFn: type, comptime I: bool, comptime R: bool, c
}, },
0b10 => { 0b10 => {
// MSR // MSR
const field_mask: u4 = @truncate(opcode >> 16 & 0xF); const field_mask = @as(u4, @truncate(opcode >> 16 & 0xF));
const rm_idx = opcode & 0xF; const rm_idx = opcode & 0xF;
const right = if (I) rotr(u32, opcode & 0xFF, (opcode >> 8 & 0xF) * 2) else cpu.r[rm_idx]; const right = if (I) rotr(u32, opcode & 0xFF, (opcode >> 8 & 0xF) * 2) else cpu.r[rm_idx];
@ -46,7 +46,7 @@ pub fn psrTransfer(comptime InstrFn: type, comptime I: bool, comptime R: bool, c
fn fieldMask(psr: *const PSR, field_mask: u4, right: u32) u32 { fn fieldMask(psr: *const PSR, field_mask: u4, right: u32) u32 {
// This bitwise ORs bits 3 and 0 of the field mask into a u2 // This bitwise ORs bits 3 and 0 of the field mask into a u2
// We do this because we only care about bits 7:0 and 31:28 of the CPSR // We do this because we only care about bits 7:0 and 31:28 of the CPSR
const bits: u2 = @truncate((field_mask >> 2 & 0x2) | (field_mask & 1)); const bits = @as(u2, @truncate((field_mask >> 2 & 0x2) | (field_mask & 1)));
const mask: u32 = switch (bits) { const mask: u32 = switch (bits) {
0b00 => 0x0000_0000, 0b00 => 0x0000_0000,

View File

@ -16,8 +16,6 @@ pub fn singleDataSwap(comptime InstrFn: type, comptime B: bool) InstrFn {
if (B) { if (B) {
// SWPB // SWPB
const value = bus.read(u8, address); const value = bus.read(u8, address);
// FIXME: I shouldn't have to use @as(u8, ...) here
bus.write(u8, address, @as(u8, @truncate(cpu.r[rm]))); bus.write(u8, address, @as(u8, @truncate(cpu.r[rm])));
cpu.r[rd] = value; cpu.r[rd] = value;
} else { } else {

View File

@ -31,8 +31,6 @@ pub fn singleDataTransfer(comptime InstrFn: type, comptime I: bool, comptime P:
if (B) { if (B) {
// STRB // STRB
const value = cpu.r[rd] + if (rd == 0xF) 4 else @as(u32, 0); // PC is 12 ahead const value = cpu.r[rd] + if (rd == 0xF) 4 else @as(u32, 0); // PC is 12 ahead
// FIXME: I shouldn't have to use @as(u8, ...) here
bus.write(u8, address, @as(u8, @truncate(value))); bus.write(u8, address, @as(u8, @truncate(value)));
} else { } else {
// STR // STR

View File

@ -16,7 +16,7 @@ pub fn exec(comptime S: bool, cpu: anytype, opcode: u32) u32 {
fn register(comptime S: bool, cpu: anytype, opcode: u32) u32 { fn register(comptime S: bool, cpu: anytype, opcode: u32) u32 {
const rs_idx = opcode >> 8 & 0xF; const rs_idx = opcode >> 8 & 0xF;
const rm = cpu.r[opcode & 0xF]; const rm = cpu.r[opcode & 0xF];
const rs: u8 = @truncate(cpu.r[rs_idx]); const rs = @as(u8, @truncate(cpu.r[rs_idx]));
return switch (@as(u2, @truncate(opcode >> 5))) { return switch (@as(u2, @truncate(opcode >> 5))) {
0b00 => lsl(S, &cpu.cpsr, rm, rs), 0b00 => lsl(S, &cpu.cpsr, rm, rs),
@ -27,10 +27,9 @@ fn register(comptime S: bool, cpu: anytype, opcode: u32) u32 {
} }
pub fn immediate(comptime S: bool, cpu: anytype, opcode: u32) u32 { pub fn immediate(comptime S: bool, cpu: anytype, opcode: u32) u32 {
const amount: u8 = @truncate(opcode >> 7 & 0x1F); const amount = @as(u8, @truncate(opcode >> 7 & 0x1F));
const rm = cpu.r[opcode & 0xF]; const rm = cpu.r[opcode & 0xF];
// FIXME: I don't think result needs to be mutable here
var result: u32 = undefined; var result: u32 = undefined;
if (amount == 0) { if (amount == 0) {
switch (@as(u2, @truncate(opcode >> 5))) { switch (@as(u2, @truncate(opcode >> 5))) {
@ -45,7 +44,7 @@ pub fn immediate(comptime S: bool, cpu: anytype, opcode: u32) u32 {
}, },
0b10 => { 0b10 => {
// ASR #0 aka ASR #32 // ASR #0 aka ASR #32
result = @bitCast(@as(i32, @bitCast(rm)) >> 31); result = @as(u32, @bitCast(@as(i32, @bitCast(rm)) >> 31));
if (S) cpu.cpsr.c.write(result >> 31 & 1 == 1); if (S) cpu.cpsr.c.write(result >> 31 & 1 == 1);
}, },
0b11 => { 0b11 => {
@ -69,7 +68,7 @@ pub fn immediate(comptime S: bool, cpu: anytype, opcode: u32) u32 {
} }
pub fn lsl(comptime S: bool, cpsr: *CPSR, rm: u32, total_amount: u8) u32 { pub fn lsl(comptime S: bool, cpsr: *CPSR, rm: u32, total_amount: u8) u32 {
const amount: u5 = @truncate(total_amount); const amount = @as(u5, @truncate(total_amount));
const bit_count: u8 = @typeInfo(u32).Int.bits; const bit_count: u8 = @typeInfo(u32).Int.bits;
var result: u32 = 0x0000_0000; var result: u32 = 0x0000_0000;
@ -78,7 +77,7 @@ pub fn lsl(comptime S: bool, cpsr: *CPSR, rm: u32, total_amount: u8) u32 {
result = rm << amount; result = rm << amount;
if (S and total_amount != 0) { if (S and total_amount != 0) {
const carry_bit: u5 = @truncate(bit_count - amount); const carry_bit = @as(u5, @truncate(bit_count - amount));
cpsr.c.write(rm >> carry_bit & 1 == 1); cpsr.c.write(rm >> carry_bit & 1 == 1);
} }
} else { } else {
@ -96,7 +95,7 @@ pub fn lsl(comptime S: bool, cpsr: *CPSR, rm: u32, total_amount: u8) u32 {
} }
pub fn lsr(comptime S: bool, cpsr: *CPSR, rm: u32, total_amount: u32) u32 { pub fn lsr(comptime S: bool, cpsr: *CPSR, rm: u32, total_amount: u32) u32 {
const amount: u5 = @truncate(total_amount); const amount = @as(u5, @truncate(total_amount));
const bit_count: u8 = @typeInfo(u32).Int.bits; const bit_count: u8 = @typeInfo(u32).Int.bits;
var result: u32 = 0x0000_0000; var result: u32 = 0x0000_0000;
@ -120,16 +119,16 @@ pub fn lsr(comptime S: bool, cpsr: *CPSR, rm: u32, total_amount: u32) u32 {
} }
pub fn asr(comptime S: bool, cpsr: *CPSR, rm: u32, total_amount: u8) u32 { pub fn asr(comptime S: bool, cpsr: *CPSR, rm: u32, total_amount: u8) u32 {
const amount: u5 = @truncate(total_amount); const amount = @as(u5, @truncate(total_amount));
const bit_count: u8 = @typeInfo(u32).Int.bits; const bit_count: u8 = @typeInfo(u32).Int.bits;
var result: u32 = 0x0000_0000; var result: u32 = 0x0000_0000;
if (total_amount < bit_count) { if (total_amount < bit_count) {
result = @bitCast(@as(i32, @bitCast(rm)) >> amount); result = @as(u32, @bitCast(@as(i32, @bitCast(rm)) >> amount));
if (S and total_amount != 0) cpsr.c.write(rm >> (amount - 1) & 1 == 1); if (S and total_amount != 0) cpsr.c.write(rm >> (amount - 1) & 1 == 1);
} else { } else {
// ASR #32 and ASR #>32 have the same result // ASR #32 and ASR #>32 have the same result
result = @bitCast(@as(i32, @bitCast(rm)) >> 31); result = @as(u32, @bitCast(@as(i32, @bitCast(rm)) >> 31));
if (S) cpsr.c.write(result >> 31 & 1 == 1); if (S) cpsr.c.write(result >> 31 & 1 == 1);
} }

View File

@ -26,12 +26,12 @@ pub fn fmt4(comptime InstrFn: type, comptime op: u4) InstrFn {
switch (op) { switch (op) {
0x0 => result = op1 & op2, // AND 0x0 => result = op1 & op2, // AND
0x1 => result = op1 ^ op2, // EOR 0x1 => result = op1 ^ op2, // EOR
0x2 => result = lsl(true, &cpu.cpsr, op1, @truncate(op2)), // LSL 0x2 => result = lsl(true, &cpu.cpsr, op1, @as(u8, @truncate(op2))), // LSL
0x3 => result = lsr(true, &cpu.cpsr, op1, @truncate(op2)), // LSR 0x3 => result = lsr(true, &cpu.cpsr, op1, @as(u8, @truncate(op2))), // LSR
0x4 => result = asr(true, &cpu.cpsr, op1, @truncate(op2)), // ASR 0x4 => result = asr(true, &cpu.cpsr, op1, @as(u8, @truncate(op2))), // ASR
0x5 => result = adc(&overflow, op1, op2, carry), // ADC 0x5 => result = adc(&overflow, op1, op2, carry), // ADC
0x6 => result = sbc(op1, op2, carry), // SBC 0x6 => result = sbc(op1, op2, carry), // SBC
0x7 => result = ror(true, &cpu.cpsr, op1, @truncate(op2)), // ROR 0x7 => result = ror(true, &cpu.cpsr, op1, @as(u8, @truncate(op2))), // ROR
0x8 => result = op1 & op2, // TST 0x8 => result = op1 & op2, // TST
0x9 => result = 0 -% op2, // NEG 0x9 => result = 0 -% op2, // NEG
0xA => result = op1 -% op2, // CMP 0xA => result = op1 -% op2, // CMP
@ -42,7 +42,7 @@ pub fn fmt4(comptime InstrFn: type, comptime op: u4) InstrFn {
overflow = tmp[1]; overflow = tmp[1];
}, },
0xC => result = op1 | op2, // ORR 0xC => result = op1 | op2, // ORR
0xD => result = @truncate(@as(u64, op2) * @as(u64, op1)), 0xD => result = @as(u32, @truncate(@as(u64, op2) * @as(u64, op1))),
0xE => result = op1 & ~op2, 0xE => result = op1 & ~op2,
0xF => result = ~op2, 0xF => result = ~op2,
} }

View File

@ -14,7 +14,7 @@ pub fn fmt1(comptime InstrFn: type, comptime op: u2, comptime offset: u5) InstrF
const rs = opcode >> 3 & 0x7; const rs = opcode >> 3 & 0x7;
const rd = opcode & 0x7; const rd = opcode & 0x7;
const result: u32 = switch (op) { const result = switch (op) {
0b00 => blk: { 0b00 => blk: {
// LSL // LSL
if (offset == 0) { if (offset == 0) {
@ -36,7 +36,7 @@ pub fn fmt1(comptime InstrFn: type, comptime op: u2, comptime offset: u5) InstrF
// ASR // ASR
if (offset == 0) { if (offset == 0) {
cpu.cpsr.c.write(cpu.r[rs] >> 31 & 1 == 1); cpu.cpsr.c.write(cpu.r[rs] >> 31 & 1 == 1);
break :blk @bitCast(@as(i32, @bitCast(cpu.r[rs])) >> 31); break :blk @as(u32, @bitCast(@as(i32, @bitCast(cpu.r[rs])) >> 31));
} else { } else {
break :blk asr(true, &cpu.cpsr, cpu.r[rs], offset); break :blk asr(true, &cpu.cpsr, cpu.r[rs], offset);
} }
@ -115,7 +115,7 @@ pub fn fmt2(comptime InstrFn: type, comptime I: bool, is_sub: bool, rn: u3) Inst
return struct { return struct {
fn inner(cpu: Arm32, _: Bus, opcode: u16) void { fn inner(cpu: Arm32, _: Bus, opcode: u16) void {
const rs = opcode >> 3 & 0x7; const rs = opcode >> 3 & 0x7;
const rd: u3 = @truncate(opcode); const rd = @as(u3, @truncate(opcode));
const op1 = cpu.r[rs]; const op1 = cpu.r[rs];
const op2: u32 = if (I) rn else cpu.r[rn]; const op2: u32 = if (I) rn else cpu.r[rn];

View File

@ -33,8 +33,6 @@ pub fn fmt78(comptime InstrFn: type, comptime op: u2, comptime T: bool) InstrFn
switch (op) { switch (op) {
0b00 => { 0b00 => {
// STRH // STRH
// FIXME: I shouldn't have to use @as(u8, ...) here
bus.write(u16, address, @as(u16, @truncate(cpu.r[rd]))); bus.write(u16, address, @as(u16, @truncate(cpu.r[rd])));
}, },
0b01 => { 0b01 => {
@ -49,8 +47,6 @@ pub fn fmt78(comptime InstrFn: type, comptime op: u2, comptime T: bool) InstrFn
0b11 => { 0b11 => {
// LDRSH // LDRSH
const value = bus.read(u16, address); const value = bus.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); cpu.r[rd] = if (address & 1 == 1) sext(u32, u8, @as(u8, @truncate(value >> 8))) else sext(u32, u16, value);
}, },
} }
@ -63,8 +59,6 @@ pub fn fmt78(comptime InstrFn: type, comptime op: u2, comptime T: bool) InstrFn
}, },
0b01 => { 0b01 => {
// STRB // STRB
// FIXME: I shouldn't have to use @as(u8, ...) here
bus.write(u8, address, @as(u8, @truncate(cpu.r[rd]))); bus.write(u8, address, @as(u8, @truncate(cpu.r[rd])));
}, },
0b10 => { 0b10 => {
@ -105,8 +99,6 @@ pub fn fmt9(comptime InstrFn: type, comptime B: bool, comptime L: bool, comptime
if (B) { if (B) {
// STRB // STRB
const address = cpu.r[rb] + offset; const address = cpu.r[rb] + offset;
// FIXME: I shouldn't have to use @as(u8, ...) here
bus.write(u8, address, @as(u8, @truncate(cpu.r[rd]))); bus.write(u8, address, @as(u8, @truncate(cpu.r[rd])));
} else { } else {
// STR // STR
@ -134,8 +126,6 @@ pub fn fmt10(comptime InstrFn: type, comptime L: bool, comptime offset: u5) Inst
cpu.r[rd] = rotr(u32, value, 8 * (address & 1)); cpu.r[rd] = rotr(u32, value, 8 * (address & 1));
} else { } else {
// STRH // STRH
// FIXME: I shouldn't have to use @as(u8, ...) here
bus.write(u16, address, @as(u16, @truncate(cpu.r[rd]))); bus.write(u16, address, @as(u16, @truncate(cpu.r[rd])));
} }
} }

View File

@ -20,7 +20,6 @@ pub fn arm(comptime Arm32: type) type {
/// Determine index into ARM InstrFn LUT /// Determine index into ARM InstrFn LUT
pub fn idx(opcode: u32) u12 { pub fn idx(opcode: u32) u12 {
// FIXME: omit these?
return @as(u12, @truncate(opcode >> 20 & 0xFF)) << 4 | @as(u12, @truncate(opcode >> 4 & 0xF)); return @as(u12, @truncate(opcode >> 20 & 0xFF)) << 4 | @as(u12, @truncate(opcode >> 4 & 0xF));
} }
@ -118,7 +117,7 @@ pub fn thumb(comptime Arm32: type) type {
/// Determine index into THUMB InstrFn LUT /// Determine index into THUMB InstrFn LUT
pub fn idx(opcode: u16) u10 { pub fn idx(opcode: u16) u10 {
return @truncate(opcode >> 6); return @as(u10, @truncate(opcode >> 6));
} }
/// Undefined THUMB Instruction Handler /// Undefined THUMB Instruction Handler