< prev index next >
src/cpu/x86/vm/assembler_x86.cpp
Print this page
@@ -875,24 +875,38 @@
// to check for them in product version.
// 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 (vex_opcode) {
+ case VEX_OPCODE_0F:
switch (0xFF & *ip) {
- case 0x61: // pcmpestri r, r/a, #8
case 0x70: // pshufd r, r/a, #8
- case 0x73: // psrldq r, #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;
- default:
+ }
+ break;
+ case VEX_OPCODE_0F_3A:
+ tail_size = 1;
break;
}
ip++; // skip opcode
debug_only(has_disp32 = true); // has both kinds of operands!
break;
@@ -2476,11 +2490,11 @@
emit_operand(dst, src);
}
void Assembler::movsbl(Register dst, Register src) { // movsxb
NOT_LP64(assert(src->has_byte_register(), "must have byte register"));
- int encode = prefix_and_encode(dst->encoding(), src->encoding(), true);
+ int encode = prefix_and_encode(dst->encoding(), false, src->encoding(), true);
emit_int8(0x0F);
emit_int8((unsigned char)0xBE);
emit_int8((unsigned char)(0xC0 | encode));
}
@@ -2593,11 +2607,11 @@
emit_operand(dst, src);
}
void Assembler::movzbl(Register dst, Register src) { // movzxb
NOT_LP64(assert(src->has_byte_register(), "must have byte register"));
- int encode = prefix_and_encode(dst->encoding(), src->encoding(), true);
+ int encode = prefix_and_encode(dst->encoding(), false, src->encoding(), true);
emit_int8(0x0F);
emit_int8((unsigned char)0xB6);
emit_int8(0xC0 | encode);
}
@@ -6447,16 +6461,16 @@
reg_enc -= 8;
}
return reg_enc;
}
-int Assembler::prefix_and_encode(int dst_enc, int src_enc, bool byteinst) {
+int Assembler::prefix_and_encode(int dst_enc, bool dst_is_byte, int src_enc, bool src_is_byte) {
if (dst_enc < 8) {
if (src_enc >= 8) {
prefix(REX_B);
src_enc -= 8;
- } else if (byteinst && src_enc >= 4) {
+ } else if ((src_is_byte && src_enc >= 4) || (dst_is_byte && dst_enc >= 4)) {
prefix(REX);
}
} else {
if (src_enc < 8) {
prefix(REX_R);
< prev index next >