1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
// Copyright (c) 2025 taitep
// SPDX-License-Identifier: MIT
//
// This file is part of TRVE (https://gitea.taitep.se/taitep/trve)
// See LICENSE file in the project root for full license text.
use crate::{
core::{Core, InstructionResult},
decode::Instruction,
};
mod mem;
pub use mem::*;
pub fn add(core: &mut Core, instr: Instruction) -> InstructionResult {
core.reg_write(
instr.rd(),
core.reg_read(instr.rs1())
.wrapping_add(core.reg_read(instr.rs2())),
);
core.advance_pc();
InstructionResult::Normal
}
pub fn sub(core: &mut Core, instr: Instruction) -> InstructionResult {
core.reg_write(
instr.rd(),
core.reg_read(instr.rs1())
.wrapping_sub(core.reg_read(instr.rs2())),
);
core.advance_pc();
InstructionResult::Normal
}
pub fn addi(core: &mut Core, instr: Instruction) -> InstructionResult {
core.reg_write(
instr.rd(),
core.reg_read(instr.rs1()).wrapping_add(instr.imm_i()),
);
core.advance_pc();
InstructionResult::Normal
}
pub fn addiw(core: &mut Core, instr: Instruction) -> InstructionResult {
let res = core.reg_read(instr.rs1()).wrapping_add(instr.imm_i()) as i32;
core.reg_write(instr.rd(), res as i64 as u64);
core.advance_pc();
InstructionResult::Normal
}
pub fn and(core: &mut Core, instr: Instruction) -> InstructionResult {
core.reg_write(
instr.rd(),
core.reg_read(instr.rs1()) & core.reg_read(instr.rs2()),
);
core.advance_pc();
InstructionResult::Normal
}
pub fn andi(core: &mut Core, instr: Instruction) -> InstructionResult {
core.reg_write(instr.rd(), core.reg_read(instr.rs1()) & instr.imm_i());
core.advance_pc();
InstructionResult::Normal
}
pub fn or(core: &mut Core, instr: Instruction) -> InstructionResult {
core.reg_write(
instr.rd(),
core.reg_read(instr.rs1()) | core.reg_read(instr.rs2()),
);
core.advance_pc();
InstructionResult::Normal
}
pub fn slli(core: &mut Core, instr: Instruction) -> InstructionResult {
core.reg_write(instr.rd(), core.reg_read(instr.rs1()) << instr.imm_shamt());
core.advance_pc();
InstructionResult::Normal
}
pub fn lui(core: &mut Core, instr: Instruction) -> InstructionResult {
core.reg_write(instr.rd(), instr.imm_u());
core.advance_pc();
InstructionResult::Normal
}
pub fn auipc(core: &mut Core, instr: Instruction) -> InstructionResult {
core.reg_write(instr.rd(), core.pc.wrapping_add(instr.imm_u()));
core.advance_pc();
InstructionResult::Normal
}
pub fn jal(core: &mut Core, instr: Instruction) -> InstructionResult {
core.reg_write(instr.rd(), core.pc.wrapping_add(4));
core.pc = core.pc.wrapping_add(instr.imm_j());
InstructionResult::Normal
}
pub fn jalr(core: &mut Core, instr: Instruction) -> InstructionResult {
core.reg_write(instr.rd(), core.pc.wrapping_add(4));
core.pc = core.reg_read(instr.rs1()).wrapping_add(instr.imm_i());
InstructionResult::Normal
}
pub fn beq(core: &mut Core, instr: Instruction) -> InstructionResult {
if core.reg_read(instr.rs1()) == core.reg_read(instr.rs2()) {
core.pc = core.pc.wrapping_add(instr.imm_b());
} else {
core.advance_pc();
}
InstructionResult::Normal
}
pub fn bne(core: &mut Core, instr: Instruction) -> InstructionResult {
if core.reg_read(instr.rs1()) != core.reg_read(instr.rs2()) {
core.pc = core.pc.wrapping_add(instr.imm_b());
} else {
core.advance_pc();
}
InstructionResult::Normal
}
|