1use yaxpeax_arch::Reader;
2use yaxpeax_arch::annotation::DescriptionSink;
3
4use crate::protected_mode::Arch;
5use crate::protected_mode::OperandSpec;
6use crate::protected_mode::DecodeError;
7use crate::protected_mode::FieldDescription;
8use crate::protected_mode::RegSpec;
9use crate::protected_mode::RegisterBank;
10use crate::protected_mode::InnerDescription;
11use crate::protected_mode::Instruction;
12use crate::protected_mode::Opcode;
13use crate::protected_mode::read_modrm;
14use crate::protected_mode::read_E;
15use crate::protected_mode::read_E_xmm;
16use crate::protected_mode::read_E_ymm;
17use crate::protected_mode::read_imm_unsigned;
18
19#[derive(Debug)]
20enum VEXOpcodeMap {
21 Map0F,
22 Map0F38,
23 Map0F3A,
24}
25
26#[derive(Debug)]
27enum VEXOpcodePrefix {
28 None,
29 Prefix66,
30 PrefixF3,
31 PrefixF2,
32}
33
34#[allow(non_camel_case_types)]
35#[derive(Debug)]
36enum VEXOperandCode {
37 Nothing,
38 VPS_71,
39 VPS_72,
40 VPS_73,
41 VMOVSS_10,
42 VMOVSD_10,
43 VMOVSD_11,
44 VMOVSS_11,
45 VMOVLPS_12,
46 VMOVHPS_16,
47 M_G_xmm,
48 G_M_xmm,
49 G_U_xmm,
50 Gd_U_xmm,
51 E_G_xmm_imm8,
52 Ud_G_xmm_imm8,
53 Ud_G_xyLmm,
54 M_G_xyLmm,
55 M_G_ymm,
56 G_E_ymm,
57 G_M_ymm,
58 Gd_U_ymm,
59 E_xmm_G_ymm_imm8,
60 Ev_G_xmm_imm8,
61 G_ExyL_V_xyLmm,
62 G_E_xmm,
63 G_E_xmm_imm8,
64 G_E_ymm_imm8,
65 G_xmm_E_xmm,
66 G_xmm_E_ymm,
67 G_ymm_E_xmm,
68 G_ymm_M_xmm,
69 G_ymm_E_ymm,
70 G_V_ymm_E_xmm,
71 M_V_G_xmm,
72 M_V_G_ymm,
73 G_V_xmm_Ed,
74 G_V_E_xyLmm,
75 G_E_xyLmm,
76 E_G_xyLmm,
77 G_E_xyLmm_imm8,
78 G_V_E_xyLmm_imm8,
79 G_V_E_xmm,
80 G_V_E_xmm_imm8,
81 G_V_E_xmm_xmm4,
82 G_V_Ed_xmm,
83 G_V_Eq_xmm,
84 G_V_E_ymm,
85 G_V_E_ymm_imm8,
86 G_V_E_ymm_ymm4,
87 G_V_xmm_Ev_imm8,
88 G_V_M_xmm,
89 G_V_M_ymm,
90 G_ymm_V_ymm_E_xmm_imm8,
91 Ed_G_xmm,
92 G_xmm_Ed,
93 G_E_V,
94 G_V_E,
95 G_E_Ib,
96 VCVT_Gd_Ed_xmm,
97 VCVT_Gd_Eq_xmm,
98 BMI1_F3,
99 MXCSR,
100}
101
102#[inline(always)]
103pub(crate) fn three_byte_vex<
104 T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>,
105 S: DescriptionSink<FieldDescription>,
106>(words: &mut T, vex_byte_one: u8, instruction: &mut Instruction, sink: &mut S) -> Result<(), DecodeError> {
107 let vex_start = words.offset() as u32 * 8 - 8;
108 let vex_byte_two = words.next().ok().ok_or(DecodeError::ExhaustedInput)?;
109 let p = vex_byte_two & 0x03;
110 let p = match p {
111 0x00 => VEXOpcodePrefix::None,
112 0x01 => VEXOpcodePrefix::Prefix66,
113 0x02 => VEXOpcodePrefix::PrefixF3,
114 0x03 => VEXOpcodePrefix::PrefixF2,
115 _ => { unreachable!("p is two bits"); }
116 };
117 sink.record(
118 vex_start + 8,
119 vex_start + 9,
120 InnerDescription::Misc(match p {
121 VEXOpcodePrefix::None => "vex.p indicates no opcode prefix",
122 VEXOpcodePrefix::Prefix66 => "vex.p indicates opcode prefix 66",
123 VEXOpcodePrefix::PrefixF3 => "vex.p indicates opcode prefix f3",
124 VEXOpcodePrefix::PrefixF2 => "vex.p indicates opcode prefix f2",
125 })
126 .with_id(vex_start)
127 );
128 let m = vex_byte_one & 0b11111;
129 sink.record(
130 vex_start + 0,
131 vex_start + 4,
132 InnerDescription::Misc(match m {
133 0b00001 => "vex.mmmmm indicates opcode escape of 0f",
134 0b00010 => "vex.mmmmm indicates opcode escape of 0f38",
135 0b00011 => "vex.mmmmm indicates opcode escape of 0f3a",
136 _ => "vex.mmmmm indicates illegal opcode escape and is invalid",
137 })
138 .with_id(vex_start)
139 );
140 let m = match m {
141 0b00001 => VEXOpcodeMap::Map0F,
142 0b00010 => VEXOpcodeMap::Map0F38,
143 0b00011 => VEXOpcodeMap::Map0F3A,
144 _ => {
145 return Err(DecodeError::InvalidOpcode);
146 }
147 };
148 instruction.regs[3] = RegSpec {
149 bank: RegisterBank::X,
150 num: ((vex_byte_two >> 3) & 0b1111) ^ 0b1111,
151 };
152 sink.record(
153 vex_start + 11,
154 vex_start + 14,
155 InnerDescription::RegisterNumber("vvvv", instruction.regs[3].num, instruction.regs[3])
156 .with_id(vex_start + 2)
157 );
158
159 sink.record(
160 vex_start + 7,
161 vex_start + 7,
162 InnerDescription::Misc(if vex_byte_one & 0b10000000 == 0 {
163 "vex.r extends extends rrr by 0b1000"
164 } else {
165 "vex.r does not alter rrr"
166 })
167 .with_id(vex_start + 1)
168 );
169 sink.record(
170 vex_start + 6,
171 vex_start + 6,
172 InnerDescription::Misc(if vex_byte_one & 0b01000000 == 0 {
173 "vex.x extends extends index reg (if used) by 0b1000"
174 } else {
175 "vex.x does not alter index reg"
176 })
177 .with_id(vex_start + 1)
178 );
179 sink.record(
180 vex_start + 5,
181 vex_start + 5,
182 InnerDescription::Misc(if vex_byte_one & 0b00100000 == 0 {
183 "vex.b extends extends base reg (if used) by 0b1000"
184 } else {
185 "vex.b does not alter base reg"
186 })
187 .with_id(vex_start + 1)
188 );
189 sink.record(
190 vex_start + 10,
191 vex_start + 10,
192 InnerDescription::Misc(if vex_byte_two & 0b100 == 0 {
193 "vex.l selects 128-bit vector sizes"
194 } else {
195 "vex.l selects 256-bit vector sizes"
196 })
197 .with_id(vex_start + 1)
198 );
199 sink.record(
200 vex_start + 15,
201 vex_start + 15,
202 InnerDescription::Misc(if vex_byte_two & 0b10000000 != 0 {
203 "vex.w selects 64-bit operand size"
204 } else {
205 "vex.w leaves default operand size"
206 })
207 .with_id(vex_start + 1)
208 );
209
210 instruction.prefixes.vex_from_c4(vex_byte_one, vex_byte_two);
211
212 sink.record(
213 vex_start + 23,
214 vex_start + 23,
215 InnerDescription::Boundary("vex prefix ends/opcode begins")
216 .with_id(vex_start + 23)
217 );
218
219 read_vex_instruction(m, words, instruction, p, sink)?;
220 instruction.regs[3].num &= 0b0111; Ok(())
222}
223
224#[inline(always)]
225pub(crate) fn two_byte_vex<
226 T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>,
227 S: DescriptionSink<FieldDescription>,
228>(words: &mut T, vex_byte: u8, instruction: &mut Instruction, sink: &mut S) -> Result<(), DecodeError> {
229 let vex_start = words.offset() as u32 * 8 - 8;
230 let p = vex_byte & 0x03;
231 let p = match p {
232 0x00 => VEXOpcodePrefix::None,
233 0x01 => VEXOpcodePrefix::Prefix66,
234 0x02 => VEXOpcodePrefix::PrefixF3,
235 0x03 => VEXOpcodePrefix::PrefixF2,
236 _ => { unreachable!("p is two bits"); }
237 };
238 instruction.regs[3] = RegSpec {
239 bank: RegisterBank::X,
240 num: ((vex_byte >> 3) & 0b1111) ^ 0b1111,
241 };
242
243 sink.record(
244 vex_start + 0,
245 vex_start + 1,
246 InnerDescription::Misc(match p {
247 VEXOpcodePrefix::None => "vex.p indicates no opcode prefix",
248 VEXOpcodePrefix::Prefix66 => "vex.p indicates opcode prefix 66",
249 VEXOpcodePrefix::PrefixF3 => "vex.p indicates opcode prefix f3",
250 VEXOpcodePrefix::PrefixF2 => "vex.p indicates opcode prefix f2",
251 })
252 .with_id(vex_start)
253 );
254
255 sink.record(
256 vex_start + 3,
257 vex_start + 6,
258 InnerDescription::RegisterNumber("vvvv", instruction.regs[3].num, instruction.regs[3])
259 .with_id(vex_start + 2)
260 );
261
262 sink.record(
263 vex_start + 2,
264 vex_start + 2,
265 InnerDescription::Misc(if vex_byte & 0b100 == 0 {
266 "vex.r extends extends rrr by 0b1000"
267 } else {
268 "vex.r does not alter rrr"
269 })
270 .with_id(vex_start + 1)
271 );
272 sink.record(
273 vex_start + 7,
274 vex_start + 7,
275 InnerDescription::Misc(if vex_byte & 0b10000000 != 0 {
276 "vex.w selects 64-bit operand size"
277 } else {
278 "vex.w leaves default operand size"
279 })
280 .with_id(vex_start + 1)
281 );
282
283 instruction.prefixes.vex_from_c5(vex_byte);
284
285 sink.record(
286 vex_start + 15,
287 vex_start + 15,
288 InnerDescription::Boundary("vex prefix ends/opcode begins")
289 .with_id(vex_start + 15)
290 );
291
292 read_vex_instruction(VEXOpcodeMap::Map0F, words, instruction, p, sink)?;
293 instruction.regs[3].num &= 0b0111; Ok(())
295}
296
297#[inline(always)]
298fn read_vex_operands<
299 T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>,
300 S: DescriptionSink<FieldDescription>,
301>(words: &mut T, instruction: &mut Instruction, operand_code: VEXOperandCode, sink: &mut S) -> Result<(), DecodeError> {
302match operand_code {
304 VEXOperandCode::VPS_71 => {
305 let modrm = read_modrm(words)?;
306 if modrm & 0xc0 != 0xc0 {
307 return Err(DecodeError::InvalidOperand);
308 }
309 #[allow(non_snake_case)]
310 let L = instruction.prefixes.vex_unchecked().l();
311
312 let bank = if L {
313 RegisterBank::Y
314 } else {
315 RegisterBank::X
316 };
317
318 let rrr = (modrm >> 3) & 0b111;
319
320 if rrr == 0b001 && L {
321 return Err(DecodeError::InvalidOpcode);
322 }
323
324 instruction.opcode = match rrr {
325 0b001 => Opcode::VPSLLW,
326 0b010 => Opcode::VPSRLW,
327 0b100 => Opcode::VPSRAW,
328 0b110 => Opcode::VPSLLW,
329 _ => {
330 return Err(DecodeError::InvalidOpcode);
331 }
332 };
333 instruction.regs[0] =
334 RegSpec::from_parts(modrm & 7, bank);
335 instruction.regs[3].bank = bank;
336 instruction.operands[0] = OperandSpec::RegVex;
337 instruction.operands[1] = OperandSpec::RegRRR;
338 instruction.imm = read_imm_unsigned(words, 1)?;
339 instruction.operands[2] = OperandSpec::ImmI8;
340 instruction.operand_count = 3;
341 Ok(())
342 }
343 VEXOperandCode::VPS_72 => {
344 let modrm = read_modrm(words)?;
345 if modrm & 0xc0 != 0xc0 {
346 return Err(DecodeError::InvalidOperand);
347 }
348
349 #[allow(non_snake_case)]
350 let L = instruction.prefixes.vex_unchecked().l();
351
352 let bank = if L {
353 RegisterBank::Y
354 } else {
355 RegisterBank::X
356 };
357
358 match (modrm >> 3) & 0b111 {
359 0b010 => {
360 instruction.opcode = Opcode::VPSRLD;
361 }
362 0b100 => {
363 instruction.opcode = Opcode::VPSRAD;
364 }
365 0b110 => {
366 instruction.opcode = Opcode::VPSLLD;
367 }
368 _ => {
369 return Err(DecodeError::InvalidOpcode);
370 }
371 }
372 instruction.regs[0] =
373 RegSpec::from_parts(modrm & 7, bank);
374 instruction.regs[3].bank = bank;
375 instruction.operands[0] = OperandSpec::RegVex;
376 instruction.operands[1] = OperandSpec::RegRRR;
377 instruction.imm = read_imm_unsigned(words, 1)?;
378 instruction.operands[2] = OperandSpec::ImmI8;
379 instruction.operand_count = 3;
380 Ok(())
381 }
382 VEXOperandCode::VPS_73 => {
383 let modrm = read_modrm(words)?;
384 if modrm & 0xc0 != 0xc0 {
385 return Err(DecodeError::InvalidOperand);
386 }
387
388 #[allow(non_snake_case)]
389 let L = instruction.prefixes.vex_unchecked().l();
390
391 let bank = if L {
392 RegisterBank::Y
393 } else {
394 RegisterBank::X
395 };
396
397 match (modrm >> 3) & 0b111 {
398 0b010 => {
399 instruction.opcode = Opcode::VPSRLQ;
400 }
401 0b011 => {
402 instruction.opcode = Opcode::VPSRLDQ;
403 }
404 0b110 => {
405 instruction.opcode = Opcode::VPSLLQ;
406 }
407 0b111 => {
408 instruction.opcode = Opcode::VPSLLDQ;
409 }
410 _ => {
411 return Err(DecodeError::InvalidOpcode);
412 }
413 }
414 instruction.regs[0] =
415 RegSpec::from_parts(modrm & 7, bank);
416 instruction.regs[3].bank = bank;
417 instruction.operands[0] = OperandSpec::RegVex;
418 instruction.operands[1] = OperandSpec::RegRRR;
419 instruction.imm = read_imm_unsigned(words, 1)?;
420 instruction.operands[2] = OperandSpec::ImmI8;
421 instruction.operand_count = 3;
422 Ok(())
423 }
424 VEXOperandCode::VMOVSS_10 |
425 VEXOperandCode::VMOVSD_10 => {
426 let modrm = read_modrm(words)?;
427 instruction.regs[0] =
428 RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
429 let mem_oper = read_E_xmm(words, instruction, modrm, sink)?;
430 instruction.operands[0] = OperandSpec::RegRRR;
431 match mem_oper {
432 OperandSpec::RegMMM => {
433 instruction.operands[1] = OperandSpec::RegVex;
434 instruction.operands[2] = OperandSpec::RegMMM;
435 instruction.operand_count = 3;
436 },
437 other => {
438 if instruction.regs[3].num != 0 {
439 return Err(DecodeError::InvalidOperand);
440 }
441 if instruction.opcode == Opcode::VMOVSS {
442 instruction.mem_size = 4;
443 } else {
444 instruction.mem_size = 8;
445 }
446 instruction.operands[1] = other;
447 instruction.operand_count = 2;
448 }
449 }
450 Ok(())
451 },
452 VEXOperandCode::VMOVSS_11 |
453 VEXOperandCode::VMOVSD_11 => {
454 let modrm = read_modrm(words)?;
455 instruction.regs[0] =
456 RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
457 let mem_oper = read_E_xmm(words, instruction, modrm, sink)?;
458 instruction.operands[2] = OperandSpec::RegRRR;
459 match mem_oper {
460 OperandSpec::RegMMM => {
461 instruction.operands[0] = OperandSpec::RegMMM;
462 instruction.operands[1] = OperandSpec::RegVex;
463 instruction.operand_count = 3;
464 },
465 other => {
466 if instruction.regs[3].num != 0 {
467 return Err(DecodeError::InvalidOperand);
468 }
469 if instruction.opcode == Opcode::VMOVSS {
470 instruction.mem_size = 4;
471 } else {
472 instruction.mem_size = 8;
473 }
474 instruction.operands[0] = other;
475 instruction.operands[1] = instruction.operands[2];
476 instruction.operand_count = 2;
477 }
478 }
479 Ok(())
480 },
481 VEXOperandCode::VMOVLPS_12 => {
482 let modrm = read_modrm(words)?;
483 instruction.opcode = if modrm & 0xc0 == 0xc0 {
484 Opcode::VMOVHLPS
485 } else {
486 instruction.mem_size = 8;
487 Opcode::VMOVLPS
488 };
489 instruction.regs[0] =
490 RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
491 instruction.operands[0] = OperandSpec::RegRRR;
492 instruction.operands[1] = OperandSpec::RegVex;
493 instruction.operands[2] = read_E_xmm(words, instruction, modrm, sink)?;
494 instruction.operand_count = 3;
495 Ok(())
496 }
497 VEXOperandCode::VMOVHPS_16 => {
498 let modrm = read_modrm(words)?;
499 instruction.opcode = if modrm & 0xc0 == 0xc0 {
500 Opcode::VMOVLHPS
501 } else {
502 instruction.mem_size = 8;
503 Opcode::VMOVHPS
504 };
505 instruction.regs[0] =
506 RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
507 instruction.operands[0] = OperandSpec::RegRRR;
508 instruction.operands[1] = OperandSpec::RegVex;
509 instruction.operands[2] = read_E_xmm(words, instruction, modrm, sink)?;
510 instruction.operand_count = 3;
511 Ok(())
512 }
513 VEXOperandCode::Nothing => {
514 if instruction.opcode == Opcode::VZEROUPPER || instruction.opcode == Opcode::VZEROALL {
515 if instruction.regs[3].num != 0 {
516 return Err(DecodeError::InvalidOperand);
517 }
518 }
519 instruction.operand_count = 0;
520 Ok(())
521 },
522 VEXOperandCode::Ev_G_xmm_imm8 => {
523 if instruction.regs[3].num != 0 {
524 return Err(DecodeError::InvalidOperand);
525 }
526 let modrm = read_modrm(words)?;
527 instruction.regs[0] =
528 RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
529 let mem_oper = read_E(words, instruction, modrm, RegisterBank::D, sink)?;
530 instruction.operands[0] = mem_oper;
531 instruction.operands[1] = OperandSpec::RegRRR;
532 instruction.operands[2] = OperandSpec::ImmU8;
533 if mem_oper != OperandSpec::RegMMM {
534 match instruction.opcode {
535 Opcode::VPEXTRB => {
536 instruction.mem_size = 1;
537 }
538 Opcode::VPEXTRW => {
539 instruction.mem_size = 2;
540 }
541 Opcode::VEXTRACTPS |
542 Opcode::VPEXTRD => {
543 instruction.mem_size = 4;
544 }
545 _ => {
546 instruction.mem_size = 8;
547 }
548 }
549 }
550 instruction.operand_count = 3;
551 instruction.imm = read_imm_unsigned(words, 1)?;
552 Ok(())
553 },
554 VEXOperandCode::G_xmm_Ed => {
555 if instruction.regs[3].num != 0 {
556 return Err(DecodeError::InvalidOperand);
557 }
558 let modrm = read_modrm(words)?;
559 instruction.regs[0] =
560 RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
561 let mem_oper = read_E(words, instruction, modrm, RegisterBank::D, sink)?;
562 instruction.operands[0] = OperandSpec::RegRRR;
563 instruction.operands[1] = mem_oper;
564 if mem_oper != OperandSpec::RegMMM {
565 instruction.mem_size = 4;
566 }
567 instruction.operand_count = 2;
568 Ok(())
569 }
570 VEXOperandCode::Ed_G_xmm => {
571 if instruction.regs[3].num != 0 {
572 return Err(DecodeError::InvalidOperand);
573 }
574 let modrm = read_modrm(words)?;
575 instruction.regs[0] =
576 RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
577 let mem_oper = read_E(words, instruction, modrm, RegisterBank::D, sink)?;
578 instruction.operands[0] = mem_oper;
579 instruction.operands[1] = OperandSpec::RegRRR;
580 if mem_oper != OperandSpec::RegMMM {
581 instruction.mem_size = 4;
582 }
583 instruction.operand_count = 2;
584 Ok(())
585 }
586 VEXOperandCode::VCVT_Gd_Ed_xmm => {
587 if instruction.regs[3].num != 0 {
588 return Err(DecodeError::InvalidOperand);
589 }
590 let modrm = read_modrm(words)?;
591 instruction.regs[0] =
592 RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::D);
593 let mem_oper = read_E(words, instruction, modrm, RegisterBank::D, sink)?;
594 if let OperandSpec::RegMMM = mem_oper {
595 instruction.regs[1].bank = RegisterBank::X;
596 } else {
597 instruction.mem_size = 4;
598 }
599 instruction.operands[0] = OperandSpec::RegRRR;
600 instruction.operands[1] = mem_oper;
601 instruction.operand_count = 2;
602 Ok(())
603 }
604 VEXOperandCode::VCVT_Gd_Eq_xmm => {
605 if instruction.regs[3].num != 0 {
606 return Err(DecodeError::InvalidOperand);
607 }
608 let modrm = read_modrm(words)?;
609 instruction.regs[0] =
610 RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::D);
611 let mem_oper = read_E(words, instruction, modrm, RegisterBank::D, sink)?;
612 if let OperandSpec::RegMMM = mem_oper {
613 instruction.regs[1].bank = RegisterBank::X;
614 } else {
615 instruction.mem_size = 8;
616 }
617 instruction.operands[0] = OperandSpec::RegRRR;
618 instruction.operands[1] = mem_oper;
619 instruction.operand_count = 2;
620 Ok(())
621 }
622 VEXOperandCode::M_G_xyLmm => {
623 if instruction.regs[3].num != 0 {
624 return Err(DecodeError::InvalidOperand);
625 }
626 #[allow(non_snake_case)]
628 let L = instruction.prefixes.vex_unchecked().l();
629 let bank = if L { RegisterBank::Y } else { RegisterBank::X };
630
631 let modrm = read_modrm(words)?;
632 instruction.regs[0] =
633 RegSpec::from_parts((modrm >> 3) & 7, bank);
634 let mem_oper = read_E(words, instruction, modrm, bank, sink)?;
635 if mem_oper == OperandSpec::RegMMM {
636 return Err(DecodeError::InvalidOperand);
637 }
638 if mem_oper != OperandSpec::RegMMM {
639 if instruction.opcode == Opcode::VMOVLPD || instruction.opcode == Opcode::VMOVHPD || instruction.opcode == Opcode::VMOVHPS {
640 instruction.mem_size = 8;
641 } else {
642 if L {
643 instruction.mem_size = 32;
644 } else {
645 instruction.mem_size = 16;
646 }
647 }
648 }
649 instruction.operands[0] = mem_oper;
650 instruction.operands[1] = OperandSpec::RegRRR;
651 instruction.operand_count = 2;
652 Ok(())
653 }
654 VEXOperandCode::M_G_xmm => {
655 if instruction.regs[3].num != 0 {
656 return Err(DecodeError::InvalidOperand);
657 }
658 let modrm = read_modrm(words)?;
659 instruction.regs[0] =
660 RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
661 let mem_oper = read_E_xmm(words, instruction, modrm, sink)?;
662 if mem_oper == OperandSpec::RegMMM {
663 return Err(DecodeError::InvalidOperand);
664 }
665 if mem_oper != OperandSpec::RegMMM {
666 if instruction.opcode == Opcode::VMOVLPD || instruction.opcode == Opcode::VMOVHPD || instruction.opcode == Opcode::VMOVHPS {
667 instruction.mem_size = 8;
668 } else {
669 instruction.mem_size = 16;
670 }
671 }
672 instruction.operands[0] = mem_oper;
673 instruction.operands[1] = OperandSpec::RegRRR;
674 instruction.operand_count = 2;
675 Ok(())
676 }
677 VEXOperandCode::Ud_G_xyLmm => {
678 if instruction.regs[3].num != 0 {
679 return Err(DecodeError::InvalidOperand);
680 }
681 #[allow(non_snake_case)]
683 let L = instruction.prefixes.vex_unchecked().l();
684 let bank = if L { RegisterBank::Y } else { RegisterBank::X };
685
686 let modrm = read_modrm(words)?;
687 instruction.regs[0] =
688 RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::D);
689 let mem_oper = read_E(words, instruction, modrm, bank, sink)?;
690 if mem_oper != OperandSpec::RegMMM {
691 return Err(DecodeError::InvalidOperand);
692 }
693 instruction.operands[0] = OperandSpec::RegRRR;
694 instruction.operands[1] = mem_oper;
695 instruction.operand_count = 2;
696 Ok(())
697 }
698 VEXOperandCode::Ud_G_xmm_imm8 => {
699 if instruction.regs[3].num != 0 {
700 return Err(DecodeError::InvalidOperand);
701 }
702 let modrm = read_modrm(words)?;
703 instruction.regs[0] =
704 RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::D);
705 let mem_oper = read_E_xmm(words, instruction, modrm, sink)?;
706 if mem_oper != OperandSpec::RegMMM {
707 return Err(DecodeError::InvalidOperand);
708 }
709 instruction.operands[0] = OperandSpec::RegRRR;
710 instruction.operands[1] = mem_oper;
711 instruction.imm = read_imm_unsigned(words, 1)?;
712 instruction.operands[2] = OperandSpec::ImmU8;
713 instruction.operand_count = 3;
714 Ok(())
715 }
716 VEXOperandCode::E_G_xmm_imm8 => {
717 if instruction.regs[3].num != 0 {
718 return Err(DecodeError::InvalidOperand);
719 }
720 let modrm = read_modrm(words)?;
721 instruction.regs[0] =
722 RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
723 let mem_oper = read_E_xmm(words, instruction, modrm, sink)?;
724 instruction.operands[0] = mem_oper;
725 instruction.operands[1] = OperandSpec::RegRRR;
726 instruction.imm = read_imm_unsigned(words, 1)?;
727 instruction.operands[2] = OperandSpec::ImmU8;
728 if mem_oper != OperandSpec::RegMMM {
729 instruction.mem_size = 16;
730 }
731 instruction.operand_count = 3;
732 Ok(())
733 }
734 VEXOperandCode::E_xmm_G_ymm_imm8 => {
735 if instruction.regs[3].num != 0 {
736 return Err(DecodeError::InvalidOperand);
737 }
738 let modrm = read_modrm(words)?;
739 instruction.regs[0] =
740 RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::Y);
741 let mem_oper = read_E_xmm(words, instruction, modrm, sink)?;
742 instruction.operands[0] = mem_oper;
743 instruction.operands[1] = OperandSpec::RegRRR;
744 instruction.imm = read_imm_unsigned(words, 1)?;
745 instruction.operands[2] = OperandSpec::ImmU8;
746 if mem_oper != OperandSpec::RegMMM {
747 instruction.mem_size = 16;
748 }
749 instruction.operand_count = 3;
750 Ok(())
751 }
752
753 VEXOperandCode::Gd_U_xmm => {
754 if instruction.regs[3].num != 0 {
755 return Err(DecodeError::InvalidOperand);
756 }
757 let modrm = read_modrm(words)?;
758 instruction.regs[0] =
759 RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::D);
760 let mem_oper = read_E_xmm(words, instruction, modrm, sink)?;
761 if mem_oper != OperandSpec::RegMMM {
762 return Err(DecodeError::InvalidOperand);
763 }
764 instruction.operands[0] = OperandSpec::RegRRR;
765 instruction.operands[1] = mem_oper;
766 instruction.operand_count = 2;
767 Ok(())
768 }
769 VEXOperandCode::Gd_U_ymm => {
770 if instruction.regs[3].num != 0 {
771 return Err(DecodeError::InvalidOperand);
772 }
773 let modrm = read_modrm(words)?;
774 instruction.regs[0] =
775 RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::D);
776 let mem_oper = read_E_ymm(words, instruction, modrm, sink)?;
777 if mem_oper != OperandSpec::RegMMM {
778 return Err(DecodeError::InvalidOperand);
779 }
780 instruction.operands[0] = OperandSpec::RegRRR;
781 instruction.operands[1] = mem_oper;
782 instruction.operand_count = 2;
783 Ok(())
784 }
785
786 op @ VEXOperandCode::G_M_xmm |
787 op @ VEXOperandCode::G_U_xmm |
788 op @ VEXOperandCode::G_E_xmm => {
789 if instruction.regs[3].num != 0 {
790 return Err(DecodeError::InvalidOperand);
791 }
792 let modrm = read_modrm(words)?;
793 match (op, modrm & 0xc0) {
794 (VEXOperandCode::G_U_xmm, 0xc0) => {
795 }
797 (VEXOperandCode::G_U_xmm, _) |
798 (VEXOperandCode::G_M_xmm, 0xc0) => {
799 return Err(DecodeError::InvalidOperand);
800 }
801 (VEXOperandCode::G_M_xmm, _) | (_, _) => { }
805 }
806 instruction.regs[0] =
807 RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
808 let mem_oper = read_E_xmm(words, instruction, modrm, sink)?;
809 instruction.operands[0] = OperandSpec::RegRRR;
810 instruction.operands[1] = mem_oper;
811 if mem_oper != OperandSpec::RegMMM {
812 if [Opcode::VBROADCASTSS, Opcode::VUCOMISS, Opcode::VCOMISS].contains(&instruction.opcode) {
813 instruction.mem_size = 4;
814 } else if [Opcode::VMOVDDUP, Opcode::VUCOMISD, Opcode::VCOMISD, Opcode::VCVTPS2PD, Opcode::VMOVD].contains(&instruction.opcode) {
815 instruction.mem_size = 8;
816 } else {
817 instruction.mem_size = 16;
818 };
819 }
820 instruction.operand_count = 2;
821 Ok(())
822 }
823 VEXOperandCode::G_xmm_E_xmm => {
824 if instruction.regs[3].num != 0 {
825 return Err(DecodeError::InvalidOperand);
826 }
827 let modrm = read_modrm(words)?;
828 instruction.regs[0] =
829 RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
830 let mem_oper = read_E_xmm(words, instruction, modrm, sink)?;
831 instruction.operands[0] = OperandSpec::RegRRR;
832 instruction.operands[1] = mem_oper;
833 if mem_oper != OperandSpec::RegMMM {
834 instruction.mem_size = 16;
835 }
836 instruction.operand_count = 2;
837 Ok(())
838 }
839 VEXOperandCode::G_xmm_E_ymm => {
840 if instruction.regs[3].num != 0 {
841 return Err(DecodeError::InvalidOperand);
842 }
843 let modrm = read_modrm(words)?;
844 instruction.regs[0] =
845 RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
846 let mem_oper = read_E_ymm(words, instruction, modrm, sink)?;
847 instruction.operands[0] = OperandSpec::RegRRR;
848 instruction.operands[1] = mem_oper;
849 if mem_oper != OperandSpec::RegMMM {
850 instruction.mem_size = 32;
851 }
852 instruction.operand_count = 2;
853 Ok(())
854 }
855 op @ VEXOperandCode::G_ymm_M_xmm |
856 op @ VEXOperandCode::G_ymm_E_xmm => {
857 if instruction.regs[3].num != 0 {
858 return Err(DecodeError::InvalidOperand);
859 }
860 let modrm = read_modrm(words)?;
861 if modrm & 0xc0 == 0xc0 {
862 if let VEXOperandCode::G_ymm_M_xmm = op {
863 return Err(DecodeError::InvalidOperand);
864 }
865 }
866 instruction.regs[0] =
867 RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::Y);
868 let mem_oper = read_E_xmm(words, instruction, modrm, sink)?;
869 instruction.operands[0] = OperandSpec::RegRRR;
870 instruction.operands[1] = mem_oper;
871 if mem_oper != OperandSpec::RegMMM {
872 if [Opcode::VBROADCASTSS].contains(&instruction.opcode) {
873 instruction.mem_size = 4;
874 } else if [Opcode::VBROADCASTSD].contains(&instruction.opcode) {
875 instruction.mem_size = 8;
876 } else {
877 instruction.mem_size = 16;
878 }
879 }
880 instruction.operand_count = 2;
881 Ok(())
882 }
883 VEXOperandCode::G_ymm_E_ymm => {
884 if instruction.regs[3].num != 0 {
885 return Err(DecodeError::InvalidOperand);
886 }
887 let modrm = read_modrm(words)?;
888 instruction.regs[0] =
889 RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::Y);
890 let mem_oper = read_E_ymm(words, instruction, modrm, sink)?;
891 instruction.operands[0] = OperandSpec::RegRRR;
892 instruction.operands[1] = mem_oper;
893 if mem_oper != OperandSpec::RegMMM {
894 instruction.mem_size = 32;
895 }
896 instruction.operand_count = 2;
897 Ok(())
898 }
899
900 op @ VEXOperandCode::M_G_ymm => {
901 if instruction.regs[3].num != 0 {
902 return Err(DecodeError::InvalidOperand);
903 }
904 let modrm = read_modrm(words)?;
905 match (op, modrm & 0xc0) {
906 (VEXOperandCode::M_G_ymm, 0xc0) => {
907 return Err(DecodeError::InvalidOperand);
908 }
909 (VEXOperandCode::M_G_ymm, _) | (_, _) => { }
913 }
914 instruction.regs[0] =
915 RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::Y);
916 let mem_oper = read_E_ymm(words, instruction, modrm, sink)?;
917 instruction.operands[0] = mem_oper;
918 instruction.operands[1] = OperandSpec::RegRRR;
919 if mem_oper != OperandSpec::RegMMM {
920 instruction.mem_size = 32;
921 }
922 instruction.operand_count = 2;
923 Ok(())
924 }
925
926 op @ VEXOperandCode::G_M_ymm |
927 op @ VEXOperandCode::G_E_ymm => {
928 if instruction.regs[3].num != 0 {
929 return Err(DecodeError::InvalidOperand);
930 }
931 let modrm = read_modrm(words)?;
932 match (op, modrm & 0xc0) {
933 (VEXOperandCode::G_M_ymm, 0xc0) => {
934 return Err(DecodeError::InvalidOperand);
935 }
936 (VEXOperandCode::G_M_ymm, _) | (_, _) => { }
940 }
941 instruction.regs[0] =
942 RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::Y);
943 let mem_oper = read_E_ymm(words, instruction, modrm, sink)?;
944 instruction.operands[0] = OperandSpec::RegRRR;
945 instruction.operands[1] = mem_oper;
946 if mem_oper != OperandSpec::RegMMM {
947 instruction.mem_size = 32;
948 }
949 instruction.operand_count = 2;
950 Ok(())
951 }
952 op @ VEXOperandCode::G_V_E_ymm |
953 op @ VEXOperandCode::G_V_M_ymm => {
954 let modrm = read_modrm(words)?;
955 if let VEXOperandCode::G_V_M_ymm = op {
956 if modrm & 0xc0 == 0xc0 {
957 return Err(DecodeError::InvalidOperand);
958 }
959 }
960 instruction.regs[0] =
961 RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::Y);
962 instruction.regs[3].bank = RegisterBank::Y;
963 let mem_oper = read_E_ymm(words, instruction, modrm, sink)?;
964 instruction.operands[0] = OperandSpec::RegRRR;
965 instruction.operands[1] = OperandSpec::RegVex;
966 instruction.operands[2] = mem_oper;
967 if mem_oper != OperandSpec::RegMMM {
968 instruction.mem_size = 32;
969 }
970 instruction.operand_count = 3;
971 Ok(())
972 }
973 VEXOperandCode::G_V_E_ymm_imm8 => {
974 let modrm = read_modrm(words)?;
975 instruction.regs[0] =
976 RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::Y);
977 instruction.regs[3].bank = RegisterBank::Y;
978 let mem_oper = read_E_ymm(words, instruction, modrm, sink)?;
979 instruction.operands[0] = OperandSpec::RegRRR;
980 instruction.operands[1] = OperandSpec::RegVex;
981 instruction.operands[2] = mem_oper;
982 instruction.imm = read_imm_unsigned(words, 1)?;
983 instruction.operands[3] = OperandSpec::ImmU8;
984 if mem_oper != OperandSpec::RegMMM {
985 instruction.mem_size = 32;
986 }
987 instruction.operand_count = 4;
988 Ok(())
989 }
990 VEXOperandCode::M_V_G_ymm => {
991 let modrm = read_modrm(words)?;
992 if modrm & 0xc0 == 0xc0 {
993 return Err(DecodeError::InvalidOperand);
994 }
995 instruction.regs[0] =
996 RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::Y);
997 instruction.regs[3].bank = RegisterBank::Y;
998 let mem_oper = read_E_ymm(words, instruction, modrm, sink)?;
999 instruction.operands[0] = mem_oper;
1000 instruction.operands[1] = OperandSpec::RegVex;
1001 instruction.operands[2] = OperandSpec::RegRRR;
1002 if mem_oper != OperandSpec::RegMMM {
1003 instruction.mem_size = 32;
1004 }
1005 instruction.operand_count = 3;
1006 Ok(())
1007 }
1008 VEXOperandCode::G_V_M_xmm => {
1009 let modrm = read_modrm(words)?;
1010 if modrm & 0xc0 == 0xc0 {
1011 return Err(DecodeError::InvalidOperand);
1012 }
1013 instruction.regs[0] =
1014 RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
1015 let mem_oper = read_E_xmm(words, instruction, modrm, sink)?;
1016 instruction.operands[0] = OperandSpec::RegRRR;
1017 instruction.operands[1] = OperandSpec::RegVex;
1018 instruction.operands[2] = mem_oper;
1019 if mem_oper != OperandSpec::RegMMM {
1020 if instruction.opcode == Opcode::VMOVLPD || instruction.opcode == Opcode::VMOVHPD {
1021 instruction.mem_size = 8;
1022 } else {
1023 instruction.mem_size = 16;
1024 }
1025 }
1026 instruction.operand_count = 3;
1027 Ok(())
1028 }
1029 VEXOperandCode::E_G_xyLmm => {
1030 if instruction.regs[3].num != 0 {
1031 return Err(DecodeError::InvalidOperand);
1032 }
1033 #[allow(non_snake_case)]
1035 let L = instruction.prefixes.vex_unchecked().l();
1036 let bank = if L { RegisterBank::Y } else { RegisterBank::X };
1037
1038 let modrm = read_modrm(words)?;
1039 instruction.regs[0] =
1040 RegSpec::from_parts((modrm >> 3) & 7, bank);
1041 let mem_oper = read_E(words, instruction, modrm, bank, sink)?;
1042 if mem_oper != OperandSpec::RegMMM {
1043 if instruction.opcode == Opcode::VMOVLPD || instruction.opcode == Opcode::VMOVHPD || instruction.opcode == Opcode::VMOVHPS {
1044 instruction.mem_size = 8;
1045 } else {
1046 if L {
1047 instruction.mem_size = 32;
1048 } else {
1049 instruction.mem_size = 16;
1050 }
1051 }
1052 }
1053 instruction.operands[0] = mem_oper;
1054 instruction.operands[1] = OperandSpec::RegRRR;
1055
1056 instruction.operand_count = 2;
1057 Ok(())
1058 }
1059 VEXOperandCode::G_V_E_xyLmm_imm8 => {
1060 #[allow(non_snake_case)]
1062 let L = instruction.prefixes.vex_unchecked().l();
1063 let bank = if L { RegisterBank::Y } else { RegisterBank::X };
1064
1065 let modrm = read_modrm(words)?;
1066 instruction.regs[0] =
1067 RegSpec::from_parts((modrm >> 3) & 7, bank);
1068 let mem_oper = read_E(words, instruction, modrm, bank, sink)?;
1069 instruction.regs[3].bank = bank;
1070 instruction.operands[0] = OperandSpec::RegRRR;
1071 instruction.operands[1] = OperandSpec::RegVex;
1072 instruction.operands[2] = mem_oper;
1073 instruction.imm = read_imm_unsigned(words, 1)?;
1074 instruction.operands[3] = OperandSpec::ImmU8;
1075 if mem_oper != OperandSpec::RegMMM {
1076 if L {
1077 instruction.mem_size = 32;
1078 } else {
1079 instruction.mem_size = 16;
1080 }
1081 }
1082 instruction.operand_count = 4;
1083 Ok(())
1084 }
1085 VEXOperandCode::G_E_xyLmm => {
1086 if instruction.regs[3].num != 0 {
1087 return Err(DecodeError::InvalidOperand);
1088 }
1089 #[allow(non_snake_case)]
1091 let L = instruction.prefixes.vex_unchecked().l();
1092 let bank = if L { RegisterBank::Y } else { RegisterBank::X };
1093
1094 let modrm = read_modrm(words)?;
1095 instruction.regs[0] =
1096 RegSpec::from_parts((modrm >> 3) & 7, bank);
1097 let mem_oper = read_E(words, instruction, modrm, bank, sink)?;
1098 instruction.operands[0] = OperandSpec::RegRRR;
1099 instruction.operands[1] = mem_oper;
1100 if mem_oper != OperandSpec::RegMMM {
1101 if L {
1102 instruction.mem_size = 32;
1103 } else {
1104 instruction.mem_size = 16;
1105 }
1106
1107 if instruction.opcode == Opcode::VMOVDDUP && !L {
1108 instruction.mem_size = 8;
1109 } else if [Opcode::VBROADCASTSS, Opcode::VUCOMISS, Opcode::VCOMISS].contains(&instruction.opcode) {
1110 instruction.mem_size = 4;
1111 } else if [Opcode::VUCOMISD, Opcode::VCOMISD, Opcode::VCVTPS2PD, Opcode::VMOVD].contains(&instruction.opcode) {
1112 instruction.mem_size = 8;
1113 };
1114 }
1115 instruction.operand_count = 2;
1116 Ok(())
1117 }
1118 VEXOperandCode::G_V_E_xyLmm => {
1119 let modrm = read_modrm(words)?;
1120 #[allow(non_snake_case)]
1122 let L = instruction.prefixes.vex_unchecked().l();
1123 let bank = if L { RegisterBank::Y } else { RegisterBank::X };
1124
1125 instruction.regs[0] =
1126 RegSpec::from_parts((modrm >> 3) & 7, bank);
1127 let mem_oper = read_E(words, instruction, modrm, bank, sink)?;
1128 instruction.regs[3].bank = bank;
1129 instruction.operands[0] = OperandSpec::RegRRR;
1130 instruction.operands[1] = OperandSpec::RegVex;
1131 instruction.operands[2] = mem_oper;
1132 if mem_oper != OperandSpec::RegMMM {
1133 if [Opcode::VSQRTSS, Opcode::VADDSS, Opcode::VMULSS, Opcode::VSUBSS, Opcode::VMINSS, Opcode::VDIVSS, Opcode::VMAXSS].contains(&instruction.opcode) {
1134 instruction.mem_size = 4;
1135 } else if [Opcode::VSQRTSD, Opcode::VADDSD, Opcode::VMULSD, Opcode::VSUBSD, Opcode::VMINSD, Opcode::VDIVSD, Opcode::VMAXSD].contains(&instruction.opcode) {
1136 instruction.mem_size = 8;
1137 } else {
1138 if L {
1139 instruction.mem_size = 32;
1140 } else {
1141 instruction.mem_size = 16;
1142 }
1143 }
1144 }
1145 instruction.operand_count = 3;
1146 Ok(())
1147 }
1148 VEXOperandCode::G_V_E_xmm => {
1149 let modrm = read_modrm(words)?;
1150 instruction.regs[0] =
1151 RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
1152 let mem_oper = read_E_xmm(words, instruction, modrm, sink)?;
1153 instruction.operands[0] = OperandSpec::RegRRR;
1154 instruction.operands[1] = OperandSpec::RegVex;
1155 instruction.operands[2] = mem_oper;
1156 if mem_oper != OperandSpec::RegMMM {
1157 if [Opcode::VSQRTSS, Opcode::VADDSS, Opcode::VMULSS, Opcode::VSUBSS, Opcode::VMINSS, Opcode::VDIVSS, Opcode::VMAXSS].contains(&instruction.opcode) {
1158 instruction.mem_size = 4;
1159 } else if [Opcode::VSQRTSD, Opcode::VADDSD, Opcode::VMULSD, Opcode::VSUBSD, Opcode::VMINSD, Opcode::VDIVSD, Opcode::VMAXSD].contains(&instruction.opcode) {
1160 instruction.mem_size = 8;
1161 } else {
1162 instruction.mem_size = 16;
1163 }
1164 }
1165 instruction.operand_count = 3;
1166 Ok(())
1167 }
1168 VEXOperandCode::G_V_Ed_xmm => {
1169 let modrm = read_modrm(words)?;
1170 instruction.regs[0] =
1171 RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
1172 let mem_oper = read_E_xmm(words, instruction, modrm, sink)?;
1173 instruction.operands[0] = OperandSpec::RegRRR;
1174 instruction.operands[1] = OperandSpec::RegVex;
1175 instruction.operands[2] = mem_oper;
1176 if mem_oper != OperandSpec::RegMMM {
1177 instruction.mem_size = 4;
1178 }
1179 instruction.operand_count = 3;
1180 Ok(())
1181 }
1182 VEXOperandCode::G_V_Eq_xmm => {
1183 let modrm = read_modrm(words)?;
1184 instruction.regs[0] =
1185 RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
1186 let mem_oper = read_E_xmm(words, instruction, modrm, sink)?;
1187 instruction.operands[0] = OperandSpec::RegRRR;
1188 instruction.operands[1] = OperandSpec::RegVex;
1189 instruction.operands[2] = mem_oper;
1190 if mem_oper != OperandSpec::RegMMM {
1191 instruction.mem_size = 8;
1192 }
1193 instruction.operand_count = 3;
1194 Ok(())
1195 }
1196 VEXOperandCode::G_V_xmm_Ed => {
1197 let modrm = read_modrm(words)?;
1198 instruction.regs[0] =
1199 RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
1200 let mem_oper = read_E(words, instruction, modrm, RegisterBank::D, sink)?;
1201 instruction.operands[0] = OperandSpec::RegRRR;
1202 instruction.operands[1] = OperandSpec::RegVex;
1203 instruction.operands[2] = mem_oper;
1204 if mem_oper != OperandSpec::RegMMM {
1205 instruction.mem_size = 4;
1206 }
1207 instruction.operand_count = 3;
1208 Ok(())
1209 }
1210 VEXOperandCode::G_V_E_xmm_imm8 => {
1211 let modrm = read_modrm(words)?;
1212 instruction.regs[0] =
1213 RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
1214 let mem_oper = read_E_xmm(words, instruction, modrm, sink)?;
1215 instruction.operands[0] = OperandSpec::RegRRR;
1216 instruction.operands[1] = OperandSpec::RegVex;
1217 instruction.operands[2] = mem_oper;
1218 instruction.imm = read_imm_unsigned(words, 1)?;
1219 instruction.operands[3] = OperandSpec::ImmU8;
1220 if mem_oper != OperandSpec::RegMMM {
1221 instruction.mem_size = 16;
1222 }
1223 instruction.operand_count = 4;
1224 Ok(())
1225 }
1226 VEXOperandCode::G_ymm_V_ymm_E_xmm_imm8 => {
1227 let modrm = read_modrm(words)?;
1228 instruction.regs[0] =
1229 RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::Y);
1230 instruction.regs[3].bank = RegisterBank::Y;
1231 let mem_oper = read_E_xmm(words, instruction, modrm, sink)?;
1232 instruction.operands[0] = OperandSpec::RegRRR;
1233 instruction.operands[1] = OperandSpec::RegVex;
1234 instruction.operands[2] = mem_oper;
1235 instruction.imm = read_imm_unsigned(words, 1)?;
1236 instruction.operands[3] = OperandSpec::ImmU8;
1237 if mem_oper != OperandSpec::RegMMM {
1238 instruction.mem_size = 16;
1239 }
1240 instruction.operand_count = 4;
1241 Ok(())
1242 }
1243 VEXOperandCode::M_V_G_xmm => {
1244 let modrm = read_modrm(words)?;
1245 if modrm & 0xc0 == 0xc0 {
1246 return Err(DecodeError::InvalidOperand);
1247 }
1248
1249 instruction.regs[0] =
1250 RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
1251 let mem_oper = read_E_xmm(words, instruction, modrm, sink)?;
1252 instruction.operands[0] = mem_oper;
1253 instruction.operands[1] = OperandSpec::RegVex;
1254 instruction.operands[2] = OperandSpec::RegRRR;
1255 if mem_oper != OperandSpec::RegMMM {
1256 instruction.mem_size = 16;
1257 }
1258 instruction.operand_count = 3;
1259 Ok(())
1260 }
1261
1262 VEXOperandCode::G_ExyL_V_xyLmm => {
1263 #[allow(non_snake_case)]
1264 let L = instruction.prefixes.vex_unchecked().l();
1265
1266 let bank = if L && instruction.opcode != Opcode::VGATHERQPS && instruction.opcode != Opcode::VPGATHERQD {
1267 RegisterBank::Y
1268 } else {
1269 RegisterBank::X
1270 };
1271
1272 let index_bank = if L {
1273 RegisterBank::Y
1274 } else {
1275 RegisterBank::X
1276 };
1277
1278 let modrm = read_modrm(words)?;
1279 instruction.regs[0] =
1280 RegSpec::from_parts((modrm >> 3) & 7, bank);
1281 let mem_oper = read_E(words, instruction, modrm, bank, sink)?;
1282 if instruction.opcode == Opcode::VPGATHERDQ {
1283 instruction.regs[2].bank = RegisterBank::X;
1284 } else {
1285 instruction.regs[2].bank = index_bank;
1286 }
1287 instruction.regs[3].bank = bank;
1288 instruction.operands[0] = OperandSpec::RegRRR;
1289 instruction.operands[1] = mem_oper;
1290 instruction.operands[2] = OperandSpec::RegVex;
1291 if mem_oper != OperandSpec::RegMMM {
1292 if instruction.opcode == Opcode::VPGATHERDD || instruction.opcode == Opcode::VPGATHERQD || instruction.opcode == Opcode::VGATHERDPS || instruction.opcode == Opcode::VGATHERQPS {
1293 instruction.mem_size = 4;
1294 } else {
1295 instruction.mem_size = 8;
1296 }
1297 }
1298 instruction.operand_count = 3;
1299 Ok(())
1300 }
1301 VEXOperandCode::G_V_E => {
1302 let modrm = read_modrm(words)?;
1303 let bank = RegisterBank::D;
1304 instruction.regs[0] =
1305 RegSpec::from_parts((modrm >> 3) & 7,bank);
1306 instruction.regs[3].bank = bank;
1307 let mem_oper = read_E(words, instruction, modrm, bank, sink)?;
1308 instruction.operands[0] = OperandSpec::RegRRR;
1309 instruction.operands[1] = OperandSpec::RegVex;
1310 instruction.operands[2] = mem_oper;
1311 if mem_oper != OperandSpec::RegMMM {
1312 instruction.mem_size = bank as u8;
1313 }
1314 instruction.operand_count = 3;
1315 Ok(())
1316 }
1317 VEXOperandCode::G_E_V => {
1318 let modrm = read_modrm(words)?;
1319 let bank = RegisterBank::D;
1320 instruction.regs[0] =
1321 RegSpec::from_parts((modrm >> 3) & 7,bank);
1322 instruction.regs[3].bank = bank;
1323 let mem_oper = read_E(words, instruction, modrm, bank, sink)?;
1324 instruction.operands[0] = OperandSpec::RegRRR;
1325 instruction.operands[1] = mem_oper;
1326 instruction.operands[2] = OperandSpec::RegVex;
1327 if mem_oper != OperandSpec::RegMMM {
1328 instruction.mem_size = bank as u8;
1329 }
1330 instruction.operand_count = 3;
1331 Ok(())
1332 }
1333 VEXOperandCode::G_E_Ib => {
1334 let modrm = read_modrm(words)?;
1335 let bank = RegisterBank::D;
1336 instruction.regs[0] =
1337 RegSpec::from_parts((modrm >> 3) & 7,bank);
1338 let mem_oper = read_E(words, instruction, modrm, bank, sink)?;
1339 instruction.operands[0] = OperandSpec::RegRRR;
1340 instruction.operands[1] = mem_oper;
1341 instruction.imm = read_imm_unsigned(words, 1)?;
1342 instruction.operands[2] = OperandSpec::ImmI8;
1343 if mem_oper != OperandSpec::RegMMM {
1344 instruction.mem_size = bank as u8;
1345 }
1346 instruction.operand_count = 3;
1347 Ok(())
1348 }
1349 VEXOperandCode::BMI1_F3 => {
1350 let modrm = read_modrm(words)?;
1351 instruction.opcode = match (modrm >> 3) & 7 {
1352 1 => {
1353 Opcode::BLSR
1354 }
1355 2 => {
1356 Opcode::BLSMSK
1357 }
1358 3 => {
1359 Opcode::BLSI
1360 }
1361 _ => {
1362 return Err(DecodeError::InvalidOpcode);
1363 }
1364 };
1365 let bank = RegisterBank::D;
1366 instruction.regs[0] =
1367 RegSpec::from_parts((modrm >> 3) & 7,bank);
1368 let mem_oper = read_E(words, instruction, modrm, bank, sink)?;
1369 instruction.operands[0] = OperandSpec::RegVex;
1370 instruction.operands[1] = mem_oper;
1371 instruction.operand_count = 2;
1372 if mem_oper != OperandSpec::RegMMM {
1373 instruction.mem_size = bank as u8;
1374 }
1375 instruction.regs[3].bank = bank;
1376 Ok(())
1377 }
1378 VEXOperandCode::MXCSR => {
1379 let modrm = read_modrm(words)?;
1380 instruction.opcode = match (modrm >> 3) & 7 {
1381 2 => {
1382 Opcode::VLDMXCSR
1383 }
1384 3 => {
1385 Opcode::VSTMXCSR
1386 }
1387 _ => {
1388 return Err(DecodeError::InvalidOpcode);
1389 }
1390 };
1391 let mem_oper = read_E(words, instruction, modrm, RegisterBank::D, sink)?;
1392 if let OperandSpec::RegMMM = mem_oper {
1393 return Err(DecodeError::InvalidOperand);
1394 }
1395 if mem_oper != OperandSpec::RegMMM {
1396 instruction.mem_size = 4;
1397 }
1398 instruction.operands[0] = mem_oper;
1399 instruction.operand_count = 1;
1400 Ok(())
1401 }
1402 VEXOperandCode::G_E_xyLmm_imm8 => {
1403 if instruction.regs[3].num != 0 {
1404 return Err(DecodeError::InvalidOperand);
1405 }
1406
1407 #[allow(non_snake_case)]
1408 let L = instruction.prefixes.vex_unchecked().l();
1409
1410 let bank = if L {
1411 RegisterBank::Y
1412 } else {
1413 RegisterBank::X
1414 };
1415
1416 let modrm = read_modrm(words)?;
1417 instruction.regs[0] =
1418 RegSpec::from_parts((modrm >> 3) & 7, bank);
1419 let mem_oper = read_E(words, instruction, modrm, bank, sink)?;
1420 instruction.operands[0] = OperandSpec::RegRRR;
1421 instruction.operands[1] = mem_oper;
1422 instruction.imm = read_imm_unsigned(words, 1)?;
1423 instruction.operands[2] = OperandSpec::ImmU8;
1424 if mem_oper != OperandSpec::RegMMM {
1425 instruction.mem_size = 16;
1426 }
1427 instruction.operand_count = 3;
1428 Ok(())
1429 }
1430 VEXOperandCode::G_E_xmm_imm8 => {
1431 if instruction.regs[3].num != 0 {
1432 return Err(DecodeError::InvalidOperand);
1433 }
1434
1435 #[allow(non_snake_case)]
1436 let L = instruction.prefixes.vex_unchecked().l();
1437 if L {
1438 return Err(DecodeError::InvalidOperand);
1439 }
1440 let modrm = read_modrm(words)?;
1441 instruction.regs[0] =
1442 RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);
1443 let mem_oper = read_E_xmm(words, instruction, modrm, sink)?;
1444 instruction.operands[0] = OperandSpec::RegRRR;
1445 instruction.operands[1] = mem_oper;
1446 instruction.imm = read_imm_unsigned(words, 1)?;
1447 instruction.operands[2] = OperandSpec::ImmU8;
1448 if mem_oper != OperandSpec::RegMMM {
1449 instruction.mem_size = 16;
1450 }
1451 instruction.operand_count = 3;
1452 Ok(())
1453 }
1454 VEXOperandCode::G_E_ymm_imm8 => {
1455 if instruction.regs[3].num != 0 {
1456 return Err(DecodeError::InvalidOperand);
1457 }
1458 let modrm = read_modrm(words)?;
1459 instruction.regs[0] =
1460 RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::Y);
1461 let mem_oper = read_E_ymm(words, instruction, modrm, sink)?;
1462 instruction.operands[0] = OperandSpec::RegRRR;
1463 instruction.operands[1] = mem_oper;
1464 instruction.imm = read_imm_unsigned(words, 1)?;
1465 instruction.operands[2] = OperandSpec::ImmU8;
1466 if mem_oper != OperandSpec::RegMMM {
1467 instruction.mem_size = 32;
1468 }
1469 instruction.operand_count = 3;
1470 Ok(())
1471 }
1472 VEXOperandCode::G_V_E_ymm_ymm4 => {
1473 let modrm = read_modrm(words)?;
1474 instruction.regs[0] =
1475 RegSpec::from_parts((modrm >> 3) & 7,RegisterBank::Y);
1476 instruction.regs[3].bank = RegisterBank::Y;
1477 let mem_oper = read_E_ymm(words, instruction, modrm, sink)?;
1478 instruction.operands[0] = OperandSpec::RegRRR;
1479 instruction.operands[1] = OperandSpec::RegVex;
1480 instruction.operands[2] = mem_oper;
1481 instruction.imm = read_imm_unsigned(words, 1)? >> 4;
1482 instruction.operands[3] = OperandSpec::Reg4;
1483 if mem_oper != OperandSpec::RegMMM {
1484 instruction.mem_size = 32;
1485 }
1486 instruction.operand_count = 4;
1487 Ok(())
1488 }
1489 VEXOperandCode::G_V_E_xmm_xmm4 => {
1490 let modrm = read_modrm(words)?;
1491 instruction.regs[0] =
1492 RegSpec::from_parts((modrm >> 3) & 7,RegisterBank::X);
1493 instruction.regs[3].bank = RegisterBank::X;
1494 let mem_oper = read_E_xmm(words, instruction, modrm, sink)?;
1495 instruction.operands[0] = OperandSpec::RegRRR;
1496 instruction.operands[1] = OperandSpec::RegVex;
1497 instruction.operands[2] = mem_oper;
1498 instruction.imm = read_imm_unsigned(words, 1)? >> 4;
1499 instruction.operands[3] = OperandSpec::Reg4;
1500 if mem_oper != OperandSpec::RegMMM {
1501 instruction.mem_size = 16;
1502 }
1503 instruction.operand_count = 4;
1504 Ok(())
1505 }
1506 VEXOperandCode::G_V_ymm_E_xmm => {
1507 let modrm = read_modrm(words)?;
1508 instruction.regs[0] =
1509 RegSpec::from_parts((modrm >> 3) & 7,RegisterBank::Y);
1510 instruction.regs[3].bank = RegisterBank::Y;
1511 let mem_oper = read_E_xmm(words, instruction, modrm, sink)?;
1512 instruction.operands[0] = OperandSpec::RegRRR;
1513 instruction.operands[1] = OperandSpec::RegVex;
1514 instruction.operands[2] = mem_oper;
1515 if mem_oper != OperandSpec::RegMMM {
1516 instruction.mem_size = 16;
1517 }
1518 instruction.operand_count = 3;
1519 Ok(())
1520 }
1521 VEXOperandCode::G_V_xmm_Ev_imm8 => {
1522 let modrm = read_modrm(words)?;
1523 instruction.regs[0] =
1524 RegSpec::from_parts((modrm >> 3) & 7,RegisterBank::X);
1525 instruction.regs[3].bank = RegisterBank::X;
1526 let mem_oper = read_E(words, instruction, modrm, RegisterBank::D, sink)?;
1528 instruction.operands[0] = OperandSpec::RegRRR;
1529 instruction.operands[1] = OperandSpec::RegVex;
1530 instruction.operands[2] = mem_oper;
1531 instruction.imm = read_imm_unsigned(words, 1)?;
1532 instruction.operands[3] = OperandSpec::ImmI8;
1533 if mem_oper != OperandSpec::RegMMM {
1534 match instruction.opcode {
1535 Opcode::VPINSRB => {
1536 instruction.mem_size = 1;
1537 }
1538 Opcode::VPINSRW => {
1539 instruction.mem_size = 2;
1540 }
1541 Opcode::VINSERTPS |
1542 Opcode::VPINSRD => {
1543 instruction.mem_size = 4;
1544 }
1545 _ => {
1546 instruction.mem_size = 8;
1547 }
1548 }
1549 }
1550 instruction.operand_count = 4;
1551 Ok(())
1552 }
1553
1554 }
1555}
1556
1557#[inline(never)]
1558fn read_vex_instruction<
1559 T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>,
1560 S: DescriptionSink<FieldDescription>,
1561>(opcode_map: VEXOpcodeMap, words: &mut T, instruction: &mut Instruction, p: VEXOpcodePrefix, sink: &mut S) -> Result<(), DecodeError> {
1562 let opcode_start = words.offset() as u32 * 8;
1563 let opc = words.next().ok().ok_or(DecodeError::ExhaustedInput)?;
1564
1565 #[allow(non_snake_case)]
1567 let L = instruction.prefixes.vex_unchecked().l();
1568
1569let (opcode, operand_code) = match opcode_map {
1574 VEXOpcodeMap::Map0F => {
1575 match p {
1576 VEXOpcodePrefix::None => {
1577 match opc {
1578 0x10 => (Opcode::VMOVUPS, VEXOperandCode::G_E_xyLmm),
1579 0x11 => (Opcode::VMOVUPS, VEXOperandCode::E_G_xyLmm),
1580 0x12 => (Opcode::Invalid, if L {
1581 return Err(DecodeError::InvalidOpcode);
1582 } else {
1583 VEXOperandCode::VMOVLPS_12
1584 }),
1585 0x13 => (Opcode::VMOVLPS, if L {
1586 return Err(DecodeError::InvalidOpcode);
1587 } else {
1588 VEXOperandCode::M_G_xmm
1589 }),
1590 0x14 => (Opcode::VUNPCKLPS, VEXOperandCode::G_V_E_xyLmm),
1591 0x15 => (Opcode::VUNPCKHPS, VEXOperandCode::G_V_E_xyLmm),
1592 0x16 => (Opcode::Invalid, if L {
1593 return Err(DecodeError::InvalidOpcode);
1594 } else {
1595 VEXOperandCode::VMOVHPS_16
1596 }),
1597 0x17 => (Opcode::VMOVHPS, if L {
1598 return Err(DecodeError::InvalidOpcode);
1599 } else {
1600 VEXOperandCode::M_G_xmm
1601 }),
1602 0x28 => (Opcode::VMOVAPS, VEXOperandCode::G_E_xyLmm),
1603 0x29 => (Opcode::VMOVAPS, VEXOperandCode::E_G_xyLmm),
1604 0x2B => (Opcode::VMOVNTPS, if L {
1605 VEXOperandCode::M_G_ymm
1606 } else {
1607 VEXOperandCode::M_G_xmm
1608 }),
1609 0x2e => (Opcode::VUCOMISS, VEXOperandCode::G_E_xmm),
1610 0x2f => (Opcode::VCOMISS, VEXOperandCode::G_E_xmm),
1611 0x50 => (Opcode::VMOVMSKPS, VEXOperandCode::Ud_G_xyLmm),
1612 0x51 => (Opcode::VSQRTPS, VEXOperandCode::G_E_xyLmm),
1613 0x52 => (Opcode::VRSQRTPS, VEXOperandCode::G_E_xyLmm),
1614 0x53 => (Opcode::VRCPPS, VEXOperandCode::G_E_xyLmm),
1615 0x54 => (Opcode::VANDPS, VEXOperandCode::G_V_E_xyLmm),
1616 0x55 => (Opcode::VANDNPS, VEXOperandCode::G_V_E_xyLmm),
1617 0x56 => (Opcode::VORPS, VEXOperandCode::G_V_E_xyLmm),
1618 0x57 => (Opcode::VXORPS, VEXOperandCode::G_V_E_xyLmm),
1619 0x58 => (Opcode::VADDPS, VEXOperandCode::G_V_E_xyLmm),
1620 0x59 => (Opcode::VMULPS, VEXOperandCode::G_V_E_xyLmm),
1621 0x5A => (Opcode::VCVTPS2PD, if L {
1622 VEXOperandCode::G_ymm_E_xmm
1623 } else {
1624 VEXOperandCode::G_E_xmm
1625 }),
1626 0x5B => (Opcode::VCVTDQ2PS, VEXOperandCode::G_E_xyLmm),
1627 0x5C => (Opcode::VSUBPS, VEXOperandCode::G_V_E_xyLmm),
1628 0x5D => (Opcode::VMINPS, VEXOperandCode::G_V_E_xyLmm),
1629 0x5E => (Opcode::VDIVPS, VEXOperandCode::G_V_E_xyLmm),
1630 0x5F => (Opcode::VMAXPS, VEXOperandCode::G_V_E_xyLmm),
1631 0x77 => if L {
1632 (Opcode::VZEROALL, VEXOperandCode::Nothing)
1633 } else {
1634 (Opcode::VZEROUPPER, VEXOperandCode::Nothing)
1635 },
1636 0xAE => (Opcode::Invalid, if L {
1637 return Err(DecodeError::InvalidOpcode);
1638 } else {
1639 VEXOperandCode::MXCSR
1640 }),
1641 0xC2 => (Opcode::VCMPPS, VEXOperandCode::G_V_E_xyLmm_imm8),
1642 0xC6 => (Opcode::VSHUFPS, VEXOperandCode::G_V_E_xyLmm_imm8),
1643 _ => {
1644 return Err(DecodeError::InvalidOpcode);
1645 }
1646 }
1647 },
1648 VEXOpcodePrefix::Prefix66 => {
1649 match opc {
16500x10 => (Opcode::VMOVUPD, VEXOperandCode::G_E_xyLmm),
1653 0x11 => (Opcode::VMOVUPD, VEXOperandCode::G_E_xyLmm),
1654 0x12 => (Opcode::VMOVLPD, if L {
1655 return Err(DecodeError::InvalidOpcode);
1656 } else {
1657 VEXOperandCode::G_V_M_xmm
1658 }),
1659 0x13 => (Opcode::VMOVLPD, if L {
1660 return Err(DecodeError::InvalidOpcode);
1661 } else {
1662 VEXOperandCode::M_G_xmm
1663 }),
1664 0x14 => (Opcode::VUNPCKLPD, VEXOperandCode::G_V_E_xyLmm),
1665 0x15 => (Opcode::VUNPCKHPD, VEXOperandCode::G_V_E_xyLmm),
1666 0x16 => (Opcode::VMOVHPD, if L {
1667 return Err(DecodeError::InvalidOpcode);
1668 } else {
1669 VEXOperandCode::G_V_M_xmm
1670 }),
1671 0x17 => (Opcode::VMOVHPD, if L {
1672 return Err(DecodeError::InvalidOpcode);
1673 } else {
1674 VEXOperandCode::M_G_xmm
1675 }),
1676 0x28 => (Opcode::VMOVAPD, VEXOperandCode::G_E_xyLmm),
1677 0x29 => (Opcode::VMOVAPD, VEXOperandCode::E_G_xyLmm),
1678 0x2B => (Opcode::VMOVNTPD, VEXOperandCode::M_G_xyLmm),
1679 0x2e => (Opcode::VUCOMISD, VEXOperandCode::G_E_xmm),
1680 0x2f => (Opcode::VCOMISD, VEXOperandCode::G_E_xmm),
1681 0x50 => (Opcode::VMOVMSKPD, if L {
1682 VEXOperandCode::Gd_U_ymm
1683 } else {
1684 VEXOperandCode::Gd_U_xmm
1685 }),
1686 0x51 => (Opcode::VSQRTPD, VEXOperandCode::G_E_xyLmm),
1687 0x54 => (Opcode::VANDPD, VEXOperandCode::G_V_E_xyLmm),
1688 0x55 => (Opcode::VANDNPD, VEXOperandCode::G_V_E_xyLmm),
1689 0x56 => (Opcode::VORPD, VEXOperandCode::G_V_E_xyLmm),
1690 0x57 => (Opcode::VXORPD, VEXOperandCode::G_V_E_xyLmm),
1691 0x58 => (Opcode::VADDPD, VEXOperandCode::G_V_E_xyLmm),
1692 0x59 => (Opcode::VMULPD, VEXOperandCode::G_V_E_xyLmm),
1693 0x5A => (Opcode::VCVTPD2PS, if L {
1694 VEXOperandCode::G_xmm_E_ymm
1695 } else {
1696 VEXOperandCode::G_xmm_E_xmm
1697 }),
1698 0x5B => (Opcode::VCVTPS2DQ, VEXOperandCode::G_E_xyLmm),
1699 0x5C => (Opcode::VSUBPD, VEXOperandCode::G_V_E_xyLmm),
1700 0x5D => (Opcode::VMINPD, VEXOperandCode::G_V_E_xyLmm),
1701 0x5E => (Opcode::VDIVPD, VEXOperandCode::G_V_E_xyLmm),
1702 0x5F => (Opcode::VMAXPD, VEXOperandCode::G_V_E_xyLmm),
1703 0x60 => (Opcode::VPUNPCKLBW, VEXOperandCode::G_V_E_xyLmm),
1704 0x61 => (Opcode::VPUNPCKLWD, VEXOperandCode::G_V_E_xyLmm),
1705 0x62 => (Opcode::VPUNPCKLDQ, VEXOperandCode::G_V_E_xyLmm),
1706 0x63 => (Opcode::VPACKSSWB, VEXOperandCode::G_V_E_xyLmm),
1707 0x64 => (Opcode::VPCMPGTB, VEXOperandCode::G_V_E_xyLmm),
1708 0x65 => (Opcode::VPCMPGTW, VEXOperandCode::G_V_E_xyLmm),
1709 0x66 => (Opcode::VPCMPGTD, VEXOperandCode::G_V_E_xyLmm),
1710 0x67 => (Opcode::VPACKUSWB, VEXOperandCode::G_V_E_xyLmm),
1711 0x68 => (Opcode::VPUNPCKHBW, VEXOperandCode::G_V_E_xyLmm),
1712 0x69 => (Opcode::VPUNPCKHWD, VEXOperandCode::G_V_E_xyLmm),
1713 0x6A => (Opcode::VPUNPCKHDQ, VEXOperandCode::G_V_E_xyLmm),
1714 0x6B => (Opcode::VPACKSSDW, VEXOperandCode::G_V_E_xyLmm),
1715 0x6C => (Opcode::VPUNPCKLQDQ, VEXOperandCode::G_V_E_xyLmm),
1716 0x6D => (Opcode::VPUNPCKHQDQ, VEXOperandCode::G_V_E_xyLmm),
1717 0x6E => {
1718 (Opcode::VMOVD, if L {
1719 return Err(DecodeError::InvalidOpcode);
1720 } else {
1721 VEXOperandCode::G_xmm_Ed
1722 })
1723 },
1724 0x6F => (Opcode::VMOVDQA, VEXOperandCode::G_E_xyLmm),
1725 0x70 => (Opcode::VPSHUFD, VEXOperandCode::G_E_xyLmm_imm8),
1726 0x71 => (Opcode::Invalid, VEXOperandCode::VPS_71),
1727 0x72 => (Opcode::Invalid, VEXOperandCode::VPS_72),
1728 0x73 => (Opcode::Invalid, VEXOperandCode::VPS_73),
1729 0x74 => (Opcode::VPCMPEQB, VEXOperandCode::G_V_E_xyLmm),
1730 0x75 => (Opcode::VPCMPEQW, VEXOperandCode::G_V_E_xyLmm),
1731 0x76 => (Opcode::VPCMPEQD, VEXOperandCode::G_V_E_xyLmm),
1732 0x7C => (Opcode::VHADDPD, VEXOperandCode::G_V_E_xyLmm),
1733 0x7D => (Opcode::VHSUBPD, VEXOperandCode::G_V_E_xyLmm),
1734 0x7E => {
1735 (Opcode::VMOVD, if L {
1736 return Err(DecodeError::InvalidOpcode);
1737 } else {
1738 VEXOperandCode::Ed_G_xmm
1739 })
1740 }
1741 0x7F => (Opcode::VMOVDQA, VEXOperandCode::E_G_xyLmm),
1742 0xC2 => (Opcode::VCMPPD, VEXOperandCode::G_V_E_xyLmm_imm8),
1743 0xC4 => (Opcode::VPINSRW, if L {
1744 return Err(DecodeError::InvalidOpcode);
1745 } else {
1746 VEXOperandCode::G_V_xmm_Ev_imm8
1747 }),
1748 0xC5 => (Opcode::VPEXTRW, if L {
1749 return Err(DecodeError::InvalidOpcode);
1750 } else {
1751 VEXOperandCode::Ud_G_xmm_imm8
1752 }),
1753 0xC6 => (Opcode::VSHUFPD, VEXOperandCode::G_V_E_xyLmm_imm8),
1754 0xD0 => (Opcode::VADDSUBPD, VEXOperandCode::G_V_E_xyLmm),
1755 0xD1 => (Opcode::VPSRLW, if L {
1756 VEXOperandCode::G_V_ymm_E_xmm
1757 } else {
1758 VEXOperandCode::G_V_E_xmm
1759 }),
1760 0xD2 => (Opcode::VPSRLD, if L {
1761 VEXOperandCode::G_V_ymm_E_xmm
1762 } else {
1763 VEXOperandCode::G_V_E_xmm
1764 }),
1765 0xD3 => (Opcode::VPSRLQ, if L {
1766 VEXOperandCode::G_V_ymm_E_xmm
1767 } else {
1768 VEXOperandCode::G_V_E_xmm
1769 }),
1770 0xD4 => (Opcode::VPADDQ, VEXOperandCode::G_V_E_xyLmm),
1771 0xD5 => (Opcode::VPMULLW, VEXOperandCode::G_V_E_xyLmm),
1772 0xD6 => (Opcode::VMOVD, if L {
1773 return Err(DecodeError::InvalidOpcode);
1774 } else {
1775 VEXOperandCode::G_E_xmm
1776 }),
1777 0xD7 => (Opcode::VPMOVMSKB, VEXOperandCode::Ud_G_xyLmm),
1778 0xD8 => (Opcode::VPSUBUSB, VEXOperandCode::G_V_E_xyLmm),
1779 0xD9 => (Opcode::VPSUBUSW, VEXOperandCode::G_V_E_xyLmm),
1780 0xDA => (Opcode::VPMINUB, VEXOperandCode::G_V_E_xyLmm),
1781 0xDB => (Opcode::VPAND, VEXOperandCode::G_V_E_xyLmm),
1782 0xDC => (Opcode::VPADDUSB, VEXOperandCode::G_V_E_xyLmm),
1783 0xDD => (Opcode::VPADDUSW, VEXOperandCode::G_V_E_xyLmm),
1784 0xDE => (Opcode::VPMAXUB, VEXOperandCode::G_V_E_xyLmm),
1785 0xDF => (Opcode::VPANDN, VEXOperandCode::G_V_E_xyLmm),
1786 0xE0 => (Opcode::VPAVGB, VEXOperandCode::G_V_E_xyLmm),
1787 0xE1 => (Opcode::VPSRAW, if L {
1788 VEXOperandCode::G_V_ymm_E_xmm
1789 } else {
1790 VEXOperandCode::G_V_E_xmm
1791 }),
1792 0xE2 => (Opcode::VPSRAD, if L {
1793 VEXOperandCode::G_V_ymm_E_xmm
1794 } else {
1795 VEXOperandCode::G_V_E_xmm
1796 }),
1797 0xE3 => (Opcode::VPAVGW, VEXOperandCode::G_V_E_xyLmm),
1798 0xE4 => (Opcode::VPMULHUW, VEXOperandCode::G_V_E_xyLmm),
1799 0xE5 => (Opcode::VPMULHW, VEXOperandCode::G_V_E_xyLmm),
1800 0xE6 => (Opcode::VCVTTPD2DQ, if L {
1801 VEXOperandCode::G_xmm_E_ymm
1802 } else {
1803 VEXOperandCode::G_E_xmm
1804 }),
1805 0xE7 => (Opcode::VMOVNTDQ, VEXOperandCode::M_G_xyLmm),
1806 0xE8 => (Opcode::VPSUBSB, VEXOperandCode::G_V_E_xyLmm),
1807 0xE9 => (Opcode::VPSUBSW, VEXOperandCode::G_V_E_xyLmm),
1808 0xEA => (Opcode::VPMINSW, VEXOperandCode::G_V_E_xyLmm),
1809 0xEB => (Opcode::VPOR, VEXOperandCode::G_V_E_xyLmm),
1810 0xEC => (Opcode::VPADDSB, VEXOperandCode::G_V_E_xyLmm),
1811 0xED => (Opcode::VPADDSW, VEXOperandCode::G_V_E_xyLmm),
1812 0xEE => (Opcode::VPMAXSW, VEXOperandCode::G_V_E_xyLmm),
1813 0xEF => (Opcode::VPXOR, VEXOperandCode::G_V_E_xyLmm),
1814 0xF1 => (Opcode::VPSLLW, if L {
1815 VEXOperandCode::G_V_ymm_E_xmm
1816 } else {
1817 VEXOperandCode::G_V_E_xmm
1818 }),
1819 0xF2 => (Opcode::VPSLLD, if L {
1820 VEXOperandCode::G_V_ymm_E_xmm
1821 } else {
1822 VEXOperandCode::G_V_E_xmm
1823 }),
1824 0xF3 => (Opcode::VPSLLQ, if L {
1825 VEXOperandCode::G_V_ymm_E_xmm
1826 } else {
1827 VEXOperandCode::G_V_E_xmm
1828 }),
1829 0xF4 => (Opcode::VPMULUDQ, VEXOperandCode::G_V_E_xyLmm),
1830 0xF5 => (Opcode::VPMADDWD, VEXOperandCode::G_V_E_xyLmm),
1831 0xF6 => (Opcode::VPSADBW, VEXOperandCode::G_V_E_xyLmm),
1832 0xF7 => (Opcode::VMASKMOVDQU, if L {
1833 return Err(DecodeError::InvalidOpcode);
1834 } else {
1835 VEXOperandCode::G_U_xmm
1836 }),
1837 0xF8 => (Opcode::VPSUBB, VEXOperandCode::G_V_E_xyLmm),
1838 0xF9 => (Opcode::VPSUBW, VEXOperandCode::G_V_E_xyLmm),
1839 0xFA => (Opcode::VPSUBD, VEXOperandCode::G_V_E_xyLmm),
1840 0xFB => (Opcode::VPSUBQ, VEXOperandCode::G_V_E_xyLmm),
1841 0xFC => (Opcode::VPADDB, VEXOperandCode::G_V_E_xyLmm),
1842 0xFD => (Opcode::VPADDW, VEXOperandCode::G_V_E_xyLmm),
1843 0xFE => (Opcode::VPADDD, VEXOperandCode::G_V_E_xyLmm),
1844 _ => {
1845 return Err(DecodeError::InvalidOpcode);
1846 }
1847 }
1848 }
1849 VEXOpcodePrefix::PrefixF2 => {
1850 match opc {
1851 0x10 => (Opcode::VMOVSD, VEXOperandCode::VMOVSD_10),
1852 0x11 => (Opcode::VMOVSD, VEXOperandCode::VMOVSD_11),
1853 0x12 => (Opcode::VMOVDDUP, VEXOperandCode::G_E_xyLmm),
1854 0x2a => (Opcode::VCVTSI2SD, {
1855 VEXOperandCode::G_V_xmm_Ed }),
1857 0x2c => (Opcode::VCVTTSD2SI, {
1858 VEXOperandCode::VCVT_Gd_Eq_xmm
1859 }),
1860 0x2d => (Opcode::VCVTSD2SI, {
1861 VEXOperandCode::VCVT_Gd_Eq_xmm
1862 }),
1863 0x51 => (Opcode::VSQRTSD, VEXOperandCode::G_V_E_xmm),
1864 0x58 => (Opcode::VADDSD, VEXOperandCode::G_V_E_xmm),
1865 0x59 => (Opcode::VMULSD, VEXOperandCode::G_V_E_xmm),
1866 0x5a => (Opcode::VCVTSD2SS, VEXOperandCode::G_V_Eq_xmm),
1867 0x5c => (Opcode::VSUBSD, VEXOperandCode::G_V_E_xmm),
1868 0x5d => (Opcode::VMINSD, VEXOperandCode::G_V_E_xmm),
1869 0x5e => (Opcode::VDIVSD, VEXOperandCode::G_V_E_xmm),
1870 0x5f => (Opcode::VMAXSD, VEXOperandCode::G_V_E_xmm),
1871 0x70 => (Opcode::VPSHUFLW, VEXOperandCode::G_E_xyLmm_imm8),
1872 0x7c => (Opcode::VHADDPS, VEXOperandCode::G_V_E_xyLmm),
1873 0x7d => (Opcode::VHSUBPS, VEXOperandCode::G_V_E_xyLmm),
1874 0xc2 => (Opcode::VCMPSD, VEXOperandCode::G_V_E_xmm_imm8),
1875 0xd0 => (Opcode::VADDSUBPS, VEXOperandCode::G_V_E_xyLmm),
1876 0xe6 => (Opcode::VCVTPD2DQ, if L {
1877 VEXOperandCode::G_xmm_E_ymm
1878 } else {
1879 VEXOperandCode::G_xmm_E_xmm
1880 }),
1881 0xf0 => (Opcode::VLDDQU, if L {
1882 VEXOperandCode::G_M_ymm
1883 } else {
1884 VEXOperandCode::G_M_xmm
1885 }),
1886 _ => {
1887 return Err(DecodeError::InvalidOpcode);
1888 }
1889 }
1890 }
1891 VEXOpcodePrefix::PrefixF3 => {
1892 match opc {
1893 0x10 => (Opcode::VMOVSS, VEXOperandCode::VMOVSS_10),
1894 0x11 => (Opcode::VMOVSS, VEXOperandCode::VMOVSS_11),
1895 0x12 => (Opcode::VMOVSLDUP, if L { VEXOperandCode::G_E_ymm } else { VEXOperandCode::G_E_xmm }),
1896 0x16 => (Opcode::VMOVSHDUP, if L { VEXOperandCode::G_E_ymm } else { VEXOperandCode::G_E_xmm }),
1897 0x2a => (Opcode::VCVTSI2SS, {
1898 VEXOperandCode::G_V_xmm_Ed
1899 }),
1900 0x2c => (Opcode::VCVTTSS2SI, {
1901 VEXOperandCode::VCVT_Gd_Ed_xmm
1902 }),
1903 0x2d => (Opcode::VCVTSS2SI, {
1904 VEXOperandCode::VCVT_Gd_Ed_xmm
1905 }),
1906 0x51 => (Opcode::VSQRTSS, VEXOperandCode::G_V_E_xmm),
1907 0x52 => (Opcode::VRSQRTSS, VEXOperandCode::G_V_E_xmm),
1908 0x53 => (Opcode::VRCPSS, VEXOperandCode::G_V_E_xmm),
1909 0x58 => (Opcode::VADDSS, VEXOperandCode::G_V_E_xmm),
1910 0x59 => (Opcode::VMULSS, VEXOperandCode::G_V_E_xmm),
1911 0x5a => (Opcode::VCVTSS2SD, VEXOperandCode::G_V_Ed_xmm),
1912 0x5b => (Opcode::VCVTTPS2DQ, if L { VEXOperandCode::G_ymm_E_ymm } else { VEXOperandCode::G_xmm_E_xmm }),
1913 0x5c => (Opcode::VSUBSS, VEXOperandCode::G_V_E_xmm),
1914 0x5d => (Opcode::VMINSS, VEXOperandCode::G_V_E_xmm),
1915 0x5e => (Opcode::VDIVSS, VEXOperandCode::G_V_E_xmm),
1916 0x5f => (Opcode::VMAXSS, VEXOperandCode::G_V_E_xmm),
1917 0x6f => (Opcode::VMOVDQU, if L { VEXOperandCode::G_E_ymm } else { VEXOperandCode::G_E_xmm }),
1918 0x70 => (Opcode::VPSHUFHW, VEXOperandCode::G_E_xyLmm_imm8),
1919 0x7e => (Opcode::VMOVD, if L { return Err(DecodeError::InvalidOpcode); } else { VEXOperandCode::G_E_xmm }),
1920 0x7f => (Opcode::VMOVDQU, VEXOperandCode::E_G_xyLmm),
1921 0xc2 => (Opcode::VCMPSS, VEXOperandCode::G_V_E_xmm_imm8),
1922 0xe6 => (Opcode::VCVTDQ2PD, if L { VEXOperandCode::G_ymm_E_xmm } else { VEXOperandCode::G_xmm_E_xmm }),
1923 _ => {
1924 return Err(DecodeError::InvalidOpcode);
1925 }
1926 }
1927 }
1928 }
1929 }
1930 VEXOpcodeMap::Map0F38 => {
1931 if let VEXOpcodePrefix::Prefix66 = p {
1933 match opc {
1935 0x00 => (Opcode::VPSHUFB, VEXOperandCode::G_V_E_xyLmm),
1936 0x01 => (Opcode::VPHADDW, VEXOperandCode::G_V_E_xyLmm),
1937 0x02 => (Opcode::VPHADDD, VEXOperandCode::G_V_E_xyLmm),
1938 0x03 => (Opcode::VPHADDSW, VEXOperandCode::G_V_E_xyLmm),
1939 0x04 => (Opcode::VPMADDUBSW, VEXOperandCode::G_V_E_xyLmm),
1940 0x05 => (Opcode::VPHSUBW, VEXOperandCode::G_V_E_xyLmm),
1941 0x06 => (Opcode::VPHSUBD, VEXOperandCode::G_V_E_xyLmm),
1942 0x07 => (Opcode::VPHSUBSW, VEXOperandCode::G_V_E_xyLmm),
1943 0x08 => (Opcode::VPSIGNB, VEXOperandCode::G_V_E_xyLmm),
1944 0x09 => (Opcode::VPSIGNW, VEXOperandCode::G_V_E_xyLmm),
1945 0x0A => (Opcode::VPSIGND, VEXOperandCode::G_V_E_xyLmm),
1946 0x0B => (Opcode::VPMULHRSW, VEXOperandCode::G_V_E_xyLmm),
1947 0x0C => (Opcode::VPERMILPS, VEXOperandCode::G_V_E_xyLmm),
1948 0x0D => (Opcode::VPERMILPD, VEXOperandCode::G_V_E_xyLmm),
1949 0x0E => (Opcode::VTESTPS, VEXOperandCode::G_E_xyLmm),
1950 0x0F => (Opcode::VTESTPD, VEXOperandCode::G_E_xyLmm),
1951 0x13 => (Opcode::VCVTPH2PS, VEXOperandCode::G_E_xyLmm),
1952 0x16 => (Opcode::VPERMPS, if L {
1953 if instruction.prefixes.vex_unchecked().w() {
1954 return Err(DecodeError::InvalidOpcode);
1955 }
1956 VEXOperandCode::G_V_E_ymm
1957 } else {
1958 return Err(DecodeError::InvalidOpcode);
1959 }),
1960 0x17 => (Opcode::VPTEST, VEXOperandCode::G_E_xyLmm),
1961 0x18 => if instruction.prefixes.vex_unchecked().w() {
1962 return Err(DecodeError::InvalidOpcode);
1963 } else {
1964 (Opcode::VBROADCASTSS, if L {
1965 VEXOperandCode::G_ymm_E_xmm
1966 } else {
1967 VEXOperandCode::G_E_xmm
1968 })
1969 },
1970 0x19 => if instruction.prefixes.vex_unchecked().w() {
1971 return Err(DecodeError::InvalidOpcode);
1972 } else {
1973 (Opcode::VBROADCASTSD, if L {
1974 VEXOperandCode::G_ymm_E_xmm
1975 } else {
1976 VEXOperandCode::G_E_xmm
1977 })
1978 }
1979 0x1A => (Opcode::VBROADCASTF128, if L {
1980 VEXOperandCode::G_ymm_M_xmm
1981 } else {
1982 return Err(DecodeError::InvalidOpcode);
1983 }),
1984 0x1C => (Opcode::VPABSB, VEXOperandCode::G_E_xyLmm),
1985 0x1D => (Opcode::VPABSW, VEXOperandCode::G_E_xyLmm),
1986 0x1E => (Opcode::VPABSD, VEXOperandCode::G_E_xyLmm),
1987 0x20 => (Opcode::VPMOVSXBW, if L {
1988 VEXOperandCode::G_ymm_E_xmm
1989 } else {
1990 VEXOperandCode::G_E_xmm
1991 }),
1992 0x21 => (Opcode::VPMOVSXBD, if L {
1993 VEXOperandCode::G_ymm_E_xmm
1994 } else {
1995 VEXOperandCode::G_E_xmm
1996 }),
1997 0x22 => (Opcode::VPMOVSXBQ, if L {
1998 VEXOperandCode::G_ymm_E_xmm
1999 } else {
2000 VEXOperandCode::G_E_xmm
2001 }),
2002 0x23 => (Opcode::VPMOVSXWD, if L {
2003 VEXOperandCode::G_ymm_E_xmm
2004 } else {
2005 VEXOperandCode::G_E_xmm
2006 }),
2007 0x24 => (Opcode::VPMOVSXWQ, if L {
2008 VEXOperandCode::G_ymm_E_xmm
2009 } else {
2010 VEXOperandCode::G_E_xmm
2011 }),
2012 0x25 => (Opcode::VPMOVSXDQ, if L {
2013 VEXOperandCode::G_ymm_E_xmm
2014 } else {
2015 VEXOperandCode::G_E_xmm
2016 }),
2017 0x28 => (Opcode::VPMULDQ, VEXOperandCode::G_V_E_xyLmm),
2018 0x29 => (Opcode::VPCMPEQQ, VEXOperandCode::G_V_E_xyLmm),
2019 0x2A => (Opcode::VMOVNTDQA, if L {
2020 VEXOperandCode::G_M_ymm
2021 } else {
2022 VEXOperandCode::G_M_xmm
2023 }),
2024 0x2B => (Opcode::VPACKUSDW, VEXOperandCode::G_V_E_xyLmm),
2025 0x2C => (Opcode::VMASKMOVPS, if L {
2026 VEXOperandCode::G_V_M_ymm
2027 } else {
2028 VEXOperandCode::G_V_M_xmm
2029 }),
2030 0x2D => (Opcode::VMASKMOVPD, if L {
2031 VEXOperandCode::G_V_M_ymm
2032 } else {
2033 VEXOperandCode::G_V_M_xmm
2034 }),
2035 0x2E => (Opcode::VMASKMOVPS, if L {
2036 VEXOperandCode::M_V_G_ymm
2037 } else {
2038 VEXOperandCode::M_V_G_xmm
2039 }),
2040 0x2F => (Opcode::VMASKMOVPD, if L {
2041 VEXOperandCode::M_V_G_ymm
2042 } else {
2043 VEXOperandCode::M_V_G_xmm
2044 }),
2045 0x30 => (Opcode::VPMOVZXBW, if L {
2046 VEXOperandCode::G_ymm_E_xmm
2047 } else {
2048 VEXOperandCode::G_E_xmm
2049 }),
2050 0x31 => (Opcode::VPMOVZXBD, if L {
2051 VEXOperandCode::G_ymm_E_xmm
2052 } else {
2053 VEXOperandCode::G_E_xmm
2054 }),
2055 0x32 => (Opcode::VPMOVZXBQ, if L {
2056 VEXOperandCode::G_ymm_E_xmm
2057 } else {
2058 VEXOperandCode::G_E_xmm
2059 }),
2060 0x33 => (Opcode::VPMOVZXWD, if L {
2061 VEXOperandCode::G_ymm_E_xmm
2062 } else {
2063 VEXOperandCode::G_E_xmm
2064 }),
2065 0x34 => (Opcode::VPMOVZXWQ, if L {
2066 VEXOperandCode::G_ymm_E_xmm
2067 } else {
2068 VEXOperandCode::G_E_xmm
2069 }),
2070 0x35 => (Opcode::VPMOVZXDQ, if L {
2071 VEXOperandCode::G_ymm_E_xmm
2072 } else {
2073 VEXOperandCode::G_E_xmm
2074 }),
2075 0x36 => (Opcode::VPERMD, if L {
2076 VEXOperandCode::G_V_E_ymm
2077 } else {
2078 return Err(DecodeError::InvalidOpcode);
2079 }),
2080 0x37 => (Opcode::VPCMPGTQ, VEXOperandCode::G_V_E_xyLmm),
2081 0x38 => (Opcode::VPMINSB, VEXOperandCode::G_V_E_xyLmm),
2082 0x39 => (Opcode::VPMINSD, VEXOperandCode::G_V_E_xyLmm),
2083 0x3A => (Opcode::VPMINUW, VEXOperandCode::G_V_E_xyLmm),
2084 0x3B => (Opcode::VPMINUD, VEXOperandCode::G_V_E_xyLmm),
2085 0x3C => (Opcode::VPMAXSB, VEXOperandCode::G_V_E_xyLmm),
2086 0x3D => (Opcode::VPMAXSD, VEXOperandCode::G_V_E_xyLmm),
2087 0x3E => (Opcode::VPMAXUW, VEXOperandCode::G_V_E_xyLmm),
2088 0x3F => (Opcode::VPMAXUD, VEXOperandCode::G_V_E_xyLmm),
2089 0x40 => (Opcode::VPMULLD, VEXOperandCode::G_V_E_xyLmm),
2090 0x41 => (Opcode::VPHMINPOSUW, if L {
2091 return Err(DecodeError::InvalidOpcode);
2092 } else {
2093 VEXOperandCode::G_E_xmm
2094 }),
2095 0x45 => if instruction.prefixes.vex_unchecked().w() {
2096 (Opcode::VPSRLVQ, VEXOperandCode::G_V_E_xyLmm)
2097 } else {
2098 (Opcode::VPSRLVD, VEXOperandCode::G_V_E_xyLmm)
2099 },
2100 0x46 => (Opcode::VPSRAVD, if L {
2101 if instruction.prefixes.vex_unchecked().w() {
2102 return Err(DecodeError::InvalidOpcode);
2103 }
2104 VEXOperandCode::G_V_E_ymm
2105 } else {
2106 if instruction.prefixes.vex_unchecked().w() {
2107 return Err(DecodeError::InvalidOpcode);
2108 }
2109 VEXOperandCode::G_V_E_xmm
2110 }),
2111 0x47 => if instruction.prefixes.vex_unchecked().w() {
2112 (Opcode::VPSLLVQ, VEXOperandCode::G_V_E_xyLmm)
2113 } else {
2114 (Opcode::VPSLLVD, VEXOperandCode::G_V_E_xyLmm)
2115 },
2116 0x58 => (Opcode::VPBROADCASTD, VEXOperandCode::G_E_xyLmm),
2117 0x59 => (Opcode::VPBROADCASTQ, VEXOperandCode::G_E_xyLmm),
2118 0x5A => (Opcode::VBROADCASTI128, if L {
2119 if instruction.prefixes.vex_unchecked().w() {
2120 return Err(DecodeError::InvalidOpcode);
2121 }
2122 VEXOperandCode::G_ymm_M_xmm
2123 } else {
2124 return Err(DecodeError::InvalidOpcode);
2125 }),
2126 0x78 => (Opcode::VPBROADCASTB, if L {
2127 VEXOperandCode::G_E_ymm
2128 } else {
2129 VEXOperandCode::G_E_ymm
2130 }),
2131 0x79 => (Opcode::VPBROADCASTW, if L {
2132 VEXOperandCode::G_E_ymm
2133 } else {
2134 VEXOperandCode::G_E_ymm
2135 }),
2136 0x8C => {
2137 if instruction.prefixes.vex_unchecked().w() {
2138 (Opcode::VPMASKMOVQ, if L {
2139 VEXOperandCode::G_V_M_ymm
2140 } else {
2141 VEXOperandCode::G_V_M_xmm
2142 })
2143 } else {
2144 (Opcode::VPMASKMOVD, if L {
2145 VEXOperandCode::G_V_M_ymm
2146 } else {
2147 VEXOperandCode::G_V_M_xmm
2148 })
2149 }
2150 },
2151 0x8E => {
2152 if instruction.prefixes.vex_unchecked().w() {
2153 (Opcode::VPMASKMOVQ, if L {
2154 VEXOperandCode::M_V_G_ymm
2155 } else {
2156 VEXOperandCode::M_V_G_xmm
2157 })
2158 } else {
2159 (Opcode::VPMASKMOVD, if L {
2160 VEXOperandCode::M_V_G_ymm
2161 } else {
2162 VEXOperandCode::M_V_G_xmm
2163 })
2164 }
2165 },
2166 0x90 => {
2167 if instruction.prefixes.vex_unchecked().w() {
2168 (Opcode::VPGATHERDQ, VEXOperandCode::G_ExyL_V_xyLmm)
2169 } else {
2170 (Opcode::VPGATHERDD, VEXOperandCode::G_ExyL_V_xyLmm)
2171 }
2172 },
2173 0x91 => {
2174 if instruction.prefixes.vex_unchecked().w() {
2175 (Opcode::VPGATHERQQ, VEXOperandCode::G_ExyL_V_xyLmm)
2176 } else {
2177 (Opcode::VPGATHERQD, VEXOperandCode::G_ExyL_V_xyLmm)
2178 }
2179 },
2180 0x92 => {
2181 if instruction.prefixes.vex_unchecked().w() {
2182 (Opcode::VGATHERDPD, VEXOperandCode::G_ExyL_V_xyLmm)
2183 } else {
2184 (Opcode::VGATHERDPS, VEXOperandCode::G_ExyL_V_xyLmm)
2185 }
2186 },
2187 0x93 => {
2188 if instruction.prefixes.vex_unchecked().w() {
2189 (Opcode::VGATHERQPD, VEXOperandCode::G_ExyL_V_xyLmm)
2190 } else {
2191 (Opcode::VGATHERQPS, VEXOperandCode::G_ExyL_V_xyLmm)
2192 }
2193 },
2194 0x96 => {
2195 if instruction.prefixes.vex_unchecked().w() {
2196 (Opcode::VFMADDSUB132PD, VEXOperandCode::G_V_E_xyLmm)
2197 } else {
2198 (Opcode::VFMADDSUB132PS, VEXOperandCode::G_V_E_xyLmm)
2199 }
2200 },
2201 0x97 => {
2202 if instruction.prefixes.vex_unchecked().w() {
2203 (Opcode::VFMSUBADD132PD, VEXOperandCode::G_V_E_xyLmm)
2204 } else {
2205 (Opcode::VFMSUBADD132PS, VEXOperandCode::G_V_E_xyLmm)
2206 }
2207 },
2208 0x98 => {
2209 if instruction.prefixes.vex_unchecked().w() {
2210 (Opcode::VFMADD132PD, VEXOperandCode::G_V_E_xyLmm)
2211 } else {
2212 (Opcode::VFMADD132PS, VEXOperandCode::G_V_E_xyLmm)
2213 }
2214 },
2215 0x99 => if instruction.prefixes.vex_unchecked().w() {
2216 (Opcode::VFMADD132SD, VEXOperandCode::G_V_E_xmm )
2217 } else {
2218 (Opcode::VFMADD132SS, VEXOperandCode::G_V_E_xmm )
2219 },
2220 0x9A => {
2221 if instruction.prefixes.vex_unchecked().w() {
2222 (Opcode::VFMSUB132PD, VEXOperandCode::G_V_E_xyLmm)
2223 } else {
2224 (Opcode::VFMSUB132PS, VEXOperandCode::G_V_E_xyLmm)
2225 }
2226 },
2227 0x9B => if instruction.prefixes.vex_unchecked().w() {
2228 (Opcode::VFMSUB132SD, VEXOperandCode::G_V_E_xmm )
2229 } else {
2230 (Opcode::VFMSUB132SS, VEXOperandCode::G_V_E_xmm )
2231 },
2232 0x9C => {
2233 if instruction.prefixes.vex_unchecked().w() {
2234 (Opcode::VFNMADD132PD, VEXOperandCode::G_V_E_xyLmm)
2235 } else {
2236 (Opcode::VFNMADD132PS, VEXOperandCode::G_V_E_xyLmm)
2237 }
2238 },
2239 0x9D => if instruction.prefixes.vex_unchecked().w() {
2240 (Opcode::VFNMADD132SD, VEXOperandCode::G_V_E_xmm )
2241 } else {
2242 (Opcode::VFNMADD132SS, VEXOperandCode::G_V_E_xmm )
2243 },
2244 0x9E => {
2245 if instruction.prefixes.vex_unchecked().w() {
2246 (Opcode::VFNMSUB132PD, VEXOperandCode::G_V_E_xyLmm)
2247 } else {
2248 (Opcode::VFNMSUB132PS, VEXOperandCode::G_V_E_xyLmm)
2249 }
2250 },
2251 0x9F => if instruction.prefixes.vex_unchecked().w() {
2252 (Opcode::VFNMSUB132SD, VEXOperandCode::G_V_E_xmm )
2253 } else {
2254 (Opcode::VFNMSUB132SS, VEXOperandCode::G_V_E_xmm )
2255 },
2256 0xA6 => {
2257 if instruction.prefixes.vex_unchecked().w() {
2258 (Opcode::VFMADDSUB213PD, VEXOperandCode::G_V_E_xyLmm)
2259 } else {
2260 (Opcode::VFMADDSUB213PS, VEXOperandCode::G_V_E_xyLmm)
2261 }
2262 },
2263 0xA7 => {
2264 if instruction.prefixes.vex_unchecked().w() {
2265 (Opcode::VFMSUBADD213PD, VEXOperandCode::G_V_E_xyLmm)
2266 } else {
2267 (Opcode::VFMSUBADD213PS, VEXOperandCode::G_V_E_xyLmm)
2268 }
2269 },
2270 0xA8 => {
2271 if instruction.prefixes.vex_unchecked().w() {
2272 (Opcode::VFMADD213PD, VEXOperandCode::G_V_E_xyLmm)
2273 } else {
2274 (Opcode::VFMADD213PS, VEXOperandCode::G_V_E_xyLmm)
2275 }
2276 },
2277 0xA9 => if instruction.prefixes.vex_unchecked().w() {
2278 (Opcode::VFMADD231SD, VEXOperandCode::G_V_E_xmm )
2279 } else {
2280 (Opcode::VFMADD231SS, VEXOperandCode::G_V_E_xmm )
2281 },
2282 0xAA => {
2283 if instruction.prefixes.vex_unchecked().w() {
2284 (Opcode::VFMSUB213PD, VEXOperandCode::G_V_E_xyLmm)
2285 } else {
2286 (Opcode::VFMSUB213PS, VEXOperandCode::G_V_E_xyLmm)
2287 }
2288 },
2289 0xAB => if instruction.prefixes.vex_unchecked().w() {
2290 (Opcode::VFMSUB231SD, VEXOperandCode::G_V_E_xmm )
2291 } else {
2292 (Opcode::VFMSUB231SS, VEXOperandCode::G_V_E_xmm )
2293 },
2294 0xAC => {
2295 if instruction.prefixes.vex_unchecked().w() {
2296 (Opcode::VFNMADD213PD, VEXOperandCode::G_V_E_xyLmm)
2297 } else {
2298 (Opcode::VFNMADD213PS, VEXOperandCode::G_V_E_xyLmm)
2299 }
2300 },
2301 0xAD => if instruction.prefixes.vex_unchecked().w() {
2302 (Opcode::VFNMADD213SD, VEXOperandCode::G_V_E_xmm )
2303 } else {
2304 (Opcode::VFNMADD213SS, VEXOperandCode::G_V_E_xmm )
2305 },
2306 0xAE => {
2307 if instruction.prefixes.vex_unchecked().w() {
2308 (Opcode::VFNMSUB213PD, VEXOperandCode::G_V_E_xyLmm)
2309 } else {
2310 (Opcode::VFNMSUB213PS, VEXOperandCode::G_V_E_xyLmm)
2311 }
2312 },
2313 0xAF => if instruction.prefixes.vex_unchecked().w() {
2314 (Opcode::VFNMSUB213SD, VEXOperandCode::G_V_E_xmm )
2315 } else {
2316 (Opcode::VFNMSUB213SS, VEXOperandCode::G_V_E_xmm )
2317 },
2318 0xB6 => {
2319 if instruction.prefixes.vex_unchecked().w() {
2320 (Opcode::VFMADDSUB231PD, VEXOperandCode::G_V_E_xyLmm)
2321 } else {
2322 (Opcode::VFMADDSUB231PS, VEXOperandCode::G_V_E_xyLmm)
2323 }
2324 },
2325 0xB7 => {
2326 if instruction.prefixes.vex_unchecked().w() {
2327 (Opcode::VFMSUBADD231PD, VEXOperandCode::G_V_E_xyLmm)
2328 } else {
2329 (Opcode::VFMSUBADD231PS, VEXOperandCode::G_V_E_xyLmm)
2330 }
2331 },
2332 0xB8 => {
2333 if instruction.prefixes.vex_unchecked().w() {
2334 (Opcode::VFMADD231PD, VEXOperandCode::G_V_E_xyLmm)
2335 } else {
2336 (Opcode::VFMADD231PS, VEXOperandCode::G_V_E_xyLmm)
2337 }
2338 },
2339 0xB9 => if instruction.prefixes.vex_unchecked().w() {
2340 (Opcode::VFMADD231SD, VEXOperandCode::G_V_E_xmm )
2341 } else {
2342 (Opcode::VFMADD231SS, VEXOperandCode::G_V_E_xmm )
2343 },
2344 0xBA => {
2345 if instruction.prefixes.vex_unchecked().w() {
2346 (Opcode::VFMSUB231PD, VEXOperandCode::G_V_E_xyLmm)
2347 } else {
2348 (Opcode::VFMSUB231PS, VEXOperandCode::G_V_E_xyLmm)
2349 }
2350 },
2351 0xBB => if instruction.prefixes.vex_unchecked().w() {
2352 (Opcode::VFMSUB231SD, VEXOperandCode::G_V_E_xmm )
2353 } else {
2354 (Opcode::VFMSUB231SS, VEXOperandCode::G_V_E_xmm )
2355 },
2356 0xBC => {
2357 if instruction.prefixes.vex_unchecked().w() {
2358 (Opcode::VFNMADD231PD, VEXOperandCode::G_V_E_xyLmm)
2359 } else {
2360 (Opcode::VFNMADD231PS, VEXOperandCode::G_V_E_xyLmm)
2361 }
2362 },
2363 0xBD => if instruction.prefixes.vex_unchecked().w() {
2364 (Opcode::VFNMADD231SD, VEXOperandCode::G_V_E_xmm )
2365 } else {
2366 (Opcode::VFNMADD231SS, VEXOperandCode::G_V_E_xmm )
2367 },
2368 0xBE => {
2369 if instruction.prefixes.vex_unchecked().w() {
2370 (Opcode::VFNMSUB231PD, VEXOperandCode::G_V_E_xyLmm)
2371 } else {
2372 (Opcode::VFNMSUB231PS, VEXOperandCode::G_V_E_xyLmm)
2373 }
2374 },
2375 0xBF => if instruction.prefixes.vex_unchecked().w() {
2376 (Opcode::VFNMSUB231SD, VEXOperandCode::G_V_E_xmm )
2377 } else {
2378 (Opcode::VFNMSUB231SS, VEXOperandCode::G_V_E_xmm )
2379 },
2380 0xDB => (Opcode::VAESIMC, if L {
2381 return Err(DecodeError::InvalidOpcode);
2382 } else {
2383 VEXOperandCode::G_E_xmm
2384 }),
2385 0xDC => (Opcode::VAESENC, VEXOperandCode::G_V_E_xyLmm),
2386 0xDD => (Opcode::VAESENCLAST, VEXOperandCode::G_V_E_xyLmm),
2387 0xDE => (Opcode::VAESDEC, VEXOperandCode::G_V_E_xyLmm),
2388 0xDF => (Opcode::VAESDECLAST, VEXOperandCode::G_V_E_xyLmm),
2389 0xF7 => (Opcode::SHLX, if L {
2390 return Err(DecodeError::InvalidOpcode);
2391 } else {
2392 VEXOperandCode::G_E_V
2393 }),
2394 _ => {
2395 return Err(DecodeError::InvalidOpcode);
2396 }
2397 }
2398 } else if let VEXOpcodePrefix::PrefixF2 = p {
2399 match opc {
2400 0xF5 => (Opcode::PDEP, if L {
2401 return Err(DecodeError::InvalidOpcode);
2402 } else {
2403 VEXOperandCode::G_V_E
2404 }),
2405 0xF6 => (Opcode::MULX, if L {
2406 return Err(DecodeError::InvalidOpcode);
2407 } else {
2408 VEXOperandCode::G_V_E
2409 }),
2410 0xF7 => (Opcode::SHRX, if L {
2411 return Err(DecodeError::InvalidOpcode);
2412 } else {
2413 VEXOperandCode::G_E_V
2414 }),
2415 _ => {
2416 return Err(DecodeError::InvalidOpcode);
2417 }
2418 }
2419 } else if let VEXOpcodePrefix::PrefixF3 = p {
2420 match opc {
2421 0xF5 => (Opcode::PEXT, if L {
2422 return Err(DecodeError::InvalidOpcode);
2423 } else {
2424 VEXOperandCode::G_V_E
2425 }),
2426 0xF7 => (Opcode::SARX, if L {
2427 return Err(DecodeError::InvalidOpcode);
2428 } else {
2429 VEXOperandCode::G_E_V
2430 }),
2431 _ => {
2432 return Err(DecodeError::InvalidOpcode);
2433 }
2434 }
2435 } else {
2436 match opc {
2437 0xF2 => (Opcode::ANDN, if L {
2438 return Err(DecodeError::InvalidOpcode);
2439 } else {
2440 VEXOperandCode::G_V_E
2441 }),
2442 0xF3 => (Opcode::Invalid, if L {
2443 return Err(DecodeError::InvalidOpcode);
2444 } else {
2445 VEXOperandCode::BMI1_F3
2446 }),
2447 0xF5 => (Opcode::BZHI, if L {
2448 return Err(DecodeError::InvalidOpcode);
2449 } else {
2450 VEXOperandCode::G_E_V
2451 }),
2452 0xF7 => (Opcode::BEXTR, if L {
2453 return Err(DecodeError::InvalidOpcode);
2454 } else {
2455 VEXOperandCode::G_E_V
2456 }),
2457 _ => {
2458 return Err(DecodeError::InvalidOpcode);
2459 }
2460 }
2461 }
2462 }
2463 VEXOpcodeMap::Map0F3A => {
2464 if let VEXOpcodePrefix::Prefix66 = p {
2465 match opc {
2467 0x00 => (Opcode::VPERMQ, if L {
2468 if !instruction.prefixes.vex_unchecked().w() {
2469 return Err(DecodeError::InvalidOpcode);
2470 }
2471 VEXOperandCode::G_E_ymm_imm8
2472 } else {
2473 return Err(DecodeError::InvalidOpcode);
2474 }),
2475 0x01 => (Opcode::VPERMPD, if L {
2476 if !instruction.prefixes.vex_unchecked().w() {
2477 return Err(DecodeError::InvalidOpcode);
2478 }
2479 VEXOperandCode::G_E_ymm_imm8
2480 } else {
2481 return Err(DecodeError::InvalidOpcode);
2482 }),
2483 0x02 => (Opcode::VPBLENDD, if instruction.prefixes.vex_unchecked().w() {
2484 return Err(DecodeError::InvalidOpcode);
2485 } else {
2486 VEXOperandCode::G_V_E_xyLmm_imm8
2487 }),
2488 0x04 => (Opcode::VPERMILPS, VEXOperandCode::G_E_xyLmm_imm8),
2489 0x05 => (Opcode::VPERMILPD, VEXOperandCode::G_E_xyLmm_imm8),
2490 0x06 => (Opcode::VPERM2F128, if L {
2491 if instruction.prefixes.vex_unchecked().w() {
2492 return Err(DecodeError::InvalidOpcode);
2493 }
2494 VEXOperandCode::G_V_E_ymm_imm8
2495 } else {
2496 return Err(DecodeError::InvalidOpcode);
2497 }),
2498 0x08 => (Opcode::VROUNDPS, VEXOperandCode::G_E_xyLmm_imm8),
2499 0x09 => (Opcode::VROUNDPD, VEXOperandCode::G_E_xyLmm_imm8),
2500 0x0A => (Opcode::VROUNDSS, VEXOperandCode::G_V_E_xmm_imm8),
2501 0x0B => (Opcode::VROUNDSD, VEXOperandCode::G_V_E_xmm_imm8),
2502 0x0C => (Opcode::VBLENDPS, VEXOperandCode::G_V_E_xyLmm_imm8),
2503 0x0D => (Opcode::VBLENDPD, VEXOperandCode::G_V_E_xyLmm_imm8),
2504 0x0E => (Opcode::VPBLENDW, VEXOperandCode::G_V_E_xyLmm_imm8),
2505 0x0F => (Opcode::VPALIGNR, VEXOperandCode::G_V_E_xyLmm_imm8),
2506 0x14 => (Opcode::VPEXTRB, if L || instruction.prefixes.vex_unchecked().w() {
2507 return Err(DecodeError::InvalidOpcode);
2508 } else {
2509 VEXOperandCode::Ev_G_xmm_imm8
2510 }),
2511 0x15 => (Opcode::VPEXTRW, if L || instruction.prefixes.vex_unchecked().w() {
2512 return Err(DecodeError::InvalidOpcode);
2513 } else {
2514 VEXOperandCode::Ev_G_xmm_imm8
2515 }),
2516 0x16 => {
2517 (Opcode::VPEXTRD, if L {
2518 return Err(DecodeError::InvalidOpcode);
2519 } else {
2520 VEXOperandCode::Ev_G_xmm_imm8
2522 })
2523 },
2524 0x17 => (Opcode::VEXTRACTPS, if L {
2525 return Err(DecodeError::InvalidOpcode);
2526 } else {
2527 VEXOperandCode::Ev_G_xmm_imm8
2528 }),
2529 0x18 => if instruction.prefixes.vex_unchecked().w() {
2530 return Err(DecodeError::InvalidOpcode);
2531 } else {
2532 (Opcode::VINSERTF128, if L {
2533 VEXOperandCode::G_ymm_V_ymm_E_xmm_imm8
2534 } else {
2535 return Err(DecodeError::InvalidOpcode);
2536 })
2537 },
2538 0x19 => if instruction.prefixes.vex_unchecked().w() {
2539 return Err(DecodeError::InvalidOpcode);
2540 } else {
2541 (Opcode::VEXTRACTF128, if L {
2542 VEXOperandCode::E_xmm_G_ymm_imm8
2543 } else {
2544 return Err(DecodeError::InvalidOpcode);
2545 })
2546 },
2547 0x1D => (Opcode::VCVTPS2PH, if L {
2548 VEXOperandCode::E_xmm_G_ymm_imm8
2549 } else {
2550 VEXOperandCode::E_G_xmm_imm8
2551 }),
2552 0x20 => (Opcode::VPINSRB, if L {
2553 return Err(DecodeError::InvalidOpcode);
2554 } else {
2555 VEXOperandCode::G_V_xmm_Ev_imm8
2556 }),
2557 0x21 => (Opcode::VINSERTPS, if L {
2558 return Err(DecodeError::InvalidOpcode);
2559 } else {
2560 VEXOperandCode::G_V_E_xmm_imm8
2561 }),
2562 0x22 => {
2563 (Opcode::VPINSRD, if L {
2564 return Err(DecodeError::InvalidOpcode);
2565 } else {
2566 VEXOperandCode::G_V_xmm_Ev_imm8
2567 })
2568 },
2569 0x38 => (Opcode::VINSERTI128, if L {
2570 VEXOperandCode::G_ymm_V_ymm_E_xmm_imm8
2571 } else {
2572 return Err(DecodeError::InvalidOpcode);
2573 }),
2574 0x39 => (Opcode::VEXTRACTI128, if L {
2575 VEXOperandCode::E_xmm_G_ymm_imm8
2576 } else {
2577 return Err(DecodeError::InvalidOpcode);
2578 }),
2579 0x40 => (Opcode::VDPPS, VEXOperandCode::G_V_E_xyLmm_imm8),
2580 0x41 => (Opcode::VDPPD, if L {
2581 return Err(DecodeError::InvalidOpcode);
2582 } else {
2583 VEXOperandCode::G_V_E_xmm_imm8
2584 }),
2585 0x42 => (Opcode::VMPSADBW, VEXOperandCode::G_V_E_xyLmm_imm8),
2586 0x44 => (Opcode::VPCLMULQDQ, if L {
2587 return Err(DecodeError::InvalidOpcode);
2588 } else {
2589 VEXOperandCode::G_V_E_xmm_imm8
2590 }),
2591 0x46 => (Opcode::VPERM2I128, if L {
2592 if instruction.prefixes.vex_unchecked().w() {
2593 return Err(DecodeError::InvalidOpcode);
2594 }
2595 VEXOperandCode::G_V_E_ymm_imm8
2596 } else {
2597 return Err(DecodeError::InvalidOpcode);
2598 }),
2599 0x4A => (Opcode::VBLENDVPS, if L {
2600 VEXOperandCode::G_V_E_ymm_ymm4
2601 } else {
2602 VEXOperandCode::G_V_E_xmm_xmm4
2603 }),
2604 0x4B => (Opcode::VBLENDVPD, if L {
2605 VEXOperandCode::G_V_E_ymm_ymm4
2606 } else {
2607 VEXOperandCode::G_V_E_xmm_xmm4
2608 }),
2609 0x4C => if instruction.prefixes.vex_unchecked().w() {
2610 return Err(DecodeError::InvalidOpcode);
2611 } else {
2612 (Opcode::VPBLENDVB, if L {
2613 VEXOperandCode::G_V_E_ymm_ymm4
2614 } else {
2615 VEXOperandCode::G_V_E_xmm_xmm4
2616 })
2617 },
2618 0x60 => (Opcode::VPCMPESTRM, VEXOperandCode::G_E_xmm_imm8),
2619 0x61 => (Opcode::VPCMPESTRI, VEXOperandCode::G_E_xmm_imm8),
2620 0x62 => (Opcode::VPCMPISTRM, VEXOperandCode::G_E_xmm_imm8),
2621 0x63 => (Opcode::VPCMPISTRI, VEXOperandCode::G_E_xmm_imm8),
2622 0xDF => (Opcode::VAESKEYGENASSIST, VEXOperandCode::G_E_xmm_imm8),
2623 _ => {
2624 return Err(DecodeError::InvalidOpcode);
2625 }
2626 }
2627 } else if let VEXOpcodePrefix::PrefixF2 = p {
2628 match opc {
2629 0xF0 => (Opcode::RORX, if L {
2630 return Err(DecodeError::InvalidOpcode);
2631 } else {
2632 VEXOperandCode::G_E_Ib
2633 }),
2634 _ => {
2635 return Err(DecodeError::InvalidOpcode);
2636 }
2637 }
2638 } else {
2639 return Err(DecodeError::InvalidOpcode);
2641 }
2642 }
2643 };
2644 instruction.opcode = opcode;
2645
2646 sink.record(
2647 opcode_start,
2648 opcode_start + 7,
2649 InnerDescription::Opcode(instruction.opcode)
2650 .with_id(opcode_start)
2651 );
2652 sink.record(
2653 opcode_start + 7,
2654 opcode_start + 7,
2655 InnerDescription::Boundary("vex opcode ends/operands begin")
2656 .with_id(opcode_start + 7)
2657 );
2658
2659 read_vex_operands(words, instruction, operand_code, sink)
2660}