lib_rv32_asm/
encode.rs

1/// Encode an integer as a bitmask for the opcode.
2#[macro_export]
3macro_rules! encode_opcode {
4    ($n:expr) => {
5        (($n as u32) & 0b0111_1111)
6    };
7}
8
9/// Encode a register number as a bitmask for rd.
10#[macro_export]
11macro_rules! encode_rd {
12    ($n:expr) => {
13        (($n as u32) << 7)
14    };
15}
16
17/// Encode a register number as a bitmask for rs1.
18#[macro_export]
19macro_rules! encode_rs1 {
20    ($n:expr) => {
21        (($n as u32) << 15)
22    };
23}
24
25/// Encode a register number as a bitmask for rs2.
26#[macro_export]
27macro_rules! encode_rs2 {
28    ($n:expr) => {
29        (($n as u32) << 20)
30    };
31}
32
33/// Encode an integer as a bitmask for func3.
34#[macro_export]
35macro_rules! encode_func3 {
36    ($n: expr) => {
37        (($n as u32) << 12)
38    };
39}
40
41/// Encode an integer as a bitmask for func7.
42#[macro_export]
43macro_rules! encode_func7 {
44    ($n: expr) => {
45        (($n as u32) << 25)
46    };
47}
48
49/// Encode and integer as a bitmask for an I-type immediate.
50#[macro_export]
51macro_rules! encode_i_imm {
52    ($n:expr) => {{
53        let n_bits = ($n & 0xFFF) as u32;
54        let mut res: u32 = 0;
55        res |= (n_bits as u32) << 20;
56        let sign_bit = if (($n as u32) & lib_rv32_common::bit!(31)) != 0 {
57            1
58        } else {
59            0
60        };
61        res |= sign_bit << 31;
62        res
63    }};
64}
65
66/// Encode and integer as a bitmask for a J-type immediate.
67#[macro_export]
68macro_rules! encode_j_imm {
69    ($n:expr) => {
70        (((($n as u32) & 0b10000000_00000000_00000000_00000000) << (31 - 31))
71            | ((($n as u32) & 0b00000000_00001111_11110000_00000000) << (12 - 12))
72            | ((($n as u32) & 0b00000000_00000000_00001000_00000000) << (20 - 11))
73            | ((($n as u32) & 0b00000000_00000000_00000111_11100000) << (25 - 5))
74            | ((($n as u32) & 0b00000000_00000000_00000000_00011110) << (21 - 1)))
75    };
76}
77
78/// Encode and integer as a bitmask for a U-type immediate.
79#[macro_export]
80macro_rules! encode_u_imm {
81    ($n:expr) => {
82        (($n as u32) << 12)
83    };
84}
85
86/// Encode and integer as a bitmask for an S-type immediate.
87#[macro_export]
88macro_rules! encode_s_imm {
89    ($n:expr) => {
90        (((($n as u32) & 0b111111100000) << 25) | ((($n as u32) & 0b000000011111) << 7))
91    };
92}
93
94/// Encode and integer as a bitmask for a B-type immediate.
95#[macro_export]
96macro_rules! encode_b_imm {
97    ($n:expr) => {
98        (((($n as u32) & 0b10000000_00000000_00000000_00000000) << (31 - 31))
99            | ((($n as u32) & 0b00000000_00000000_00000111_11100000) << (25 - 5))
100            | ((($n as u32) & 0b00000000_00000000_00000000_00011110) << (8 - 1))
101            | ((($n as u32) & 0b00000000_00000000_00001000_00000000) >> (11 - 7)))
102    };
103}