# HG changeset patch # User Roland Schatz # Date 1407846949 -7200 # Node ID 88df5d7b1001dbd7e81688a284ad9dd3a9b3b482 # Parent c914e5837b4bf7adcc222eacf0aab0d22b16ff74 Correctly parse VEX encoded instructions in Assembler::locate_operand. diff -r c914e5837b4b -r 88df5d7b1001 src/cpu/x86/vm/assembler_x86.cpp --- a/src/cpu/x86/vm/assembler_x86.cpp Tue Aug 12 14:13:50 2014 +0200 +++ b/src/cpu/x86/vm/assembler_x86.cpp Tue Aug 12 14:35:49 2014 +0200 @@ -666,21 +666,35 @@ // Check second byte NOT_LP64(assert((0xC0 & *ip) == 0xC0, "shouldn't have LDS and LES instructions")); + int vex_opcode; // First byte if ((0xFF & *inst) == VEX_3bytes) { + vex_opcode = VEX_OPCODE_MASK & *ip; ip++; // third byte is_64bit = ((VEX_W & *ip) == VEX_W); + } else { + vex_opcode = VEX_OPCODE_0F; } ip++; // opcode // To find the end of instruction (which == end_pc_operand). - switch (0xFF & *ip) { - case 0x61: // pcmpestri r, r/a, #8 - case 0x70: // pshufd r, r/a, #8 - case 0x73: // psrldq r, #8 - tail_size = 1; // the imm8 - break; - default: - break; + switch (vex_opcode) { + case VEX_OPCODE_0F: + switch (0xFF & *ip) { + case 0x70: // pshufd r, r/a, #8 + case 0x71: // ps[rl|ra|ll]w r, #8 + case 0x72: // ps[rl|ra|ll]d r, #8 + case 0x73: // ps[rl|ra|ll]q r, #8 + case 0xC2: // cmp[ps|pd|ss|sd] r, r, r/a, #8 + case 0xC4: // pinsrw r, r, r/a, #8 + case 0xC5: // pextrw r/a, r, #8 + case 0xC6: // shufp[s|d] r, r, r/a, #8 + tail_size = 1; // the imm8 + break; + } + break; + case VEX_OPCODE_0F_3A: + tail_size = 1; + break; } ip++; // skip opcode debug_only(has_disp32 = true); // has both kinds of operands! diff -r c914e5837b4b -r 88df5d7b1001 src/cpu/x86/vm/assembler_x86.hpp --- a/src/cpu/x86/vm/assembler_x86.hpp Tue Aug 12 14:13:50 2014 +0200 +++ b/src/cpu/x86/vm/assembler_x86.hpp Tue Aug 12 14:35:49 2014 +0200 @@ -521,7 +521,8 @@ VEX_OPCODE_NONE = 0x0, VEX_OPCODE_0F = 0x1, VEX_OPCODE_0F_38 = 0x2, - VEX_OPCODE_0F_3A = 0x3 + VEX_OPCODE_0F_3A = 0x3, + VEX_OPCODE_MASK = 0x1F }; enum WhichOperand {