Skip to content

Commit 1fd0516

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 1fd0516

File tree

12 files changed

+73
-67
lines changed

12 files changed

+73
-67
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: 24 additions & 24 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,
@@ -38,25 +38,25 @@ impl RiscVDecoder {
3838
pub fn rv32gc() -> Self {
3939
Self::new(
4040
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,
41+
Extensions::I
42+
| Extensions::M
43+
| Extensions::A
44+
| Extensions::F
45+
| Extensions::C
46+
| Extensions::XTHEADCONDMOV,
4747
)
4848
}
4949

5050
/// Create a decoder with full RV64GC support.
5151
pub fn rv64gc() -> Self {
5252
Self::new(
5353
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,
54+
Extensions::I
55+
| Extensions::M
56+
| Extensions::A
57+
| Extensions::F
58+
| Extensions::D
59+
| Extensions::C,
6060
)
6161
}
6262

@@ -229,7 +229,7 @@ impl RiscVDecoder {
229229
| ((instruction >> 6) & 0x1) << 6 // imm[6] from instruction[6]
230230
| ((instruction >> 9) & 0x3) << 7; // imm[8:7] from instruction[9:8]
231231

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

@@ -334,20 +334,20 @@ mod tests {
334334
fn test_refactored_decoder_creation() {
335335
let decoder = RiscVDecoder::rv32gc();
336336
assert_eq!(decoder.xlen, Xlen::X32);
337-
assert!(decoder.extensions & extension_masks::I != 0);
337+
assert!(decoder.extensions.contains(Extensions::I));
338338

339339
let decoder = RiscVDecoder::rv64gc();
340340
assert_eq!(decoder.xlen, Xlen::X64);
341-
assert!(decoder.extensions & extension_masks::I != 0);
341+
assert!(decoder.extensions.contains(Extensions::I));
342342

343343
let decoder = RiscVDecoder::rv64gc();
344344
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);
345+
assert!(decoder.extensions.contains(Extensions::I));
346+
assert!(decoder.extensions.contains(Extensions::M));
347+
assert!(decoder.extensions.contains(Extensions::A));
348+
assert!(decoder.extensions.contains(Extensions::F));
349+
assert!(decoder.extensions.contains(Extensions::D));
350+
assert!(decoder.extensions.contains(Extensions::C));
351351
}
352352

353353
#[test]

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

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,21 @@
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 I = 1 << 0;
15+
const M = 1 << 1;
16+
const A = 1 << 2;
17+
const F = 1 << 3;
18+
const D = 1 << 4;
19+
const C = 1 << 5;
20+
const XTHEADCONDMOV = 1 << 6;
21+
}
22+
}
823

924
/// Trait that all instruction set extensions must implement.
1025
#[allow(clippy::too_many_arguments)]
@@ -65,7 +80,7 @@ pub trait InstructionExtension: Sync {
6580
fn name(&self) -> &'static str;
6681

6782
/// Check if this extension is enabled for the given configuration.
68-
fn is_enabled(&self, extensions: u32) -> bool;
83+
fn is_enabled(&self, extensions: Extensions) -> bool;
6984
}
7085

7186
// Standard RISC-V extension modules
@@ -99,14 +114,3 @@ pub fn create_extensions() -> Vec<Box<dyn InstructionExtension>> {
99114
Box::new(XTheadCondMovExtension::new()),
100115
]
101116
}
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)