1380 emit_int8((unsigned char)(0xC8 | encode)); |
1380 emit_int8((unsigned char)(0xC8 | encode)); |
1381 } |
1381 } |
1382 |
1382 |
1383 void Assembler::blsil(Register dst, Register src) { |
1383 void Assembler::blsil(Register dst, Register src) { |
1384 assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported"); |
1384 assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported"); |
1385 int encode = vex_prefix_0F38_and_encode(rbx, dst, src, false); |
1385 int encode = vex_prefix_0F38_and_encode_legacy(rbx, dst, src, false); |
1386 emit_int8((unsigned char)0xF3); |
1386 emit_int8((unsigned char)0xF3); |
1387 emit_int8((unsigned char)(0xC0 | encode)); |
1387 emit_int8((unsigned char)(0xC0 | encode)); |
1388 } |
1388 } |
1389 |
1389 |
1390 void Assembler::blsil(Register dst, Address src) { |
1390 void Assembler::blsil(Register dst, Address src) { |
1391 InstructionMark im(this); |
1391 InstructionMark im(this); |
1392 assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported"); |
1392 assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported"); |
1393 vex_prefix_0F38(rbx, dst, src, false); |
1393 vex_prefix_0F38_legacy(rbx, dst, src, false); |
1394 emit_int8((unsigned char)0xF3); |
1394 emit_int8((unsigned char)0xF3); |
1395 emit_operand(rbx, src); |
1395 emit_operand(rbx, src); |
1396 } |
1396 } |
1397 |
1397 |
1398 void Assembler::blsmskl(Register dst, Register src) { |
1398 void Assembler::blsmskl(Register dst, Register src) { |
1399 assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported"); |
1399 assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported"); |
1400 int encode = vex_prefix_0F38_and_encode(rdx, dst, src, false); |
1400 int encode = vex_prefix_0F38_and_encode_legacy(rdx, dst, src, false); |
1401 emit_int8((unsigned char)0xF3); |
1401 emit_int8((unsigned char)0xF3); |
1402 emit_int8((unsigned char)(0xC0 | encode)); |
1402 emit_int8((unsigned char)(0xC0 | encode)); |
1403 } |
1403 } |
1404 |
1404 |
1405 void Assembler::blsmskl(Register dst, Address src) { |
1405 void Assembler::blsmskl(Register dst, Address src) { |
3132 InstructionMark im(this); |
3133 InstructionMark im(this); |
3133 int vector_len = AVX_256bit; |
3134 int vector_len = AVX_256bit; |
3134 assert(dst != xnoreg, "sanity"); |
3135 assert(dst != xnoreg, "sanity"); |
3135 int dst_enc = dst->encoding(); |
3136 int dst_enc = dst->encoding(); |
3136 // swap src<->dst for encoding |
3137 // swap src<->dst for encoding |
3137 vex_prefix(src, 0, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_38, false, vector_len); |
3138 vex_prefix(src, 0, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_38, false, vector_len, true, false); |
3138 emit_int8(0x17); |
3139 emit_int8(0x17); |
3139 emit_operand(dst, src); |
3140 emit_operand(dst, src); |
3140 } |
3141 } |
3141 |
3142 |
3142 void Assembler::vptest(XMMRegister dst, XMMRegister src) { |
3143 void Assembler::vptest(XMMRegister dst, XMMRegister src) { |
3143 assert(VM_Version::supports_avx(), ""); |
3144 assert(VM_Version::supports_avx(), ""); |
3144 int vector_len = AVX_256bit; |
3145 int vector_len = AVX_256bit; |
3145 int encode = vex_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, |
3146 int encode = vex_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, |
3146 vector_len, VEX_OPCODE_0F_38); |
3147 vector_len, VEX_OPCODE_0F_38, true, false); |
3147 emit_int8(0x17); |
3148 emit_int8(0x17); |
3148 emit_int8((unsigned char)(0xC0 | encode)); |
3149 emit_int8((unsigned char)(0xC0 | encode)); |
3149 } |
3150 } |
3150 |
3151 |
3151 void Assembler::punpcklbw(XMMRegister dst, Address src) { |
3152 void Assembler::punpcklbw(XMMRegister dst, Address src) { |
3152 NOT_LP64(assert(VM_Version::supports_sse2(), "")); |
3153 NOT_LP64(assert(VM_Version::supports_sse2(), "")); |
3153 assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes"); |
3154 assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes"); |
3154 if (VM_Version::supports_evex()) { |
3155 if (VM_Version::supports_evex()) { |
3155 tuple_type = EVEX_FVM; |
3156 tuple_type = EVEX_FVM; |
3156 } |
3157 } |
3157 emit_simd_arith(0x60, dst, src, VEX_SIMD_66); |
3158 emit_simd_arith(0x60, dst, src, VEX_SIMD_66, false, (VM_Version::supports_avx512vlbw() == false)); |
3158 } |
3159 } |
3159 |
3160 |
3160 void Assembler::punpcklbw(XMMRegister dst, XMMRegister src) { |
3161 void Assembler::punpcklbw(XMMRegister dst, XMMRegister src) { |
3161 NOT_LP64(assert(VM_Version::supports_sse2(), "")); |
3162 NOT_LP64(assert(VM_Version::supports_sse2(), "")); |
3162 emit_simd_arith(0x60, dst, src, VEX_SIMD_66); |
3163 emit_simd_arith(0x60, dst, src, VEX_SIMD_66, false, (VM_Version::supports_avx512vlbw() == false)); |
3163 } |
3164 } |
3164 |
3165 |
3165 void Assembler::punpckldq(XMMRegister dst, Address src) { |
3166 void Assembler::punpckldq(XMMRegister dst, Address src) { |
3166 NOT_LP64(assert(VM_Version::supports_sse2(), "")); |
3167 NOT_LP64(assert(VM_Version::supports_sse2(), "")); |
3167 assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes"); |
3168 assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes"); |
4985 vector_len, VEX_OPCODE_0F_38, false); |
4986 vector_len, VEX_OPCODE_0F_38, false); |
4986 emit_int8(0x58); |
4987 emit_int8(0x58); |
4987 emit_int8((unsigned char)(0xC0 | encode)); |
4988 emit_int8((unsigned char)(0xC0 | encode)); |
4988 } |
4989 } |
4989 |
4990 |
4990 // duplicate 4-bytes integer data from src into 8 locations in dest |
4991 // duplicate 1-byte integer data from src into 16||32|64 locations in dest : requires AVX512BW and AVX512VL |
|
4992 void Assembler::evpbroadcastb(XMMRegister dst, XMMRegister src, int vector_len) { |
|
4993 assert(VM_Version::supports_evex(), ""); |
|
4994 int encode = vex_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, |
|
4995 vector_len, VEX_OPCODE_0F_38, false); |
|
4996 emit_int8(0x78); |
|
4997 emit_int8((unsigned char)(0xC0 | encode)); |
|
4998 } |
|
4999 |
|
5000 void Assembler::evpbroadcastb(XMMRegister dst, Address src, int vector_len) { |
|
5001 assert(VM_Version::supports_evex(), ""); |
|
5002 tuple_type = EVEX_T1S; |
|
5003 input_size_in_bits = EVEX_8bit; |
|
5004 InstructionMark im(this); |
|
5005 assert(dst != xnoreg, "sanity"); |
|
5006 int dst_enc = dst->encoding(); |
|
5007 // swap src<->dst for encoding |
|
5008 vex_prefix(src, dst_enc, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_38, false, vector_len); |
|
5009 emit_int8(0x78); |
|
5010 emit_operand(dst, src); |
|
5011 } |
|
5012 |
|
5013 // duplicate 2-byte integer data from src into 8|16||32 locations in dest : requires AVX512BW and AVX512VL |
|
5014 void Assembler::evpbroadcastw(XMMRegister dst, XMMRegister src, int vector_len) { |
|
5015 assert(VM_Version::supports_evex(), ""); |
|
5016 int encode = vex_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, |
|
5017 vector_len, VEX_OPCODE_0F_38, false); |
|
5018 emit_int8(0x79); |
|
5019 emit_int8((unsigned char)(0xC0 | encode)); |
|
5020 } |
|
5021 |
|
5022 void Assembler::evpbroadcastw(XMMRegister dst, Address src, int vector_len) { |
|
5023 assert(VM_Version::supports_evex(), ""); |
|
5024 tuple_type = EVEX_T1S; |
|
5025 input_size_in_bits = EVEX_16bit; |
|
5026 InstructionMark im(this); |
|
5027 assert(dst != xnoreg, "sanity"); |
|
5028 int dst_enc = dst->encoding(); |
|
5029 // swap src<->dst for encoding |
|
5030 vex_prefix(src, dst_enc, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_38, false, vector_len); |
|
5031 emit_int8(0x79); |
|
5032 emit_operand(dst, src); |
|
5033 } |
|
5034 |
|
5035 // duplicate 4-byte integer data from src into 4|8|16 locations in dest : requires AVX512VL |
4991 void Assembler::evpbroadcastd(XMMRegister dst, XMMRegister src, int vector_len) { |
5036 void Assembler::evpbroadcastd(XMMRegister dst, XMMRegister src, int vector_len) { |
4992 assert(VM_Version::supports_evex(), ""); |
5037 assert(VM_Version::supports_evex(), ""); |
4993 int encode = vex_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, |
5038 int encode = vex_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, |
4994 vector_len, VEX_OPCODE_0F_38, false); |
5039 vector_len, VEX_OPCODE_0F_38, false); |
4995 emit_int8(0x58); |
5040 emit_int8(0x58); |
|
5041 emit_int8((unsigned char)(0xC0 | encode)); |
|
5042 } |
|
5043 |
|
5044 void Assembler::evpbroadcastd(XMMRegister dst, Address src, int vector_len) { |
|
5045 assert(VM_Version::supports_evex(), ""); |
|
5046 tuple_type = EVEX_T1S; |
|
5047 input_size_in_bits = EVEX_32bit; |
|
5048 InstructionMark im(this); |
|
5049 assert(dst != xnoreg, "sanity"); |
|
5050 int dst_enc = dst->encoding(); |
|
5051 // swap src<->dst for encoding |
|
5052 vex_prefix(src, dst_enc, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_38, false, vector_len); |
|
5053 emit_int8(0x58); |
|
5054 emit_operand(dst, src); |
|
5055 } |
|
5056 |
|
5057 // duplicate 8-byte integer data from src into 4|8|16 locations in dest : requires AVX512VL |
|
5058 void Assembler::evpbroadcastq(XMMRegister dst, XMMRegister src, int vector_len) { |
|
5059 assert(VM_Version::supports_evex(), ""); |
|
5060 int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, |
|
5061 VEX_OPCODE_0F_38, true, vector_len, false, false); |
|
5062 emit_int8(0x59); |
|
5063 emit_int8((unsigned char)(0xC0 | encode)); |
|
5064 } |
|
5065 |
|
5066 void Assembler::evpbroadcastq(XMMRegister dst, Address src, int vector_len) { |
|
5067 assert(VM_Version::supports_evex(), ""); |
|
5068 tuple_type = EVEX_T1S; |
|
5069 input_size_in_bits = EVEX_64bit; |
|
5070 InstructionMark im(this); |
|
5071 assert(dst != xnoreg, "sanity"); |
|
5072 int dst_enc = dst->encoding(); |
|
5073 // swap src<->dst for encoding |
|
5074 vex_prefix(src, dst_enc, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_38, true, vector_len); |
|
5075 emit_int8(0x59); |
|
5076 emit_operand(dst, src); |
|
5077 } |
|
5078 |
|
5079 // duplicate single precision fp from src into 4|8|16 locations in dest : requires AVX512VL |
|
5080 void Assembler::evpbroadcastss(XMMRegister dst, XMMRegister src, int vector_len) { |
|
5081 assert(VM_Version::supports_evex(), ""); |
|
5082 int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, |
|
5083 VEX_OPCODE_0F_38, false, vector_len, false, false); |
|
5084 emit_int8(0x18); |
|
5085 emit_int8((unsigned char)(0xC0 | encode)); |
|
5086 } |
|
5087 |
|
5088 void Assembler::evpbroadcastss(XMMRegister dst, Address src, int vector_len) { |
|
5089 assert(VM_Version::supports_evex(), ""); |
|
5090 tuple_type = EVEX_T1S; |
|
5091 input_size_in_bits = EVEX_32bit; |
|
5092 InstructionMark im(this); |
|
5093 assert(dst != xnoreg, "sanity"); |
|
5094 int dst_enc = dst->encoding(); |
|
5095 // swap src<->dst for encoding |
|
5096 vex_prefix(src, 0, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_38, false, vector_len); |
|
5097 emit_int8(0x18); |
|
5098 emit_operand(dst, src); |
|
5099 } |
|
5100 |
|
5101 // duplicate double precision fp from src into 2|4|8 locations in dest : requires AVX512VL |
|
5102 void Assembler::evpbroadcastsd(XMMRegister dst, XMMRegister src, int vector_len) { |
|
5103 assert(VM_Version::supports_evex(), ""); |
|
5104 int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, |
|
5105 VEX_OPCODE_0F_38, true, vector_len, false, false); |
|
5106 emit_int8(0x19); |
|
5107 emit_int8((unsigned char)(0xC0 | encode)); |
|
5108 } |
|
5109 |
|
5110 void Assembler::evpbroadcastsd(XMMRegister dst, Address src, int vector_len) { |
|
5111 assert(VM_Version::supports_evex(), ""); |
|
5112 tuple_type = EVEX_T1S; |
|
5113 input_size_in_bits = EVEX_64bit; |
|
5114 InstructionMark im(this); |
|
5115 assert(dst != xnoreg, "sanity"); |
|
5116 int dst_enc = dst->encoding(); |
|
5117 // swap src<->dst for encoding |
|
5118 vex_prefix(src, 0, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_38, true, vector_len); |
|
5119 emit_int8(0x19); |
|
5120 emit_operand(dst, src); |
|
5121 } |
|
5122 |
|
5123 // duplicate 1-byte integer data from src into 16||32|64 locations in dest : requires AVX512BW and AVX512VL |
|
5124 void Assembler::evpbroadcastb(XMMRegister dst, Register src, int vector_len) { |
|
5125 assert(VM_Version::supports_evex(), ""); |
|
5126 int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, |
|
5127 VEX_OPCODE_0F_38, false, vector_len, false, false); |
|
5128 emit_int8(0x7A); |
|
5129 emit_int8((unsigned char)(0xC0 | encode)); |
|
5130 } |
|
5131 |
|
5132 // duplicate 2-byte integer data from src into 8|16||32 locations in dest : requires AVX512BW and AVX512VL |
|
5133 void Assembler::evpbroadcastw(XMMRegister dst, Register src, int vector_len) { |
|
5134 assert(VM_Version::supports_evex(), ""); |
|
5135 int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, |
|
5136 VEX_OPCODE_0F_38, false, vector_len, false, false); |
|
5137 emit_int8(0x7B); |
|
5138 emit_int8((unsigned char)(0xC0 | encode)); |
|
5139 } |
|
5140 |
|
5141 // duplicate 4-byte integer data from src into 4|8|16 locations in dest : requires AVX512VL |
|
5142 void Assembler::evpbroadcastd(XMMRegister dst, Register src, int vector_len) { |
|
5143 assert(VM_Version::supports_evex(), ""); |
|
5144 int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, |
|
5145 VEX_OPCODE_0F_38, false, vector_len, false, false); |
|
5146 emit_int8(0x7C); |
|
5147 emit_int8((unsigned char)(0xC0 | encode)); |
|
5148 } |
|
5149 |
|
5150 // duplicate 8-byte integer data from src into 4|8|16 locations in dest : requires AVX512VL |
|
5151 void Assembler::evpbroadcastq(XMMRegister dst, Register src, int vector_len) { |
|
5152 assert(VM_Version::supports_evex(), ""); |
|
5153 int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, |
|
5154 VEX_OPCODE_0F_38, true, vector_len, false, false); |
|
5155 emit_int8(0x7C); |
4996 emit_int8((unsigned char)(0xC0 | encode)); |
5156 emit_int8((unsigned char)(0xC0 | encode)); |
4997 } |
5157 } |
4998 |
5158 |
4999 // Carry-Less Multiplication Quadword |
5159 // Carry-Less Multiplication Quadword |
5000 void Assembler::pclmulqdq(XMMRegister dst, XMMRegister src, int mask) { |
5160 void Assembler::pclmulqdq(XMMRegister dst, XMMRegister src, int mask) { |
6317 emit_int8((unsigned char)(0xC8 | encode)); |
6473 emit_int8((unsigned char)(0xC8 | encode)); |
6318 } |
6474 } |
6319 |
6475 |
6320 void Assembler::blsiq(Register dst, Register src) { |
6476 void Assembler::blsiq(Register dst, Register src) { |
6321 assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported"); |
6477 assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported"); |
6322 int encode = vex_prefix_0F38_and_encode_q(rbx, dst, src); |
6478 int encode = vex_prefix_0F38_and_encode_q_legacy(rbx, dst, src); |
6323 emit_int8((unsigned char)0xF3); |
6479 emit_int8((unsigned char)0xF3); |
6324 emit_int8((unsigned char)(0xC0 | encode)); |
6480 emit_int8((unsigned char)(0xC0 | encode)); |
6325 } |
6481 } |
6326 |
6482 |
6327 void Assembler::blsiq(Register dst, Address src) { |
6483 void Assembler::blsiq(Register dst, Address src) { |
6328 InstructionMark im(this); |
6484 InstructionMark im(this); |
6329 assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported"); |
6485 assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported"); |
6330 vex_prefix_0F38_q(rbx, dst, src); |
6486 vex_prefix_0F38_q_legacy(rbx, dst, src); |
6331 emit_int8((unsigned char)0xF3); |
6487 emit_int8((unsigned char)0xF3); |
6332 emit_operand(rbx, src); |
6488 emit_operand(rbx, src); |
6333 } |
6489 } |
6334 |
6490 |
6335 void Assembler::blsmskq(Register dst, Register src) { |
6491 void Assembler::blsmskq(Register dst, Register src) { |
6336 assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported"); |
6492 assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported"); |
6337 int encode = vex_prefix_0F38_and_encode_q(rdx, dst, src); |
6493 int encode = vex_prefix_0F38_and_encode_q_legacy(rdx, dst, src); |
6338 emit_int8((unsigned char)0xF3); |
6494 emit_int8((unsigned char)0xF3); |
6339 emit_int8((unsigned char)(0xC0 | encode)); |
6495 emit_int8((unsigned char)(0xC0 | encode)); |
6340 } |
6496 } |
6341 |
6497 |
6342 void Assembler::blsmskq(Register dst, Address src) { |
6498 void Assembler::blsmskq(Register dst, Address src) { |
6343 InstructionMark im(this); |
6499 InstructionMark im(this); |
6344 assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported"); |
6500 assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported"); |
6345 vex_prefix_0F38_q(rdx, dst, src); |
6501 vex_prefix_0F38_q_legacy(rdx, dst, src); |
6346 emit_int8((unsigned char)0xF3); |
6502 emit_int8((unsigned char)0xF3); |
6347 emit_operand(rdx, src); |
6503 emit_operand(rdx, src); |
6348 } |
6504 } |
6349 |
6505 |
6350 void Assembler::blsrq(Register dst, Register src) { |
6506 void Assembler::blsrq(Register dst, Register src) { |
6351 assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported"); |
6507 assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported"); |
6352 int encode = vex_prefix_0F38_and_encode_q(rcx, dst, src); |
6508 int encode = vex_prefix_0F38_and_encode_q_legacy(rcx, dst, src); |
6353 emit_int8((unsigned char)0xF3); |
6509 emit_int8((unsigned char)0xF3); |
6354 emit_int8((unsigned char)(0xC0 | encode)); |
6510 emit_int8((unsigned char)(0xC0 | encode)); |
6355 } |
6511 } |
6356 |
6512 |
6357 void Assembler::blsrq(Register dst, Address src) { |
6513 void Assembler::blsrq(Register dst, Address src) { |
6358 InstructionMark im(this); |
6514 InstructionMark im(this); |
6359 assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported"); |
6515 assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported"); |
6360 vex_prefix_0F38_q(rcx, dst, src); |
6516 vex_prefix_0F38_q_legacy(rcx, dst, src); |
6361 emit_int8((unsigned char)0xF3); |
6517 emit_int8((unsigned char)0xF3); |
6362 emit_operand(rcx, src); |
6518 emit_operand(rcx, src); |
6363 } |
6519 } |
6364 |
6520 |
6365 void Assembler::cdqq() { |
6521 void Assembler::cdqq() { |