704 // Try STFLE. Possible INVOP will cause defaults to be used. |
704 // Try STFLE. Possible INVOP will cause defaults to be used. |
705 Label getFEATURES; |
705 Label getFEATURES; |
706 Label getCPUFEATURES; // fcode = -1 (cache) |
706 Label getCPUFEATURES; // fcode = -1 (cache) |
707 Label getCIPHERFEATURES; // fcode = -2 (cipher) |
707 Label getCIPHERFEATURES; // fcode = -2 (cipher) |
708 Label getMSGDIGESTFEATURES; // fcode = -3 (SHA) |
708 Label getMSGDIGESTFEATURES; // fcode = -3 (SHA) |
|
709 Label getVECTORFEATURES; // fcode = -4 (OS support for vector instructions) |
709 Label checkLongDispFast; |
710 Label checkLongDispFast; |
710 Label noLongDisp; |
711 Label noLongDisp; |
711 Label posDisp, negDisp; |
712 Label posDisp, negDisp; |
712 Label errRTN; |
713 Label errRTN; |
713 a->z_ltgfr(Z_R0, Z_ARG2); // Buf len to r0 and test. |
714 a->z_ltgfr(Z_R0, Z_ARG2); // Buf len to r0 and test. |
714 a->z_brl(getFEATURES); // negative -> Get machine features. |
715 a->z_brl(getFEATURES); // negative -> Get machine features not covered by facility list. |
715 a->z_brz(checkLongDispFast); // zero -> Check for high-speed Long Displacement Facility. |
716 a->z_brz(checkLongDispFast); // zero -> Check for high-speed Long Displacement Facility. |
716 a->z_aghi(Z_R0, -1); |
717 a->z_aghi(Z_R0, -1); |
717 a->z_stfle(0, Z_ARG1); |
718 a->z_stfle(0, Z_ARG1); |
718 a->z_lg(Z_R1, 0, Z_ARG1); // Get first DW of facility list. |
719 a->z_lg(Z_R1, 0, Z_ARG1); // Get first DW of facility list. |
719 a->z_lgr(Z_RET, Z_R0); // Calculate rtn value for success. |
720 a->z_lgr(Z_RET, Z_R0); // Calculate rtn value for success. |
734 a->z_bre(getCPUFEATURES); |
735 a->z_bre(getCPUFEATURES); |
735 a->z_cghi(Z_R0, -2); // -2: Extract detailed crypto capabilities (cipher instructions). |
736 a->z_cghi(Z_R0, -2); // -2: Extract detailed crypto capabilities (cipher instructions). |
736 a->z_bre(getCIPHERFEATURES); |
737 a->z_bre(getCIPHERFEATURES); |
737 a->z_cghi(Z_R0, -3); // -3: Extract detailed crypto capabilities (msg digest instructions). |
738 a->z_cghi(Z_R0, -3); // -3: Extract detailed crypto capabilities (msg digest instructions). |
738 a->z_bre(getMSGDIGESTFEATURES); |
739 a->z_bre(getMSGDIGESTFEATURES); |
|
740 a->z_cghi(Z_R0, -4); // -4: Verify vector instruction availability (OS support). |
|
741 a->z_bre(getVECTORFEATURES); |
739 |
742 |
740 a->z_xgr(Z_RET, Z_RET); // Not a valid function code. |
743 a->z_xgr(Z_RET, Z_RET); // Not a valid function code. |
741 a->z_br(Z_R14); // Return "operation aborted". |
744 a->z_br(Z_R14); // Return "operation aborted". |
742 |
745 |
743 // Try KIMD/KLMD query function to get details about msg digest (secure hash, SHA) instructions. |
746 // Try KIMD/KLMD query function to get details about msg digest (secure hash, SHA) instructions. |
762 |
765 |
763 // Use EXTRACT CPU ATTRIBUTE instruction to get information about cache layout. |
766 // Use EXTRACT CPU ATTRIBUTE instruction to get information about cache layout. |
764 a->bind(getCPUFEATURES); |
767 a->bind(getCPUFEATURES); |
765 a->z_xgr(Z_R0,Z_R0); // as recommended in instruction documentation |
768 a->z_xgr(Z_R0,Z_R0); // as recommended in instruction documentation |
766 a->z_ecag(Z_RET,Z_R0,0,Z_ARG3); // Extract information as requested by Z_ARG1 contents. |
769 a->z_ecag(Z_RET,Z_R0,0,Z_ARG3); // Extract information as requested by Z_ARG1 contents. |
|
770 a->z_br(Z_R14); |
|
771 |
|
772 // Use a vector instruction to verify OS support. Will fail with SIGFPE if OS support is missing. |
|
773 a->bind(getVECTORFEATURES); |
|
774 a->z_vtm(Z_V0,Z_V0); // non-destructive vector instruction. Will cause SIGFPE if not supported. |
767 a->z_br(Z_R14); |
775 a->z_br(Z_R14); |
768 |
776 |
769 // Check the performance of the Long Displacement Facility, i.e. find out if we are running on z900 or newer. |
777 // Check the performance of the Long Displacement Facility, i.e. find out if we are running on z900 or newer. |
770 a->bind(checkLongDispFast); |
778 a->bind(checkLongDispFast); |
771 a->z_llill(Z_R0, 0xffff); // preset #iterations |
779 a->z_llill(Z_R0, 0xffff); // preset #iterations |
960 buffer[i] = 0L; |
968 buffer[i] = 0L; |
961 } |
969 } |
962 _nfeatures = 0; |
970 _nfeatures = 0; |
963 } |
971 } |
964 |
972 |
|
973 if (has_VectorFacility()) { |
|
974 // Verify that feature can actually be used. OS support required. |
|
975 call_getFeatures(buffer, -4, 0); |
|
976 if (printVerbose) { |
|
977 ttyLocker ttyl; |
|
978 if (has_VectorFacility()) { |
|
979 tty->print_cr(" Vector Facility has been verified to be supported by OS"); |
|
980 } else { |
|
981 tty->print_cr(" Vector Facility has been disabled - not supported by OS"); |
|
982 } |
|
983 } |
|
984 } |
|
985 |
965 // Extract Crypto Facility details. |
986 // Extract Crypto Facility details. |
966 if (has_Crypto()) { |
987 if (has_Crypto()) { |
967 // Get cipher features. |
988 // Get cipher features. |
968 used_len = call_getFeatures(buffer, -2, 0); |
989 used_len = call_getFeatures(buffer, -2, 0); |
969 for (int i = 0; i < buf_len; i++) { |
990 for (int i = 0; i < buf_len; i++) { |