yaxpeax_x86/protected_mode/
vex.rs

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; // ignore bit 4 in 32-bit mode
221    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; // ignore bit 4 in 32-bit mode
294    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> {
302//    println!("operand code: {:?}", operand_code);
303    match 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            // the name of this bit is `L` in the documentation, so use the same name here.
627            #[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            // the name of this bit is `L` in the documentation, so use the same name here.
682            #[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                    /* this is the only accepted operand */
796                }
797                (VEXOperandCode::G_U_xmm, _) |
798                (VEXOperandCode::G_M_xmm, 0xc0) => {
799                    return Err(DecodeError::InvalidOperand);
800                }
801                (VEXOperandCode::G_M_xmm, _) | // otherwise it's memory-constrained and a memory operand
802                (_, _) => {                    // ... or unconstrained
803                    /* and this is always accepted */
804                }
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, _) | // otherwise it's memory-constrained and a memory operand
910                (_, _) => {                    // ... or unconstrained
911                    /* and this is always accepted */
912                }
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, _) | // otherwise it's memory-constrained and a memory operand
937                (_, _) => {                    // ... or unconstrained
938                    /* and this is always accepted */
939                }
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            // the name of this bit is `L` in the documentation, so use the same name here.
1034            #[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            // the name of this bit is `L` in the documentation, so use the same name here.
1061            #[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            // the name of this bit is `L` in the documentation, so use the same name here.
1090            #[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            // the name of this bit is `L` in the documentation, so use the same name here.
1121            #[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            // TODO: but the memory access is word-sized
1527            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    // the name of this bit is `L` in the documentation, so use the same name here.
1566    #[allow(non_snake_case)]
1567    let L = instruction.prefixes.vex_unchecked().l();
1568
1569//    println!("reading vex instruction from opcode prefix {:?}, L: {}, opc: {:#x}, map:{:?}", p, L, opc, opcode_map);
1570//    println!("w? {}", instruction.prefixes.vex_unchecked().w());
1571
1572    // several combinations simply have no instructions. check for those first.
1573    let (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 {
1650//                        0x0a => (Opcode::VROUNDSS, VEXOperandCode::G_V_E_xmm_imm8),
1651//                        0x0b => (Opcode::VROUNDSD, VEXOperandCode::G_V_E_xmm_imm8),
1652                        0x10 => (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 // 32-bit last operand
1856                        }),
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            // TODO: verify rejecting invalid W bit
1932            if let VEXOpcodePrefix::Prefix66 = p {
1933                // possibly valid!
1934                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 /* 64bit */)
2217                    } else {
2218                        (Opcode::VFMADD132SS, VEXOperandCode::G_V_E_xmm /* 64bit */)
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 /* 64bit */)
2229                    } else {
2230                        (Opcode::VFMSUB132SS, VEXOperandCode::G_V_E_xmm /* 64bit */)
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 /* 64bit */)
2241                    } else {
2242                        (Opcode::VFNMADD132SS, VEXOperandCode::G_V_E_xmm /* 64bit */)
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 /* 64bit */)
2253                    } else {
2254                        (Opcode::VFNMSUB132SS, VEXOperandCode::G_V_E_xmm /* 64bit */)
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 /* 64bit */)
2279                    } else {
2280                        (Opcode::VFMADD231SS, VEXOperandCode::G_V_E_xmm /* 64bit */)
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 /* 64bit */)
2291                    } else {
2292                        (Opcode::VFMSUB231SS, VEXOperandCode::G_V_E_xmm /* 64bit */)
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 /* 64bit */)
2303                    } else {
2304                        (Opcode::VFNMADD213SS, VEXOperandCode::G_V_E_xmm /* 64bit */)
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 /* 64bit */)
2315                    } else {
2316                        (Opcode::VFNMSUB213SS, VEXOperandCode::G_V_E_xmm /* 64bit */)
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 /* 64bit */)
2341                    } else {
2342                        (Opcode::VFMADD231SS, VEXOperandCode::G_V_E_xmm /* 64bit */)
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 /* 64bit */)
2353                    } else {
2354                        (Opcode::VFMSUB231SS, VEXOperandCode::G_V_E_xmm /* 64bit */)
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 /* 64bit */)
2365                    } else {
2366                        (Opcode::VFNMADD231SS, VEXOperandCode::G_V_E_xmm /* 64bit */)
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 /* 64bit */)
2377                    } else {
2378                        (Opcode::VFNMSUB231SS, VEXOperandCode::G_V_E_xmm /* 64bit */)
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                // possibly valid!
2466                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                            // varies on W
2521                            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                // the only VEX* 0f3a instructions have an implied 66 prefix.
2640                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}