< prev index next >

src/cpu/x86/vm/assembler_x86.cpp

Print this page

        

*** 1603,1612 **** --- 1603,1691 ---- void Assembler::cpuid() { emit_int8(0x0F); 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); }
*** 6002,6011 **** --- 6081,6098 ---- emit_int8(0x0F); emit_int8((unsigned char)0xA5); 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); emit_int8((unsigned char)(0xC0 | src->encoding() << 3 | dst->encoding())); }
*** 6187,6196 **** --- 6274,6317 ---- if (reg->encoding() >= 8) { prefix(REX_B); } } + 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()) { prefix(REX_XB); } else {
< prev index next >