bad64/
reg.rs

1use core::fmt;
2
3use cstr_core::CStr;
4use num_traits::ToPrimitive;
5
6use bad64_sys::*;
7
8/// A register
9#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, FromPrimitive, ToPrimitive)]
10#[repr(u32)]
11#[allow(non_camel_case_types)]
12pub enum Reg {
13    W0 = Register_REG_W0 as u32,
14    W1 = Register_REG_W1 as u32,
15    W2 = Register_REG_W2 as u32,
16    W3 = Register_REG_W3 as u32,
17    W4 = Register_REG_W4 as u32,
18    W5 = Register_REG_W5 as u32,
19    W6 = Register_REG_W6 as u32,
20    W7 = Register_REG_W7 as u32,
21    W8 = Register_REG_W8 as u32,
22    W9 = Register_REG_W9 as u32,
23    W10 = Register_REG_W10 as u32,
24    W11 = Register_REG_W11 as u32,
25    W12 = Register_REG_W12 as u32,
26    W13 = Register_REG_W13 as u32,
27    W14 = Register_REG_W14 as u32,
28    W15 = Register_REG_W15 as u32,
29    W16 = Register_REG_W16 as u32,
30    W17 = Register_REG_W17 as u32,
31    W18 = Register_REG_W18 as u32,
32    W19 = Register_REG_W19 as u32,
33    W20 = Register_REG_W20 as u32,
34    W21 = Register_REG_W21 as u32,
35    W22 = Register_REG_W22 as u32,
36    W23 = Register_REG_W23 as u32,
37    W24 = Register_REG_W24 as u32,
38    W25 = Register_REG_W25 as u32,
39    W26 = Register_REG_W26 as u32,
40    W27 = Register_REG_W27 as u32,
41    W28 = Register_REG_W28 as u32,
42    W29 = Register_REG_W29 as u32,
43    W30 = Register_REG_W30 as u32,
44    WZR = Register_REG_WZR as u32,
45    WSP = Register_REG_WSP as u32,
46    X0 = Register_REG_X0 as u32,
47    X1 = Register_REG_X1 as u32,
48    X2 = Register_REG_X2 as u32,
49    X3 = Register_REG_X3 as u32,
50    X4 = Register_REG_X4 as u32,
51    X5 = Register_REG_X5 as u32,
52    X6 = Register_REG_X6 as u32,
53    X7 = Register_REG_X7 as u32,
54    X8 = Register_REG_X8 as u32,
55    X9 = Register_REG_X9 as u32,
56    X10 = Register_REG_X10 as u32,
57    X11 = Register_REG_X11 as u32,
58    X12 = Register_REG_X12 as u32,
59    X13 = Register_REG_X13 as u32,
60    X14 = Register_REG_X14 as u32,
61    X15 = Register_REG_X15 as u32,
62    X16 = Register_REG_X16 as u32,
63    X17 = Register_REG_X17 as u32,
64    X18 = Register_REG_X18 as u32,
65    X19 = Register_REG_X19 as u32,
66    X20 = Register_REG_X20 as u32,
67    X21 = Register_REG_X21 as u32,
68    X22 = Register_REG_X22 as u32,
69    X23 = Register_REG_X23 as u32,
70    X24 = Register_REG_X24 as u32,
71    X25 = Register_REG_X25 as u32,
72    X26 = Register_REG_X26 as u32,
73    X27 = Register_REG_X27 as u32,
74    X28 = Register_REG_X28 as u32,
75    X29 = Register_REG_X29 as u32,
76    X30 = Register_REG_X30 as u32,
77    XZR = Register_REG_XZR as u32,
78    SP = Register_REG_SP as u32,
79    V0 = Register_REG_V0 as u32,
80    V1 = Register_REG_V1 as u32,
81    V2 = Register_REG_V2 as u32,
82    V3 = Register_REG_V3 as u32,
83    V4 = Register_REG_V4 as u32,
84    V5 = Register_REG_V5 as u32,
85    V6 = Register_REG_V6 as u32,
86    V7 = Register_REG_V7 as u32,
87    V8 = Register_REG_V8 as u32,
88    V9 = Register_REG_V9 as u32,
89    V10 = Register_REG_V10 as u32,
90    V11 = Register_REG_V11 as u32,
91    V12 = Register_REG_V12 as u32,
92    V13 = Register_REG_V13 as u32,
93    V14 = Register_REG_V14 as u32,
94    V15 = Register_REG_V15 as u32,
95    V16 = Register_REG_V16 as u32,
96    V17 = Register_REG_V17 as u32,
97    V18 = Register_REG_V18 as u32,
98    V19 = Register_REG_V19 as u32,
99    V20 = Register_REG_V20 as u32,
100    V21 = Register_REG_V21 as u32,
101    V22 = Register_REG_V22 as u32,
102    V23 = Register_REG_V23 as u32,
103    V24 = Register_REG_V24 as u32,
104    V25 = Register_REG_V25 as u32,
105    V26 = Register_REG_V26 as u32,
106    V27 = Register_REG_V27 as u32,
107    V28 = Register_REG_V28 as u32,
108    V29 = Register_REG_V29 as u32,
109    V30 = Register_REG_V30 as u32,
110    V31 = Register_REG_V31 as u32,
111    B0 = Register_REG_B0 as u32,
112    B1 = Register_REG_B1 as u32,
113    B2 = Register_REG_B2 as u32,
114    B3 = Register_REG_B3 as u32,
115    B4 = Register_REG_B4 as u32,
116    B5 = Register_REG_B5 as u32,
117    B6 = Register_REG_B6 as u32,
118    B7 = Register_REG_B7 as u32,
119    B8 = Register_REG_B8 as u32,
120    B9 = Register_REG_B9 as u32,
121    B10 = Register_REG_B10 as u32,
122    B11 = Register_REG_B11 as u32,
123    B12 = Register_REG_B12 as u32,
124    B13 = Register_REG_B13 as u32,
125    B14 = Register_REG_B14 as u32,
126    B15 = Register_REG_B15 as u32,
127    B16 = Register_REG_B16 as u32,
128    B17 = Register_REG_B17 as u32,
129    B18 = Register_REG_B18 as u32,
130    B19 = Register_REG_B19 as u32,
131    B20 = Register_REG_B20 as u32,
132    B21 = Register_REG_B21 as u32,
133    B22 = Register_REG_B22 as u32,
134    B23 = Register_REG_B23 as u32,
135    B24 = Register_REG_B24 as u32,
136    B25 = Register_REG_B25 as u32,
137    B26 = Register_REG_B26 as u32,
138    B27 = Register_REG_B27 as u32,
139    B28 = Register_REG_B28 as u32,
140    B29 = Register_REG_B29 as u32,
141    B30 = Register_REG_B30 as u32,
142    B31 = Register_REG_B31 as u32,
143    H0 = Register_REG_H0 as u32,
144    H1 = Register_REG_H1 as u32,
145    H2 = Register_REG_H2 as u32,
146    H3 = Register_REG_H3 as u32,
147    H4 = Register_REG_H4 as u32,
148    H5 = Register_REG_H5 as u32,
149    H6 = Register_REG_H6 as u32,
150    H7 = Register_REG_H7 as u32,
151    H8 = Register_REG_H8 as u32,
152    H9 = Register_REG_H9 as u32,
153    H10 = Register_REG_H10 as u32,
154    H11 = Register_REG_H11 as u32,
155    H12 = Register_REG_H12 as u32,
156    H13 = Register_REG_H13 as u32,
157    H14 = Register_REG_H14 as u32,
158    H15 = Register_REG_H15 as u32,
159    H16 = Register_REG_H16 as u32,
160    H17 = Register_REG_H17 as u32,
161    H18 = Register_REG_H18 as u32,
162    H19 = Register_REG_H19 as u32,
163    H20 = Register_REG_H20 as u32,
164    H21 = Register_REG_H21 as u32,
165    H22 = Register_REG_H22 as u32,
166    H23 = Register_REG_H23 as u32,
167    H24 = Register_REG_H24 as u32,
168    H25 = Register_REG_H25 as u32,
169    H26 = Register_REG_H26 as u32,
170    H27 = Register_REG_H27 as u32,
171    H28 = Register_REG_H28 as u32,
172    H29 = Register_REG_H29 as u32,
173    H30 = Register_REG_H30 as u32,
174    H31 = Register_REG_H31 as u32,
175    S0 = Register_REG_S0 as u32,
176    S1 = Register_REG_S1 as u32,
177    S2 = Register_REG_S2 as u32,
178    S3 = Register_REG_S3 as u32,
179    S4 = Register_REG_S4 as u32,
180    S5 = Register_REG_S5 as u32,
181    S6 = Register_REG_S6 as u32,
182    S7 = Register_REG_S7 as u32,
183    S8 = Register_REG_S8 as u32,
184    S9 = Register_REG_S9 as u32,
185    S10 = Register_REG_S10 as u32,
186    S11 = Register_REG_S11 as u32,
187    S12 = Register_REG_S12 as u32,
188    S13 = Register_REG_S13 as u32,
189    S14 = Register_REG_S14 as u32,
190    S15 = Register_REG_S15 as u32,
191    S16 = Register_REG_S16 as u32,
192    S17 = Register_REG_S17 as u32,
193    S18 = Register_REG_S18 as u32,
194    S19 = Register_REG_S19 as u32,
195    S20 = Register_REG_S20 as u32,
196    S21 = Register_REG_S21 as u32,
197    S22 = Register_REG_S22 as u32,
198    S23 = Register_REG_S23 as u32,
199    S24 = Register_REG_S24 as u32,
200    S25 = Register_REG_S25 as u32,
201    S26 = Register_REG_S26 as u32,
202    S27 = Register_REG_S27 as u32,
203    S28 = Register_REG_S28 as u32,
204    S29 = Register_REG_S29 as u32,
205    S30 = Register_REG_S30 as u32,
206    S31 = Register_REG_S31 as u32,
207    D0 = Register_REG_D0 as u32,
208    D1 = Register_REG_D1 as u32,
209    D2 = Register_REG_D2 as u32,
210    D3 = Register_REG_D3 as u32,
211    D4 = Register_REG_D4 as u32,
212    D5 = Register_REG_D5 as u32,
213    D6 = Register_REG_D6 as u32,
214    D7 = Register_REG_D7 as u32,
215    D8 = Register_REG_D8 as u32,
216    D9 = Register_REG_D9 as u32,
217    D10 = Register_REG_D10 as u32,
218    D11 = Register_REG_D11 as u32,
219    D12 = Register_REG_D12 as u32,
220    D13 = Register_REG_D13 as u32,
221    D14 = Register_REG_D14 as u32,
222    D15 = Register_REG_D15 as u32,
223    D16 = Register_REG_D16 as u32,
224    D17 = Register_REG_D17 as u32,
225    D18 = Register_REG_D18 as u32,
226    D19 = Register_REG_D19 as u32,
227    D20 = Register_REG_D20 as u32,
228    D21 = Register_REG_D21 as u32,
229    D22 = Register_REG_D22 as u32,
230    D23 = Register_REG_D23 as u32,
231    D24 = Register_REG_D24 as u32,
232    D25 = Register_REG_D25 as u32,
233    D26 = Register_REG_D26 as u32,
234    D27 = Register_REG_D27 as u32,
235    D28 = Register_REG_D28 as u32,
236    D29 = Register_REG_D29 as u32,
237    D30 = Register_REG_D30 as u32,
238    D31 = Register_REG_D31 as u32,
239    Q0 = Register_REG_Q0 as u32,
240    Q1 = Register_REG_Q1 as u32,
241    Q2 = Register_REG_Q2 as u32,
242    Q3 = Register_REG_Q3 as u32,
243    Q4 = Register_REG_Q4 as u32,
244    Q5 = Register_REG_Q5 as u32,
245    Q6 = Register_REG_Q6 as u32,
246    Q7 = Register_REG_Q7 as u32,
247    Q8 = Register_REG_Q8 as u32,
248    Q9 = Register_REG_Q9 as u32,
249    Q10 = Register_REG_Q10 as u32,
250    Q11 = Register_REG_Q11 as u32,
251    Q12 = Register_REG_Q12 as u32,
252    Q13 = Register_REG_Q13 as u32,
253    Q14 = Register_REG_Q14 as u32,
254    Q15 = Register_REG_Q15 as u32,
255    Q16 = Register_REG_Q16 as u32,
256    Q17 = Register_REG_Q17 as u32,
257    Q18 = Register_REG_Q18 as u32,
258    Q19 = Register_REG_Q19 as u32,
259    Q20 = Register_REG_Q20 as u32,
260    Q21 = Register_REG_Q21 as u32,
261    Q22 = Register_REG_Q22 as u32,
262    Q23 = Register_REG_Q23 as u32,
263    Q24 = Register_REG_Q24 as u32,
264    Q25 = Register_REG_Q25 as u32,
265    Q26 = Register_REG_Q26 as u32,
266    Q27 = Register_REG_Q27 as u32,
267    Q28 = Register_REG_Q28 as u32,
268    Q29 = Register_REG_Q29 as u32,
269    Q30 = Register_REG_Q30 as u32,
270    Q31 = Register_REG_Q31 as u32,
271    Z0 = Register_REG_Z0 as u32,
272    Z1 = Register_REG_Z1 as u32,
273    Z2 = Register_REG_Z2 as u32,
274    Z3 = Register_REG_Z3 as u32,
275    Z4 = Register_REG_Z4 as u32,
276    Z5 = Register_REG_Z5 as u32,
277    Z6 = Register_REG_Z6 as u32,
278    Z7 = Register_REG_Z7 as u32,
279    Z8 = Register_REG_Z8 as u32,
280    Z9 = Register_REG_Z9 as u32,
281    Z10 = Register_REG_Z10 as u32,
282    Z11 = Register_REG_Z11 as u32,
283    Z12 = Register_REG_Z12 as u32,
284    Z13 = Register_REG_Z13 as u32,
285    Z14 = Register_REG_Z14 as u32,
286    Z15 = Register_REG_Z15 as u32,
287    Z16 = Register_REG_Z16 as u32,
288    Z17 = Register_REG_Z17 as u32,
289    Z18 = Register_REG_Z18 as u32,
290    Z19 = Register_REG_Z19 as u32,
291    Z20 = Register_REG_Z20 as u32,
292    Z21 = Register_REG_Z21 as u32,
293    Z22 = Register_REG_Z22 as u32,
294    Z23 = Register_REG_Z23 as u32,
295    Z24 = Register_REG_Z24 as u32,
296    Z25 = Register_REG_Z25 as u32,
297    Z26 = Register_REG_Z26 as u32,
298    Z27 = Register_REG_Z27 as u32,
299    Z28 = Register_REG_Z28 as u32,
300    Z29 = Register_REG_Z29 as u32,
301    Z30 = Register_REG_Z30 as u32,
302    Z31 = Register_REG_Z31 as u32,
303    P0 = Register_REG_P0 as u32,
304    P1 = Register_REG_P1 as u32,
305    P2 = Register_REG_P2 as u32,
306    P3 = Register_REG_P3 as u32,
307    P4 = Register_REG_P4 as u32,
308    P5 = Register_REG_P5 as u32,
309    P6 = Register_REG_P6 as u32,
310    P7 = Register_REG_P7 as u32,
311    P8 = Register_REG_P8 as u32,
312    P9 = Register_REG_P9 as u32,
313    P10 = Register_REG_P10 as u32,
314    P11 = Register_REG_P11 as u32,
315    P12 = Register_REG_P12 as u32,
316    P13 = Register_REG_P13 as u32,
317    P14 = Register_REG_P14 as u32,
318    P15 = Register_REG_P15 as u32,
319    P16 = Register_REG_P16 as u32,
320    P17 = Register_REG_P17 as u32,
321    P18 = Register_REG_P18 as u32,
322    P19 = Register_REG_P19 as u32,
323    P20 = Register_REG_P20 as u32,
324    P21 = Register_REG_P21 as u32,
325    P22 = Register_REG_P22 as u32,
326    P23 = Register_REG_P23 as u32,
327    P24 = Register_REG_P24 as u32,
328    P25 = Register_REG_P25 as u32,
329    P26 = Register_REG_P26 as u32,
330    P27 = Register_REG_P27 as u32,
331    P28 = Register_REG_P28 as u32,
332    P29 = Register_REG_P29 as u32,
333    P30 = Register_REG_P30 as u32,
334    P31 = Register_REG_P31 as u32,
335    ZT0 = Register_REG_ZT0 as u32,
336}
337
338const_assert_eq!(Register_REG_END, Register_REG_ZT0 + 1);
339
340impl Reg {
341    /// Returns the register name
342    ///
343    /// # Examples
344    /// ```
345    /// use bad64::Reg;
346    ///
347    /// assert_eq!(Reg::X0.name(), "x0");
348    /// ```
349    pub fn name(&self) -> &'static str {
350        #[cfg(target_os = "windows")]
351        {
352            unsafe { CStr::from_ptr(get_register_name(self.to_i32().unwrap()) as _) }
353                .to_str()
354                .unwrap()
355        }
356        #[cfg(not(target_os = "windows"))]
357        {
358            unsafe { CStr::from_ptr(get_register_name(self.to_u32().unwrap()) as _) }
359                .to_str()
360                .unwrap()
361        }
362    }
363
364    /// Returns the register size
365    ///
366    /// # Examples
367    /// ```
368    /// use bad64::Reg;
369    ///
370    /// assert_eq!(Reg::X0.size(), 8);
371    /// assert_eq!(Reg::V0.size(), 16);
372    /// ```
373    ///
374    /// ```
375    /// use bad64::{decode, Operand, Reg};
376    ///
377    /// // add x0, x1, #0x41  - "\x20\x04\x01\x91"
378    /// let decoded = decode(0x91010420, 0x1000).unwrap();
379    ///
380    /// let op = decoded.operands()[0];
381    ///
382    /// assert_eq!(op, Operand::Reg { reg: Reg::X0, arrspec: None });
383    ///
384    /// match op {
385    ///     Operand::Reg { reg: r, .. } => assert_eq!(r.size(), 8),
386    ///     _ => assert!(false),
387    /// };
388    /// ```
389    pub fn size(&self) -> usize {
390        #[cfg(target_os = "windows")]
391        {
392            unsafe { bad64_sys::get_register_size(self.to_i32().unwrap()) as usize }
393        }
394        #[cfg(not(target_os = "windows"))]
395        {
396            unsafe { bad64_sys::get_register_size(self.to_u32().unwrap()) as usize }
397        }
398    }
399
400    /// Returns register's SIMD status
401    ///
402    /// # Example
403    /// ```
404    /// use bad64::Reg;
405    ///
406    /// assert_eq!(Reg::V0.is_simd(), true);
407    /// assert_eq!(Reg::D0.is_simd(), false);
408    /// assert_eq!(Reg::X0.is_simd(), false);
409    /// assert_eq!(Reg::Z0.is_simd(), false);
410    /// assert_eq!(Reg::P0.is_simd(), false);
411    /// ```
412    pub fn is_simd(&self) -> bool {
413        self.to_u32().unwrap() >= Reg::V0.to_u32().unwrap()
414            && self.to_u32().unwrap() <= Reg::V31.to_u32().unwrap()
415    }
416
417    /// Returns register's SVE status
418    ///
419    /// # Example
420    /// ```
421    /// use bad64::Reg;
422    ///
423    /// assert_eq!(Reg::Z0.is_sve(), true);
424    /// assert_eq!(Reg::V0.is_sve(), false);
425    /// assert_eq!(Reg::D0.is_sve(), false);
426    /// assert_eq!(Reg::X0.is_sve(), false);
427    /// assert_eq!(Reg::P0.is_simd(), false);
428    /// ```
429    pub fn is_sve(&self) -> bool {
430        self.to_u32().unwrap() >= Reg::Z0.to_u32().unwrap()
431            && self.to_u32().unwrap() <= Reg::Z31.to_u32().unwrap()
432    }
433
434    /// Returns register's predicate status
435    ///
436    /// # Example
437    /// ```
438    /// use bad64::Reg;
439    ///
440    /// assert_eq!(Reg::P0.is_pred(), true);
441    /// assert_eq!(Reg::V0.is_pred(), false);
442    /// assert_eq!(Reg::D0.is_pred(), false);
443    /// assert_eq!(Reg::X0.is_pred(), false);
444    /// assert_eq!(Reg::Z0.is_pred(), false);
445    /// ```
446    pub fn is_pred(&self) -> bool {
447        self.to_u32().unwrap() >= Reg::P0.to_u32().unwrap()
448            && self.to_u32().unwrap() <= Reg::P31.to_u32().unwrap()
449    }
450}
451
452impl fmt::Display for Reg {
453    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
454        write!(f, "{}", self.name())
455    }
456}