iced_x86/formatter/
fmt_utils_all.rs1use crate::{Code, CodeSize, Instruction, Register};
5
6#[must_use]
7pub(super) const fn is_rep_repe_repne_instruction(code: Code) -> bool {
8 matches!(
9 code,
10 Code::Insb_m8_DX
11 | Code::Insw_m16_DX
12 | Code::Insd_m32_DX
13 | Code::Outsb_DX_m8
14 | Code::Outsw_DX_m16
15 | Code::Outsd_DX_m32
16 | Code::Movsb_m8_m8
17 | Code::Movsw_m16_m16
18 | Code::Movsd_m32_m32
19 | Code::Movsq_m64_m64
20 | Code::Cmpsb_m8_m8
21 | Code::Cmpsw_m16_m16
22 | Code::Cmpsd_m32_m32
23 | Code::Cmpsq_m64_m64
24 | Code::Stosb_m8_AL
25 | Code::Stosw_m16_AX
26 | Code::Stosd_m32_EAX
27 | Code::Stosq_m64_RAX
28 | Code::Lodsb_AL_m8
29 | Code::Lodsw_AX_m16
30 | Code::Lodsd_EAX_m32
31 | Code::Lodsq_RAX_m64
32 | Code::Scasb_AL_m8
33 | Code::Scasw_AX_m16
34 | Code::Scasd_EAX_m32
35 | Code::Scasq_RAX_m64
36 | Code::Montmul_16
37 | Code::Montmul_32
38 | Code::Montmul_64
39 | Code::Xsha1_16
40 | Code::Xsha1_32
41 | Code::Xsha1_64
42 | Code::Xsha256_16
43 | Code::Xsha256_32
44 | Code::Xsha256_64
45 | Code::Xstore_16
46 | Code::Xstore_32
47 | Code::Xstore_64
48 | Code::Xcryptecb_16
49 | Code::Xcryptecb_32
50 | Code::Xcryptecb_64
51 | Code::Xcryptcbc_16
52 | Code::Xcryptcbc_32
53 | Code::Xcryptcbc_64
54 | Code::Xcryptctr_16
55 | Code::Xcryptctr_32
56 | Code::Xcryptctr_64
57 | Code::Xcryptcfb_16
58 | Code::Xcryptcfb_32
59 | Code::Xcryptcfb_64
60 | Code::Xcryptofb_16
61 | Code::Xcryptofb_32
62 | Code::Xcryptofb_64
63 | Code::Ccs_hash_16
64 | Code::Ccs_hash_32
65 | Code::Ccs_hash_64
66 | Code::Ccs_encrypt_16
67 | Code::Ccs_encrypt_32
68 | Code::Ccs_encrypt_64
69 | Code::Via_undoc_F30FA6F0_16
70 | Code::Via_undoc_F30FA6F0_32
71 | Code::Via_undoc_F30FA6F0_64
72 | Code::Via_undoc_F30FA6F8_16
73 | Code::Via_undoc_F30FA6F8_32
74 | Code::Via_undoc_F30FA6F8_64
75 | Code::Xsha512_16
76 | Code::Xsha512_32
77 | Code::Xsha512_64
78 | Code::Xstore_alt_16
79 | Code::Xstore_alt_32
80 | Code::Xstore_alt_64
81 | Code::Xsha512_alt_16
82 | Code::Xsha512_alt_32
83 | Code::Xsha512_alt_64
84 )
85}
86
87#[must_use]
88pub(super) const fn show_rep_or_repe_prefix_bool(code: Code, show_useless_prefixes: bool) -> bool {
89 if show_useless_prefixes || is_rep_repe_repne_instruction(code) {
90 true
91 } else {
92 match code {
94 Code::Retnw | Code::Retnd | Code::Retnq => true,
95 _ => show_useless_prefixes,
96 }
97 }
98}
99
100#[must_use]
101pub(super) const fn show_repne_prefix_bool(code: Code, show_useless_prefixes: bool) -> bool {
102 if show_useless_prefixes || is_rep_repe_repne_instruction(code) {
104 true
105 } else {
106 show_useless_prefixes
107 }
108}
109
110#[must_use]
111pub(super) fn is_code64(code_size: CodeSize) -> bool {
112 code_size == CodeSize::Code64 || code_size == CodeSize::Unknown
113}
114
115#[must_use]
116pub(super) fn get_default_segment_register(instruction: &Instruction) -> Register {
117 let base_reg = instruction.memory_base();
118 if base_reg == Register::BP || base_reg == Register::EBP || base_reg == Register::ESP || base_reg == Register::RBP || base_reg == Register::RSP {
119 Register::SS
120 } else {
121 Register::DS
122 }
123}
124
125#[must_use]
126pub(super) fn show_segment_prefix_bool(mut default_seg_reg: Register, instruction: &Instruction, show_useless_prefixes: bool) -> bool {
127 if instruction.code().ignores_segment() {
128 return show_useless_prefixes;
129 }
130 let prefix_seg = instruction.segment_prefix();
131 debug_assert_ne!(prefix_seg, Register::None);
132 if is_code64(instruction.code_size()) {
133 if prefix_seg == Register::FS || prefix_seg == Register::GS {
135 true
136 } else {
137 show_useless_prefixes
138 }
139 } else {
140 if default_seg_reg == Register::None {
141 default_seg_reg = get_default_segment_register(instruction);
142 }
143 if prefix_seg != default_seg_reg {
144 true
145 } else {
146 show_useless_prefixes
147 }
148 }
149}
150
151#[must_use]
152pub(super) const fn is_repe_or_repne_instruction(code: Code) -> bool {
153 matches!(
154 code,
155 Code::Cmpsb_m8_m8
156 | Code::Cmpsw_m16_m16
157 | Code::Cmpsd_m32_m32
158 | Code::Cmpsq_m64_m64
159 | Code::Scasb_AL_m8
160 | Code::Scasw_AX_m16
161 | Code::Scasd_EAX_m32
162 | Code::Scasq_RAX_m64
163 )
164}
165
166#[must_use]
167#[inline]
168pub(super) const fn is_notrack_prefix_branch(code: Code) -> bool {
169 const _: () = assert!(Code::Jmp_rm16 as u32 + 1 == Code::Jmp_rm32 as u32);
170 const _: () = assert!(Code::Jmp_rm16 as u32 + 2 == Code::Jmp_rm64 as u32);
171 const _: () = assert!(Code::Call_rm16 as u32 + 1 == Code::Call_rm32 as u32);
172 const _: () = assert!(Code::Call_rm16 as u32 + 2 == Code::Call_rm64 as u32);
173 (code as u32).wrapping_sub(Code::Jmp_rm16 as u32) <= 2 || (code as u32).wrapping_sub(Code::Call_rm16 as u32) <= 2
174}