1#[macro_export]
27macro_rules! extract_bits {
28 ($num:expr, $start:expr, $end:expr) => {{
29 let bit_size = std::mem::size_of_val(&$num) * 8;
30 if $start <0 || $end >= bit_size {
31 Err($crate::DisassemblerError::BitExtractionError("Index out of bounds"))
32 } else if $start > $end {
33 Err($crate::DisassemblerError::BitExtractionError("Start index must be less than or equal to end index"))
34 } else {
35 let mask = (1 << ($end - $start + 1)) - 1;
36 Ok(($num >> $start) & mask)
37 }
38 }};
39}
40
41#[macro_export]
68macro_rules! sign_extend32 {
69 ($num:expr, $curr_size:expr) => {{
70 if $curr_size > 32 {
71 Err($crate::DisassemblerError::BitExtensionError("Size exceeds 32 bits"))
72 } else {
73 let sign_bit: u32 = 1 << ($curr_size - 1);
74 let mask: u32 = (1 << $curr_size - 1) - 1;
75 let sign_extended: u32 = if $num & sign_bit != 0 {
76 ($num as u32) | !mask
77 } else {
78 $num
79 };
80 Ok(sign_extended as i32)
81 }
82 }};
83}
84
85pub(crate) use {
86 extract_bits,
87 sign_extend32,
88};
89
90
91#[cfg(test)]
92mod tests {
93 use super::*;
94
95 #[test]
96 fn test_extract_bits_from_u64() {
97 let number: u64 = 0b1101_1111_1001_1111_1111_1111_1111_1010_1110_1111_1001_1111_1111_1111_1111_1010;
98 let result = extract_bits!(number, 0, 3);
99 assert_eq!(result, Ok(0b1010));
100
101 let result = extract_bits!(number, 4, 7);
102 assert_eq!(result, Ok(0b1111));
103
104 let result = extract_bits!(number, 20, 23);
105 assert_eq!(result, Ok(0b1001));
106
107 let result = extract_bits!(number, 24, 31);
108 assert_eq!(result, Ok(0b1110_1111));
109
110 let result = extract_bits!(number, 56, 63);
111 assert_eq!(result, Ok(0b1101_1111));
112 }
113
114 #[test]
115 fn test_extract_bits_from_i64() {
116 let number: i64 = 0b101_1111_1001_1111_1111_1111_1111_1010_1110_1111_1001_1111_1111_1111_1111_1010;
117 let result = extract_bits!(number, 0, 3);
118 assert_eq!(result, Ok(0b1010));
119
120 let result = extract_bits!(number, 4, 7);
121 assert_eq!(result, Ok(0b1111));
122
123 let result = extract_bits!(number, 20, 23);
124 assert_eq!(result, Ok(0b1001));
125
126 let result = extract_bits!(number, 24, 31);
127 assert_eq!(result, Ok(0b1110_1111));
128
129 let result = extract_bits!(number, 56, 63);
130 assert_eq!(result, Ok(0b101_1111));
131 }
132
133 #[test]
134 fn test_extract_bits_u32() {
135 let number: u32 = 0b1011_1111_1001_1111_1111_1111_1111_1010;
136 let result = extract_bits!(number, 0, 3);
137 assert_eq!(result, Ok(0b1010));
138
139 let result = extract_bits!(number, 4, 7);
140 assert_eq!(result, Ok(0b1111));
141
142 let result = extract_bits!(number, 20, 23);
143 assert_eq!(result, Ok(0b1001));
144
145 let result = extract_bits!(number, 24, 31);
146 assert_eq!(result, Ok(0b1011_1111));
147 }
148
149 #[test]
150 fn test_extract_bits_i32() {
151 let number: u32 = 0b011_1111_1001_1111_1111_1111_1111_1010;
152 let result = extract_bits!(number, 0, 3);
153 assert_eq!(result, Ok(0b1010));
154
155 let result = extract_bits!(number, 4, 7);
156 assert_eq!(result, Ok(0b1111));
157
158 let result = extract_bits!(number, 20, 23);
159 assert_eq!(result, Ok(0b1001));
160
161 let result = extract_bits!(number, 24, 31);
162 assert_eq!(result, Ok(0b011_1111));
163 }
164
165 #[test]
166 fn test_extract_bits_u16() {
167 let number: u16 = 0b1100_1111_1001_1111;
168 let result = extract_bits!(number, 0, 3);
169 assert_eq!(result, Ok(0b1111));
170
171 let result = extract_bits!(number, 4, 7);
172 assert_eq!(result, Ok(0b1001));
173
174 let result = extract_bits!(number, 8, 11);
175 assert_eq!(result, Ok(0b1111));
176
177 let result = extract_bits!(number, 12, 15);
178 assert_eq!(result, Ok(0b1100));
179 }
180
181 #[test]
182 fn test_extract_bits_i16() {
183 let number: u16 = 0b100_1111_1001_1111;
184 let result = extract_bits!(number, 0, 3);
185 assert_eq!(result, Ok(0b1111));
186
187 let result = extract_bits!(number, 4, 7);
188 assert_eq!(result, Ok(0b1001));
189
190 let result = extract_bits!(number, 8, 11);
191 assert_eq!(result, Ok(0b1111));
192
193 let result = extract_bits!(number, 12, 15);
194 assert_eq!(result, Ok(0b100));
195 }
196
197 #[test]
198 fn test_extract_bits_u8() {
199 let number: u8 = 0b1011_1010;
200 let result = extract_bits!(number, 0, 3);
201 assert_eq!(result, Ok(0b1010));
202
203 let result = extract_bits!(number, 4, 7);
204 assert_eq!(result, Ok(0b1011));
205 }
206
207 #[test]
208 fn test_extract_bits_i8() {
209 let number: u8 = 0b011_1010;
210 let result = extract_bits!(number, 0, 3);
211 assert_eq!(result, Ok(0b1010));
212
213 let result = extract_bits!(number, 4, 7);
214 assert_eq!(result, Ok(0b011));
215 }
216
217 #[test]
218 fn test_sign_extend32(){
219 let bits: u32 = 0b0010;
220 let result = sign_extend32!(bits, 3).unwrap();
221 assert_eq!(result, 2);
222
223 let bits: u32 = 0b1010;
224 let result = sign_extend32!(bits, 4).unwrap();
225 assert_eq!(result, -6);
226
227 let bits: u32 = 0b1010;
228 let result = sign_extend32!(bits, 5).unwrap();
229 assert_eq!(result, 10);
230 }
231
232}