@@ -418,25 +418,21 @@ ReadPrefixes:
418
418
vexIndex = pos
419
419
inst .Prefix [pos ] = p
420
420
inst .Prefix [pos + 1 ] = Prefix (src [pos + 1 ])
421
- pos += 1
422
- continue
423
- } else {
424
- nprefix = pos
425
- break ReadPrefixes
421
+ pos += 2
426
422
}
423
+ nprefix = pos
424
+ break ReadPrefixes
427
425
case 0xC4 :
428
426
if pos == 0 && pos + 2 < len (src ) && (mode == 64 || (mode == 32 && src [pos + 1 ]& 0xc0 == 0xc0 )) {
429
427
vex = p
430
428
vexIndex = pos
431
429
inst .Prefix [pos ] = p
432
430
inst .Prefix [pos + 1 ] = Prefix (src [pos + 1 ])
433
431
inst .Prefix [pos + 2 ] = Prefix (src [pos + 2 ])
434
- pos += 2
435
- continue
436
- } else {
437
- nprefix = pos
438
- break ReadPrefixes
432
+ pos += 3
439
433
}
434
+ nprefix = pos
435
+ break ReadPrefixes
440
436
}
441
437
442
438
if pos >= len (inst .Prefix ) {
@@ -855,48 +851,71 @@ Decode:
855
851
}
856
852
continue
857
853
}
854
+
855
+ vexFlag := (prefix & 0xf00 ) >> 8
858
856
ok := false
859
- if prefix == 0 {
860
- ok = true
861
- } else if prefix .IsREX () {
862
- rexUsed |= prefix
863
- if rex & prefix == prefix {
864
- ok = true
857
+
858
+ if vexFlag != 0 {
859
+ if vex == 0 {
860
+ continue
865
861
}
866
- } else if prefix .IsVEX () {
867
- if vex == prefix {
868
- var vexL Prefix
869
- if vex == 0xC5 {
870
- vexL = inst .Prefix [vexIndex + 1 ]
871
- } else {
872
- vexL = inst .Prefix [vexIndex + 2 ]
862
+
863
+ var vexW , vexL , vexP Prefix
864
+ if vex == 0xC4 {
865
+ vexW = inst .Prefix [vexIndex + 2 ] & 0x80
866
+ vexL = inst .Prefix [vexIndex + 2 ] & 0x04
867
+ vexP = inst .Prefix [vexIndex + 2 ] & 0x03
868
+ } else {
869
+ vexL = inst .Prefix [vexIndex + 1 ] & 0x04
870
+ vexP = inst .Prefix [vexIndex + 1 ] & 0x03
871
+ }
872
+
873
+ switch vexFlag {
874
+ case 1 :
875
+ // all good (any vex prefix, any W)
876
+ case 2 :
877
+ // check for W0
878
+ if vexW != 0 {
879
+ continue
880
+ }
881
+ case 3 :
882
+ // check for W1 (only valid with 0xC4)
883
+ if vexW == 0 {
884
+ continue
873
885
}
886
+ default :
887
+ println ("unknown vex prefix flag" , vexFlag )
888
+ return Inst {Len : pos }, errInternal
889
+ }
874
890
891
+ // this is looking good, check the prefix
892
+ switch prefix & 0xFF {
893
+ case 0 :
894
+ ok = true
895
+ case 0x66 :
896
+ ok = vexP == 1
897
+ case 0xF3 :
898
+ ok = vexP == 2
899
+ case 0xF2 :
900
+ ok = vexP == 3
901
+ }
902
+
903
+ if ok {
904
+ // TODO: bit of a hack, some instructions ignore the L bit
875
905
if vexL & 4 == 0 {
876
906
dataMode = 128
877
907
} else {
878
908
dataMode = 256
879
909
}
880
- ok = true
881
910
}
882
- } else if dataMode >= 128 && (prefix == 0x66 || prefix == 0xF2 || prefix == 0xF3 ) {
883
- var vexM , vexP Prefix
884
- if vex == 0xC5 {
885
- vexM = 1 // 2 byte vex always implies 0F
886
- vexP = inst .Prefix [vexIndex + 1 ]
887
- } else {
888
- vexM = inst .Prefix [vexIndex + 1 ]
889
- vexP = inst .Prefix [vexIndex + 2 ]
890
- }
891
- _ = vexM
911
+ }
892
912
893
- switch prefix {
894
- case 0x66 :
895
- ok = vexP & 3 == 1
896
- case 0xF3 :
897
- ok = vexP & 3 == 2
898
- case 0xF2 :
899
- ok = vexP & 3 == 3
913
+ if prefix == 0 {
914
+ ok = true
915
+ } else if prefix .IsREX () {
916
+ rexUsed |= prefix
917
+ if rex & prefix == prefix {
918
+ ok = true
900
919
}
901
920
} else {
902
921
if prefix == 0xF3 {
0 commit comments