Skip to content

Commit

Permalink
cleanups
Browse files Browse the repository at this point in the history
  • Loading branch information
poszu committed Jan 9, 2025
1 parent c404c64 commit 7c76746
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 156 deletions.
2 changes: 1 addition & 1 deletion core/src/disassembler/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ impl InstructionProcessor for InstructionTranspilerNew {
fn process_auipc(&mut self, dec_insn: UType) -> Self::InstructionResult {
Ok(Instruction::Auipc(
Register::try_from(dec_insn.rd)?,
dec_insn.imm,
dec_insn.imm as u32,
))
}

Expand Down
13 changes: 1 addition & 12 deletions core/src/disassembler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,11 @@ pub use elf::*;
use instruction::transpile;
use std::{collections::BTreeMap, fs::File, io::Read};

use crate::{instruction::Instruction, runtime::Program};
use crate::runtime::Program;

use athena_interface::MethodSelector;

impl Program {
pub const fn new(instructions: Vec<Instruction>, pc_start: u32, pc_base: u32) -> Self {
Self {
instructions,
symbol_table: BTreeMap::new(),
selector_table: BTreeMap::new(),
pc_start,
pc_base,
memory_image: BTreeMap::new(),
}
}

/// Disassemble an ELF to a program that be executed by the VM.
pub fn from(input: &[u8]) -> anyhow::Result<Self> {
// Check the magic number
Expand Down
2 changes: 1 addition & 1 deletion core/src/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pub enum Instruction {
/// RV32IM/RV32EM base instructions
// U-type
Lui(Register, u32), // Load Upper Immediate
Auipc(Register, i32), // Add Upper Immediate to PC
Auipc(Register, u32), // Add Upper Immediate to PC

// J-type
Jal(Register, i32), // Jump and Link
Expand Down
47 changes: 20 additions & 27 deletions core/src/runtime/mod.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
pub mod gdbstub;
pub mod hooks;
mod io;
mod opcode;
mod program;
mod register;
mod state;
mod syscall;

use anyhow::anyhow;
use athena_interface::MethodSelector;
pub use opcode::*;
pub use program::*;
pub use register::*;
pub use state::*;
Expand Down Expand Up @@ -280,7 +278,7 @@ impl<'host> Runtime<'host> {
// Add upper immediate to PC
Instruction::Auipc(rd, imm) => {
// NOTE: the immediate is already shifted left by 12
let value = self.state.pc.wrapping_add_signed(imm);
let value = self.state.pc.wrapping_add(imm);
self.rw(rd, value);
}

Expand Down Expand Up @@ -634,13 +632,11 @@ impl<'host> Runtime<'host> {
tracing::debug!("HALT: zero PC (possibly returned from a function execution");
return Ok(Some(Event::Halted));
}

let relative_pc = self.state.pc.wrapping_sub(self.program.pc_base);
let max_pc = self.program.instructions.len() as u32 * 4;
if relative_pc >= max_pc {
tracing::warn!(relative_pc, max_pc, "HALT: out of instructions");
if self.program.instruction(self.state.pc).is_none() {
tracing::warn!(pc = self.state.pc, "HALT: out of instructions");
return Ok(Some(Event::Halted));
}

Ok(None)
}

Expand Down Expand Up @@ -1057,31 +1053,28 @@ pub mod tests {
fn test_auipc() {
// Test adding different immediate values to PC
// PC starts at 0, so we can easily calculate expected results
let mut runtime = Runtime::new(Program::default(), None, AthenaCoreOpts::default(), None);

let instructions = vec![
// Add small positive immediate
Instruction::Auipc(Register::X5, 1 << 12), // 1 << 12 = 4096
// Add larger positive immediate
Instruction::Auipc(Register::X6, 0x7FF << 12), // 0x7FF << 12 = 0x7FF000
// Add maximum positive immediate
Instruction::Auipc(Register::X7, 0xFFFFF << 12), // 0xFFFFF << 12 = 0xFFFFF000
];

let program = Program::new(instructions, 0, 0);
let mut runtime = Runtime::new(program, None, AthenaCoreOpts::default(), None);
runtime.execute().unwrap();

// First AUIPC: PC = 0, imm = 1
// Expected: 0 + (1 << 12) = 4096
// First AUIPC: PC = 0, imm = 0x1000
runtime
.execute_instruction(Instruction::Auipc(Register::X5, 0x1000))
.unwrap();
assert_eq!(runtime.register(Register::X5), 4096);
assert_eq!(4, runtime.state.pc);

// Second AUIPC: PC = 4, imm = 0x7FF
// Expected: 4 + (0x7FF << 12) = 0x7FF004
// Second AUIPC: PC = 4, imm = 0x7FF000
runtime
.execute_instruction(Instruction::Auipc(Register::X6, 0x7FF000))
.unwrap();
assert_eq!(runtime.register(Register::X6), 0x7FF004);
assert_eq!(8, runtime.state.pc);

// Third AUIPC: PC = 8, imm = 0xFFFFF
// Expected: 8 + (0xFFFFF << 12) = 0xFFFFF008
// Third AUIPC: PC = 8, imm = 0xFFFFF000
runtime
.execute_instruction(Instruction::Auipc(Register::X7, 0xFFFFF000))
.unwrap();
assert_eq!(runtime.register(Register::X7), 0xFFFFF008);
assert_eq!(12, runtime.state.pc);
}

#[test]
Expand Down
113 changes: 0 additions & 113 deletions core/src/runtime/opcode.rs

This file was deleted.

15 changes: 13 additions & 2 deletions core/src/runtime/program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,19 @@ pub struct Program {
}

impl Program {
pub const fn new(instructions: Vec<Instruction>, pc_start: u32, pc_base: u32) -> Self {
Self {
instructions,
symbol_table: BTreeMap::new(),
selector_table: BTreeMap::new(),
pc_start,
pc_base,
memory_image: BTreeMap::new(),
}
}

pub(crate) fn instruction(&self, pc: u32) -> Option<Instruction> {
let idx = ((pc - self.pc_base) / 4) as usize;
self.instructions.get(idx).copied()
let idx = pc.wrapping_sub(self.pc_base) / 4;
self.instructions.get(idx as usize).copied()
}
}

0 comments on commit 7c76746

Please sign in to comment.