1235 case Op_AddReductionVL:
1236 if (UseAVX < 3) // only EVEX : vector connectivity becomes an issue here
1237 ret_value = false;
1238 break;
1239 case Op_AddReductionVI:
1240 if (UseSSE < 3) // requires at least SSE3
1241 ret_value = false;
1242 break;
1243 case Op_MulReductionVI:
1244 if (UseSSE < 4) // requires at least SSE4
1245 ret_value = false;
1246 break;
1247 case Op_AddReductionVF:
1248 case Op_AddReductionVD:
1249 case Op_MulReductionVF:
1250 case Op_MulReductionVD:
1251 if (UseSSE < 1) // requires at least SSE
1252 ret_value = false;
1253 break;
1254 case Op_SqrtVD:
1255 if (UseAVX < 1) // enabled for AVX only
1256 ret_value = false;
1257 break;
1258 case Op_CompareAndSwapL:
1259 #ifdef _LP64
1260 case Op_CompareAndSwapP:
1261 #endif
1262 if (!VM_Version::supports_cx8())
1263 ret_value = false;
1264 break;
1265 case Op_CMoveVD:
1266 if (UseAVX < 1 || UseAVX > 2)
1267 ret_value = false;
1268 break;
1269 case Op_StrIndexOf:
1270 if (!UseSSE42Intrinsics)
1271 ret_value = false;
1272 break;
1273 case Op_StrIndexOfChar:
1274 if (!UseSSE42Intrinsics)
2563 __ xorpd($dst$$XMMRegister, ExternalAddress(double_signflip()));
2564 %}
2565 ins_pipe(pipe_slow);
2566 %}
2567
2568 instruct negD_reg_reg(regD dst, regD src) %{
2569 predicate(UseAVX > 0);
2570 match(Set dst (NegD src));
2571 ins_cost(150);
2572 format %{ "vnegatess $dst, $src, [0x8000000000000000]\t"
2573 "# neg double by sign flipping" %}
2574 ins_encode %{
2575 __ vnegatesd($dst$$XMMRegister, $src$$XMMRegister,
2576 ExternalAddress(double_signflip()));
2577 %}
2578 ins_pipe(pipe_slow);
2579 %}
2580
2581 instruct sqrtF_reg(regF dst, regF src) %{
2582 predicate(UseSSE>=1);
2583 match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
2584
2585 format %{ "sqrtss $dst, $src" %}
2586 ins_cost(150);
2587 ins_encode %{
2588 __ sqrtss($dst$$XMMRegister, $src$$XMMRegister);
2589 %}
2590 ins_pipe(pipe_slow);
2591 %}
2592
2593 instruct sqrtF_mem(regF dst, memory src) %{
2594 predicate(UseSSE>=1);
2595 match(Set dst (ConvD2F (SqrtD (ConvF2D (LoadF src)))));
2596
2597 format %{ "sqrtss $dst, $src" %}
2598 ins_cost(150);
2599 ins_encode %{
2600 __ sqrtss($dst$$XMMRegister, $src$$Address);
2601 %}
2602 ins_pipe(pipe_slow);
2603 %}
2604
2605 instruct sqrtF_imm(regF dst, immF con) %{
2606 predicate(UseSSE>=1);
2607 match(Set dst (ConvD2F (SqrtD (ConvF2D con))));
2608 format %{ "sqrtss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
2609 ins_cost(150);
2610 ins_encode %{
2611 __ sqrtss($dst$$XMMRegister, $constantaddress($con));
2612 %}
2613 ins_pipe(pipe_slow);
2614 %}
2615
2616 instruct sqrtD_reg(regD dst, regD src) %{
2617 predicate(UseSSE>=2);
2618 match(Set dst (SqrtD src));
2619
2620 format %{ "sqrtsd $dst, $src" %}
2621 ins_cost(150);
2622 ins_encode %{
2623 __ sqrtsd($dst$$XMMRegister, $src$$XMMRegister);
2624 %}
2625 ins_pipe(pipe_slow);
2626 %}
2627
8371 %}
8372 ins_pipe( pipe_slow );
8373 %}
8374
8375 // ------------------------------ Shift ---------------------------------------
8376
8377 // Left and right shift count vectors are the same on x86
8378 // (only lowest bits of xmm reg are used for count).
8379 instruct vshiftcnt(vecS dst, rRegI cnt) %{
8380 match(Set dst (LShiftCntV cnt));
8381 match(Set dst (RShiftCntV cnt));
8382 format %{ "movd $dst,$cnt\t! load shift count" %}
8383 ins_encode %{
8384 __ movdl($dst$$XMMRegister, $cnt$$Register);
8385 %}
8386 ins_pipe( pipe_slow );
8387 %}
8388
8389 // --------------------------------- Sqrt --------------------------------------
8390
8391 // Floating point vector sqrt - double precision only
8392 instruct vsqrt2D_reg(vecX dst, vecX src) %{
8393 predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
8394 match(Set dst (SqrtVD src));
8395 format %{ "vsqrtpd $dst,$src\t! sqrt packed2D" %}
8396 ins_encode %{
8397 int vector_len = 0;
8398 __ vsqrtpd($dst$$XMMRegister, $src$$XMMRegister, vector_len);
8399 %}
8400 ins_pipe( pipe_slow );
8401 %}
8402
8403 instruct vsqrt2D_mem(vecX dst, memory mem) %{
8404 predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
8405 match(Set dst (SqrtVD (LoadVector mem)));
8406 format %{ "vsqrtpd $dst,$mem\t! sqrt packed2D" %}
8407 ins_encode %{
8408 int vector_len = 0;
8409 __ vsqrtpd($dst$$XMMRegister, $mem$$Address, vector_len);
8410 %}
8411 ins_pipe( pipe_slow );
8434 %}
8435
8436 instruct vsqrt8D_reg(vecZ dst, vecZ src) %{
8437 predicate(UseAVX > 2 && n->as_Vector()->length() == 8);
8438 match(Set dst (SqrtVD src));
8439 format %{ "vsqrtpd $dst,$src\t! sqrt packed8D" %}
8440 ins_encode %{
8441 int vector_len = 2;
8442 __ vsqrtpd($dst$$XMMRegister, $src$$XMMRegister, vector_len);
8443 %}
8444 ins_pipe( pipe_slow );
8445 %}
8446
8447 instruct vsqrt8D_mem(vecZ dst, memory mem) %{
8448 predicate(UseAVX > 2 && n->as_Vector()->length() == 8);
8449 match(Set dst (SqrtVD (LoadVector mem)));
8450 format %{ "vsqrtpd $dst,$mem\t! sqrt packed8D" %}
8451 ins_encode %{
8452 int vector_len = 2;
8453 __ vsqrtpd($dst$$XMMRegister, $mem$$Address, vector_len);
8454 %}
8455 ins_pipe( pipe_slow );
8456 %}
8457
8458 // ------------------------------ LeftShift -----------------------------------
8459
8460 // Shorts/Chars vector left shift
8461 instruct vsll2S(vecS dst, vecS shift) %{
8462 predicate(UseAVX == 0 && n->as_Vector()->length() == 2);
8463 match(Set dst (LShiftVS dst shift));
8464 format %{ "psllw $dst,$shift\t! left shift packed2S" %}
8465 ins_encode %{
8466 __ psllw($dst$$XMMRegister, $shift$$XMMRegister);
8467 %}
8468 ins_pipe( pipe_slow );
8469 %}
8470
8471 instruct vsll2S_imm(vecS dst, immI8 shift) %{
8472 predicate(UseAVX == 0 && n->as_Vector()->length() == 2);
8473 match(Set dst (LShiftVS dst shift));
|
1235 case Op_AddReductionVL:
1236 if (UseAVX < 3) // only EVEX : vector connectivity becomes an issue here
1237 ret_value = false;
1238 break;
1239 case Op_AddReductionVI:
1240 if (UseSSE < 3) // requires at least SSE3
1241 ret_value = false;
1242 break;
1243 case Op_MulReductionVI:
1244 if (UseSSE < 4) // requires at least SSE4
1245 ret_value = false;
1246 break;
1247 case Op_AddReductionVF:
1248 case Op_AddReductionVD:
1249 case Op_MulReductionVF:
1250 case Op_MulReductionVD:
1251 if (UseSSE < 1) // requires at least SSE
1252 ret_value = false;
1253 break;
1254 case Op_SqrtVD:
1255 case Op_SqrtVF:
1256 if (UseAVX < 1) // enabled for AVX only
1257 ret_value = false;
1258 break;
1259 case Op_CompareAndSwapL:
1260 #ifdef _LP64
1261 case Op_CompareAndSwapP:
1262 #endif
1263 if (!VM_Version::supports_cx8())
1264 ret_value = false;
1265 break;
1266 case Op_CMoveVD:
1267 if (UseAVX < 1 || UseAVX > 2)
1268 ret_value = false;
1269 break;
1270 case Op_StrIndexOf:
1271 if (!UseSSE42Intrinsics)
1272 ret_value = false;
1273 break;
1274 case Op_StrIndexOfChar:
1275 if (!UseSSE42Intrinsics)
2564 __ xorpd($dst$$XMMRegister, ExternalAddress(double_signflip()));
2565 %}
2566 ins_pipe(pipe_slow);
2567 %}
2568
2569 instruct negD_reg_reg(regD dst, regD src) %{
2570 predicate(UseAVX > 0);
2571 match(Set dst (NegD src));
2572 ins_cost(150);
2573 format %{ "vnegatess $dst, $src, [0x8000000000000000]\t"
2574 "# neg double by sign flipping" %}
2575 ins_encode %{
2576 __ vnegatesd($dst$$XMMRegister, $src$$XMMRegister,
2577 ExternalAddress(double_signflip()));
2578 %}
2579 ins_pipe(pipe_slow);
2580 %}
2581
2582 instruct sqrtF_reg(regF dst, regF src) %{
2583 predicate(UseSSE>=1);
2584 match(Set dst (SqrtF src));
2585
2586 format %{ "sqrtss $dst, $src" %}
2587 ins_cost(150);
2588 ins_encode %{
2589 __ sqrtss($dst$$XMMRegister, $src$$XMMRegister);
2590 %}
2591 ins_pipe(pipe_slow);
2592 %}
2593
2594 instruct sqrtF_mem(regF dst, memory src) %{
2595 predicate(UseSSE>=1);
2596 match(Set dst (SqrtF (LoadF src)));
2597
2598 format %{ "sqrtss $dst, $src" %}
2599 ins_cost(150);
2600 ins_encode %{
2601 __ sqrtss($dst$$XMMRegister, $src$$Address);
2602 %}
2603 ins_pipe(pipe_slow);
2604 %}
2605
2606 instruct sqrtF_imm(regF dst, immF con) %{
2607 predicate(UseSSE>=1);
2608 match(Set dst (SqrtF con));
2609
2610 format %{ "sqrtss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
2611 ins_cost(150);
2612 ins_encode %{
2613 __ sqrtss($dst$$XMMRegister, $constantaddress($con));
2614 %}
2615 ins_pipe(pipe_slow);
2616 %}
2617
2618 instruct sqrtD_reg(regD dst, regD src) %{
2619 predicate(UseSSE>=2);
2620 match(Set dst (SqrtD src));
2621
2622 format %{ "sqrtsd $dst, $src" %}
2623 ins_cost(150);
2624 ins_encode %{
2625 __ sqrtsd($dst$$XMMRegister, $src$$XMMRegister);
2626 %}
2627 ins_pipe(pipe_slow);
2628 %}
2629
8373 %}
8374 ins_pipe( pipe_slow );
8375 %}
8376
8377 // ------------------------------ Shift ---------------------------------------
8378
8379 // Left and right shift count vectors are the same on x86
8380 // (only lowest bits of xmm reg are used for count).
8381 instruct vshiftcnt(vecS dst, rRegI cnt) %{
8382 match(Set dst (LShiftCntV cnt));
8383 match(Set dst (RShiftCntV cnt));
8384 format %{ "movd $dst,$cnt\t! load shift count" %}
8385 ins_encode %{
8386 __ movdl($dst$$XMMRegister, $cnt$$Register);
8387 %}
8388 ins_pipe( pipe_slow );
8389 %}
8390
8391 // --------------------------------- Sqrt --------------------------------------
8392
8393 // Floating point vector sqrt
8394 instruct vsqrt2D_reg(vecX dst, vecX src) %{
8395 predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
8396 match(Set dst (SqrtVD src));
8397 format %{ "vsqrtpd $dst,$src\t! sqrt packed2D" %}
8398 ins_encode %{
8399 int vector_len = 0;
8400 __ vsqrtpd($dst$$XMMRegister, $src$$XMMRegister, vector_len);
8401 %}
8402 ins_pipe( pipe_slow );
8403 %}
8404
8405 instruct vsqrt2D_mem(vecX dst, memory mem) %{
8406 predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
8407 match(Set dst (SqrtVD (LoadVector mem)));
8408 format %{ "vsqrtpd $dst,$mem\t! sqrt packed2D" %}
8409 ins_encode %{
8410 int vector_len = 0;
8411 __ vsqrtpd($dst$$XMMRegister, $mem$$Address, vector_len);
8412 %}
8413 ins_pipe( pipe_slow );
8436 %}
8437
8438 instruct vsqrt8D_reg(vecZ dst, vecZ src) %{
8439 predicate(UseAVX > 2 && n->as_Vector()->length() == 8);
8440 match(Set dst (SqrtVD src));
8441 format %{ "vsqrtpd $dst,$src\t! sqrt packed8D" %}
8442 ins_encode %{
8443 int vector_len = 2;
8444 __ vsqrtpd($dst$$XMMRegister, $src$$XMMRegister, vector_len);
8445 %}
8446 ins_pipe( pipe_slow );
8447 %}
8448
8449 instruct vsqrt8D_mem(vecZ dst, memory mem) %{
8450 predicate(UseAVX > 2 && n->as_Vector()->length() == 8);
8451 match(Set dst (SqrtVD (LoadVector mem)));
8452 format %{ "vsqrtpd $dst,$mem\t! sqrt packed8D" %}
8453 ins_encode %{
8454 int vector_len = 2;
8455 __ vsqrtpd($dst$$XMMRegister, $mem$$Address, vector_len);
8456 %}
8457 ins_pipe( pipe_slow );
8458 %}
8459
8460 instruct vsqrt2F_reg(vecX dst, vecX src) %{
8461 predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
8462 match(Set dst (SqrtVF src));
8463 format %{ "vsqrtps $dst,$src\t! sqrt packed2F" %}
8464 ins_encode %{
8465 int vector_len = 0;
8466 __ vsqrtps($dst$$XMMRegister, $src$$XMMRegister, vector_len);
8467 %}
8468 ins_pipe( pipe_slow );
8469 %}
8470
8471 instruct vsqrt2F_mem(vecX dst, memory mem) %{
8472 predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
8473 match(Set dst (SqrtVF (LoadVector mem)));
8474 format %{ "vsqrtps $dst,$mem\t! sqrt packed2F" %}
8475 ins_encode %{
8476 int vector_len = 0;
8477 __ vsqrtps($dst$$XMMRegister, $mem$$Address, vector_len);
8478 %}
8479 ins_pipe( pipe_slow );
8480 %}
8481
8482 instruct vsqrt4F_reg(vecX dst, vecX src) %{
8483 predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
8484 match(Set dst (SqrtVF src));
8485 format %{ "vsqrtps $dst,$src\t! sqrt packed4F" %}
8486 ins_encode %{
8487 int vector_len = 0;
8488 __ vsqrtps($dst$$XMMRegister, $src$$XMMRegister, vector_len);
8489 %}
8490 ins_pipe( pipe_slow );
8491 %}
8492
8493 instruct vsqrt4F_mem(vecX dst, memory mem) %{
8494 predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
8495 match(Set dst (SqrtVF (LoadVector mem)));
8496 format %{ "vsqrtps $dst,$mem\t! sqrt packed4F" %}
8497 ins_encode %{
8498 int vector_len = 0;
8499 __ vsqrtps($dst$$XMMRegister, $mem$$Address, vector_len);
8500 %}
8501 ins_pipe( pipe_slow );
8502 %}
8503
8504 instruct vsqrt8F_reg(vecY dst, vecY src) %{
8505 predicate(UseAVX > 0 && n->as_Vector()->length() == 8);
8506 match(Set dst (SqrtVF src));
8507 format %{ "vsqrtps $dst,$src\t! sqrt packed8F" %}
8508 ins_encode %{
8509 int vector_len = 1;
8510 __ vsqrtps($dst$$XMMRegister, $src$$XMMRegister, vector_len);
8511 %}
8512 ins_pipe( pipe_slow );
8513 %}
8514
8515 instruct vsqrt8F_mem(vecY dst, memory mem) %{
8516 predicate(UseAVX > 0 && n->as_Vector()->length() == 8);
8517 match(Set dst (SqrtVF (LoadVector mem)));
8518 format %{ "vsqrtps $dst,$mem\t! sqrt packed8F" %}
8519 ins_encode %{
8520 int vector_len = 1;
8521 __ vsqrtps($dst$$XMMRegister, $mem$$Address, vector_len);
8522 %}
8523 ins_pipe( pipe_slow );
8524 %}
8525
8526 instruct vsqrt16F_reg(vecZ dst, vecZ src) %{
8527 predicate(UseAVX > 2 && n->as_Vector()->length() == 16);
8528 match(Set dst (SqrtVF src));
8529 format %{ "vsqrtps $dst,$src\t! sqrt packed16F" %}
8530 ins_encode %{
8531 int vector_len = 2;
8532 __ vsqrtps($dst$$XMMRegister, $src$$XMMRegister, vector_len);
8533 %}
8534 ins_pipe( pipe_slow );
8535 %}
8536
8537 instruct vsqrt16F_mem(vecZ dst, memory mem) %{
8538 predicate(UseAVX > 2 && n->as_Vector()->length() == 16);
8539 match(Set dst (SqrtVF (LoadVector mem)));
8540 format %{ "vsqrtps $dst,$mem\t! sqrt packed16F" %}
8541 ins_encode %{
8542 int vector_len = 2;
8543 __ vsqrtps($dst$$XMMRegister, $mem$$Address, vector_len);
8544 %}
8545 ins_pipe( pipe_slow );
8546 %}
8547
8548 // ------------------------------ LeftShift -----------------------------------
8549
8550 // Shorts/Chars vector left shift
8551 instruct vsll2S(vecS dst, vecS shift) %{
8552 predicate(UseAVX == 0 && n->as_Vector()->length() == 2);
8553 match(Set dst (LShiftVS dst shift));
8554 format %{ "psllw $dst,$shift\t! left shift packed2S" %}
8555 ins_encode %{
8556 __ psllw($dst$$XMMRegister, $shift$$XMMRegister);
8557 %}
8558 ins_pipe( pipe_slow );
8559 %}
8560
8561 instruct vsll2S_imm(vecS dst, immI8 shift) %{
8562 predicate(UseAVX == 0 && n->as_Vector()->length() == 2);
8563 match(Set dst (LShiftVS dst shift));
|