summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core.rs3
-rw-r--r--src/decode.rs8
-rw-r--r--src/instructions.rs11
-rw-r--r--src/instructions/rvi.rs5
-rw-r--r--src/mem.rs4
5 files changed, 24 insertions, 7 deletions
diff --git a/src/core.rs b/src/core.rs
index 07df2f5..64a6a25 100644
--- a/src/core.rs
+++ b/src/core.rs
@@ -164,7 +164,7 @@ impl Core {
let instr = Instruction(instr);
if let Err(e) = find_and_exec(instr, self) {
- eprintln!("instr: {:08x}", instr.0);
+ dbg!(instr);
return Err(e);
}
@@ -174,6 +174,7 @@ impl Core {
fn throw_exception(&mut self, exception: Exception) {
eprintln!("Exception: {exception:?}");
dbg!(self.pc, self.x_regs);
+ dbg!(self.x_regs[10]);
}
pub fn reset(&mut self, pc: u64) {
diff --git a/src/decode.rs b/src/decode.rs
index 616f7f7..7f58516 100644
--- a/src/decode.rs
+++ b/src/decode.rs
@@ -6,9 +6,15 @@
const MASK_REGISTER: u32 = 0x1f;
-#[derive(Debug, Clone, Copy)]
+#[derive(Clone, Copy)]
pub struct Instruction(pub u32);
+impl std::fmt::Debug for Instruction {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ f.write_fmt(format_args!("{:08x}", self.0))
+ }
+}
+
#[allow(dead_code)]
impl Instruction {
#[inline]
diff --git a/src/instructions.rs b/src/instructions.rs
index 90f2e28..2a224b3 100644
--- a/src/instructions.rs
+++ b/src/instructions.rs
@@ -131,6 +131,7 @@ pub(crate) fn find_and_exec(instr: Instruction, core: &mut Core) -> Result<(), E
// FENCE is just implemented as a SeqCst fence always here
// I dont yet care about the potential performance issue this may bring
std::sync::atomic::fence(std::sync::atomic::Ordering::SeqCst);
+ core.advance_pc();
Ok(())
}
_ => illegal(instr),
@@ -142,7 +143,15 @@ pub(crate) fn find_and_exec(instr: Instruction, core: &mut Core) -> Result<(), E
Err(ExceptionType::EnvironmentCallFromMMode.with_no_value())
}
(0b000, 0b000000000001, 0, 0) => Err(ExceptionType::Breakpoint.with_no_value()),
- _ => illegal(instr),
+ _ => {
+ // Temporarily allowing unrecognized instructions here to be able to run
+ // the official ISA tests, which perform CSR operations but work just fine
+ // without them
+ eprintln!("Unrecognized instruction within SYSTEM opcode");
+ dbg!(instr);
+ core.advance_pc();
+ Ok(())
+ }
},
_ => illegal(instr),
}
diff --git a/src/instructions/rvi.rs b/src/instructions/rvi.rs
index 424e9e4..78267ea 100644
--- a/src/instructions/rvi.rs
+++ b/src/instructions/rvi.rs
@@ -32,7 +32,7 @@ instr_op!(srl, srli, |x, shamt| x >> (shamt & 0b111111));
instr_op!(
srlw,
srliw,
- |x, shamt| (x >> (shamt & 0b11111)) as i32 as i64 as u64
+ |x, shamt| (x as u32 >> (shamt & 0b11111)) as i32 as i64 as u64
);
instr_op!(sra, srai, |x, shamt| (x as i64 >> (shamt & 0b111111))
as u64);
@@ -64,8 +64,9 @@ pub fn jal(core: &mut Core, instr: Instruction) -> Result<(), Exception> {
}
pub fn jalr(core: &mut Core, instr: Instruction) -> Result<(), Exception> {
+ let target = core.reg_read(instr.rs1()).wrapping_add(instr.imm_i()) & !1;
core.reg_write(instr.rd(), core.pc.wrapping_add(4));
- core.pc = core.reg_read(instr.rs1()).wrapping_add(instr.imm_i());
+ core.pc = target;
Ok(())
}
diff --git a/src/mem.rs b/src/mem.rs
index e3cbe82..a3b087c 100644
--- a/src/mem.rs
+++ b/src/mem.rs
@@ -263,8 +263,8 @@ impl Ram {
if !addr.is_multiple_of(8) {
let high_word_addr = addr.wrapping_add(4);
- let low_word = self.read_byte(addr)?;
- let high_word = self.read_byte(high_word_addr)?;
+ let low_word = self.read_word(addr)?;
+ let high_word = self.read_word(high_word_addr)?;
return Ok((low_word as u64) | (high_word as u64) << 32);
}