< prev index next >

src/hotspot/cpu/x86/assembler_x86.cpp

Print this page

        

*** 135,144 **** --- 135,146 ---- Address::Address(int disp, address loc, relocInfo::relocType rtype) { _base = noreg; _index = noreg; _scale = no_scale; _disp = disp; + _xmmindex = xnoreg; + _isxmmindex = false; switch (rtype) { case relocInfo::external_word_type: _rspec = external_word_Relocation::spec(loc); break; case relocInfo::internal_word_type:
*** 174,183 **** --- 176,187 ---- _base = noreg; _index = noreg; _scale = no_scale; _disp = (intptr_t) loc; _rspec = spec; + _xmmindex = xnoreg; + _isxmmindex = false; } #endif // _LP64
*** 606,615 **** --- 610,634 ---- } } emit_operand((Register)reg, base, index, scale, disp, rspec); } + void Assembler::emit_operand(XMMRegister reg, Register base, XMMRegister index, + Address::ScaleFactor scale, int disp, + RelocationHolder const& rspec) { + if (UseAVX > 2) { + int xreg_enc = reg->encoding(); + int xmmindex_enc = index->encoding(); + XMMRegister new_reg = as_XMMRegister(xreg_enc & 0xf); + XMMRegister new_index = as_XMMRegister(xmmindex_enc & 0xf); + emit_operand((Register)new_reg, base, (Register)new_index, scale, disp, rspec); + return; + } + emit_operand((Register)reg, base, (Register)index, scale, disp, rspec); + } + + // Secret local extension to Assembler::WhichOperand: #define end_pc_operand (_WhichOperand_limit) address Assembler::locate_operand(address inst, WhichOperand which) { // Decode the given instruction, and return the address of
*** 1106,1117 **** --- 1125,1140 ---- adr._rspec, rip_relative_correction); } void Assembler::emit_operand(XMMRegister reg, Address adr) { + if (adr.isxmmindex()) { + emit_operand(reg, adr._base, adr._xmmindex, adr._scale, adr._disp, adr._rspec); + } else { emit_operand(reg, adr._base, adr._index, adr._scale, adr._disp, adr._rspec); + } } // MMX operations void Assembler::emit_operand(MMXRegister reg, Address adr) { assert(!adr.base_needs_rex() && !adr.index_needs_rex(), "no extended registers");
*** 3394,3403 **** --- 3417,3435 ---- emit_int8(0x06); emit_int8(0xC0 | encode); emit_int8(imm8); } + void Assembler::evpermi2q(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) { + assert(VM_Version::supports_evex(), ""); + InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true); + attributes.set_is_evex_instruction(); + int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes); + emit_int8(0x76); + emit_int8((unsigned char)(0xC0 | encode)); + } + void Assembler::pause() { emit_int8((unsigned char)0xF3); emit_int8((unsigned char)0x90); }
*** 3845,3854 **** --- 3877,3897 ---- vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes); emit_int8(0x30); emit_operand(dst, src); } + void Assembler::vpmovzxbw(XMMRegister dst, XMMRegister src, int vector_len) { + assert(vector_len == AVX_128bit? VM_Version::supports_avx() : + vector_len == AVX_256bit? VM_Version::supports_avx2() : + vector_len == AVX_512bit? VM_Version::supports_avx512bw() : 0, ""); + InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ false); + int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes); + emit_int8(0x30); + emit_int8((unsigned char) (0xC0 | encode)); + } + + void Assembler::evpmovzxbw(XMMRegister dst, KRegister mask, Address src, int vector_len) { assert(is_vector_masking(), ""); assert(VM_Version::supports_avx512vlbw(), ""); assert(dst != xnoreg, "sanity"); InstructionMark im(this);
*** 3858,3868 **** attributes.set_is_evex_instruction(); vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes); emit_int8(0x30); emit_operand(dst, src); } - void Assembler::evpmovwb(Address dst, XMMRegister src, int vector_len) { assert(VM_Version::supports_avx512vlbw(), ""); assert(src != xnoreg, "sanity"); InstructionMark im(this); InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); --- 3901,3910 ----
*** 3886,3895 **** --- 3928,3959 ---- vex_prefix(dst, 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F_38, &attributes); emit_int8(0x30); emit_operand(src, dst); } + void Assembler::evpmovdb(Address dst, XMMRegister src, int vector_len) { + assert(VM_Version::supports_evex(), ""); + assert(src != xnoreg, "sanity"); + InstructionMark im(this); + InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false); + attributes.set_address_attributes(/* tuple_type */ EVEX_QVM, /* input_size_in_bits */ EVEX_NObit); + attributes.set_is_evex_instruction(); + vex_prefix(dst, 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_0F_38, &attributes); + emit_int8(0x31); + emit_operand(src, dst); + } + + void Assembler::vpmovzxwd(XMMRegister dst, XMMRegister src, int vector_len) { + assert(vector_len == AVX_128bit? VM_Version::supports_avx() : + vector_len == AVX_256bit? VM_Version::supports_avx2() : + vector_len == AVX_512bit? VM_Version::supports_evex() : 0, " "); + InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ false); + int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes); + emit_int8(0x33); + emit_int8((unsigned char)(0xC0 | encode)); + } + // generic void Assembler::pop(Register dst) { int encode = prefix_and_encode(dst->encoding()); emit_int8(0x58 | encode); }
*** 6046,6055 **** --- 6110,6137 ---- int encode = vex_prefix_and_encode(dst->encoding(), src->encoding(), shift->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes); emit_int8((unsigned char)0xD3); emit_int8((unsigned char)(0xC0 | encode)); } + void Assembler::evpsrlvw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) { + assert(VM_Version::supports_avx512bw(), ""); + InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true); + attributes.set_is_evex_instruction(); + int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes); + emit_int8(0x10); + emit_int8((unsigned char)(0xC0 | encode)); + } + + void Assembler::evpsllvw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) { + assert(VM_Version::supports_avx512bw(), ""); + InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true); + attributes.set_is_evex_instruction(); + int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes); + emit_int8(0x12); + emit_int8((unsigned char)(0xC0 | encode)); + } + // Shift packed integers arithmetically right by specified number of bits. void Assembler::psraw(XMMRegister dst, int shift) { NOT_LP64(assert(VM_Version::supports_sse2(), "")); InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true); // XMM4 is for /4 encoding: 66 0F 71 /4 ib
*** 6147,6156 **** --- 6229,6247 ---- vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes); emit_int8((unsigned char)0xDB); emit_operand(dst, src); } + void Assembler::vpandq(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) { + assert(VM_Version::supports_evex(), ""); + InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true); + int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes); + emit_int8((unsigned char)0xDB); + emit_int8((unsigned char)(0xC0 | encode)); + } + + void Assembler::pandn(XMMRegister dst, XMMRegister src) { NOT_LP64(assert(VM_Version::supports_sse2(), "")); InstructionAttr attributes(AVX_128bit, /* vex_w */ VM_Version::supports_evex(), /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true); attributes.set_rex_vex_w_reverted(); int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
*** 6182,6191 **** --- 6273,6291 ---- vex_prefix(src, nds->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes); emit_int8((unsigned char)0xEB); emit_operand(dst, src); } + void Assembler::vporq(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) { + assert(VM_Version::supports_evex(), ""); + InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true); + int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes); + emit_int8((unsigned char)0xEB); + emit_int8((unsigned char)(0xC0 | encode)); + } + + void Assembler::pxor(XMMRegister dst, XMMRegister src) { NOT_LP64(assert(VM_Version::supports_sse2(), "")); InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true); int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F, &attributes); emit_int8((unsigned char)0xEF);
*** 6793,6802 **** --- 6893,6916 ---- int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes); emit_int8(0x7C); emit_int8((unsigned char)(0xC0 | encode)); } + void Assembler::evpgatherdd(XMMRegister dst, KRegister mask, Address src, int vector_len) { + assert(VM_Version::supports_evex(), ""); + assert(dst != xnoreg, "sanity"); + InstructionMark im(this); + InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ false, /* uses_vl */ true); + attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit); + attributes.reset_is_clear_context(); + attributes.set_embedded_opmask_register_specifier(mask); + attributes.set_is_evex_instruction(); + // swap src<->dst for encoding + vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes); + emit_int8((unsigned char)0x90); + emit_operand(dst, src); + } // Carry-Less Multiplication Quadword void Assembler::pclmulqdq(XMMRegister dst, XMMRegister src, int mask) { assert(VM_Version::supports_clmul(), ""); InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
*** 7418,7428 **** } void Assembler::vex_prefix(Address adr, int nds_enc, int xreg_enc, VexSimdPrefix pre, VexOpcode opc, InstructionAttr *attributes) { bool vex_r = ((xreg_enc & 8) == 8) ? 1 : 0; bool vex_b = adr.base_needs_rex(); ! bool vex_x = adr.index_needs_rex(); set_attributes(attributes); attributes->set_current_assembler(this); // if vector length is turned off, revert to AVX for vectors smaller than 512-bit if (UseAVX > 2 && _legacy_mode_vl && attributes->uses_vl()) { --- 7532,7547 ---- } void Assembler::vex_prefix(Address adr, int nds_enc, int xreg_enc, VexSimdPrefix pre, VexOpcode opc, InstructionAttr *attributes) { bool vex_r = ((xreg_enc & 8) == 8) ? 1 : 0; bool vex_b = adr.base_needs_rex(); ! bool vex_x; ! if (adr.isxmmindex()) { ! vex_x = adr.xmmindex_needs_rex(); ! } else { ! vex_x = adr.index_needs_rex(); ! } set_attributes(attributes); attributes->set_current_assembler(this); // if vector length is turned off, revert to AVX for vectors smaller than 512-bit if (UseAVX > 2 && _legacy_mode_vl && attributes->uses_vl()) {
*** 7455,7465 **** _is_managed = false; if (UseAVX > 2 && !attributes->is_legacy_mode()) { bool evex_r = (xreg_enc >= 16); ! bool evex_v = (nds_enc >= 16); attributes->set_is_evex_instruction(); evex_prefix(vex_r, vex_b, vex_x, evex_r, evex_v, nds_enc, pre, opc); } else { if (UseAVX > 2 && attributes->is_rex_vex_w_reverted()) { attributes->set_rex_vex_w(false); --- 7574,7590 ---- _is_managed = false; if (UseAVX > 2 && !attributes->is_legacy_mode()) { bool evex_r = (xreg_enc >= 16); ! bool evex_v; ! // EVEX.V' is set to true when VSIB is used as we may need to use higher order XMM registers (16-31) ! if (adr.isxmmindex()) { ! evex_v = ((adr._xmmindex->encoding() > 15) ? true : false); ! } else { ! evex_v = (nds_enc >= 16); ! } attributes->set_is_evex_instruction(); evex_prefix(vex_r, vex_b, vex_x, evex_r, evex_v, nds_enc, pre, opc); } else { if (UseAVX > 2 && attributes->is_rex_vex_w_reverted()) { attributes->set_rex_vex_w(false);
< prev index next >