@@ -179,6 +179,8 @@ public Rex2Decoder(Decoder[] map0decoders, Decoder[] map1decoders)
179179
180180 public override X86Instruction Decode ( uint rex2Prefix , X86Disassembler disasm )
181181 {
182+ if ( disasm . decodingContext . RexPrefix )
183+ return disasm . CreateInvalidInstruction ( ) ;
182184 if ( ! disasm . TryReadByte ( out var rex2 ) )
183185 return disasm . CreateInvalidInstruction ( ) ;
184186 if ( ! disasm . TryReadByte ( out var op ) )
@@ -521,13 +523,15 @@ public class EvexDecoder : Decoder
521523 private readonly Decoder [ ] decoders0F38 ;
522524 private readonly Decoder [ ] decoders0F3A ;
523525 private readonly Decoder [ ] decodersLegacy ;
526+ private readonly bool isApx ;
524527
525528 private static readonly Bitfield p0Reserved = new Bitfield ( 2 , 2 ) ;
526529 private static readonly Bitfield p1Reserved = new Bitfield ( 2 , 1 ) ;
527530 private static readonly Bitfield p1Vvvv = new Bitfield ( 3 , 4 ) ;
528531
529- public EvexDecoder ( Decoder [ ] legacy , Decoder [ ] decoders0F , Decoder [ ] decoders0F38 , Decoder [ ] decoders0F3A )
532+ public EvexDecoder ( bool isApx , Decoder [ ] legacy , Decoder [ ] decoders0F , Decoder [ ] decoders0F38 , Decoder [ ] decoders0F3A )
530533 {
534+ this . isApx = isApx ;
531535 this . decoders0F = decoders0F ;
532536 this . decoders0F38 = decoders0F38 ;
533537 this . decoders0F3A = decoders0F3A ;
@@ -536,7 +540,7 @@ public EvexDecoder(Decoder[] legacy, Decoder[] decoders0F, Decoder[] decoders0F3
536540
537541 public override X86Instruction Decode ( uint op , X86Disassembler disasm )
538542 {
539- // 62 must be the first byte. The presence of previous
543+ // 0x62 must be the first byte. The presence of previous
540544 // prefixes is an error (according to Intel manual 2.6, vol 2A).
541545 var ctx = disasm . decodingContext ;
542546 if ( ctx . F2Prefix |
@@ -546,26 +550,24 @@ public override X86Instruction Decode(uint op, X86Disassembler disasm)
546550 return disasm . CreateInvalidInstruction ( ) ;
547551 // The EVEX prefix consists of a leading 0x62 byte, and three
548552 // packed payload bytes P0, P1, and P2.
549- //$TODO: this is incomplete: there are many missing flags.
550553 if ( ! disasm . TryReadByte ( out byte p0 ) ||
551554 ! disasm . TryReadByte ( out byte p1 ) ||
552555 ! disasm . TryReadByte ( out byte p2 ) ||
553- p0Reserved . Read ( p0 ) != 0 ||
554- p1Reserved . Read ( p1 ) != 1 )
556+ ( ! isApx && p0Reserved . Read ( p0 ) != 0 ) ||
557+ ( ! isApx && p1Reserved . Read ( p1 ) != 1 ) )
555558 {
556559 return disasm . CreateInvalidInstruction ( ) ;
557560 }
558- var mm = p0 & 3 ;
561+ var mmm = p0 & 7 ;
559562 var rxb = ~ p0 >> 5 ;
560563 var pp = p1 & 3 ;
561564 var w = p1 >> 7 ;
562- var vvvv = p1Vvvv . Read ( ~ ( uint ) p1 ) ;
563- if ( ! Bits . IsBitSet ( p2 , 3 ) )
564- vvvv |= 0x10 ;
565+ var vvvvv = p1Vvvv . Read ( ~ ( uint ) p1 ) ;
566+ vvvvv |= ( uint ) ( ~ p2 << 1 ) & 0x10 ;
565567 ctx . RexPrefix = true ;
566568 ctx . IsVex = true ;
567569 ctx . IsEvex = true ;
568- ctx . VexRegister = ( byte ) vvvv ;
570+ ctx . VexRegister = ( byte ) vvvvv ;
569571 ctx . VexLongCode = ( byte ) ( ( p2 >> 5 ) & 3 ) ;
570572 ctx . OpMask = ( byte ) ( p2 & 7 ) ;
571573 ctx . IsWide = w != 0 ;
@@ -581,16 +583,27 @@ public override X86Instruction Decode(uint op, X86Disassembler disasm)
581583 ctx . SizeOverridePrefix = pp == 1 ;
582584
583585 Decoder [ ] decoders ;
584- switch ( mm )
586+ switch ( mmm )
585587 {
586588 case 2 : decoders = decoders0F38 ; break ;
587589 case 3 : decoders = decoders0F3A ; break ;
588- case 4 : decoders = decodersLegacy ; break ;
590+ case 4 :
591+ decoders = decodersLegacy ;
592+ ctx . EvexNF = Bits . IsBitSet ( p2 , 2 ) ;
593+ if ( Bits . IsBitSet ( p2 , 4 ) )
594+ {
595+ ctx . NewDataDestination = ( int ) vvvvv ;
596+ }
597+ else if ( vvvvv != 0 )
598+ {
599+ return disasm . CreateInvalidInstruction ( ) ;
600+ }
601+ break ;
589602 default : decoders = decoders0F ; break ;
590603 }
591604 if ( ! disasm . TryReadByte ( out byte op2 ) )
592605 return disasm . CreateInvalidInstruction ( ) ;
593- TraceEvex ( ctx , mm , op2 ) ;
606+ TraceEvex ( ctx , mmm , op2 ) ;
594607 return decoders [ op2 ] . Decode ( op2 , disasm ) ;
595608 }
596609 }
0 commit comments