1use core::fmt;
21
22pub type Result<T> = core::result::Result<T, Error>;
24
25#[derive(Debug, Clone, PartialEq, Eq)]
27#[non_exhaustive]
28pub enum Error {
29 InvalidMachineMode,
31
32 InvalidStackWidth,
34
35 DecodeFailed(DecodeError),
37
38 EncodeFailed(EncodeError),
40
41 IncompleteInstruction {
43 needed: usize,
45 },
46
47 InsufficientBytes,
49
50 InstructionTooLong,
52
53 InvalidEncoding,
55
56 BufferTooSmall,
58
59 InvalidOperand,
61
62 NotYetImplemented(&'static str),
64
65 UndefinedInstruction {
67 opcode: u8,
69 reason: UndefinedReason,
71 },
72
73 InvalidPrefixCombination {
75 prefixes: &'static str,
77 },
78
79 EvexEncodingError {
81 kind: EvexErrorKind,
83 },
84
85 ModeNotSupported {
87 mode: &'static str,
89 feature: &'static str,
91 },
92}
93
94#[derive(Debug, Clone, Copy, PartialEq, Eq)]
96pub enum UndefinedReason {
97 Reserved,
99 NeverDefined,
101 Removed,
103 ModeInvalid,
105 InvalidPrefix,
107}
108
109#[derive(Debug, Clone, Copy, PartialEq, Eq)]
111pub enum EvexErrorKind {
112 InvalidMaskRegister,
114 ZeroingWithoutMask,
116 InvalidRoundingMode,
118 SaeNotSupported,
120 InvalidBroadcast,
122 InvalidVectorLength,
124 EmbeddedRoundingRequiresReg,
126}
127
128impl fmt::Display for Error {
129 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
130 match self {
131 Error::InvalidMachineMode => write!(f, "invalid machine mode"),
132 Error::InvalidStackWidth => write!(f, "invalid stack width"),
133 Error::DecodeFailed(e) => write!(f, "decode failed: {}", e),
134 Error::EncodeFailed(e) => write!(f, "encode failed: {}", e),
135 Error::IncompleteInstruction { needed } => {
136 write!(f, "incomplete instruction, need {} more bytes", needed)
137 }
138 Error::InsufficientBytes => write!(f, "insufficient bytes to decode instruction"),
139 Error::InstructionTooLong => {
140 write!(f, "instruction exceeds maximum length of 15 bytes")
141 }
142 Error::InvalidEncoding => write!(f, "invalid instruction encoding"),
143 Error::BufferTooSmall => write!(f, "buffer too small"),
144 Error::InvalidOperand => write!(f, "invalid operand"),
145 Error::NotYetImplemented(msg) => write!(f, "not yet implemented: {}", msg),
146 Error::UndefinedInstruction { opcode, reason } => {
147 let reason_str = match reason {
148 UndefinedReason::Reserved => "reserved opcode",
149 UndefinedReason::NeverDefined => "undefined opcode",
150 UndefinedReason::Removed => "removed opcode",
151 UndefinedReason::ModeInvalid => "invalid in current mode",
152 UndefinedReason::InvalidPrefix => "invalid prefix combination",
153 };
154 write!(
155 f,
156 "undefined instruction: opcode 0x{:02X} ({})",
157 opcode, reason_str
158 )
159 }
160 Error::InvalidPrefixCombination { prefixes } => {
161 write!(f, "invalid prefix combination: {}", prefixes)
162 }
163 Error::EvexEncodingError { kind } => {
164 let kind_str = match kind {
165 EvexErrorKind::InvalidMaskRegister => "invalid mask register (must be k0-k7)",
166 EvexErrorKind::ZeroingWithoutMask => "zeroing mode requires non-zero mask",
167 EvexErrorKind::InvalidRoundingMode => "invalid rounding mode encoding",
168 EvexErrorKind::SaeNotSupported => "SAE not supported for this instruction",
169 EvexErrorKind::InvalidBroadcast => "broadcast not valid for this operand",
170 EvexErrorKind::InvalidVectorLength => "vector length not supported",
171 EvexErrorKind::EmbeddedRoundingRequiresReg => {
172 "embedded rounding requires register operand"
173 }
174 };
175 write!(f, "EVEX encoding error: {}", kind_str)
176 }
177 Error::ModeNotSupported { mode, feature } => {
178 write!(f, "{} not supported in {} mode", feature, mode)
179 }
180 }
181 }
182}
183
184#[cfg(feature = "std")]
185impl std::error::Error for Error {}
186
187#[derive(Debug, Clone, Copy, PartialEq, Eq)]
189pub enum DecodeError {
190 NoMoreData,
192
193 InvalidOpcode,
195
196 InvalidModRM,
198
199 InvalidSIB,
201
202 InvalidDisplacement,
204
205 InvalidImmediate,
207
208 InvalidPrefix,
210
211 InternalError,
213
214 UndefinedOpcode,
216
217 ReservedOpcode,
219
220 VexError,
222
223 EvexError,
225
226 XopError,
228
229 ThreeDNowError,
231
232 InvalidLockPrefix,
234
235 InvalidRepPrefix,
237
238 RexInLegacyMode,
240
241 TooLong,
243
244 InvalidRegister,
246
247 MissingModRM,
249
250 MissingSIB,
252}
253
254impl fmt::Display for DecodeError {
255 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
256 match self {
257 DecodeError::NoMoreData => write!(f, "no more data to decode"),
258 DecodeError::InvalidOpcode => write!(f, "invalid opcode"),
259 DecodeError::InvalidModRM => write!(f, "invalid ModRM byte"),
260 DecodeError::InvalidSIB => write!(f, "invalid SIB byte"),
261 DecodeError::InvalidDisplacement => write!(f, "invalid displacement"),
262 DecodeError::InvalidImmediate => write!(f, "invalid immediate value"),
263 DecodeError::InvalidPrefix => write!(f, "invalid prefix combination"),
264 DecodeError::InternalError => write!(f, "internal decoder error"),
265 DecodeError::UndefinedOpcode => write!(f, "undefined opcode"),
266 DecodeError::ReservedOpcode => write!(f, "reserved opcode"),
267 DecodeError::VexError => write!(f, "VEX prefix error"),
268 DecodeError::EvexError => write!(f, "EVEX prefix error"),
269 DecodeError::XopError => write!(f, "XOP prefix error"),
270 DecodeError::ThreeDNowError => write!(f, "3DNow! instruction error"),
271 DecodeError::InvalidLockPrefix => write!(f, "invalid LOCK prefix"),
272 DecodeError::InvalidRepPrefix => write!(f, "invalid REP/REPE prefix"),
273 DecodeError::RexInLegacyMode => write!(f, "REX prefix in legacy mode"),
274 DecodeError::TooLong => write!(f, "instruction exceeds 15 bytes"),
275 DecodeError::InvalidRegister => write!(f, "invalid register encoding"),
276 DecodeError::MissingModRM => write!(f, "missing mandatory ModRM byte"),
277 DecodeError::MissingSIB => write!(f, "missing mandatory SIB byte"),
278 }
279 }
280}
281
282#[cfg(feature = "std")]
283impl std::error::Error for DecodeError {}
284
285#[derive(Debug, Clone, Copy, PartialEq, Eq)]
287pub enum EncodeError {
288 InvalidInstruction,
290
291 InvalidMnemonic,
293
294 InvalidOperandCombination,
296
297 UnsupportedInMode,
299
300 RegisterError,
302
303 ImmediateOutOfRange,
305
306 DisplacementOutOfRange,
308
309 InternalError,
311
312 MaskRegisterError,
314
315 ZeroingModeError,
317
318 RoundingModeError,
320
321 SaeError,
323
324 BroadcastError,
326
327 VexNotPossible,
329
330 EvexRequired,
332
333 MemoryOperandRequired,
335
336 RegisterOperandRequired,
338
339 InvalidScaleFactor,
341
342 RspAsIndexRegister,
344
345 BaseRequiresDisplacement,
347
348 NotEncodable,
350}
351
352impl fmt::Display for EncodeError {
353 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
354 match self {
355 EncodeError::InvalidInstruction => write!(f, "invalid instruction for encoding"),
356 EncodeError::InvalidMnemonic => write!(f, "invalid mnemonic"),
357 EncodeError::InvalidOperandCombination => write!(f, "invalid operand combination"),
358 EncodeError::UnsupportedInMode => {
359 write!(f, "unsupported instruction in current machine mode")
360 }
361 EncodeError::RegisterError => write!(f, "register encoding error"),
362 EncodeError::ImmediateOutOfRange => write!(f, "immediate value out of range"),
363 EncodeError::DisplacementOutOfRange => write!(f, "displacement out of range"),
364 EncodeError::InternalError => write!(f, "internal encoder error"),
365 EncodeError::MaskRegisterError => write!(f, "AVX-512 mask register error"),
366 EncodeError::ZeroingModeError => write!(f, "AVX-512 zeroing mode error"),
367 EncodeError::RoundingModeError => write!(f, "AVX-512 rounding mode error"),
368 EncodeError::SaeError => write!(f, "AVX-512 SAE error"),
369 EncodeError::BroadcastError => write!(f, "AVX-512 broadcast error"),
370 EncodeError::VexNotPossible => write!(f, "VEX encoding not possible (EVEX required)"),
371 EncodeError::EvexRequired => write!(f, "EVEX encoding required"),
372 EncodeError::MemoryOperandRequired => write!(f, "memory operand required"),
373 EncodeError::RegisterOperandRequired => write!(f, "register operand required"),
374 EncodeError::InvalidScaleFactor => {
375 write!(f, "invalid scale factor (must be 1, 2, 4, or 8)")
376 }
377 EncodeError::RspAsIndexRegister => write!(f, "RSP cannot be used as index register"),
378 EncodeError::BaseRequiresDisplacement => {
379 write!(f, "RBP/R13 as base requires displacement")
380 }
381 EncodeError::NotEncodable => write!(f, "instruction not encodable"),
382 }
383 }
384}
385
386#[cfg(feature = "std")]
387impl std::error::Error for EncodeError {}