Skip to content

Commit 08cb4c5

Browse files
refactor: use bitflags-based Extensions for RISC-V decoder
- Replace the old u32-based extension_masks with a bitflags::bitflags Extensions type in riscv::extensions - Update RiscVDecoder, RiscVHandler, and all RISC-V extension is_enabled implementations to use Extensions::contains() - Keep the existing RiscVExtensions type in riscv::arch for CLI-level configuration unchange Signed-off-by: manchangfengxu <manchangfengxu@openatom.club>
1 parent 70efc2a commit 08cb4c5

File tree

12 files changed

+60
-73
lines changed

12 files changed

+60
-73
lines changed

Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

robustone-core/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ edition = "2024"
55

66
[dependencies]
77
hex = "0.4"
8+
bitflags = "2.10.0"
89

910
[features]
1011
default = ["riscv"]

robustone-core/src/riscv/decoder.rs

Lines changed: 10 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +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::{InstructionExtension, create_extensions, extension_masks};
7+
use super::extensions::{Extensions, InstructionExtension, create_extensions};
88
use super::types::*;
99
use crate::error::DisasmError;
1010

@@ -19,13 +19,13 @@ pub enum Xlen {
1919
/// Refactored RISC-V instruction decoder using extension modules.
2020
pub struct RiscVDecoder {
2121
xlen: Xlen,
22-
extensions: u32,
22+
extensions: Extensions,
2323
extension_handlers: Vec<Box<dyn InstructionExtension>>,
2424
}
2525

2626
impl RiscVDecoder {
2727
/// Construct a decoder with the provided XLEN and extension bitmask.
28-
pub fn new(xlen: Xlen, extensions: u32) -> Self {
28+
pub fn new(xlen: Xlen, extensions: Extensions) -> Self {
2929
let extension_handlers = create_extensions();
3030
Self {
3131
xlen,
@@ -36,28 +36,12 @@ impl RiscVDecoder {
3636

3737
/// Create a decoder with full RV32GC support.
3838
pub fn rv32gc() -> Self {
39-
Self::new(
40-
Xlen::X32,
41-
extension_masks::I
42-
| extension_masks::M
43-
| extension_masks::A
44-
| extension_masks::F
45-
| extension_masks::C
46-
| extension_masks::XTHEADCONDMOV,
47-
)
39+
Self::new(Xlen::X32, Extensions::G | Extensions::C)
4840
}
4941

5042
/// Create a decoder with full RV64GC support.
5143
pub fn rv64gc() -> Self {
52-
Self::new(
53-
Xlen::X64,
54-
extension_masks::I
55-
| extension_masks::M
56-
| extension_masks::A
57-
| extension_masks::F
58-
| extension_masks::D
59-
| extension_masks::C,
60-
)
44+
Self::new(Xlen::X64, Extensions::G | Extensions::C)
6145
}
6246

6347
/// Decode a single instruction located at `address`.
@@ -229,7 +213,7 @@ impl RiscVDecoder {
229213
| ((instruction >> 6) & 0x1) << 6 // imm[6] from instruction[6]
230214
| ((instruction >> 9) & 0x3) << 7; // imm[8:7] from instruction[9:8]
231215

232-
if self.extensions & extension_masks::C == 0 {
216+
if !self.extensions.contains(Extensions::C) {
233217
eprintln!("Warning: Decoding compressed instruction while C extension is disabled");
234218
}
235219

@@ -334,20 +318,16 @@ mod tests {
334318
fn test_refactored_decoder_creation() {
335319
let decoder = RiscVDecoder::rv32gc();
336320
assert_eq!(decoder.xlen, Xlen::X32);
337-
assert!(decoder.extensions & extension_masks::I != 0);
321+
assert!(decoder.extensions.contains(Extensions::I));
338322

339323
let decoder = RiscVDecoder::rv64gc();
340324
assert_eq!(decoder.xlen, Xlen::X64);
341-
assert!(decoder.extensions & extension_masks::I != 0);
325+
assert!(decoder.extensions.contains(Extensions::I));
342326

343327
let decoder = RiscVDecoder::rv64gc();
344328
assert_eq!(decoder.xlen, Xlen::X64);
345-
assert!(decoder.extensions & extension_masks::I != 0);
346-
assert!(decoder.extensions & extension_masks::M != 0);
347-
assert!(decoder.extensions & extension_masks::A != 0);
348-
assert!(decoder.extensions & extension_masks::F != 0);
349-
assert!(decoder.extensions & extension_masks::D != 0);
350-
assert!(decoder.extensions & extension_masks::C != 0);
329+
assert!(decoder.extensions.contains(Extensions::G));
330+
assert!(decoder.extensions.contains(Extensions::C));
351331
}
352332

353333
#[test]

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

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,22 @@
55
66
use super::decoder::{RiscVDecodedInstruction, Xlen};
77
use crate::error::DisasmError;
8+
use bitflags::bitflags;
9+
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;
22+
}
23+
}
824

925
/// Trait that all instruction set extensions must implement.
1026
#[allow(clippy::too_many_arguments)]
@@ -65,7 +81,7 @@ pub trait InstructionExtension: Sync {
6581
fn name(&self) -> &'static str;
6682

6783
/// Check if this extension is enabled for the given configuration.
68-
fn is_enabled(&self, extensions: u32) -> bool;
84+
fn is_enabled(&self, extensions: Extensions) -> bool;
6985
}
7086

7187
// Standard RISC-V extension modules
@@ -99,14 +115,3 @@ pub fn create_extensions() -> Vec<Box<dyn InstructionExtension>> {
99115
Box::new(XTheadCondMovExtension::new()),
100116
]
101117
}
102-
103-
/// Extension bit masks for standard RISC-V and XuanTie extensions.
104-
pub mod extension_masks {
105-
pub const I: u32 = 0b001; // Base Integer Instruction Set
106-
pub const M: u32 = 0b010; // Multiply and Divide
107-
pub const A: u32 = 0b100; // Atomic Instructions
108-
pub const F: u32 = 0b1000; // Single-Precision Floating-Point
109-
pub const D: u32 = 0b10000; // Double-Precision Floating-Point
110-
pub const C: u32 = 0b100000; // Compressed Instructions
111-
pub const XTHEADCONDMOV: u32 = 0b1000000; // XTheadCondMov - Conditional Move
112-
}

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,8 @@ use super::super::shared::{
99
registers::{RegisterManager, RegisterNameProvider},
1010
};
1111
use super::super::types::*;
12-
use super::InstructionExtension;
12+
use super::{Extensions, InstructionExtension};
1313
use crate::error::DisasmError;
14-
use crate::riscv::extensions::extension_masks;
1514

1615
/// RVA Atomic Instructions Extension
1716
pub struct RvaExtension {
@@ -116,9 +115,9 @@ impl InstructionExtension for RvaExtension {
116115
"A"
117116
}
118117

119-
fn is_enabled(&self, extensions: u32) -> bool {
118+
fn is_enabled(&self, extensions: Extensions) -> bool {
120119
// A extension bit (bit 2)
121-
extensions & extension_masks::A != 0
120+
extensions.contains(Extensions::A)
122121
}
123122

124123
fn try_decode_standard(

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,8 @@ use super::super::shared::{
1010
registers::{RegisterManager, RegisterNameProvider},
1111
};
1212
use super::super::types::*;
13-
use super::InstructionExtension;
13+
use super::{Extensions, InstructionExtension};
1414
use crate::error::DisasmError;
15-
use crate::riscv::extensions::extension_masks;
1615

1716
/// RVC Compressed Instructions Extension
1817
pub struct RvcExtension {
@@ -371,9 +370,9 @@ impl InstructionExtension for RvcExtension {
371370
"C"
372371
}
373372

374-
fn is_enabled(&self, extensions: u32) -> bool {
373+
fn is_enabled(&self, extensions: Extensions) -> bool {
375374
// C extension bit (bit 5)
376-
extensions & extension_masks::C != 0
375+
extensions.contains(Extensions::C)
377376
}
378377

379378
fn try_decode_standard(

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,8 @@ use super::super::shared::{
99
registers::{RegisterManager, RegisterNameProvider},
1010
};
1111
use super::super::types::*;
12-
use super::InstructionExtension;
12+
use super::{Extensions, InstructionExtension};
1313
use crate::error::DisasmError;
14-
use crate::riscv::extensions::extension_masks;
1514

1615
/// RVD Double-Precision Floating-Point Extension
1716
pub struct RvdExtension {
@@ -176,9 +175,9 @@ impl InstructionExtension for RvdExtension {
176175
"D"
177176
}
178177

179-
fn is_enabled(&self, extensions: u32) -> bool {
178+
fn is_enabled(&self, extensions: Extensions) -> bool {
180179
// D extension bit (bit 4)
181-
extensions & extension_masks::D != 0
180+
extensions.contains(Extensions::D)
182181
}
183182

184183
fn try_decode_standard(

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,8 @@ use super::super::shared::{
99
registers::{RegisterManager, RegisterNameProvider},
1010
};
1111
use super::super::types::*;
12-
use super::InstructionExtension;
12+
use super::{Extensions, InstructionExtension};
1313
use crate::error::DisasmError;
14-
use crate::riscv::extensions::extension_masks;
1514

1615
/// RVF Single-Precision Floating-Point Extension
1716
pub struct RvfExtension {
@@ -176,9 +175,9 @@ impl InstructionExtension for RvfExtension {
176175
"F"
177176
}
178177

179-
fn is_enabled(&self, extensions: u32) -> bool {
178+
fn is_enabled(&self, extensions: Extensions) -> bool {
180179
// F extension bit (bit 3)
181-
extensions & extension_masks::F != 0
180+
extensions.contains(Extensions::F)
182181
}
183182

184183
fn try_decode_standard(

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

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,8 @@ use super::super::shared::{
1313
registers::RegisterManager,
1414
};
1515
use super::super::types::*;
16-
use super::InstructionExtension;
16+
use super::{Extensions, InstructionExtension};
1717
use crate::error::DisasmError;
18-
use crate::riscv::extensions::extension_masks;
1918

2019
/// RV32I/RV64I Base Integer Extension
2120
pub struct RviExtension {
@@ -643,9 +642,9 @@ impl InstructionExtension for RviExtension {
643642
"I"
644643
}
645644

646-
fn is_enabled(&self, extensions: u32) -> bool {
645+
fn is_enabled(&self, extensions: Extensions) -> bool {
647646
// I extension is always enabled (bit 0)
648-
extensions & extension_masks::I != 0
647+
extensions.contains(Extensions::I)
649648
}
650649

651650
fn try_decode_standard(
@@ -731,8 +730,8 @@ mod tests {
731730
fn test_rvi_extension_creation() {
732731
let extension = RviExtension::new();
733732
assert_eq!(extension.name(), "I");
734-
assert!(extension.is_enabled(0b001));
735-
assert!(!extension.is_enabled(0b010));
733+
assert!(extension.is_enabled(Extensions::I));
734+
assert!(!extension.is_enabled(Extensions::M));
736735
}
737736

738737
#[test]

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,8 @@ use super::super::shared::{
1010
registers::{RegisterManager, RegisterNameProvider},
1111
};
1212
use super::super::types::*;
13-
use super::InstructionExtension;
13+
use super::{Extensions, InstructionExtension};
1414
use crate::error::DisasmError;
15-
use crate::riscv::extensions::extension_masks;
1615

1716
/// RVM Multiply and Divide Extension
1817
pub struct RvmExtension {
@@ -101,9 +100,9 @@ impl InstructionExtension for RvmExtension {
101100
"M"
102101
}
103102

104-
fn is_enabled(&self, extensions: u32) -> bool {
103+
fn is_enabled(&self, extensions: Extensions) -> bool {
105104
// M extension bit (bit 1)
106-
extensions & extension_masks::M != 0
105+
extensions.contains(Extensions::M)
107106
}
108107

109108
fn try_decode_standard(

0 commit comments

Comments
 (0)