Skip to content

Commit

Permalink
Remove allocations from instruction fetchers
Browse files Browse the repository at this point in the history
  • Loading branch information
twvd committed Dec 16, 2023
1 parent 1e9a4ff commit be6dccb
Show file tree
Hide file tree
Showing 6 changed files with 25 additions and 9 deletions.
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ default-run = "siena"

[dependencies]
anyhow = { version = "1.0.75", features = ["backtrace"] }
arrayvec = "0.7.4"
clap = { version = "4.4.6", features = ["derive"] }
colored = "2.0.4"
dbg_hex = "0.1.1"
Expand Down
5 changes: 3 additions & 2 deletions src/snes/cpu_65816/cpu.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use anyhow::Result;
use arrayvec::ArrayVec;
use num_traits::ToPrimitive;
use serde::{Deserialize, Serialize};

use crate::snes::bus::{Address, Bus, BusIterator, ADDRESS_MASK};
use crate::tickable::Ticks;

use super::alu;
use super::instruction::{AddressingMode, Instruction, InstructionType};
use super::instruction::{AddressingMode, Instruction, InstructionType, MAX_INSTRUCTION_LEN};
use super::regs::{Flag, Register, RegisterFile, RegisterWidth};

/// Main SNES CPU (65816)
Expand Down Expand Up @@ -62,7 +63,7 @@ where

/// Fetches and decodes the next instruction at PC
pub fn fetch_next_instr(&mut self) -> Result<Instruction> {
let mut fetched: Vec<u8> = vec![];
let mut fetched: ArrayVec<u8, MAX_INSTRUCTION_LEN> = ArrayVec::new();

for p in 0.. {
let pc = (self.regs.k as Address) << 16 | self.regs.pc.wrapping_add(p) as Address;
Expand Down
9 changes: 6 additions & 3 deletions src/snes/cpu_65816/instruction.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
use std::fmt;

use anyhow::Result;
use arrayvec::ArrayVec;
use thiserror::Error;

use super::instruction_table::INSTRUCTION_TABLE;

pub const MAX_INSTRUCTION_LEN: usize = 4;

/// Instruction addressing mode
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum AddressingMode {
Expand Down Expand Up @@ -257,7 +260,7 @@ pub struct Instruction {
pub immediate: [u32; 2],

/// Raw bytes
pub raw: Vec<u8>,
pub raw: ArrayVec<u8, MAX_INSTRUCTION_LEN>,

/// Instruction length
pub len: usize,
Expand All @@ -266,7 +269,7 @@ pub struct Instruction {
impl Instruction {
/// Try to decode a single instruction from an iterator.
pub fn decode(stream: &mut impl Iterator<Item = u8>, m: bool, x: bool) -> Result<Instruction> {
let mut raw: Vec<u8> = vec![];
let mut raw: ArrayVec<u8, MAX_INSTRUCTION_LEN> = ArrayVec::new();
let mut rd = || -> Result<u8> {
let b = stream.next().ok_or(DecodeErr::EndOfStream)?;
raw.push(b);
Expand All @@ -275,7 +278,7 @@ impl Instruction {

let opcode = rd()?;
let def = &INSTRUCTION_TABLE[opcode as usize];
let mut args = [0; 4];
let mut args = [0; MAX_INSTRUCTION_LEN];
let len = def.mode.get_fetch_len(m, x);
for i in 0..(len - 1) {
args[i] = rd()?;
Expand Down
5 changes: 3 additions & 2 deletions src/snes/cpu_spc700/cpu.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use anyhow::Result;
use arrayvec::ArrayVec;
use serde::{Deserialize, Serialize};

use crate::snes::bus::{Bus, BusIterator};
use crate::tickable::Ticks;

use super::instruction::{Instruction, InstructionType, Operand};
use super::instruction::{Instruction, InstructionType, Operand, MAX_INSTRUCTION_LEN};
use super::regs::{Flag, Register, RegisterFile};

pub type SpcAddress = u16;
Expand Down Expand Up @@ -47,7 +48,7 @@ where

/// Fetches and decodes the next instruction at PC
pub fn fetch_next_instr(&mut self) -> Result<Instruction> {
let mut fetched: Vec<u8> = vec![];
let mut fetched: ArrayVec<u8, MAX_INSTRUCTION_LEN> = ArrayVec::new();

for i in 0.. {
let pc = self.regs.pc as SpcAddress;
Expand Down
7 changes: 5 additions & 2 deletions src/snes/cpu_spc700/instruction.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
use std::fmt;

use anyhow::Result;
use arrayvec::ArrayVec;
use thiserror::Error;

use super::instruction_table::INSTRUCTION_TABLE;
use super::regs::Register;

pub const MAX_INSTRUCTION_LEN: usize = 3;

/// Instruction operands
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum Operand {
Expand Down Expand Up @@ -135,7 +138,7 @@ pub struct Instruction {
pub immediate: [u8; 2],

/// Raw bytes
pub raw: Vec<u8>,
pub raw: ArrayVec<u8, MAX_INSTRUCTION_LEN>,

/// Instruction length
pub len: usize,
Expand All @@ -144,7 +147,7 @@ pub struct Instruction {
impl Instruction {
/// Try to decode a single instruction from an iterator.
pub fn decode(stream: &mut impl Iterator<Item = u8>) -> Result<Instruction> {
let mut raw: Vec<u8> = vec![];
let mut raw: ArrayVec<u8, MAX_INSTRUCTION_LEN> = ArrayVec::new();
let mut rd = || -> Result<u8> {
let b = stream.next().ok_or(DecodeErr::EndOfStream)?;
raw.push(b);
Expand Down

0 comments on commit be6dccb

Please sign in to comment.