--- a/hotspot/src/cpu/x86/vm/assembler_x86.cpp Wed Sep 16 13:16:17 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp Wed Sep 16 15:54:32 2015 -0700
@@ -1604,6 +1604,85 @@
emit_int8((unsigned char)0xA2);
}
+// Opcode / Instruction Op / En 64 - Bit Mode Compat / Leg Mode Description Implemented
+// F2 0F 38 F0 / r CRC32 r32, r / m8 RM Valid Valid Accumulate CRC32 on r / m8. v
+// F2 REX 0F 38 F0 / r CRC32 r32, r / m8* RM Valid N.E. Accumulate CRC32 on r / m8. -
+// F2 REX.W 0F 38 F0 / r CRC32 r64, r / m8 RM Valid N.E. Accumulate CRC32 on r / m8. -
+//
+// F2 0F 38 F1 / r CRC32 r32, r / m16 RM Valid Valid Accumulate CRC32 on r / m16. v
+//
+// F2 0F 38 F1 / r CRC32 r32, r / m32 RM Valid Valid Accumulate CRC32 on r / m32. v
+//
+// F2 REX.W 0F 38 F1 / r CRC32 r64, r / m64 RM Valid N.E. Accumulate CRC32 on r / m64. v
+void Assembler::crc32(Register crc, Register v, int8_t sizeInBytes) {
+ assert(VM_Version::supports_sse4_2(), "");
+ int8_t w = 0x01;
+ Prefix p = Prefix_EMPTY;
+
+ emit_int8((int8_t)0xF2);
+ switch (sizeInBytes) {
+ case 1:
+ w = 0;
+ break;
+ case 2:
+ case 4:
+ break;
+ LP64_ONLY(case 8:)
+ // This instruction is not valid in 32 bits
+ // Note:
+ // http://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf
+ //
+ // Page B - 72 Vol. 2C says
+ // qwreg2 to qwreg 1111 0010 : 0100 1R0B : 0000 1111 : 0011 1000 : 1111 0000 : 11 qwreg1 qwreg2
+ // mem64 to qwreg 1111 0010 : 0100 1R0B : 0000 1111 : 0011 1000 : 1111 0000 : mod qwreg r / m
+ // F0!!!
+ // while 3 - 208 Vol. 2A
+ // F2 REX.W 0F 38 F1 / r CRC32 r64, r / m64 RM Valid N.E.Accumulate CRC32 on r / m64.
+ //
+ // the 0 on a last bit is reserved for a different flavor of this instruction :
+ // F2 REX.W 0F 38 F0 / r CRC32 r64, r / m8 RM Valid N.E.Accumulate CRC32 on r / m8.
+ p = REX_W;
+ break;
+ default:
+ assert(0, "Unsupported value for a sizeInBytes argument");
+ break;
+ }
+ LP64_ONLY(prefix(crc, v, p);)
+ emit_int8((int8_t)0x0F);
+ emit_int8(0x38);
+ emit_int8((int8_t)(0xF0 | w));
+ emit_int8(0xC0 | ((crc->encoding() & 0x7) << 3) | (v->encoding() & 7));
+}
+
+void Assembler::crc32(Register crc, Address adr, int8_t sizeInBytes) {
+ assert(VM_Version::supports_sse4_2(), "");
+ InstructionMark im(this);
+ int8_t w = 0x01;
+ Prefix p = Prefix_EMPTY;
+
+ emit_int8((int8_t)0xF2);
+ switch (sizeInBytes) {
+ case 1:
+ w = 0;
+ break;
+ case 2:
+ case 4:
+ break;
+ LP64_ONLY(case 8:)
+ // This instruction is not valid in 32 bits
+ p = REX_W;
+ break;
+ default:
+ assert(0, "Unsupported value for a sizeInBytes argument");
+ break;
+ }
+ LP64_ONLY(prefix(crc, adr, p);)
+ emit_int8((int8_t)0x0F);
+ emit_int8(0x38);
+ emit_int8((int8_t)(0xF0 | w));
+ emit_operand(crc, adr);
+}
+
void Assembler::cvtdq2pd(XMMRegister dst, XMMRegister src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
emit_simd_arith_nonds(0xE6, dst, src, VEX_SIMD_F3, /* no_mask_reg */ false, /* legacy_mode */ true);
@@ -6223,6 +6302,14 @@
emit_int8((unsigned char)(0xC0 | src->encoding() << 3 | dst->encoding()));
}
+// 0F A4 / r ib
+void Assembler::shldl(Register dst, Register src, int8_t imm8) {
+ emit_int8(0x0F);
+ emit_int8((unsigned char)0xA4);
+ emit_int8((unsigned char)(0xC0 | src->encoding() << 3 | dst->encoding()));
+ emit_int8(imm8);
+}
+
void Assembler::shrdl(Register dst, Register src) {
emit_int8(0x0F);
emit_int8((unsigned char)0xAD);
@@ -6408,6 +6495,40 @@
}
}
+void Assembler::prefix(Register dst, Register src, Prefix p) {
+ if (src->encoding() >= 8) {
+ p = (Prefix)(p | REX_B);
+ }
+ if (dst->encoding() >= 8) {
+ p = (Prefix)( p | REX_R);
+ }
+ if (p != Prefix_EMPTY) {
+ // do not generate an empty prefix
+ prefix(p);
+ }
+}
+
+void Assembler::prefix(Register dst, Address adr, Prefix p) {
+ if (adr.base_needs_rex()) {
+ if (adr.index_needs_rex()) {
+ assert(false, "prefix(Register dst, Address adr, Prefix p) does not support handling of an X");
+ } else {
+ prefix(REX_B);
+ }
+ } else {
+ if (adr.index_needs_rex()) {
+ assert(false, "prefix(Register dst, Address adr, Prefix p) does not support handling of an X");
+ }
+ }
+ if (dst->encoding() >= 8) {
+ p = (Prefix)(p | REX_R);
+ }
+ if (p != Prefix_EMPTY) {
+ // do not generate an empty prefix
+ prefix(p);
+ }
+}
+
void Assembler::prefix(Address adr) {
if (adr.base_needs_rex()) {
if (adr.index_needs_rex()) {