1use std::io::{Read, Write};
2
3use crate::traits::{Address, InsnRead, InsnWrite, Reloc};
4
5use super::{X86Register, X86RegisterClass};
6
7#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
8pub enum Prefix {
9 Lock,
10 Rep,
11 Repnz,
12 Repz,
13}
14
15#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
16pub enum X86Mode {
17 Real,
18 Protected,
19 Virtual8086,
20 Compatibility,
21 Long,
22}
23
24impl X86Mode {
25 pub fn default_mode_for(target: &Target) -> Option<X86Mode> {
26 match target.arch() {
27 target_tuples::Architecture::I86 => Some(X86Mode::Real),
28 target_tuples::Architecture::I8086 => Some(X86Mode::Real),
29 target_tuples::Architecture::I086 => Some(X86Mode::Real),
30 target_tuples::Architecture::I186 => Some(X86Mode::Real),
31 target_tuples::Architecture::I286 => Some(X86Mode::Real),
32 target_tuples::Architecture::I386 => Some(X86Mode::Protected),
33 target_tuples::Architecture::I486 => Some(X86Mode::Protected),
34 target_tuples::Architecture::I586 => Some(X86Mode::Protected),
35 target_tuples::Architecture::I686 => Some(X86Mode::Protected),
36 target_tuples::Architecture::X86_64 => Some(X86Mode::Long),
37 _ => None,
38 }
39 }
40
41 pub fn largest_gpr(&self) -> X86RegisterClass {
42 match self {
43 Self::Real | Self::Virtual8086 => X86RegisterClass::Word,
44 Self::Protected | Self::Compatibility => X86RegisterClass::Double,
45 Self::Long => X86RegisterClass::Quad,
46 }
47 }
48}
49
50#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
51pub enum X86OperandType {
52 ModRM(X86RegisterClass),
55 ModRMMem,
57 Reg(X86RegisterClass),
60 OpReg(X86RegisterClass),
63
64 ModRMGeneral,
66
67 ModRMMode,
69
70 ModRMSib(X86RegisterClass),
72
73 ModRMReal(X86RegisterClass),
75
76 ModRMReg(X86RegisterClass),
78
79 ModRMScalar(X86RegisterClass),
81
82 VexReg,
84 VexModRM,
86 VexModRMScalar(X86RegisterClass),
88
89 VexPrefix(X86RegisterClass),
92
93 RegGeneral,
95
96 OpRegGeneral,
98
99 OpRegMode,
101
102 AReg(X86RegisterClass),
105
106 ARegGeneral,
108
109 ARegMode,
111
112 DReg(X86RegisterClass),
113
114 DRegGeneral,
115
116 CReg(X86RegisterClass),
117
118 CRegGeneral,
119
120 Flags(X86RegisterClass),
121
122 FlagsMode,
123
124 Insn,
126 VecInsn,
128 Imm(usize),
130
131 ImmGeneral,
133
134 ImmGeneralWide,
136
137 Rel(usize),
139
140 RelGeneral,
142
143 RControlBits(u8),
145
146 Seg,
148
149 AvxReg,
151
152 AvxMem,
154
155 Moff(X86RegisterClass),
156 MoffGeneral,
157
158 MemDest(X86RegisterClass),
161 MemDestGeneral,
163 MemSrc(X86RegisterClass),
166 MemSrcGeneral,
168}
169
170macro_rules! define_x86_instructions {
171 {
172 $(($enum:ident, $mnemonic:literal, $opcode:literal, [$($operand:expr),*] $(, [$($mode:ident),*] $(, [$($feature:ident),*])?)?)),* $(,)?
173 } => {
174 #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
175 #[non_exhaustive]
176 pub enum X86Opcode {
177 $($enum,)* __NoMoreOpcodes
178 }
179
180 impl X86Opcode{
181 pub fn opcode(&self) -> u64 {
182 match self {
183 $(Self::$enum => $opcode,)*
184 Self::__NoMoreOpcodes => unreachable!(),
185 }
186 }
187
188 pub fn operands(&self) -> &'static [X86OperandType] {
189 match self {
190 $(Self::$enum => &[$($operand),*],)*
191 Self::__NoMoreOpcodes => unreachable!(),
192 }
193 }
194
195 pub fn mnemonic(&self) -> &'static str {
196 match self {
197 $(Self:: $enum => $mnemonic,)*
198 Self::__NoMoreOpcodes => unreachable!(),
199 }
200 }
201
202 pub fn valid_in_mode(&self, modes: &X86Mode) -> bool {
203 #[allow(unreachable_code)] match self{
205 $(Self:: $enum =>{ $(return match modes {
206 $(X86Mode:: $mode => true,)*
207 _ => false
208 };)? true}),*
209 Self::__NoMoreOpcodes => unreachable!(),
210 }
211 }
212
213 }
214
215 impl std::fmt::Display for X86Opcode {
216 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
217 match self {
218 $(Self::$enum => f.write_str($mnemonic),)*
219 Self::__NoMoreOpcodes => unreachable!(),
220 }
221 }
222 }
223
224 pub const X86_OPCODES: [X86Opcode; X86Opcode::__NoMoreOpcodes as usize] = [ $(X86Opcode::$enum,)* ];
225 }
226}
227
228use target_tuples::Target;
229use X86OperandType::*;
230use X86RegisterClass::*;
231
232define_x86_instructions! {
233 (AddMR8, "add", 0x00, [ModRM(Byte), Reg(Byte)]),
234 (AddMR, "add", 0x01, [ModRMGeneral, RegGeneral]),
235 (AddRM8, "add", 0x02, [Reg(Byte), ModRM(Byte)]),
236 (AddRM, "add", 0x03, [RegGeneral, ModRMGeneral]),
237 (AddAImm8,"add", 0x04, [AReg(Byte), Imm(1)]),
238 (AddAImm, "add", 0x05, [ARegGeneral, ImmGeneral]),
239 (OrMR8, "or", 0x08, [ModRM(Byte), Reg(Byte)]),
240 (OrMR, "or", 0x09, [ModRMGeneral, RegGeneral]),
241 (OrRM8, "or", 0x0A, [Reg(Byte), ModRM(Byte)]),
242 (OrRM, "or", 0x0B, [RegGeneral, ModRMGeneral]),
243 (OrAImm8, "or", 0x0C, [AReg(Byte), Imm(1)]),
244 (OrAImm, "or", 0x0D, [ARegGeneral, ImmGeneral]),
245 (AdcMR8, "adc", 0x10, [ModRM(Byte), Reg(Byte)]),
246 (AdcMR, "adc", 0x11, [ModRMGeneral, RegGeneral]),
247 (AdcRM8, "adc", 0x12, [Reg(Byte), ModRM(Byte)]),
248 (AdcRM, "adc", 0x13, [RegGeneral, ModRMGeneral]),
249 (AdcAImm8,"adc", 0x14, [AReg(Byte), Imm(1)]),
250 (AdcAImm, "adc", 0x15, [ARegGeneral, ImmGeneral]),
251 (SbbMR8, "sbb", 0x18, [ModRM(Byte), Reg(Byte)]),
252 (SbbMR, "sbb", 0x19, [ModRMGeneral, RegGeneral]),
253 (SbbRM8, "sbb", 0x1A, [Reg(Byte), ModRM(Byte)]),
254 (SbbRM, "sbb", 0x1B, [RegGeneral, ModRMGeneral]),
255 (SbbAImm8,"sbb", 0x1C, [AReg(Byte), Imm(1)]),
256 (SbbaImm, "sbb", 0x1D, [ARegGeneral, ImmGeneral]),
257 (AndMR8, "and", 0x20, [ModRM(Byte), Reg(Byte)]),
258 (AndMR, "and", 0x21, [ModRMGeneral, RegGeneral]),
259 (AndRM8, "and", 0x22, [Reg(Byte), ModRM(Byte)]),
260 (AndRM, "and", 0x23, [RegGeneral, ModRMGeneral]),
261 (AndAImm8,"and", 0x24, [AReg(Byte), Imm(1)]),
262 (AndAImm, "and", 0x25, [ARegGeneral, ImmGeneral]),
263 (SubMR8, "sub", 0x28, [ModRM(Byte), Reg(Byte)]),
264 (SubMR, "sub", 0x29, [ModRMGeneral, RegGeneral]),
265 (SubRM8, "sub", 0x2A, [Reg(Byte), ModRM(Byte)]),
266 (SubRM, "sub", 0x2B, [RegGeneral, ModRMGeneral]),
267 (SubAImm8,"sub", 0x2C, [AReg(Byte), Imm(1)]),
268 (SubAImm, "sub", 0x2D, [ARegGeneral, ImmGeneral]),
269 (XorMR8, "xor", 0x30, [ModRM(Byte), Reg(Byte)]),
270 (XorMR, "xor", 0x31, [ModRMGeneral, RegGeneral]),
271 (XorRM8, "xor", 0x32, [Reg(Byte), ModRM(Byte)]),
272 (XorRM, "xor", 0x33, [RegGeneral, ModRMGeneral]),
273 (XorAImm8,"xor", 0x34, [AReg(Byte), Imm(1)]),
274 (XorAImm, "xor", 0x35, [ARegGeneral, ImmGeneral]),
275 (CmpMR8, "cmp", 0x38, [ModRM(Byte), Reg(Byte)]),
276 (CmpMR, "cmp", 0x39, [ModRMGeneral, RegGeneral]),
277 (CmpRM8, "cmp", 0x3A, [Reg(Byte), ModRM(Byte)]),
278 (CmpRM, "cmp", 0x3B, [RegGeneral, ModRMGeneral]),
279 (CmpAImm8,"cmp", 0x3C, [AReg(Byte), Imm(1)]),
280 (CmpAImm, "cmp", 0x3D, [ARegGeneral, ImmGeneral]),
281 (IncR, "inc", 0x40, [OpRegMode], [Real, Protected, Virtual8086, Compatibility]),
282 (Rex, "rex", 0x40, [Insn], [Long]),
283 (RexB, "rex.b",0x41, [Insn], [Long]),
284 (RexX, "rex.x",0x42, [Insn], [Long]),
285 (RexXB, "rex.xb",0x43, [Insn], [Long]),
286 (RexR, "rex.r", 0x44, [Insn], [Long]),
287 (RexRB, "rex.rb",0x45, [Insn], [Long]),
288 (RexRX, "rex.rx",0x46, [Insn], [Long]),
289 (RexRXB, "rex.rxb", 0x47, [Insn], [Long]),
290 (DecR, "dec", 0x48, [OpRegMode], [Real, Protected, Virtual8086, Compatibility]),
291 (RexW, "rex.w", 0x48, [Insn], [Long]),
292 (RexWB, "rex.wb",0x49, [Insn], [Long]),
293 (RexWX, "rex.wx",0x4A, [Insn], [Long]),
294 (RexWXB, "rex.wxb",0x4B, [Insn], [Long]),
295 (RexWR, "rex.wr", 0x4C, [Insn], [Long]),
296 (RexWRB, "rex.wrb",0x4D, [Insn], [Long]),
297 (RexWRX, "rex.wrx",0x4E, [Insn], [Long]),
298 (RexWRXB, "rex.wrxb", 0x4F, [Insn], [Long]),
299 (Push, "push",0x50, [OpRegMode]),
300 (Pop, "pop", 0x58, [OpRegMode]),
301 (Movsxd, "movsxd",0x63, [RegGeneral, ModRM(Double)]),
302 (FsSeg, "fs", 0x64, [Insn]),
303 (GsSeg, "gs", 0x65, [Insn]),
304 (OpSize, "66h", 0x66, [Insn]),
305 (AddrSize,"67h", 0x67, [Insn]),
306 (PushImm, "push",0x68, [ImmGeneral]),
307 (IMul, "imul",0x69, [RegGeneral, ModRMGeneral, ImmGeneral]),
308 (PushImm8,"push",0x6A, [Imm(8)]),
309 (IMul8, "imul",0x6B, [RegGeneral, ModRMGeneral, Imm(8)]),
310 (Insb, "ins", 0x6C, [ModRM(Byte), DReg(Byte)]),
311 (Ins, "ins", 0x6D, [ModRMGeneral, DRegGeneral]),
312 (Outsb, "outs",0x6E, [DReg(Byte), ModRM(Byte)]),
313 (Outs, "outs",0x6F, [DRegGeneral, ModRMGeneral]),
314 (Jo, "jo", 0x70, [Rel(8)]),
315 (Jno, "jno", 0x71, [Rel(8)]),
316 (Jb, "jb", 0x72, [Rel(8)]),
317 (Jae, "jae", 0x73, [Rel(8)]),
318 (Jz, "jz", 0x74, [Rel(8)]),
319 (Jnz, "jnz", 0x75, [Rel(8)]),
320 (Jbe, "jbe", 0x76, [Rel(8)]),
321 (Ja, "ja", 0x77, [Rel(8)]),
322 (Js, "js", 0x78, [Rel(8)]),
323 (Jns, "jns", 0x79, [Rel(8)]),
324 (Jp, "jp", 0x7A, [Rel(8)]),
325 (Jnp, "jnp", 0x7B, [Rel(8)]),
326 (Jl, "jl", 0x7C, [Rel(8)]),
327 (Jge, "jge", 0x7D, [Rel(8)]),
328 (Jle, "jle", 0x7E, [Rel(8)]),
329 (Jg, "jg", 0x7F, [Rel(8)]),
330 (AddImm8, "add", 0x80, [RControlBits(0), ModRM(Byte), Imm(8)]),
331 (OrImm8, "or", 0x80, [RControlBits(1), ModRM(Byte), Imm(8)]),
332 (AdcImm8, "adc", 0x80, [RControlBits(2), ModRM(Byte), Imm(8)]),
333 (SbbImm8, "sbb", 0x80, [RControlBits(3), ModRM(Byte), Imm(8)]),
334 (AndImm8, "and", 0x80, [RControlBits(4), ModRM(Byte), Imm(8)]),
335 (SubImm8, "sub", 0x80, [RControlBits(5), ModRM(Byte), Imm(8)]),
336 (XorImm8, "xor", 0x80, [RControlBits(6), ModRM(Byte), Imm(8)]),
337 (CmpImm8, "cmp", 0x80, [RControlBits(6), ModRM(Byte), Imm(8)]),
338 (AddImm, "add", 0x81, [RControlBits(0), ModRMGeneral, ImmGeneral]),
339 (OrImm, "or", 0x81, [RControlBits(1), ModRMGeneral, ImmGeneral]),
340 (AdcImm, "adc", 0x81, [RControlBits(2), ModRMGeneral, ImmGeneral]),
341 (SbbImm, "sbb", 0x81, [RControlBits(3), ModRMGeneral, ImmGeneral]),
342 (AndImm, "and", 0x81, [RControlBits(4), ModRMGeneral, ImmGeneral]),
343 (SubImm, "sub", 0x81, [RControlBits(5), ModRMGeneral, ImmGeneral]),
344 (XorImm, "xor", 0x81, [RControlBits(6), ModRMGeneral, ImmGeneral]),
345 (CmpImm, "cmp", 0x81, [RControlBits(7), ModRMGeneral, ImmGeneral]),
346 (AddGImm8,"add", 0x83, [RControlBits(0), ModRMGeneral, Imm(8)]),
347 (OrGImm8, "or", 0x83, [RControlBits(1), ModRMGeneral, Imm(8)]),
348 (AdcGImm8,"adc", 0x83, [RControlBits(2), ModRMGeneral, Imm(8)]),
349 (SbbGImm8,"sbb", 0x83, [RControlBits(3), ModRMGeneral, Imm(8)]),
350 (AndGImm8,"and", 0x83, [RControlBits(4), ModRMGeneral, Imm(8)]),
351 (SubGImm8,"sub", 0x83, [RControlBits(5), ModRMGeneral, Imm(8)]),
352 (XorGImm8,"xor", 0x83, [RControlBits(6), ModRMGeneral, Imm(8)]),
353 (CmpGImm8,"cmp", 0x83, [RControlBits(7), ModRMGeneral, Imm(8)]),
354 (Test8, "test",0x84, [ModRM(Byte),Reg(Byte)]),
355 (Test, "test",0x85, [ModRMGeneral, RegGeneral]),
356 (Xchg8, "xchg",0x86, [Reg(Byte), ModRM(Byte)]),
357 (Xchg, "xchg",0x87, [RegGeneral, ModRMGeneral]),
358 (MovMR8, "mov", 0x88, [ModRM(Byte),Reg(Byte)]),
359 (MovMR, "mov", 0x89, [ModRMGeneral, RegGeneral]),
360 (MovRM8, "mov", 0x8A, [Reg(Byte), ModRM(Byte)]),
361 (MovRM, "mov", 0x8B, [RegGeneral, ModRMGeneral]),
362 (MovRMS, "mov", 0x8C, [ModRMGeneral, Reg(Sreg)]),
363 (Lea, "lea", 0x8D, [RegGeneral, ModRMGeneral]),
364 (MovSRM, "mov", 0x8E, [Reg(Sreg), ModRM(Word)]),
365 (PopMR, "pop", 0x8F, [ModRMMode]),
366 (Nop90, "nop", 0x90, []),
367 (XchgReg, "xchg",0x90, [OpRegGeneral,ARegGeneral]),
368 (Cbw, "cbw", 0x98, [AReg(Word), AReg(Byte)]),
369 (Cwde, "cwde", 0x98, [AReg(Double), AReg(Word)]),
370 (Cdqe, "cdqe", 0x98, [AReg(Quad), AReg(Word)]),
371 (Cwd, "cwd", 0x99, [DReg(Word), AReg(Word)]),
372 (Cdq, "cdq", 0x99, [DReg(Double), DReg(Double)]),
373 (Cdo, "cqo", 0x99, [DReg(Quad),DReg(Quad)]),
374 (Fwait, "fwait", 0x9B, []),
375 (Pushf, "pushf", 0x9C, [FlagsMode]),
376 (Popf, "popf", 0x9D, [FlagsMode]),
377 (Sahf,"sahf",0x9E, []),
378 (Lahf, "lahf", 0x9F, []),
379 (MovAlM, "mov", 0xA0, [AReg(Byte), Moff(Byte)]),
380 (MovAregM, "mov", 0xA1, [ARegGeneral, MoffGeneral]),
381 (MovMAl, "mov", 0xA2, [Moff(Byte), AReg(Byte)]),
382 (MovMAreg, "mov", 0xA3, [MoffGeneral, ARegGeneral]),
383 (Movsb,"movs", 0xA4, [MemDest(Byte),MemSrc(Byte)]),
384 (Movs, "movs", 0xA5, [MemDestGeneral, MemSrcGeneral]),
385 (Cmpsb, "cmps", 0xA6, [MemDest(Byte),MemSrc(Byte)]),
386 (Cmps, "cmps", 0xA7, [MemDestGeneral, MemSrcGeneral]),
387 (TestAreg8, "test", 0xA8, [AReg(Byte),Imm(8)]),
388 (TestAreg, "test", 0xA9, [ARegGeneral,ImmGeneral]),
389 (Stosb, "stos", 0xAA, [MemDest(Byte),AReg(Byte)]),
390 (Stos, "stos", 0xAB,[MemDestGeneral,ARegGeneral]),
391 (Lodsb, "lods",0xAC, [AReg(Byte),MemSrc(Byte)]),
392 (Lods, "lods", 0xAD, [ARegGeneral, MemSrcGeneral]),
393 (Scasb, "scas", 0xAE, [MemDest(Byte), AReg(Byte)]),
394 (Scas, "scas", 0xAF, [MemDestGeneral, ARegGeneral]),
395 (MovImm8, "mov", 0xB0, [OpReg(Byte),Imm(8)]),
396 (MovImm, "mov", 0xB8, [OpRegGeneral, ImmGeneralWide]),
397 (RolImm8, "rol", 0xC0, [RControlBits(0),ModRM(Byte),Imm(8)]),
398 (RorImm8, "ror", 0xC0, [RControlBits(1),ModRM(Byte),Imm(8)]),
399 (RclImm8, "rcl", 0xC0, [RControlBits(2),ModRM(Byte),Imm(8)]),
400 (RcrImm8, "rcr", 0xC0, [RControlBits(3),ModRM(Byte), Imm(8)]),
401 (ShlImm8, "shl", 0xC0, [RControlBits(4), ModRM(Byte), Imm(8)]),
402 (ShrImm8, "shr", 0xC0, [RControlBits(5),ModRM(Byte),Imm(8)]),
403 (Shl2Imm8, "shl", 0xC0, [RControlBits(6), ModRM(Byte), Imm(8)]),
404 (SarImm8, "sar", 0xC0, [RControlBits(7), ModRM(Byte), Imm(8)]),
405 (RolImm, "rol", 0xC1, [RControlBits(0), ModRMGeneral,Imm(8)]),
406 (RorImm, "ror", 0xC1, [RControlBits(1), ModRMGeneral,Imm(8)]),
407 (RclImm, "rcl", 0xC1, [RControlBits(2), ModRMGeneral,Imm(8)]),
408 (RcrImm, "rcr", 0xC1, [RControlBits(3), ModRMGeneral, Imm(8)]),
409 (ShlImm, "shl", 0xC1, [RControlBits(4), ModRMGeneral, Imm(8)]),
410 (ShrImm, "shr", 0xC1, [RControlBits(5), ModRMGeneral,Imm(8)]),
411 (Shl2Imm, "shl", 0xC1, [RControlBits(6), ModRMGeneral, Imm(8)]),
412 (SarImm, "sar", 0xC1, [RControlBits(7), ModRMGeneral, Imm(8)]),
413 (RetnPop, "retn", 0xC2, [Imm(16)]),
414 (Retn, "retn", 0xC3, []),
415 (MovImmM8, "mov", 0xC6, [RControlBits(0),ModRM(Byte), Imm(8)]),
416 (MovImmM, "mov", 0xC7, [RControlBits(0),ModRMGeneral, ImmGeneral]),
417 (Enter, "enter", 0xC8, [Imm(16),Imm(8)]),
418 (Leave,"leave", 0xC9, []),
419 (RetfPop, "retf", 0xCA, [Imm(16)]),
420 (Retf, "retf", 0xCB, []),
421 (Int3, "int3", 0xCC, []),
422 (Int,"int", 0xCD, [Imm(8)]),
423 (IntO, "into",0xCE,[]),
424 (IRet,"iret",0xCF, []),
425 (Rol8, "rol", 0xD0, [RControlBits(0),ModRM(Byte)]),
426 (Ror8, "ror", 0xD0, [RControlBits(1),ModRM(Byte)]),
427 (Rcl8, "rcl", 0xD0, [RControlBits(2),ModRM(Byte)]),
428 (Rcr8, "rcr", 0xD0, [RControlBits(3),ModRM(Byte)]),
429 (Shl8, "shl", 0xD0, [RControlBits(4), ModRM(Byte)]),
430 (Shr8, "shr", 0xD0, [RControlBits(5),ModRM(Byte)]),
431 (Shl2_8, "shl", 0xD0, [RControlBits(6), ModRM(Byte)]),
432 (Sar8, "sar", 0xD0, [RControlBits(7), ModRM(Byte)]),
433 (Rol, "rol", 0xD1, [RControlBits(0), ModRMGeneral]),
434 (Ror, "ror", 0xD1, [RControlBits(1), ModRMGeneral]),
435 (Rcl, "rcl", 0xD1, [RControlBits(2), ModRMGeneral]),
436 (Rcr, "rcr", 0xD1, [RControlBits(3), ModRMGeneral]),
437 (Shl, "shl", 0xD1, [RControlBits(4), ModRMGeneral]),
438 (Shr, "shr", 0xD1, [RControlBits(5), ModRMGeneral]),
439 (Shl2, "shl", 0xD1, [RControlBits(6), ModRMGeneral]),
440 (Sar, "sar", 0xD1, [RControlBits(7), ModRMGeneral]),
441 (RolCL8, "rol", 0xD2, [RControlBits(0), ModRM(Byte) , CReg(Byte)]),
442 (RorCL8, "ror", 0xD2, [RControlBits(1), ModRM(Byte) , CReg(Byte)]),
443 (RclCL8, "rcl", 0xD2, [RControlBits(2), ModRM(Byte) , CReg(Byte)]),
444 (RcrCL8, "rcr", 0xD2, [RControlBits(3), ModRM(Byte) , CReg(Byte)]),
445 (ShlCL8, "shl", 0xD2, [RControlBits(4), ModRM(Byte) , CReg(Byte)]),
446 (ShrCL8, "shr", 0xD2, [RControlBits(5), ModRM(Byte) , CReg(Byte)]),
447 (Shl2CL8, "shl", 0xD2, [RControlBits(6), ModRM(Byte) , CReg(Byte)]),
448 (SarCL8, "sar", 0xD2, [RControlBits(7), ModRM(Byte) , CReg(Byte)]),
449 (RolCL, "rol", 0xD3, [RControlBits(0), ModRMGeneral, CReg(Byte)]),
450 (RorCL, "ror", 0xD3, [RControlBits(1), ModRMGeneral, CReg(Byte)]),
451 (RclCL, "rcl", 0xD3, [RControlBits(2), ModRMGeneral, CReg(Byte)]),
452 (RcrCL, "rcr", 0xD3, [RControlBits(3), ModRMGeneral, CReg(Byte)]),
453 (ShlCL, "shl", 0xD3, [RControlBits(4), ModRMGeneral, CReg(Byte)]),
454 (ShrCL, "shr", 0xD3, [RControlBits(5), ModRMGeneral, CReg(Byte)]),
455 (Shl2CL, "shl", 0xD3, [RControlBits(6), ModRMGeneral, CReg(Byte)]),
456 (SarCL, "sar", 0xD3, [RControlBits(7), ModRMGeneral, CReg(Byte)]),
457 (Xlat, "xlat", 0xD7, [ModRM(Byte)]),
458 (Fadd, "fadd", 0xD8, [RControlBits(0), ModRMReal(Double)]),
460 (Fmul, "fmul", 0xD8, [RControlBits(1), ModRMReal(Double)]),
461 (Fcom, "fcom", 0xD8, [RControlBits(2),ModRMReal(Double)]),
462 (Fcomp, "fcomp",0xD8, [RControlBits(3), ModRMReal(Double)]),
463 (Fsub, "fsub", 0xD8, [RControlBits(4), ModRMReal(Double)]),
464 (Fsubr, "fsubr", 0xD8, [RControlBits(5), ModRMReal(Double)]),
465 (Fdiv, "fdiv", 0xD8, [RControlBits(6), ModRMReal(Double)]),
466 (Fdivr, "fdivr", 0xD8, [RControlBits(7), ModRMReal(Double)]),
467 (Fld, "fld", 0xD9, [RControlBits(0), ModRMReal(Double)]),
468 (Fxch, "fxch", 0xD9, [RControlBits(1),ModRM(St)]),
469 (Fst, "fst",0xD9, [RControlBits(2),ModRMReal(Double)]),
470 (Fstp, "fstp", 0xD9, [RControlBits(3), ModRMReal(Double)]),
471 (Fldenv, "fldenv",0xD9, [RControlBits(4),ModRMMem]),
472 (Fchs, "fchs", 0xD9E0, []),
473 (Fabs, "fabs", 0xD9E1, []),
474 (Ftst, "ftst", 0xD9E4, []),
475 (Fxam, "fxam", 0xD9E5, []),
476 (Fldcw, "fldcw", 0xD9, [RControlBits(5),ModRMMem]),
477 (Fld1, "fld1", 0xD9E8,[]),
478 (FldL2T, "fldl2t", 0xD9E9, []),
479 (FldL2E, "fldl2e", 0xD9EA, []),
480 (FldPi, "fldpi", 0xD9EB, []),
481 (Fldlg2, "fldlg2", 0xD9EC, []),
482 (Fldln2, "fldln2", 0xD9ED, []),
483 (Fldz, "fldz", 0xD9EE, []),
484 (Fnstenv, "fnstenv", 0xD9, [RControlBits(6), ModRMMem]),
485 (Fstenv, "fstenv", 0x9BD9, [RControlBits(6), ModRMMem]),
486 (F2Xm1, "f2xm1", 0xD9F0, []),
487 (FYl2x, "fyl2x", 0xD9F1, []),
488 (Fptan, "fptan", 0xD9F2, []),
489 (Fpatan, "fpatan", 0xD9F3, []),
490 (Fxtract, "fxtract", 0xD9F4, []),
491 (Fprem1, "fprem1", 0xD9F5, []),
492 (FDecStp, "fdecstp", 0xD9F6, []),
493 (FIncStp, "fincstp", 0xD9F7, []),
494 (Fnstcw, "fnstcw", 0xD9, [RControlBits(6), ModRMMem]),
495 (Fstcw, "fstcw", 0x9BD9, [RControlBits(6), ModRMMem]),
496 (Fprem, "fprem", 0xD9F8, []),
497 (FYl2Xp1, "fyl2xp1", 0xD9F9, []),
498 (Fsqrt, "fsqrt", 0xD9FA, []),
499 (Fsincos, "fsincos", 0xD9FB, []),
500 (Frndint, "frndint", 0xD9FC, []),
501 (Fscale, "fscale", 0xD9FD, []),
502 (Fsin, "fsin", 0xD9FE, []),
503 (Fcos, "fcos", 0xD9FF, []),
504 (FCmovB, "fcmovb", 0xDA, [RControlBits(0),ModRMReg(St)]),
505 (FIadd, "fiadd", 0xDA, [RControlBits(0),ModRMReal(Double)]),
506 (FCmovE, "fcmove", 0xDA, [RControlBits(1), ModRMReg(St)]),
507 (FImul, "fimul", 0xDA, [RControlBits(1), ModRMReal(Double)]),
508 (FCmovBE, "fcmovbe", 0xDA, [RControlBits(2),ModRMReg(St)]),
509 (FIcom, "ficom", 0xDA, [RControlBits(2), ModRMReal(Double)]),
510 (FCmovU, "fcmovu", 0xDA, [RControlBits(3), ModRMReg(St)]),
511 (FIcomp, "ficomp", 0xDA, [RControlBits(3), ModRMReal(Double)]),
512 (FISub, "fisub", 0xDA, [RControlBits(4), ModRMReal(Double)]),
513 (FUcompp, "fucompp", 0xDA, [RControlBits(5), ModRMReg(St)]),
514 (FISubr, "fisubr", 0xDA, [RControlBits(5), ModRMReal(Double)]),
515 (FIdiv, "fidiv", 0xDA, [RControlBits(6), ModRMReal(Double)]),
516 (FIdivr, "fidivr", 0xDA, [RControlBits(7), ModRMReal(Double)]),
517 (FCmovNb, "fcmovnb", 0xDA, [RControlBits(0), ModRMReg(St)]),
518 (FIld, "fild", 0xDB, [RControlBits(0), ModRMReal(Double)]),
519 (FCmovNe, "fcmovne", 0xDB, [RControlBits(1), ModRMReg(St)]),
520 (FISttp, "fisttp", 0xDB, [RControlBits(1), ModRMReal(Double)]),
521 (FCmovNbe, "fcmovnbe", 0xDB, [RControlBits(2), ModRMReg(St)]),
522 (FIst, "fist", 0xDB, [RControlBits(2), ModRMReal(Double)]),
523 (FCMovNu, "fcmovnu", 0xDB, [RControlBits(3), ModRMReg(St)]),
524 (FIstp, "fistp", 0xDB, [RControlBits(3), ModRMReal(Double)]),
525 (Fneni, "fneni", 0xDBE0, []),
526 (Fndisi, "fndisi", 0xDBE1, []),
527 (Fnclex, "fnclex", 0xDBE2, []),
528 (Fclex, "fclex", 0x9BDBE2, []),
529 (Fninit, "fninit", 0xDBE3, []),
530 (Finit, "finit", 0x9BDBE3, []),
531 (Fnsetpm, "fnsetpm", 0xDBE4, []),
532 (Fld80, "fld", 0xDB, [RControlBits(5), ModRMReal(St)]),
533 (Fucmpi, "fucmpi", 0xDB, [RControlBits(6), ModRMReg(St)]),
534 (Fcmpi, "fcmpi", 0xDB, [RControlBits(7), ModRMReg(St)]),
535 (Fadd64, "fadd", 0xDC, [RControlBits(0), ModRMReal(Quad)]),
536 (Fmul64, "fmul", 0xDC, [RControlBits(1), ModRMReal(Quad)]),
537 (Fcom64, "fcom", 0xDC, [RControlBits(2), ModRMReal(Quad)]),
538 (Fcomp64, "fcomp", 0xDC, [RControlBits(3), ModRMReal(Quad)]),
539 (Fsub64, "fsub", 0xDC, [RControlBits(4), ModRMReal(Quad)]),
540 (Fsubr64, "fsubr", 0xDC, [RControlBits(5), ModRMReal(Quad)]),
541 (Fdiv64, "fdiv", 0xDC, [RControlBits(6), ModRMReal(Quad)]),
542 (Fdivr64, "fdivr",0xDC, [RControlBits(7), ModRMReal(Quad)]),
543 (LoopNz, "loopnz", 0xE0, [CRegGeneral, Rel(8)]),
544 (LoopZ, "loopz", 0xE1, [CRegGeneral, Rel(8)]),
545 (Loop, "loop", 0xE2, [CRegGeneral, Rel(8)]),
546 (Jcxz, "jcxz", 0xE3, [CRegGeneral, Rel(8)]),
547 (InImm8, "in", 0xE4, [AReg(Byte), Imm(8)]),
548 (InImm, "in", 0xE5, [ARegGeneral, Imm(8)]),
549 (OutImm8, "out", 0xE6, [AReg(Byte),Imm(8)]),
550 (OutImm, "out", 0xE7, [ARegGeneral, Imm(8)]),
551 (Call, "call", 0xE8, [RelGeneral]),
552 (Jmp, "jmp", 0xE9, [RelGeneral]),
553 (Jmpf, "jmpf", 0xEA, [Seg, RelGeneral]),
554 (Jmp8, "jmp", 0xEB, [Rel(8)]),
555 (In8, "in", 0xEC, [AReg(Byte), DReg(Word)]),
556 (In, "in", 0xED, [ARegGeneral, DReg(Word)]),
557 (Out8, "out", 0xEE, [AReg(Byte), DReg(Word)]),
558 (Out, "out", 0xEF, [ARegGeneral, DReg(Word)]),
559 (Int1, "int1", 0xF1, []),
560 (Hlt, "hlt", 0xF4, []),
561 (Cmc, "cmc", 0xF5, []),
562 (TestImm8, "test", 0xF6, [RControlBits(0), ModRM(Byte), Imm(8)]),
563 (TestImm82, "test", 0xF6, [RControlBits(0), ModRM(Byte), Imm(8)]),
564 (Not8, "not", 0xF6, [RControlBits(2), ModRM(Byte)]),
565 (Neg8, "neg", 0xF6, [RControlBits(3), ModRM(Byte)]),
566 (MulAl8, "mul",0xF6, [RControlBits(4), ModRM(Byte)]),
567 (IMulAl8, "imul", 0xF6, [RControlBits(5), ModRM(Byte)]),
568 (DivAx8, "div", 0xF6, [RControlBits(6), ModRM(Byte)]),
569 (IDivAx8, "idiv", 0xF6, [RControlBits(7), ModRM(Byte)]),
570 (TestImm, "test", 0xF7, [RControlBits(0), ModRMGeneral, ImmGeneral]),
571 (TestImm2, "test", 0xF7, [RControlBits(0), ModRMGeneral, ImmGeneral]),
572 (Not, "not", 0xF7, [RControlBits(2), ModRMGeneral]),
573 (Neg, "neg", 0xF7, [RControlBits(3), ModRMGeneral]),
574 (MulAreg, "mul",0xF7, [RControlBits(4), ARegGeneral, DRegGeneral, ModRMGeneral]),
575 (IMulAreg, "imul", 0xF7, [RControlBits(5), ARegGeneral, DRegGeneral, ModRMGeneral]),
576 (Div, "div", 0xF7, [RControlBits(6), ARegGeneral, DRegGeneral, ModRMGeneral]),
577 (IDiv, "idiv", 0xF7, [RControlBits(7), ARegGeneral, DRegGeneral, ModRMGeneral]),
578 (Clc, "clc", 0xF8, []),
579 (Stc, "stc", 0xF9, []),
580 (Cli, "cli", 0xFA, []),
581 (Sti, "sti", 0xFB, []),
582 (Cld, "cld", 0xFC, []),
583 (Std, "std", 0xFD, []),
584 (Inc8, "inc", 0xFE, [RControlBits(0), ModRM(Byte)]),
585 (Dec8, "dec", 0xFE, [RControlBits(1), ModRM(Byte)]),
586 (Inc, "inc", 0xFF, [RControlBits(0), ModRMGeneral]),
587 (Dec, "dec", 0xFF, [RControlBits(1), ModRMGeneral]),
588 (CallInd, "call", 0xFF, [RControlBits(2), ModRMGeneral]),
589 (Callf, "callf", 0xFF, [RControlBits(3), ModRMMem]),
590 (JmpInd, "jmp", 0xFF, [RControlBits(4), ModRMGeneral]),
591 (JmpfInd, "jmp", 0xFF, [RControlBits(5), ModRMMem]),
592 (PushRM, "push", 0xFF, [RControlBits(6), ModRMMode]),
593 (Ud2, "ud2", 0x0F0B, []),
594 (MovUpsRM, "movups", 0x0F10, [Reg(Xmm),ModRM(Xmm)]),
595 (MovSsRM, "movss", 0xF30F10, [Reg(Xmm), ModRMScalar(Double)]),
596 (MovUpdRM, "movupd", 0x660F10, [Reg(Xmm), ModRM(Xmm)]),
597 (MovSdRM, "movsd", 0xF20F10, [Reg(Xmm), ModRMScalar(Quad)]),
598 (VMovUpsRM, "vmovups", 0x0F10, [VexReg,VexModRM]),
599 (VMovSsRM, "vmovss", 0xF30F10, [VexReg, VexModRMScalar(Double)]),
600 (VMovUpdRM, "vmovupd", 0x660F10, [VexReg, VexModRM]),
601 (VMovSdRM, "vmovsd", 0xF20F10, [VexReg, VexModRMScalar(Quad)]),
602 (MovUpsMR, "movups", 0x0F11, [ModRM(Xmm),Reg(Xmm)]),
603 (MovSsMR, "movss", 0xF30F11, [ModRMScalar(Double),Reg(Xmm)]),
604 (MovUpdMR, "movupd", 0x660F11, [ModRM(Xmm),Reg(Xmm)]),
605 (MovSdMR, "movsd", 0xF20F11, [ModRMScalar(Quad), Reg(Xmm)]),
606 (VMovUpsMR, "vmovups", 0x0F11, [VexModRM,VexReg]),
607 (VMovSsMR, "vmovss", 0xF30F11, [VexModRMScalar(Double),VexReg]),
608 (VMovUpdMR, "vmovupd", 0x660F11, [VexModRM,VexReg]),
609 (VMovSdMR, "vmovsd", 0xF20F11, [VexModRMScalar(Quad),VexReg]),
610 (MovDRM, "movd", 0x0F6E, [Reg(Mmx),ModRM(Double)]),
611 (MovQRM, "movq", 0x0F6F, [Reg(Mmx),ModRM(Quad)]),
612 (MovDMR, "movd", 0x0F7E, [Reg(Mmx),ModRM(Double)]),
613 (MovQMR, "movq", 0x0F7F, [ModRM(Quad),Reg(Mmx)]),
614 (MFence, "mfence", 0x0FAE, []),
615
616 (TileLoadD, "tileloadd", 0xF20F384B,[VexPrefix(Xmm), Reg(Tmm), ModRMSib(Tmm)], [Long]),
617 (TileLoadDT1, "tileloaddt1", 0x660F384B,[VexPrefix(Xmm), Reg(Tmm), ModRMSib(Tmm)], [Long]),
618 (TileStoreD, "tilestored", 0xF30F384B, [VexPrefix(Xmm),ModRMSib(Tmm),Reg(Tmm)], [Long]),
619
620}
621
622#[derive(Clone, Debug, Hash, PartialEq, Eq)]
623pub enum ModRMRegOrSib {
624 Reg(X86Register),
625 Abs(Address),
626 RipRel(Address),
627 Sib {
628 scale: u32,
629 index: X86Register,
630 base: X86Register,
631 },
632 Index16 {
633 base: X86Register,
634 index: X86Register,
635 },
636}
637
638#[derive(Clone, Debug, Hash, PartialEq, Eq)]
639pub enum ModRM {
640 Indirect {
641 size: X86RegisterClass,
642 mode: ModRMRegOrSib,
643 },
644 IndirectDisp8 {
645 size: X86RegisterClass,
646 mode: ModRMRegOrSib,
647 disp8: i8,
648 },
649 IndirectDisp32 {
650 size: X86RegisterClass,
651 mode: ModRMRegOrSib,
652 disp32: i32,
653 },
654 Direct(X86Register),
655}
656
657impl ModRM {
658 pub fn with_disp32(self, disp: i32) -> Option<Self> {
659 match self {
660 ModRM::Indirect {
661 mode: ModRMRegOrSib::RipRel(_),
662 ..
663 }
664 | ModRM::Indirect {
665 mode: ModRMRegOrSib::Abs(_),
666 ..
667 } => todo!("[disp32]/[rIP+disp32]"),
668 ModRM::Indirect { size, mode } => Some(Self::IndirectDisp32 {
669 size,
670 mode,
671 disp32: disp,
672 }),
673 ModRM::IndirectDisp8 { size, mode, disp8 } => Some(ModRM::IndirectDisp32 {
674 size,
675 mode,
676 disp32: (disp8 as i32) + disp,
677 }),
678 ModRM::IndirectDisp32 { size, mode, disp32 } => Some(ModRM::IndirectDisp32 {
679 size,
680 mode,
681 disp32: disp32 + disp,
682 }),
683 ModRM::Direct(_) => None,
684 }
685 }
686
687 pub fn resize(self, size: X86RegisterClass) -> Option<ModRM> {
688 match self {
689 ModRM::Indirect { mode, .. } => Some(ModRM::Indirect { size, mode }),
690 ModRM::IndirectDisp8 { disp8, mode, .. } => {
691 Some(ModRM::IndirectDisp8 { size, mode, disp8 })
692 }
693 ModRM::IndirectDisp32 { mode, disp32, .. } => {
694 Some(ModRM::IndirectDisp32 { size, mode, disp32 })
695 }
696 ModRM::Direct(_) => None,
697 }
698 }
699}
700
701#[derive(Clone, Debug, Hash, PartialEq, Eq)]
702pub enum X86Operand {
703 Register(X86Register),
704 ModRM(ModRM),
705 Immediate(u64),
706 RelAddr(Address),
707 AbsAddr(Address),
708 FarAddr { sreg: X86Register, addr: Address },
709 FarRelAddr { sreg: X86Register, addr: Address },
710 FarModRM { sreg: X86Register, modrm: ModRM },
711}
712
713#[derive(Clone, Debug)]
714pub struct X86Instruction {
715 opc: X86Opcode,
716 operands: Vec<X86Operand>,
717 mode_override: Option<X86Mode>,
718}
719
720impl X86Instruction {
721 pub const fn new(opc: X86Opcode, operands: Vec<X86Operand>) -> Self {
722 Self {
723 opc,
724 operands,
725 mode_override: None,
726 }
727 }
728
729 pub const fn new_in_mode(opc: X86Opcode, operands: Vec<X86Operand>, mode: X86Mode) -> Self {
730 Self {
731 opc,
732 operands,
733 mode_override: Some(mode),
734 }
735 }
736
737 pub const fn opcode(&self) -> X86Opcode {
738 self.opc
739 }
740
741 pub fn operands(&self) -> &[X86Operand] {
742 &self.operands
743 }
744
745 pub fn mode_override(&self) -> Option<X86Mode> {
746 self.mode_override
747 }
748}
749
750macro_rules! zop_insns{
751 [$($name:ident),* $(,)?] => {
752 #[allow(non_upper_case_globals)]
753 impl X86Instruction{
754 $(pub const $name: X86Instruction = X86Instruction::new(X86Opcode:: $name, Vec::new());)*
755 }
756 }
757}
758
759zop_insns! {
760 Nop90,
761 Retn,
762 Leave,
763 Retf,
764 IRet,
765 Fneni,
766 Fndisi,
767 Hlt,
768 Cmc,
769 Clc,
770 Stc,
771 Cli,
772 Sti,
773 Cld,
774 Std,
775 Ud2,
776 Int3,
777 MFence
778}
779
780#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
781pub struct X86Decoder<R> {
782 reader: R,
783 mode: X86Mode,
784}
785
786impl<R> X86Decoder<R> {
787 pub const fn new(reader: R, defmode: X86Mode) -> Self {
788 Self {
789 reader,
790 mode: defmode,
791 }
792 }
793
794 pub fn into_inner(self) -> R {
795 self.reader
796 }
797
798 pub fn reader_mut(&mut self) -> &mut R {
799 &mut self.reader
800 }
801
802 pub fn mode(&self) -> X86Mode {
803 self.mode
804 }
805
806 pub fn set_mode(&mut self, mode: X86Mode) {
807 self.mode = mode;
808 }
809}
810
811impl<R: Read> Read for X86Decoder<R> {
812 fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
813 self.reader.read(buf)
814 }
815}
816
817impl<R: InsnRead> InsnRead for X86Decoder<R> {
818 fn read_addr(&mut self, size: usize, rel: bool) -> std::io::Result<Address> {
819 self.reader.read_addr(size, rel)
820 }
821
822 fn read_reloc(
823 &mut self,
824 size: usize,
825 rel: bool,
826 offset: Option<isize>,
827 ) -> std::io::Result<Option<Address>> {
828 self.reader.read_reloc(size, rel, offset)
829 }
830}
831
832impl<R: InsnRead> X86Decoder<R> {
833 pub fn read_insn(&mut self) -> std::io::Result<X86Instruction> {
834 todo!()
835 }
836}
837
838#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
839pub struct X86Encoder<W> {
840 writer: W,
841 mode: X86Mode,
842}
843
844impl<W> X86Encoder<W> {
845 pub const fn new(writer: W, defmode: X86Mode) -> Self {
846 Self {
847 writer,
848 mode: defmode,
849 }
850 }
851
852 pub fn into_inner(self) -> W {
853 self.writer
854 }
855
856 pub fn writer_mut(&mut self) -> &mut W {
857 &mut self.writer
858 }
859
860 pub fn mode(&self) -> X86Mode {
861 self.mode
862 }
863
864 pub fn set_mode(&mut self, mode: X86Mode) {
865 self.mode = mode;
866 }
867}
868
869impl<W: Write> Write for X86Encoder<W> {
870 fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
871 self.writer.write(buf)
872 }
873
874 fn flush(&mut self) -> std::io::Result<()> {
875 self.writer.flush()
876 }
877}
878
879impl<W: InsnWrite> InsnWrite for X86Encoder<W> {
880 fn write_addr(&mut self, size: usize, addr: Address, rel: bool) -> std::io::Result<()> {
881 self.writer.write_addr(size, addr, rel)
882 }
883
884 fn offset(&self) -> usize {
885 self.writer.offset()
886 }
887
888 fn write_reloc(&mut self, reloc: Reloc) -> std::io::Result<()> {
889 self.writer.write_reloc(reloc)
890 }
891}
892
893pub struct ModRMAndPrefixes {
894 pub rex: Option<u8>,
895 pub size_override: Option<u8>,
896 pub addr_override: Option<u8>,
897 pub modrm: u8,
898 pub sib: Option<u8>,
899 pub disp: Option<(usize, i64)>,
900 pub addr: Option<(usize, Address, bool)>,
901}
902
903pub fn encode_modrm(modrm: ModRM, r: u8, mode: X86Mode) -> ModRMAndPrefixes {
904 let mut output = ModRMAndPrefixes {
905 rex: None,
906 size_override: None,
907 addr_override: None,
908 modrm: 0,
909 sib: None,
910 disp: None,
911 addr: None,
912 };
913 if r > 8 {
914 *output.rex.get_or_insert(0x40) |= 0x04;
915 }
916
917 let size = match modrm {
920 ModRM::Indirect { size, .. }
921 | ModRM::IndirectDisp8 { size, .. }
922 | ModRM::IndirectDisp32 { size, .. } => size,
923 ModRM::Direct(r) => r.class(),
924 };
925
926 let addr_size = match modrm {
928 ModRM::Direct(_) => {
929 mode.largest_gpr() }
931 ModRM::Indirect {
932 mode: ModRMRegOrSib::Reg(r),
933 ..
934 }
935 | ModRM::IndirectDisp8 {
936 mode: ModRMRegOrSib::Reg(r),
937 ..
938 }
939 | ModRM::IndirectDisp32 {
940 mode: ModRMRegOrSib::Reg(r),
941 ..
942 } => {
943 if r.regnum() >= 8 {
944 *output.rex.get_or_insert(0x40) |= 0x0;
945 }
946 r.class()
947 }
948 ModRM::Indirect {
949 mode: ModRMRegOrSib::Sib { index, base, .. },
950 ..
951 }
952 | ModRM::IndirectDisp8 {
953 mode: ModRMRegOrSib::Sib { index, base, .. },
954 ..
955 }
956 | ModRM::IndirectDisp32 {
957 mode: ModRMRegOrSib::Sib { index, base, .. },
958 ..
959 } => {
960 if base.regnum() >= 8 {
961 *output.rex.get_or_insert(0x40) |= 0x01;
962 }
963 if index.regnum() >= 8 {
964 *output.rex.get_or_insert(0x40) |= 0x02;
965 }
966 assert!(base.class() == index.class());
967 base.class()
968 }
969 ModRM::Indirect {
970 mode: ModRMRegOrSib::Index16 { .. },
971 ..
972 }
973 | ModRM::IndirectDisp8 {
974 mode: ModRMRegOrSib::Index16 { .. },
975 ..
976 }
977 | ModRM::IndirectDisp32 {
978 mode: ModRMRegOrSib::Index16 { .. },
979 ..
980 } => X86RegisterClass::Word,
981 ModRM::Indirect {
982 mode: ModRMRegOrSib::Abs(_),
983 ..
984 }
985 | ModRM::Indirect {
986 mode: ModRMRegOrSib::RipRel(_),
987 ..
988 } => mode.largest_gpr(),
989 mode => panic!("Invalid ModRM byte {:?}", mode),
990 };
991
992 match (size, mode) {
994 (X86RegisterClass::Byte, _) => {}
995 (X86RegisterClass::ByteRex, X86Mode::Long) => {}
996 (X86RegisterClass::Word, X86Mode::Real | X86Mode::Virtual8086) => {}
997 (X86RegisterClass::Double, X86Mode::Real | X86Mode::Virtual8086)
998 | (X86RegisterClass::Word, _) => {
999 output.size_override = Some(0x66);
1000 }
1001 (X86RegisterClass::Double, _) => {}
1002 (X86RegisterClass::Quad, X86Mode::Long) => {
1003 *output.rex.get_or_insert(0x40) |= 0x08;
1004 }
1005 (
1006 X86RegisterClass::Xmm
1007 | X86RegisterClass::Ymm
1008 | X86RegisterClass::Zmm
1009 | X86RegisterClass::St
1010 | X86RegisterClass::Mmx,
1011 _,
1012 )
1013 | (X86RegisterClass::Tmm, X86Mode::Long) => {}
1014 (size, mode) => panic!("Operand size {:?} not supported in mode {:?}", size, mode),
1015 };
1016
1017 match (addr_size, mode) {
1018 (X86RegisterClass::Word, X86Mode::Real | X86Mode::Virtual8086)
1019 | (X86RegisterClass::Double, X86Mode::Protected | X86Mode::Compatibility)
1020 | (X86RegisterClass::Quad, X86Mode::Long) => {}
1021 (X86RegisterClass::Double, X86Mode::Real | X86Mode::Virtual8086 | X86Mode::Long)
1022 | (X86RegisterClass::Word, X86Mode::Protected | X86Mode::Compatibility) => {
1023 output.addr_override = Some(0x67)
1024 }
1025 (size, mode) => panic!("Operand size {:?} not supported in mode {:?}", size, mode),
1026 }
1027
1028 match modrm {
1030 ModRM::Direct(reg) => {
1031 if reg.class() == X86RegisterClass::Byte && reg.regnum() > 3 && output.rex.is_some() {
1032 panic!("Cannot encode register {:?} with a REX prefix", reg);
1033 } else if reg.class() == X86RegisterClass::ByteRex {
1034 output.rex.get_or_insert(0x40);
1035 }
1036 output.modrm = 0xC0 | ((r & 0x7) << 3) | (reg.regnum() & 0x7);
1037 }
1038 ModRM::Indirect {
1039 mode: ModRMRegOrSib::Index16 { base, index },
1040 ..
1041 } => {
1042 output.modrm = match (base, index) {
1043 (X86Register::Bx, X86Register::Si) => (r & 0x7) << 3,
1044 (X86Register::Bx, X86Register::Di) => 0x01 | ((r & 0x7) << 3),
1045 (X86Register::Bp, X86Register::Si) => 0x02 | ((r & 0x7) << 3),
1046 (X86Register::Bp, X86Register::Di) => 0x03 | ((r & 0x7) << 3),
1047 (base, index) => panic!("16-bit addresses cannot encode [{}+{}]", base, index),
1048 };
1049 }
1050 ModRM::IndirectDisp8 {
1051 mode: ModRMRegOrSib::Index16 { base, index },
1052 disp8,
1053 ..
1054 } => {
1055 output.disp = Some((1, disp8.into()));
1056 output.modrm = match (base, index) {
1057 (X86Register::Bx, X86Register::Si) => 0x40 | ((r & 0x7) << 3),
1058 (X86Register::Bx, X86Register::Di) => 0x41 | ((r & 0x7) << 3),
1059 (X86Register::Bp, X86Register::Si) => 0x42 | ((r & 0x7) << 3),
1060 (X86Register::Bp, X86Register::Di) => 0x43 | ((r & 0x7) << 3),
1061 (base, index) => panic!("16-bit addresses cannot encode [{}+{}]", base, index),
1062 };
1063 }
1064 ModRM::IndirectDisp32 {
1065 mode: ModRMRegOrSib::Index16 { base, index },
1066 disp32,
1067 ..
1068 } => {
1069 output.disp = Some((2, disp32.into()));
1070 output.modrm = match (base, index) {
1071 (X86Register::Bx, X86Register::Si) => 0x80 | ((r & 0x7) << 3),
1072 (X86Register::Bx, X86Register::Di) => 0x81 | ((r & 0x7) << 3),
1073 (X86Register::Bp, X86Register::Si) => 0x82 | ((r & 0x7) << 3),
1074 (X86Register::Bp, X86Register::Di) => 0x83 | ((r & 0x7) << 3),
1075 (base, index) => panic!("16-bit addresses cannot encode [{}+{}]", base, index),
1076 };
1077 }
1078 ModRM::Indirect {
1079 mode: ModRMRegOrSib::Reg(reg),
1080 ..
1081 } if addr_size == X86RegisterClass::Word => {
1082 output.modrm = match reg {
1083 X86Register::Si => 0x04 | ((r & 0x7) << 3),
1084 X86Register::Di => 0x05 | ((r & 0x7) << 3),
1085 X86Register::Bx => 0x07 | ((r & 0x7) << 3),
1086 reg => panic!("16-bit addresses cannot encode [{}]", reg),
1087 }
1088 }
1089 ModRM::IndirectDisp8 {
1090 mode: ModRMRegOrSib::Reg(reg),
1091 disp8,
1092 ..
1093 } if addr_size == X86RegisterClass::Word => {
1094 output.disp = Some((1, disp8.into()));
1095 output.modrm = match reg {
1096 X86Register::Si => 0x44 | ((r & 0x7) << 3),
1097 X86Register::Di => 0x45 | ((r & 0x7) << 3),
1098 X86Register::Bp => 0x46 | ((r & 0x7) << 3),
1099 X86Register::Bx => 0x47 | ((r & 0x7) << 3),
1100 reg => panic!("16-bit addresses cannot encode [{}]", reg),
1101 }
1102 }
1103 ModRM::IndirectDisp32 {
1104 mode: ModRMRegOrSib::Reg(reg),
1105 disp32,
1106 ..
1107 } if addr_size == X86RegisterClass::Word => {
1108 output.disp = Some((2, disp32.into()));
1109 output.modrm = match reg {
1110 X86Register::Si => 0x84 | ((r & 0x7) << 3),
1111 X86Register::Di => 0x85 | ((r & 0x7) << 3),
1112 X86Register::Bp => 0x86 | ((r & 0x7) << 3),
1113 X86Register::Bx => 0x87 | ((r & 0x7) << 3),
1114 reg => panic!("16-bit addresses cannot encode [{}]", reg),
1115 }
1116 }
1117 ModRM::Indirect {
1118 mode: ModRMRegOrSib::Reg(reg),
1119 ..
1120 } => {
1121 match reg.regnum() & 0x7 {
1122 4 => {
1123 output.modrm = 0x04 | ((r & 0x7) << 3);
1125 output.sib = Some(0x24)
1126 }
1127 5 => {
1128 output.modrm = 0x45 | ((r & 0x7) << 3);
1130 output.disp = Some((1, 0));
1131 }
1132 n => output.modrm = ((r & 0x7) << 3) | n,
1133 }
1134 }
1135 ModRM::Indirect {
1136 mode: ModRMRegOrSib::RipRel(addr),
1137 ..
1138 } => {
1139 if mode == X86Mode::Long {
1140 output.modrm = 0x05 | ((r & 0x7) << 3);
1141 output.addr = Some((4, addr, true));
1142 } else {
1143 panic!("[rip+{:?}] is not supported in this mode", addr)
1144 }
1145 }
1146 ModRM::Indirect {
1147 mode: ModRMRegOrSib::Abs(addr),
1148 ..
1149 } => {
1150 if mode == X86Mode::Long {
1151 output.modrm = 0x04 | ((r & 0x7) << 3);
1154 output.sib = Some(0x25);
1155 output.addr = Some((4, addr, false));
1156 } else if addr_size == X86RegisterClass::Word {
1157 output.modrm = 0x06 | ((r & 0x7) << 3);
1158 output.addr = Some((2, addr, false));
1159 } else {
1160 output.modrm = 0x05 | ((r & 0x7) << 3);
1161 output.addr = Some((4, addr, false))
1162 }
1163 }
1164 ModRM::Indirect {
1165 mode: ModRMRegOrSib::Sib { scale, index, base },
1166 ..
1167 } => {
1168 output.modrm = 0x04 | ((r & 0x7) << 3);
1169 if index.regnum() == 4 {
1170 panic!("Cannot encode SIB byte with {:?} as index", index);
1171 }
1172 if base.regnum() & 0x7 == 5 {
1173 output.modrm |= 0x40;
1174 output.sib = Some(
1175 ((scale.trailing_zeros() as u8 + 1) << 6)
1176 | ((index.regnum() & 0x7) << 3)
1177 | (0x05),
1178 );
1179 output.disp = Some((1, 0));
1180 } else {
1181 output.sib = Some(
1182 ((scale.trailing_zeros() as u8 + 1) << 6)
1183 | ((index.regnum() & 0x7) << 3)
1184 | (base.regnum()),
1185 )
1186 }
1187 }
1188 ModRM::IndirectDisp8 {
1189 mode: ModRMRegOrSib::Sib { scale, index, base },
1190 disp8,
1191 ..
1192 } => {
1193 output.modrm = 0x44 | ((r & 0x7) << 3);
1194 output.disp = Some((1, disp8.into()));
1195 if index.regnum() == 4 {
1196 panic!("Cannot encode SIB byte with {:?} as index", index);
1197 }
1198 output.sib = Some(
1199 ((scale.trailing_zeros() as u8 + 1) << 6)
1200 | ((index.regnum() & 0x7) << 3)
1201 | (base.regnum()),
1202 )
1203 }
1204 ModRM::IndirectDisp32 {
1205 mode: ModRMRegOrSib::Sib { scale, index, base },
1206 disp32,
1207 ..
1208 } => {
1209 output.modrm = 0x84 | ((r & 0x7) << 3);
1210 output.disp = Some((4, disp32.into()));
1211 if index.regnum() == 4 {
1212 panic!("Cannot encode SIB byte with {:?} as index", index);
1213 }
1214 output.sib = Some(
1215 ((scale.trailing_zeros() as u8 + 1) << 6)
1216 | ((index.regnum() & 0x7) << 3)
1217 | (base.regnum()),
1218 )
1219 }
1220 ModRM::IndirectDisp8 {
1221 mode: ModRMRegOrSib::Reg(reg),
1222 disp8,
1223 ..
1224 } => {
1225 if reg.regnum() & 0x7 == 4 {
1226 output.modrm = 0x44 | ((r & 0x7) << 3);
1228 output.sib = Some(0x24)
1229 } else {
1230 output.modrm = 0x40 | (reg.regnum() & 0x7) | ((r & 0x7) << 3)
1231 }
1232 output.disp = Some((1, disp8.into()))
1233 }
1234 ModRM::IndirectDisp32 {
1235 mode: ModRMRegOrSib::Reg(reg),
1236 disp32,
1237 ..
1238 } => {
1239 if reg.regnum() & 0x7 == 4 {
1240 output.modrm = 0x84 | ((r & 0x7) << 3);
1242 output.sib = Some(0x24)
1243 } else {
1244 output.modrm = 0x80 | (reg.regnum() & 0x7) | ((r & 0x7) << 3)
1245 }
1246 output.disp = Some((4, disp32.into()))
1247 }
1248 modrm => todo!("{:?}", modrm),
1249 }
1250
1251 output
1252}
1253
1254impl<W: InsnWrite> X86Encoder<W> {
1255 pub fn write_insn(&mut self, insn: X86Instruction) -> std::io::Result<()> {
1256 let mode = insn.mode_override().unwrap_or(self.mode);
1257 let opcode_long = insn.opcode().opcode();
1258 let mut opcode = if opcode_long < 0x100 {
1259 vec![opcode_long as u8]
1260 } else if opcode_long < 0x10000 {
1261 vec![(opcode_long >> 8) as u8, opcode_long as u8]
1262 } else if opcode_long < 0x1000000 {
1263 vec![
1264 (opcode_long >> 16) as u8,
1265 (opcode_long >> 8) as u8,
1266 opcode_long as u8,
1267 ]
1268 } else {
1269 vec![
1270 (opcode_long >> 24) as u8,
1271 (opcode_long >> 16) as u8,
1272 (opcode_long >> 8) as u8,
1273 opcode_long as u8,
1274 ]
1275 };
1276 match insn.opcode().operands() {
1277 [] => {
1278 assert!(insn.operands.is_empty());
1279 self.writer.write_all(&opcode)
1280 }
1281 [Imm(n)] => {
1282 assert_eq!(insn.operands.len(), 1);
1283
1284 self.writer.write_all(&opcode)?;
1285
1286 match &insn.operands[0] {
1287 X86Operand::Immediate(imm) => self.writer.write_all(&imm.to_ne_bytes()[..*n]),
1288 X86Operand::AbsAddr(addr) => {
1289 self.writer.write_addr(*n / 8, addr.clone(), false)
1290 }
1291 op => panic!("Invalid operand {:?} for Immediate", op),
1292 }
1293 }
1294 [Rel(n)] => {
1295 let n = *n;
1296 assert_eq!(insn.operands.len(), 1);
1297
1298 self.writer.write_all(&opcode)?;
1299
1300 match &insn.operands[0] {
1301 X86Operand::Immediate(imm) => self.writer.write_all(&imm.to_ne_bytes()[..n]),
1302 X86Operand::AbsAddr(addr) => self.writer.write_addr(n, addr.clone(), true),
1303 op => panic!("Invalid operand {:?} for Immediate", op),
1304 }
1305 }
1306 [Insn] => todo!(),
1307 [OpRegMode] => {
1308 let reg = match &insn.operands[0] {
1309 X86Operand::Register(r) => r,
1310 op => panic!("Invalid operand {:?} for OpRegMode", op),
1311 };
1312
1313 match (reg.class(), mode) {
1314 (X86RegisterClass::Word, X86Mode::Real | X86Mode::Virtual8086)
1315 | (X86RegisterClass::Double, X86Mode::Protected | X86Mode::Compatibility)
1316 | (X86RegisterClass::Quad, X86Mode::Long) => {}
1317 (X86RegisterClass::Word, _)
1318 | (X86RegisterClass::Double, X86Mode::Real | X86Mode::Virtual8086) => {
1319 self.writer.write_all(&[0x66])?;
1320 }
1321 (_, mode) => panic!("Register {} is not valid in mode {:?}", reg, mode),
1322 }
1323
1324 *opcode.last_mut().unwrap() += reg.regnum() & 0x7;
1325 let mut opcode = &opcode[..];
1326 let sse_prefix = opcode[0];
1327
1328 match sse_prefix {
1329 0x66 | 0xF2 | 0xF3 => {
1330 self.writer.write_all(core::slice::from_ref(&sse_prefix))?;
1331 opcode = &opcode[1..]
1332 }
1333 _ => {}
1334 }
1335
1336 if reg.regnum() > 8 {
1337 self.writer.write_all(&[0x41])?;
1338 }
1339
1340 self.writer.write_all(opcode)
1341 }
1342 [ModRM(cl1), Reg(cl2)] if cl1 == cl2 => {
1343 let reg = match &insn.operands[1] {
1344 X86Operand::Register(r) => *r,
1345 op => panic!("Invalid operand {:?} for Reg({:?})", op, cl2),
1346 };
1347
1348 let modrm = match &insn.operands[0] {
1349 X86Operand::Register(r) => ModRM::Direct(*r),
1350 X86Operand::ModRM(modrm) => modrm.clone(),
1351 X86Operand::RelAddr(addr) => ModRM::Indirect {
1352 size: *cl1,
1353 mode: ModRMRegOrSib::RipRel(addr.clone()),
1354 },
1355 X86Operand::AbsAddr(addr) => ModRM::Indirect {
1356 size: *cl1,
1357 mode: ModRMRegOrSib::Abs(addr.clone()),
1358 },
1359 op => panic!("Invalid operand {:?} for ModRM({:?})", op, cl1),
1360 };
1361
1362 let mut encoding = encode_modrm(modrm, reg.regnum(), mode);
1363
1364 if reg.class() == X86RegisterClass::Byte
1365 && encoding.rex.is_some()
1366 && reg.regnum() > 3
1367 {
1368 panic!("Cannot encode {} with a rex prefix", reg);
1369 } else if reg.class() == X86RegisterClass::ByteRex {
1370 encoding.rex.get_or_insert(0x40); }
1372 let mut opcode = &opcode[..];
1373 let sse_prefix = opcode[0];
1374
1375 self.writer.write_all(
1376 encoding
1377 .size_override
1378 .as_ref()
1379 .map(core::slice::from_ref)
1380 .unwrap_or(&[]),
1381 )?;
1382 self.writer.write_all(
1383 encoding
1384 .addr_override
1385 .as_ref()
1386 .map(core::slice::from_ref)
1387 .unwrap_or(&[]),
1388 )?;
1389
1390 match sse_prefix {
1391 0x66 | 0xF2 | 0xF3 => {
1392 self.writer.write_all(core::slice::from_ref(&sse_prefix))?;
1393 opcode = &opcode[1..]
1394 }
1395 _ => {}
1396 }
1397
1398 self.writer.write_all(
1399 encoding
1400 .rex
1401 .as_ref()
1402 .map(core::slice::from_ref)
1403 .unwrap_or(&[]),
1404 )?;
1405
1406 self.writer.write_all(opcode)?;
1407 self.writer
1408 .write_all(core::slice::from_ref(&encoding.modrm))?;
1409 self.writer.write_all(
1410 encoding
1411 .sib
1412 .as_ref()
1413 .map(core::slice::from_ref)
1414 .unwrap_or(&[]),
1415 )?;
1416 match (encoding.disp, encoding.addr) {
1417 (Some((size, disp)), None) => {
1418 self.writer.write_all(&disp.to_ne_bytes()[..size])?
1419 }
1420 (None, Some((size, addr, pcrel))) => {
1421 self.writer.write_addr(size * 8, addr, pcrel)?
1422 }
1423 (None, None) => {}
1424 (Some(_), Some(_)) => {
1425 panic!("Cannot encode both an address and a displacement")
1426 }
1427 }
1428 Ok(())
1429 }
1430 [Reg(cl2), ModRM(cl1)] if cl1 == cl2 => {
1431 let reg = match &insn.operands[0] {
1432 X86Operand::Register(r) => *r,
1433 op => panic!("Invalid operand {:?} for Reg({:?})", op, cl2),
1434 };
1435
1436 let modrm = match &insn.operands[1] {
1437 X86Operand::Register(r) => ModRM::Direct(*r),
1438 X86Operand::ModRM(modrm) => modrm.clone(),
1439 X86Operand::RelAddr(addr) => ModRM::Indirect {
1440 size: *cl1,
1441 mode: ModRMRegOrSib::RipRel(addr.clone()),
1442 },
1443 X86Operand::AbsAddr(addr) => ModRM::Indirect {
1444 size: *cl1,
1445 mode: ModRMRegOrSib::Abs(addr.clone()),
1446 },
1447 op => panic!("Invalid operand {:?} for ModRM({:?})", op, cl1),
1448 };
1449
1450 let mut encoding = encode_modrm(modrm, reg.regnum(), mode);
1451
1452 if reg.class() == X86RegisterClass::Byte
1453 && encoding.rex.is_some()
1454 && reg.regnum() > 3
1455 {
1456 panic!("Cannot encode {} with a rex prefix", reg);
1457 } else if reg.class() == X86RegisterClass::ByteRex {
1458 encoding.rex.get_or_insert(0x40); }
1460 let mut opcode = &opcode[..];
1461 let sse_prefix = opcode[0];
1462
1463 self.writer.write_all(
1464 encoding
1465 .size_override
1466 .as_ref()
1467 .map(core::slice::from_ref)
1468 .unwrap_or(&[]),
1469 )?;
1470 self.writer.write_all(
1471 encoding
1472 .addr_override
1473 .as_ref()
1474 .map(core::slice::from_ref)
1475 .unwrap_or(&[]),
1476 )?;
1477
1478 match sse_prefix {
1479 0x66 | 0xF2 | 0xF3 => {
1480 self.writer.write_all(core::slice::from_ref(&sse_prefix))?;
1481 opcode = &opcode[1..]
1482 }
1483 _ => {}
1484 }
1485
1486 self.writer.write_all(
1487 encoding
1488 .rex
1489 .as_ref()
1490 .map(core::slice::from_ref)
1491 .unwrap_or(&[]),
1492 )?;
1493
1494 self.writer.write_all(opcode)?;
1495 self.writer
1496 .write_all(core::slice::from_ref(&encoding.modrm))?;
1497 self.writer.write_all(
1498 encoding
1499 .sib
1500 .as_ref()
1501 .map(core::slice::from_ref)
1502 .unwrap_or(&[]),
1503 )?;
1504 match (encoding.disp, encoding.addr) {
1505 (Some((size, disp)), None) => {
1506 self.writer.write_all(&disp.to_ne_bytes()[..size])?
1507 }
1508 (None, Some((size, addr, pcrel))) => {
1509 self.writer.write_addr(size, addr, pcrel)?
1510 }
1511 (None, None) => {}
1512 (Some(_), Some(_)) => {
1513 panic!("Cannot encode both an address and a displacement")
1514 }
1515 }
1516 Ok(())
1517 }
1518 [ModRMGeneral, RegGeneral] => {
1519 let reg = match &insn.operands[1] {
1520 X86Operand::Register(r) => *r,
1521 op => panic!("Invalid operand {:?} for RegGeneral", op),
1522 };
1523
1524 let modrm = match &insn.operands[0] {
1525 X86Operand::Register(r) => ModRM::Direct(*r),
1526 X86Operand::ModRM(modrm) => modrm.clone(),
1527 X86Operand::RelAddr(addr) => ModRM::Indirect {
1528 size: reg.class(),
1529 mode: ModRMRegOrSib::RipRel(addr.clone()),
1530 },
1531 X86Operand::AbsAddr(addr) => ModRM::Indirect {
1532 size: reg.class(),
1533 mode: ModRMRegOrSib::Abs(addr.clone()),
1534 },
1535 op => panic!("Invalid operand {:?} for ModRMGeneral", op),
1536 };
1537
1538 let encoding = encode_modrm(modrm, reg.regnum(), mode);
1539
1540 let mut opcode = &opcode[..];
1541 let sse_prefix = opcode[0];
1542
1543 self.writer.write_all(
1544 encoding
1545 .size_override
1546 .as_ref()
1547 .map(core::slice::from_ref)
1548 .unwrap_or(&[]),
1549 )?;
1550 self.writer.write_all(
1551 encoding
1552 .addr_override
1553 .as_ref()
1554 .map(core::slice::from_ref)
1555 .unwrap_or(&[]),
1556 )?;
1557
1558 match sse_prefix {
1559 0x66 | 0xF2 | 0xF3 => {
1560 self.writer.write_all(core::slice::from_ref(&sse_prefix))?;
1561 opcode = &opcode[1..]
1562 }
1563 _ => {}
1564 }
1565
1566 self.writer.write_all(
1567 encoding
1568 .rex
1569 .as_ref()
1570 .map(core::slice::from_ref)
1571 .unwrap_or(&[]),
1572 )?;
1573
1574 self.writer.write_all(opcode)?;
1575 self.writer
1576 .write_all(core::slice::from_ref(&encoding.modrm))?;
1577 self.writer.write_all(
1578 encoding
1579 .sib
1580 .as_ref()
1581 .map(core::slice::from_ref)
1582 .unwrap_or(&[]),
1583 )?;
1584 match (encoding.disp, encoding.addr) {
1585 (Some((size, disp)), None) => {
1586 self.writer.write_all(&disp.to_ne_bytes()[..size])?
1587 }
1588 (None, Some((size, addr, pcrel))) => {
1589 self.writer.write_addr(size, addr, pcrel)?
1590 }
1591 (None, None) => {}
1592 (Some(_), Some(_)) => {
1593 panic!("Cannot encode both an address and a displacement")
1594 }
1595 }
1596 Ok(())
1597 }
1598 [RegGeneral, ModRMGeneral] => {
1599 let reg = match &insn.operands[0] {
1600 X86Operand::Register(r) => *r,
1601 op => panic!("Invalid operand {:?} for RegGeneral", op),
1602 };
1603
1604 let modrm = match &insn.operands[1] {
1605 X86Operand::Register(r) => ModRM::Direct(*r),
1606 X86Operand::ModRM(modrm) => modrm.clone(),
1607 X86Operand::RelAddr(addr) => ModRM::Indirect {
1608 size: reg.class(),
1609 mode: ModRMRegOrSib::RipRel(addr.clone()),
1610 },
1611 X86Operand::AbsAddr(addr) => ModRM::Indirect {
1612 size: reg.class(),
1613 mode: ModRMRegOrSib::Abs(addr.clone()),
1614 },
1615 op => panic!("Invalid operand {:?} for ModRMGeneral", op),
1616 };
1617
1618 let encoding = encode_modrm(modrm, reg.regnum(), mode);
1619
1620 let mut opcode = &opcode[..];
1621 let sse_prefix = opcode[0];
1622
1623 self.writer.write_all(
1624 encoding
1625 .size_override
1626 .as_ref()
1627 .map(core::slice::from_ref)
1628 .unwrap_or(&[]),
1629 )?;
1630 self.writer.write_all(
1631 encoding
1632 .addr_override
1633 .as_ref()
1634 .map(core::slice::from_ref)
1635 .unwrap_or(&[]),
1636 )?;
1637
1638 match sse_prefix {
1639 0x66 | 0xF2 | 0xF3 => {
1640 self.writer.write_all(core::slice::from_ref(&sse_prefix))?;
1641 opcode = &opcode[1..]
1642 }
1643 _ => {}
1644 }
1645
1646 self.writer.write_all(
1647 encoding
1648 .rex
1649 .as_ref()
1650 .map(core::slice::from_ref)
1651 .unwrap_or(&[]),
1652 )?;
1653
1654 self.writer.write_all(opcode)?;
1655 self.writer
1656 .write_all(core::slice::from_ref(&encoding.modrm))?;
1657 self.writer.write_all(
1658 encoding
1659 .sib
1660 .as_ref()
1661 .map(core::slice::from_ref)
1662 .unwrap_or(&[]),
1663 )?;
1664 match (encoding.disp, encoding.addr) {
1665 (Some((size, disp)), None) => {
1666 self.writer.write_all(&disp.to_ne_bytes()[..size])?
1667 }
1668 (None, Some((size, addr, pcrel))) => {
1669 self.writer.write_addr(size * 8, addr, pcrel)?
1670 }
1671 (None, None) => {}
1672 (Some(_), Some(_)) => {
1673 panic!("Cannot encode both an address and a displacement")
1674 }
1675 }
1676 Ok(())
1677 }
1678 [RControlBits(b), ModRMGeneral, ImmGeneral] => {
1679 let modrm = match &insn.operands[0] {
1680 X86Operand::Register(r) => ModRM::Direct(*r),
1681 X86Operand::ModRM(modrm) => modrm.clone(),
1682 X86Operand::RelAddr(addr) => ModRM::Indirect {
1683 size: mode.largest_gpr(),
1684 mode: ModRMRegOrSib::RipRel(addr.clone()),
1685 },
1686 X86Operand::AbsAddr(addr) => ModRM::Indirect {
1687 size: mode.largest_gpr(),
1688 mode: ModRMRegOrSib::Abs(addr.clone()),
1689 },
1690 op => panic!("Invalid operand {:?} for ModRMGeneral", op),
1691 };
1692
1693 let size = match modrm {
1694 ModRM::Indirect { size, .. } => size,
1695 ModRM::IndirectDisp8 { size, .. } => size,
1696 ModRM::IndirectDisp32 { size, .. } => size,
1697 ModRM::Direct(r) => r.class(),
1698 };
1699
1700 let encoding = encode_modrm(modrm, *b, mode);
1701
1702 let mut opcode = &opcode[..];
1703 let sse_prefix = opcode[0];
1704
1705 self.writer.write_all(
1706 encoding
1707 .size_override
1708 .as_ref()
1709 .map(core::slice::from_ref)
1710 .unwrap_or(&[]),
1711 )?;
1712 self.writer.write_all(
1713 encoding
1714 .addr_override
1715 .as_ref()
1716 .map(core::slice::from_ref)
1717 .unwrap_or(&[]),
1718 )?;
1719
1720 match sse_prefix {
1721 0x66 | 0xF2 | 0xF3 => {
1722 self.writer.write_all(core::slice::from_ref(&sse_prefix))?;
1723 opcode = &opcode[1..]
1724 }
1725 _ => {}
1726 }
1727
1728 self.writer.write_all(
1729 encoding
1730 .rex
1731 .as_ref()
1732 .map(core::slice::from_ref)
1733 .unwrap_or(&[]),
1734 )?;
1735
1736 self.writer.write_all(opcode)?;
1737 self.writer
1738 .write_all(core::slice::from_ref(&encoding.modrm))?;
1739 self.writer.write_all(
1740 encoding
1741 .sib
1742 .as_ref()
1743 .map(core::slice::from_ref)
1744 .unwrap_or(&[]),
1745 )?;
1746
1747 match (encoding.disp, encoding.addr) {
1748 (Some((size, disp)), None) => {
1749 self.writer.write_all(&disp.to_ne_bytes()[..size])?;
1750 }
1751 (None, Some((size, addr, pcrel))) => {
1752 self.writer.write_addr(size * 8, addr, pcrel)?;
1753 }
1754 (None, None) => {}
1755 (Some(_), Some(_)) => {
1756 panic!("Cannot encode both an address and a displacement")
1757 }
1758 }
1759
1760 let n = match size {
1761 X86RegisterClass::Word => 2,
1762 _ => 4,
1763 };
1764
1765 match &insn.operands[1] {
1766 X86Operand::Immediate(imm) => self.writer.write_all(&imm.to_ne_bytes()[..n]),
1767 X86Operand::AbsAddr(addr) => self.writer.write_addr(n * 8, addr.clone(), false),
1768 op => panic!("Invalid operand {:?} for Immediate", op),
1769 }
1770 }
1771 [RControlBits(b), ModRM(Byte), Imm(8)] => {
1772 let modrm = match &insn.operands[0] {
1773 X86Operand::Register(r) => ModRM::Direct(*r),
1774 X86Operand::ModRM(modrm) => modrm.clone(),
1775 X86Operand::RelAddr(addr) => ModRM::Indirect {
1776 size: mode.largest_gpr(),
1777 mode: ModRMRegOrSib::RipRel(addr.clone()),
1778 },
1779 X86Operand::AbsAddr(addr) => ModRM::Indirect {
1780 size: mode.largest_gpr(),
1781 mode: ModRMRegOrSib::Abs(addr.clone()),
1782 },
1783 op => panic!("Invalid operand {:?} for ModRMGeneral", op),
1784 };
1785
1786 let encoding = encode_modrm(modrm, *b, mode);
1787
1788 let mut opcode = &opcode[..];
1789 let sse_prefix = opcode[0];
1790
1791 self.writer.write_all(
1792 encoding
1793 .size_override
1794 .as_ref()
1795 .map(core::slice::from_ref)
1796 .unwrap_or(&[]),
1797 )?;
1798 self.writer.write_all(
1799 encoding
1800 .addr_override
1801 .as_ref()
1802 .map(core::slice::from_ref)
1803 .unwrap_or(&[]),
1804 )?;
1805
1806 match sse_prefix {
1807 0x66 | 0xF2 | 0xF3 => {
1808 self.writer.write_all(core::slice::from_ref(&sse_prefix))?;
1809 opcode = &opcode[1..]
1810 }
1811 _ => {}
1812 }
1813
1814 self.writer.write_all(
1815 encoding
1816 .rex
1817 .as_ref()
1818 .map(core::slice::from_ref)
1819 .unwrap_or(&[]),
1820 )?;
1821
1822 self.writer.write_all(opcode)?;
1823 self.writer
1824 .write_all(core::slice::from_ref(&encoding.modrm))?;
1825 self.writer.write_all(
1826 encoding
1827 .sib
1828 .as_ref()
1829 .map(core::slice::from_ref)
1830 .unwrap_or(&[]),
1831 )?;
1832
1833 match (encoding.disp, encoding.addr) {
1834 (Some((size, disp)), None) => {
1835 self.writer.write_all(&disp.to_ne_bytes()[..size])?;
1836 }
1837 (None, Some((size, addr, pcrel))) => {
1838 self.writer.write_addr(size * 8, addr, pcrel)?;
1839 }
1840 (None, None) => {}
1841 (Some(_), Some(_)) => {
1842 panic!("Cannot encode both an address and a displacement")
1843 }
1844 }
1845
1846 match &insn.operands[1] {
1847 X86Operand::Immediate(imm) => self.writer.write_all(&imm.to_ne_bytes()[..1]),
1848 X86Operand::AbsAddr(addr) => self.writer.write_addr(8, addr.clone(), false),
1849 op => panic!("Invalid operand {:?} for Immediate", op),
1850 }
1851 }
1852 [RControlBits(b), ModRMGeneral, Imm(8)] => {
1853 let modrm = match &insn.operands[0] {
1854 X86Operand::Register(r) => ModRM::Direct(*r),
1855 X86Operand::ModRM(modrm) => modrm.clone(),
1856 X86Operand::RelAddr(addr) => ModRM::Indirect {
1857 size: mode.largest_gpr(),
1858 mode: ModRMRegOrSib::RipRel(addr.clone()),
1859 },
1860 X86Operand::AbsAddr(addr) => ModRM::Indirect {
1861 size: mode.largest_gpr(),
1862 mode: ModRMRegOrSib::Abs(addr.clone()),
1863 },
1864 op => panic!("Invalid operand {:?} for ModRMGeneral", op),
1865 };
1866
1867 let encoding = encode_modrm(modrm, *b, mode);
1868
1869 let mut opcode = &opcode[..];
1870 let sse_prefix = opcode[0];
1871
1872 self.writer.write_all(
1873 encoding
1874 .size_override
1875 .as_ref()
1876 .map(core::slice::from_ref)
1877 .unwrap_or(&[]),
1878 )?;
1879 self.writer.write_all(
1880 encoding
1881 .addr_override
1882 .as_ref()
1883 .map(core::slice::from_ref)
1884 .unwrap_or(&[]),
1885 )?;
1886
1887 match sse_prefix {
1888 0x66 | 0xF2 | 0xF3 => {
1889 self.writer.write_all(core::slice::from_ref(&sse_prefix))?;
1890 opcode = &opcode[1..]
1891 }
1892 _ => {}
1893 }
1894
1895 self.writer.write_all(
1896 encoding
1897 .rex
1898 .as_ref()
1899 .map(core::slice::from_ref)
1900 .unwrap_or(&[]),
1901 )?;
1902
1903 self.writer.write_all(opcode)?;
1904 self.writer
1905 .write_all(core::slice::from_ref(&encoding.modrm))?;
1906 self.writer.write_all(
1907 encoding
1908 .sib
1909 .as_ref()
1910 .map(core::slice::from_ref)
1911 .unwrap_or(&[]),
1912 )?;
1913
1914 match (encoding.disp, encoding.addr) {
1915 (Some((size, disp)), None) => {
1916 self.writer.write_all(&disp.to_ne_bytes()[..size])?;
1917 }
1918 (None, Some((size, addr, pcrel))) => {
1919 self.writer.write_addr(size * 8, addr, pcrel)?;
1920 }
1921 (None, None) => {}
1922 (Some(_), Some(_)) => {
1923 panic!("Cannot encode both an address and a displacement")
1924 }
1925 }
1926
1927 match &insn.operands[1] {
1928 X86Operand::Immediate(imm) => self.writer.write_all(&imm.to_ne_bytes()[..1]),
1929 X86Operand::AbsAddr(addr) => self.writer.write_addr(8, addr.clone(), false),
1930 op => panic!("Invalid operand {:?} for Immediate", op),
1931 }
1932 }
1933 [RelGeneral] => {
1934 let size = match mode {
1935 X86Mode::Virtual8086 | X86Mode::Real => 2,
1936 _ => 4,
1937 };
1938
1939 let mut opcode = &opcode[..];
1940 let sse_prefix = opcode[0];
1941
1942 match sse_prefix {
1943 0x66 | 0xF2 | 0xF3 => {
1944 self.writer.write_all(core::slice::from_ref(&sse_prefix))?;
1945 opcode = &opcode[1..]
1946 }
1947 _ => {}
1948 }
1949
1950 self.writer.write_all(opcode)?;
1951
1952 match &insn.operands[0] {
1953 X86Operand::RelAddr(addr) => {
1954 self.writer.write_addr(size * 8, addr.clone(), true)
1955 }
1956 op => panic!("Invalid Operand for RelGeneral {:?}", op),
1957 }
1958 }
1959 [OpRegGeneral, ImmGeneralWide] => {
1960 let reg = match &insn.operands[0] {
1961 X86Operand::Register(r) => r,
1962 op => panic!("Invalid Operand for {:?}", op),
1963 };
1964
1965 let mut rex = None;
1966 if reg.regnum() > 7 {
1967 *rex.get_or_insert(0x40) |= 0x1;
1968 }
1969
1970 let opsize = match (reg.class(), mode) {
1971 (X86RegisterClass::Word, X86Mode::Real | X86Mode::Virtual8086)
1972 | (
1973 X86RegisterClass::Double,
1974 X86Mode::Protected | X86Mode::Compatibility | X86Mode::Long,
1975 ) => None,
1976 (X86RegisterClass::Word, _)
1977 | (X86RegisterClass::Double, X86Mode::Real | X86Mode::Virtual8086) => {
1978 Some(0x66)
1979 }
1980 (X86RegisterClass::Quad, X86Mode::Long) => None,
1981 (class, mode) => {
1982 panic!("Unsupported register class {:?} in mode {:?}", class, mode)
1983 }
1984 };
1985
1986 let immsize = reg.class().size(mode);
1987
1988 self.writer
1989 .write_all(opsize.as_ref().map(core::slice::from_ref).unwrap_or(&[]))?;
1990
1991 *opcode.last_mut().unwrap() += reg.regnum() & 0x7;
1992 let mut opcode = &opcode[..];
1993 let sse_prefix = opcode[0];
1994
1995 match sse_prefix {
1996 0x66 | 0xF2 | 0xF3 => {
1997 self.writer.write_all(core::slice::from_ref(&sse_prefix))?;
1998 opcode = &opcode[1..]
1999 }
2000 _ => {}
2001 }
2002
2003 self.writer
2004 .write_all(rex.as_ref().map(core::slice::from_ref).unwrap_or(&[]))?;
2005
2006 self.writer.write_all(opcode)?;
2007 match &insn.operands[1] {
2008 X86Operand::Immediate(i) => self.writer.write_all(&i.to_le_bytes()[0..immsize]),
2009 X86Operand::AbsAddr(addr) => {
2010 self.writer.write_addr(immsize * 8, addr.clone(), false)
2011 }
2012 op => panic!("Invalid operand {:?} for ImmGeneralWide", op),
2013 }
2014 }
2015 m => panic!("Unsupported Addressing Mode {:?}", m),
2016 }
2017 }
2018}
2019
2020#[cfg(test)]
2021mod test {
2022
2023 use crate::x86::X86Register;
2024
2025 use super::{ModRM, X86Encoder, X86Instruction, X86Mode, X86Opcode, X86Operand};
2026
2027 use crate::test::TestWriter;
2028
2029 #[test]
2030 fn test_encoder_simple() {
2031 let mut enc = X86Encoder::new(TestWriter { inner: Vec::new() }, X86Mode::Protected);
2032 enc.write_insn(X86Instruction::Retn).unwrap();
2033 assert_eq!(&*enc.writer_mut().inner, &[0xC3]);
2034 }
2035
2036 #[test]
2037 fn test_encoder_modrm_reg32() {
2038 let mut enc = X86Encoder::new(TestWriter { inner: Vec::new() }, X86Mode::Protected);
2039 enc.write_insn(X86Instruction::new(
2040 X86Opcode::XorMR,
2041 vec![
2042 X86Operand::ModRM(ModRM::Direct(X86Register::Eax)),
2043 X86Operand::Register(X86Register::Eax),
2044 ],
2045 ))
2046 .unwrap();
2047
2048 assert_eq!(&*enc.writer_mut().inner, &[0x31, 0xC0]);
2049 }
2050
2051 #[test]
2052 fn test_encoder_modrm_reg32_long() {
2053 let mut enc = X86Encoder::new(TestWriter { inner: Vec::new() }, X86Mode::Long);
2054 enc.write_insn(X86Instruction::new(
2055 X86Opcode::XorMR,
2056 vec![
2057 X86Operand::ModRM(ModRM::Direct(X86Register::Eax)),
2058 X86Operand::Register(X86Register::Eax),
2059 ],
2060 ))
2061 .unwrap();
2062
2063 assert_eq!(&*enc.writer_mut().inner, &[0x31, 0xC0]);
2064 }
2065
2066 #[test]
2067 fn test_encoder_modrm_reg32_real() {
2068 let mut enc = X86Encoder::new(TestWriter { inner: Vec::new() }, X86Mode::Real);
2069 enc.write_insn(X86Instruction::new(
2070 X86Opcode::XorMR,
2071 vec![
2072 X86Operand::ModRM(ModRM::Direct(X86Register::Eax)),
2073 X86Operand::Register(X86Register::Eax),
2074 ],
2075 ))
2076 .unwrap();
2077
2078 assert_eq!(&*enc.writer_mut().inner, &[0x66, 0x31, 0xC0]);
2079 }
2080
2081 #[test]
2082 fn test_encoder_modrm_reg16_real() {
2083 let mut enc = X86Encoder::new(TestWriter { inner: Vec::new() }, X86Mode::Real);
2084 enc.write_insn(X86Instruction::new(
2085 X86Opcode::XorMR,
2086 vec![
2087 X86Operand::ModRM(ModRM::Direct(X86Register::Ax)),
2088 X86Operand::Register(X86Register::Ax),
2089 ],
2090 ))
2091 .unwrap();
2092
2093 assert_eq!(&*enc.writer_mut().inner, &[0x31, 0xC0]);
2094 }
2095
2096 #[test]
2097 fn test_encoder_modrm_reg16_protected() {
2098 let mut enc = X86Encoder::new(TestWriter { inner: Vec::new() }, X86Mode::Protected);
2099 enc.write_insn(X86Instruction::new(
2100 X86Opcode::XorMR,
2101 vec![
2102 X86Operand::ModRM(ModRM::Direct(X86Register::Ax)),
2103 X86Operand::Register(X86Register::Ax),
2104 ],
2105 ))
2106 .unwrap();
2107
2108 assert_eq!(&*enc.writer_mut().inner, &[0x66, 0x31, 0xC0]);
2109 }
2110
2111 #[test]
2112 fn test_encoder_modrm_reg16_long() {
2113 let mut enc = X86Encoder::new(TestWriter { inner: Vec::new() }, X86Mode::Long);
2114 enc.write_insn(X86Instruction::new(
2115 X86Opcode::XorMR,
2116 vec![
2117 X86Operand::ModRM(ModRM::Direct(X86Register::Ax)),
2118 X86Operand::Register(X86Register::Ax),
2119 ],
2120 ))
2121 .unwrap();
2122
2123 assert_eq!(&*enc.writer_mut().inner, &[0x66, 0x31, 0xC0]);
2124 }
2125
2126 #[test]
2127 fn test_encoder_modrm_reg64_long() {
2128 let mut enc = X86Encoder::new(TestWriter { inner: Vec::new() }, X86Mode::Long);
2129 enc.write_insn(X86Instruction::new(
2130 X86Opcode::XorMR,
2131 vec![
2132 X86Operand::ModRM(ModRM::Direct(X86Register::Rax)),
2133 X86Operand::Register(X86Register::Rax),
2134 ],
2135 ))
2136 .unwrap();
2137
2138 assert_eq!(&*enc.writer_mut().inner, &[0x48, 0x31, 0xC0]);
2139 }
2140
2141 #[test]
2142 fn test_encoder_opreg_mode() {
2143 let mut enc = X86Encoder::new(TestWriter { inner: Vec::new() }, X86Mode::Protected);
2144 enc.write_insn(X86Instruction::new(
2145 X86Opcode::Push,
2146 vec![X86Operand::Register(X86Register::Eax)],
2147 ))
2148 .unwrap();
2149 assert_eq!(&*enc.writer_mut().inner, &[0x50]);
2150 }
2151
2152 #[test]
2153 fn test_encoder_opreg_mode_long() {
2154 let mut enc = X86Encoder::new(TestWriter { inner: Vec::new() }, X86Mode::Long);
2155 enc.write_insn(X86Instruction::new(
2156 X86Opcode::Push,
2157 vec![X86Operand::Register(X86Register::Rax)],
2158 ))
2159 .unwrap();
2160 assert_eq!(&*enc.writer_mut().inner, &[0x50]);
2161 }
2162
2163 #[test]
2164 fn test_encoder_opreg_mode_protected_r16() {
2165 let mut enc = X86Encoder::new(TestWriter { inner: Vec::new() }, X86Mode::Protected);
2166 enc.write_insn(X86Instruction::new(
2167 X86Opcode::Push,
2168 vec![X86Operand::Register(X86Register::Ax)],
2169 ))
2170 .unwrap();
2171 assert_eq!(&*enc.writer_mut().inner, &[0x66, 0x50]);
2172 }
2173
2174 #[test]
2175 fn test_encoder_opreg_mode_long_r16() {
2176 let mut enc = X86Encoder::new(TestWriter { inner: Vec::new() }, X86Mode::Long);
2177 enc.write_insn(X86Instruction::new(
2178 X86Opcode::Push,
2179 vec![X86Operand::Register(X86Register::Ax)],
2180 ))
2181 .unwrap();
2182 assert_eq!(&*enc.writer_mut().inner, &[0x66, 0x50]);
2183 }
2184
2185 #[test]
2186 fn test_encoder_opreg_mode_real_r32() {
2187 let mut enc = X86Encoder::new(TestWriter { inner: Vec::new() }, X86Mode::Real);
2188 enc.write_insn(X86Instruction::new(
2189 X86Opcode::Push,
2190 vec![X86Operand::Register(X86Register::Eax)],
2191 ))
2192 .unwrap();
2193 assert_eq!(&*enc.writer_mut().inner, &[0x66, 0x50]);
2194 }
2195
2196 #[test]
2197 #[should_panic]
2198 fn test_encoder_opreg_mode_long_r32() {
2199 let mut enc = X86Encoder::new(TestWriter { inner: Vec::new() }, X86Mode::Long);
2200 let _ = enc.write_insn(X86Instruction::new(
2201 X86Opcode::Push,
2202 vec![X86Operand::Register(X86Register::Eax)],
2203 ));
2204 }
2205}