< prev index next >

src/hotspot/cpu/x86/x86.ad

Print this page
rev 47825 : Support vectorization of sqrt for float


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));


< prev index next >