Skip to content

Commit 6a1040d

Browse files
feat: split RISC-V extensions into standard and thead modules
- Move standard and T-Head extensions into standard/ and thead/ modules - Update decoder, handler and tests to use the new Extensions API Signed-off-by: manchangfengxu <manchangfengxu@openatom.club>
1 parent 08cb4c5 commit 6a1040d

File tree

11 files changed

+192
-98
lines changed

11 files changed

+192
-98
lines changed

robustone-core/src/riscv/decoder.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
//! is implemented as a separate module, making the codebase more maintainable
55
//! and easier to extend with new instructions.
66
7+
use super::extensions::standard::StandardExtensions;
78
use super::extensions::{Extensions, InstructionExtension, create_extensions};
89
use super::types::*;
910
use crate::error::DisasmError;
@@ -36,12 +37,12 @@ impl RiscVDecoder {
3637

3738
/// Create a decoder with full RV32GC support.
3839
pub fn rv32gc() -> Self {
39-
Self::new(Xlen::X32, Extensions::G | Extensions::C)
40+
Self::new(Xlen::X32, Extensions::rv32gc())
4041
}
4142

4243
/// Create a decoder with full RV64GC support.
4344
pub fn rv64gc() -> Self {
44-
Self::new(Xlen::X64, Extensions::G | Extensions::C)
45+
Self::new(Xlen::X64, Extensions::rv64gc())
4546
}
4647

4748
/// Decode a single instruction located at `address`.
@@ -115,7 +116,7 @@ impl RiscVDecoder {
115116

116117
// Try each enabled extension in order
117118
for extension in &self.extension_handlers {
118-
if !extension.is_enabled(self.extensions) {
119+
if !extension.is_enabled(&self.extensions) {
119120
continue;
120121
}
121122

@@ -213,13 +214,13 @@ impl RiscVDecoder {
213214
| ((instruction >> 6) & 0x1) << 6 // imm[6] from instruction[6]
214215
| ((instruction >> 9) & 0x3) << 7; // imm[8:7] from instruction[9:8]
215216

216-
if !self.extensions.contains(Extensions::C) {
217+
if !self.extensions.standard.contains(StandardExtensions::C) {
217218
eprintln!("Warning: Decoding compressed instruction while C extension is disabled");
218219
}
219220

220221
// Try each enabled extension for compressed instructions
221222
for extension in &self.extension_handlers {
222-
if !extension.is_enabled(self.extensions) {
223+
if !extension.is_enabled(&self.extensions) {
223224
continue;
224225
}
225226

@@ -318,16 +319,16 @@ mod tests {
318319
fn test_refactored_decoder_creation() {
319320
let decoder = RiscVDecoder::rv32gc();
320321
assert_eq!(decoder.xlen, Xlen::X32);
321-
assert!(decoder.extensions.contains(Extensions::I));
322+
assert!(decoder.extensions.standard.contains(StandardExtensions::I));
322323

323324
let decoder = RiscVDecoder::rv64gc();
324325
assert_eq!(decoder.xlen, Xlen::X64);
325-
assert!(decoder.extensions.contains(Extensions::I));
326+
assert!(decoder.extensions.standard.contains(StandardExtensions::I));
326327

327328
let decoder = RiscVDecoder::rv64gc();
328329
assert_eq!(decoder.xlen, Xlen::X64);
329-
assert!(decoder.extensions.contains(Extensions::G));
330-
assert!(decoder.extensions.contains(Extensions::C));
330+
assert!(decoder.extensions.standard.contains(StandardExtensions::G));
331+
assert!(decoder.extensions.standard.contains(StandardExtensions::C));
331332
}
332333

333334
#[test]

robustone-core/src/riscv/extensions/mod.rs

Lines changed: 50 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,43 @@
55
66
use super::decoder::{RiscVDecodedInstruction, Xlen};
77
use crate::error::DisasmError;
8-
use bitflags::bitflags;
98

10-
bitflags! {
11-
/// Bitflags representing enabled RISC-V extensions.
12-
#[derive(Clone, Copy)]
13-
pub struct Extensions: u32 {
14-
const G = Self::I.bits() | Self::M.bits() | Self::A.bits() | Self::F.bits() | Self::D.bits();
15-
const I = 1 << 0;
16-
const M = 1 << 1;
17-
const A = 1 << 2;
18-
const F = 1 << 3;
19-
const D = 1 << 4;
20-
const C = 1 << 5;
21-
const XTHEADCONDMOV = 1 << 6;
9+
// Submodules grouping standard and custom-specific extensions.
10+
pub mod standard;
11+
pub mod thead;
12+
13+
use standard::StandardExtensions;
14+
use thead::THeadExtensions;
15+
16+
/// Aggregated extension configuration passed to RISC-V extension handlers.
17+
pub struct Extensions {
18+
pub(crate) standard: StandardExtensions,
19+
pub(crate) thead: THeadExtensions,
20+
}
21+
22+
impl Extensions {
23+
/// Convenience configuration for RV32GC profile with all standard and
24+
/// no T-Head custom extensions enabled.
25+
pub fn rv32gc() -> Self {
26+
Self {
27+
standard: StandardExtensions::G | StandardExtensions::C,
28+
thead: THeadExtensions::empty(),
29+
}
30+
}
31+
32+
/// Convenience configuration for RV64GC profile with all standard and
33+
/// no T-Head custom extensions enabled.
34+
pub fn rv64gc() -> Self {
35+
Self {
36+
standard: StandardExtensions::G | StandardExtensions::C,
37+
thead: THeadExtensions::empty(),
38+
}
39+
}
40+
41+
/// Enables all available T-Head custom extensions on this configuration.
42+
pub fn set_thead(mut self) -> Self {
43+
self.thead |= THeadExtensions::all();
44+
self
2245
}
2346
}
2447

@@ -81,27 +104,24 @@ pub trait InstructionExtension: Sync {
81104
fn name(&self) -> &'static str;
82105

83106
/// Check if this extension is enabled for the given configuration.
84-
fn is_enabled(&self, extensions: Extensions) -> bool;
107+
fn is_enabled(&self, extensions: &Extensions) -> bool;
85108
}
86109

87110
// Standard RISC-V extension modules
88-
pub mod rva; // RVA - Atomic Instructions
89-
pub mod rvc; // RVC - Compressed Instructions
90-
pub mod rvd; // RVD - Double-Precision Floating-Point
91-
pub mod rvf; // RVF - Single-Precision Floating-Point
92-
pub mod rvi; // RV32I/RV64I - Base Integer Instruction Set
93-
pub mod rvm; // RVM - Multiply and Divide Instructions
111+
// RVA - Atomic Instructions
112+
// RVC - Compressed Instructions
113+
// RVD - Double-Precision Floating-Point
114+
// RVF - Single-Precision Floating-Point
115+
// RV32I/RV64I - Base Integer Instruction Set
116+
// RVM - Multiply and Divide Instructions
94117

95-
// XuanTie vendor extension modules
96-
pub mod xtheadcondmov; // XTheadCondMov - Conditional Move Instructions
118+
// XuanTie custom extension modules
119+
// XTheadCondMov - Conditional Move Instructions
97120

98-
use rva::RvaExtension;
99-
use rvc::RvcExtension;
100-
use rvd::RvdExtension;
101-
use rvf::RvfExtension;
102-
use rvi::RviExtension;
103-
use rvm::RvmExtension;
104-
use xtheadcondmov::XTheadCondMovExtension;
121+
use standard::{
122+
RvaExtension, RvcExtension, RvdExtension, RvfExtension, RviExtension, RvmExtension,
123+
};
124+
use thead::CondMovExtension;
105125

106126
/// Create all available standard RISC-V extensions.
107127
pub fn create_extensions() -> Vec<Box<dyn InstructionExtension>> {
@@ -112,6 +132,6 @@ pub fn create_extensions() -> Vec<Box<dyn InstructionExtension>> {
112132
Box::new(RvfExtension::new()),
113133
Box::new(RvdExtension::new()),
114134
Box::new(RvcExtension::new()),
115-
Box::new(XTheadCondMovExtension::new()),
135+
Box::new(CondMovExtension::new()),
116136
]
117137
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//! Standard RISC-V extensions and configuration.
2+
//!
3+
//! This module defines the `StandardExtensions` bitflags for core RISC-V
4+
//! extensions (I/M/A/F/D/C) and re-exports the corresponding extension
5+
//! handler types under the `standard` namespace.
6+
7+
use bitflags::bitflags;
8+
9+
pub mod rva;
10+
pub mod rvc;
11+
pub mod rvd;
12+
pub mod rvf;
13+
pub mod rvi;
14+
pub mod rvm;
15+
16+
pub use rva::RvaExtension;
17+
pub use rvc::RvcExtension;
18+
pub use rvd::RvdExtension;
19+
pub use rvf::RvfExtension;
20+
pub use rvi::RviExtension;
21+
pub use rvm::RvmExtension;
22+
23+
bitflags! {
24+
/// Bitflags representing enabled standard RISC-V extensions.
25+
pub struct StandardExtensions: u32 {
26+
const I = 1;
27+
const M = 1 << 1;
28+
const A = 1 << 2;
29+
const F = 1 << 3;
30+
const D = 1 << 4;
31+
const C = 1 << 5;
32+
/// Shorthand for the standard G profile (IMAFD).
33+
const G = Self::I.bits()
34+
| Self::M.bits()
35+
| Self::A.bits()
36+
| Self::F.bits()
37+
| Self::D.bits();
38+
}
39+
}

robustone-core/src/riscv/extensions/rva.rs renamed to robustone-core/src/riscv/extensions/standard/rva.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@
33
//! This module implements the RISC-V atomic instructions extension (A extension),
44
//! which provides atomic memory operations for synchronization and concurrency.
55
6-
use super::super::decoder::{RiscVDecodedInstruction, Xlen};
7-
use super::super::shared::{
6+
use super::StandardExtensions;
7+
use crate::error::DisasmError;
8+
use crate::riscv::decoder::{RiscVDecodedInstruction, Xlen};
9+
use crate::riscv::extensions::{Extensions, InstructionExtension};
10+
use crate::riscv::shared::{
811
operands::convenience,
912
registers::{RegisterManager, RegisterNameProvider},
1013
};
11-
use super::super::types::*;
12-
use super::{Extensions, InstructionExtension};
13-
use crate::error::DisasmError;
14+
use crate::riscv::types::*;
1415

1516
/// RVA Atomic Instructions Extension
1617
pub struct RvaExtension {
@@ -115,9 +116,9 @@ impl InstructionExtension for RvaExtension {
115116
"A"
116117
}
117118

118-
fn is_enabled(&self, extensions: Extensions) -> bool {
119+
fn is_enabled(&self, extensions: &Extensions) -> bool {
119120
// A extension bit (bit 2)
120-
extensions.contains(Extensions::A)
121+
extensions.standard.contains(StandardExtensions::A)
121122
}
122123

123124
fn try_decode_standard(

robustone-core/src/riscv/extensions/rvc.rs renamed to robustone-core/src/riscv/extensions/standard/rvc.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,16 @@
33
//! This module implements the RISC-V compressed instruction extension (C extension),
44
//! which provides 16-bit compressed versions of common instructions to improve code density.
55
6-
use super::super::decoder::{RiscVDecodedInstruction, Xlen};
7-
use super::super::shared::{
6+
use super::StandardExtensions;
7+
use crate::error::DisasmError;
8+
use crate::riscv::decoder::{RiscVDecodedInstruction, Xlen};
9+
use crate::riscv::extensions::{Extensions, InstructionExtension};
10+
use crate::riscv::shared::{
811
encoding::convenience as encoding_conv,
912
operands::convenience,
1013
registers::{RegisterManager, RegisterNameProvider},
1114
};
12-
use super::super::types::*;
13-
use super::{Extensions, InstructionExtension};
14-
use crate::error::DisasmError;
15+
use crate::riscv::types::*;
1516

1617
/// RVC Compressed Instructions Extension
1718
pub struct RvcExtension {
@@ -370,9 +371,9 @@ impl InstructionExtension for RvcExtension {
370371
"C"
371372
}
372373

373-
fn is_enabled(&self, extensions: Extensions) -> bool {
374+
fn is_enabled(&self, extensions: &Extensions) -> bool {
374375
// C extension bit (bit 5)
375-
extensions.contains(Extensions::C)
376+
extensions.standard.contains(StandardExtensions::C)
376377
}
377378

378379
fn try_decode_standard(

robustone-core/src/riscv/extensions/rvd.rs renamed to robustone-core/src/riscv/extensions/standard/rvd.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@
33
//! This module implements the RISC-V double-precision floating-point extension (D extension),
44
//! which provides IEEE 754 double-precision floating-point operations.
55
6-
use super::super::decoder::{RiscVDecodedInstruction, Xlen};
7-
use super::super::shared::{
6+
use super::StandardExtensions;
7+
use crate::error::DisasmError;
8+
use crate::riscv::decoder::{RiscVDecodedInstruction, Xlen};
9+
use crate::riscv::extensions::{Extensions, InstructionExtension};
10+
use crate::riscv::shared::{
811
operands::convenience,
912
registers::{RegisterManager, RegisterNameProvider},
1013
};
11-
use super::super::types::*;
12-
use super::{Extensions, InstructionExtension};
13-
use crate::error::DisasmError;
14+
use crate::riscv::types::*;
1415

1516
/// RVD Double-Precision Floating-Point Extension
1617
pub struct RvdExtension {
@@ -175,9 +176,9 @@ impl InstructionExtension for RvdExtension {
175176
"D"
176177
}
177178

178-
fn is_enabled(&self, extensions: Extensions) -> bool {
179+
fn is_enabled(&self, extensions: &Extensions) -> bool {
179180
// D extension bit (bit 4)
180-
extensions.contains(Extensions::D)
181+
extensions.standard.contains(StandardExtensions::D)
181182
}
182183

183184
fn try_decode_standard(

robustone-core/src/riscv/extensions/rvf.rs renamed to robustone-core/src/riscv/extensions/standard/rvf.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@
33
//! This module implements the RISC-V single-precision floating-point extension (F extension),
44
//! which provides IEEE 754 single-precision floating-point operations.
55
6-
use super::super::decoder::{RiscVDecodedInstruction, Xlen};
7-
use super::super::shared::{
6+
use super::StandardExtensions;
7+
use crate::error::DisasmError;
8+
use crate::riscv::decoder::{RiscVDecodedInstruction, Xlen};
9+
use crate::riscv::extensions::{Extensions, InstructionExtension};
10+
use crate::riscv::shared::{
811
operands::convenience,
912
registers::{RegisterManager, RegisterNameProvider},
1013
};
11-
use super::super::types::*;
12-
use super::{Extensions, InstructionExtension};
13-
use crate::error::DisasmError;
14+
use crate::riscv::types::*;
1415

1516
/// RVF Single-Precision Floating-Point Extension
1617
pub struct RvfExtension {
@@ -175,9 +176,9 @@ impl InstructionExtension for RvfExtension {
175176
"F"
176177
}
177178

178-
fn is_enabled(&self, extensions: Extensions) -> bool {
179+
fn is_enabled(&self, extensions: &Extensions) -> bool {
179180
// F extension bit (bit 3)
180-
extensions.contains(Extensions::F)
181+
extensions.standard.contains(StandardExtensions::F)
181182
}
182183

183184
fn try_decode_standard(

0 commit comments

Comments
 (0)