comparison src/cpu/x86/vm/assembler_x86.cpp @ 16784:88df5d7b1001

Correctly parse VEX encoded instructions in Assembler::locate_operand.
author Roland Schatz <roland.schatz@oracle.com>
date Tue, 12 Aug 2014 14:35:49 +0200
parents 77cb0f0e5e3f
children 52b4284cb496
comparison
equal deleted inserted replaced
16783:c914e5837b4b 16784:88df5d7b1001
664 // to check for them in product version. 664 // to check for them in product version.
665 665
666 // Check second byte 666 // Check second byte
667 NOT_LP64(assert((0xC0 & *ip) == 0xC0, "shouldn't have LDS and LES instructions")); 667 NOT_LP64(assert((0xC0 & *ip) == 0xC0, "shouldn't have LDS and LES instructions"));
668 668
669 int vex_opcode;
669 // First byte 670 // First byte
670 if ((0xFF & *inst) == VEX_3bytes) { 671 if ((0xFF & *inst) == VEX_3bytes) {
672 vex_opcode = VEX_OPCODE_MASK & *ip;
671 ip++; // third byte 673 ip++; // third byte
672 is_64bit = ((VEX_W & *ip) == VEX_W); 674 is_64bit = ((VEX_W & *ip) == VEX_W);
675 } else {
676 vex_opcode = VEX_OPCODE_0F;
673 } 677 }
674 ip++; // opcode 678 ip++; // opcode
675 // To find the end of instruction (which == end_pc_operand). 679 // To find the end of instruction (which == end_pc_operand).
676 switch (0xFF & *ip) { 680 switch (vex_opcode) {
677 case 0x61: // pcmpestri r, r/a, #8 681 case VEX_OPCODE_0F:
678 case 0x70: // pshufd r, r/a, #8 682 switch (0xFF & *ip) {
679 case 0x73: // psrldq r, #8 683 case 0x70: // pshufd r, r/a, #8
680 tail_size = 1; // the imm8 684 case 0x71: // ps[rl|ra|ll]w r, #8
681 break; 685 case 0x72: // ps[rl|ra|ll]d r, #8
682 default: 686 case 0x73: // ps[rl|ra|ll]q r, #8
683 break; 687 case 0xC2: // cmp[ps|pd|ss|sd] r, r, r/a, #8
688 case 0xC4: // pinsrw r, r, r/a, #8
689 case 0xC5: // pextrw r/a, r, #8
690 case 0xC6: // shufp[s|d] r, r, r/a, #8
691 tail_size = 1; // the imm8
692 break;
693 }
694 break;
695 case VEX_OPCODE_0F_3A:
696 tail_size = 1;
697 break;
684 } 698 }
685 ip++; // skip opcode 699 ip++; // skip opcode
686 debug_only(has_disp32 = true); // has both kinds of operands! 700 debug_only(has_disp32 = true); // has both kinds of operands!
687 break; 701 break;
688 702