4786 __ delayed()->stf(FloatRegisterImpl::D, F14, state, 0x38); |
4786 __ delayed()->stf(FloatRegisterImpl::D, F14, state, 0x38); |
4787 |
4787 |
4788 return start; |
4788 return start; |
4789 } |
4789 } |
4790 |
4790 |
|
4791 /* Single and multi-block ghash operations */ |
|
4792 address generate_ghash_processBlocks() { |
|
4793 __ align(CodeEntryAlignment); |
|
4794 Label L_ghash_loop, L_aligned, L_main; |
|
4795 StubCodeMark mark(this, "StubRoutines", "ghash_processBlocks"); |
|
4796 address start = __ pc(); |
|
4797 |
|
4798 Register state = I0; |
|
4799 Register subkeyH = I1; |
|
4800 Register data = I2; |
|
4801 Register len = I3; |
|
4802 |
|
4803 __ save_frame(0); |
|
4804 |
|
4805 __ ldx(state, 0, O0); |
|
4806 __ ldx(state, 8, O1); |
|
4807 |
|
4808 // Loop label for multiblock operations |
|
4809 __ BIND(L_ghash_loop); |
|
4810 |
|
4811 // Check if 'data' is unaligned |
|
4812 __ andcc(data, 7, G1); |
|
4813 __ br(Assembler::zero, false, Assembler::pt, L_aligned); |
|
4814 __ delayed()->nop(); |
|
4815 |
|
4816 Register left_shift = L1; |
|
4817 Register right_shift = L2; |
|
4818 Register data_ptr = L3; |
|
4819 |
|
4820 // Get left and right shift values in bits |
|
4821 __ sll(G1, LogBitsPerByte, left_shift); |
|
4822 __ mov(64, right_shift); |
|
4823 __ sub(right_shift, left_shift, right_shift); |
|
4824 |
|
4825 // Align to read 'data' |
|
4826 __ sub(data, G1, data_ptr); |
|
4827 |
|
4828 // Load first 8 bytes of 'data' |
|
4829 __ ldx(data_ptr, 0, O4); |
|
4830 __ sllx(O4, left_shift, O4); |
|
4831 __ ldx(data_ptr, 8, O5); |
|
4832 __ srlx(O5, right_shift, G4); |
|
4833 __ bset(G4, O4); |
|
4834 |
|
4835 // Load second 8 bytes of 'data' |
|
4836 __ sllx(O5, left_shift, O5); |
|
4837 __ ldx(data_ptr, 16, G4); |
|
4838 __ srlx(G4, right_shift, G4); |
|
4839 __ ba(L_main); |
|
4840 __ delayed()->bset(G4, O5); |
|
4841 |
|
4842 // If 'data' is aligned, load normally |
|
4843 __ BIND(L_aligned); |
|
4844 __ ldx(data, 0, O4); |
|
4845 __ ldx(data, 8, O5); |
|
4846 |
|
4847 __ BIND(L_main); |
|
4848 __ ldx(subkeyH, 0, O2); |
|
4849 __ ldx(subkeyH, 8, O3); |
|
4850 |
|
4851 __ xor3(O0, O4, O0); |
|
4852 __ xor3(O1, O5, O1); |
|
4853 |
|
4854 __ xmulxhi(O0, O3, G3); |
|
4855 __ xmulx(O0, O2, O5); |
|
4856 __ xmulxhi(O1, O2, G4); |
|
4857 __ xmulxhi(O1, O3, G5); |
|
4858 __ xmulx(O0, O3, G1); |
|
4859 __ xmulx(O1, O3, G2); |
|
4860 __ xmulx(O1, O2, O3); |
|
4861 __ xmulxhi(O0, O2, O4); |
|
4862 |
|
4863 __ mov(0xE1, O0); |
|
4864 __ sllx(O0, 56, O0); |
|
4865 |
|
4866 __ xor3(O5, G3, O5); |
|
4867 __ xor3(O5, G4, O5); |
|
4868 __ xor3(G5, G1, G1); |
|
4869 __ xor3(G1, O3, G1); |
|
4870 __ srlx(G2, 63, O1); |
|
4871 __ srlx(G1, 63, G3); |
|
4872 __ sllx(G2, 63, O3); |
|
4873 __ sllx(G2, 58, O2); |
|
4874 __ xor3(O3, O2, O2); |
|
4875 |
|
4876 __ sllx(G1, 1, G1); |
|
4877 __ or3(G1, O1, G1); |
|
4878 |
|
4879 __ xor3(G1, O2, G1); |
|
4880 |
|
4881 __ sllx(G2, 1, G2); |
|
4882 |
|
4883 __ xmulxhi(G1, O0, O1); |
|
4884 __ xmulx(G1, O0, O2); |
|
4885 __ xmulxhi(G2, O0, O3); |
|
4886 __ xmulx(G2, O0, G1); |
|
4887 |
|
4888 __ xor3(O4, O1, O4); |
|
4889 __ xor3(O5, O2, O5); |
|
4890 __ xor3(O5, O3, O5); |
|
4891 |
|
4892 __ sllx(O4, 1, O2); |
|
4893 __ srlx(O5, 63, O3); |
|
4894 |
|
4895 __ or3(O2, O3, O0); |
|
4896 |
|
4897 __ sllx(O5, 1, O1); |
|
4898 __ srlx(G1, 63, O2); |
|
4899 __ or3(O1, O2, O1); |
|
4900 __ xor3(O1, G3, O1); |
|
4901 |
|
4902 __ deccc(len); |
|
4903 __ br(Assembler::notZero, true, Assembler::pt, L_ghash_loop); |
|
4904 __ delayed()->add(data, 16, data); |
|
4905 |
|
4906 __ stx(O0, I0, 0); |
|
4907 __ stx(O1, I0, 8); |
|
4908 |
|
4909 __ ret(); |
|
4910 __ delayed()->restore(); |
|
4911 |
|
4912 return start; |
|
4913 } |
|
4914 |
4791 void generate_initial() { |
4915 void generate_initial() { |
4792 // Generates all stubs and initializes the entry points |
4916 // Generates all stubs and initializes the entry points |
4793 |
4917 |
4794 //------------------------------------------------------------------------------------------------------------------------ |
4918 //------------------------------------------------------------------------------------------------------------------------ |
4795 // entry points that exist in all platforms |
4919 // entry points that exist in all platforms |