1 | //! Utility macros. |
2 | |
3 | // Helper macro used to trigger const eval errors when the const generic immediate value `imm` is |
4 | // not a round number. |
5 | #[allow (unused)] |
6 | macro_rules! static_assert_rounding { |
7 | ($imm:ident) => { |
8 | static_assert!( |
9 | $imm == 4 || $imm == 8 || $imm == 9 || $imm == 10 || $imm == 11, |
10 | "Invalid IMM value" |
11 | ) |
12 | }; |
13 | } |
14 | |
15 | // Helper macro used to trigger const eval errors when the const generic immediate value `imm` is |
16 | // not a sae number. |
17 | #[allow (unused)] |
18 | macro_rules! static_assert_sae { |
19 | ($imm:ident) => { |
20 | static_assert!($imm == 4 || $imm == 8, "Invalid IMM value" ) |
21 | }; |
22 | } |
23 | |
24 | // Helper macro used to trigger const eval errors when the const generic immediate value `imm` is |
25 | // not an extended rounding number |
26 | #[allow (unused)] |
27 | macro_rules! static_assert_extended_rounding { |
28 | ($imm: ident) => { |
29 | static_assert!(($imm & 7) < 5 && ($imm & !15) == 0, "Invalid IMM value" ) |
30 | }; |
31 | } |
32 | |
33 | // Helper macro used to trigger const eval errors when the const generic immediate value `imm` is |
34 | // not a mantissas sae number. |
35 | #[allow (unused)] |
36 | macro_rules! static_assert_mantissas_sae { |
37 | ($imm:ident) => { |
38 | static_assert!($imm == 4 || $imm == 8 || $imm == 12, "Invalid IMM value" ) |
39 | }; |
40 | } |
41 | |
42 | // Helper macro used to trigger const eval errors when the const generic immediate value `SCALE` is |
43 | // not valid for gather instructions: the only valid scale values are 1, 2, 4 and 8. |
44 | #[allow (unused)] |
45 | macro_rules! static_assert_imm8_scale { |
46 | ($imm:ident) => { |
47 | static_assert!( |
48 | $imm == 1 || $imm == 2 || $imm == 4 || $imm == 8, |
49 | "Invalid SCALE value" |
50 | ) |
51 | }; |
52 | } |
53 | |
54 | #[cfg (test)] |
55 | macro_rules! assert_approx_eq { |
56 | ($a:expr, $b:expr, $eps:expr) => {{ |
57 | let (a, b) = (&$a, &$b); |
58 | assert!( |
59 | (*a - *b).abs() < $eps, |
60 | "assertion failed: `(left !== right)` \ |
61 | (left: `{:?}`, right: `{:?}`, expect diff: `{:?}`, real diff: `{:?}`)" , |
62 | *a, |
63 | *b, |
64 | $eps, |
65 | (*a - *b).abs() |
66 | ); |
67 | }}; |
68 | } |
69 | |
70 | // x86-32 wants to use a 32-bit address size, but asm! defaults to using the full |
71 | // register name (e.g. rax). We have to explicitly override the placeholder to |
72 | // use the 32-bit register name in that case. |
73 | |
74 | #[cfg (target_pointer_width = "32" )] |
75 | macro_rules! vpl { |
76 | ($inst:expr) => { |
77 | concat!($inst, ", [{p:e}]" ) |
78 | }; |
79 | } |
80 | #[cfg (target_pointer_width = "64" )] |
81 | macro_rules! vpl { |
82 | ($inst:expr) => { |
83 | concat!($inst, ", [{p}]" ) |
84 | }; |
85 | } |
86 | |
87 | #[cfg (target_pointer_width = "32" )] |
88 | macro_rules! vps { |
89 | ($inst1:expr, $inst2:expr) => { |
90 | concat!($inst1, " [{p:e}]" , $inst2) |
91 | }; |
92 | } |
93 | #[cfg (target_pointer_width = "64" )] |
94 | macro_rules! vps { |
95 | ($inst1:expr, $inst2:expr) => { |
96 | concat!($inst1, " [{p}]" , $inst2) |
97 | }; |
98 | } |
99 | |