hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp
changeset 38051 d092550d625d
parent 37466 287c4ebd11b0
parent 38018 1dc6c6f21231
child 38135 e06e2d071465
equal deleted inserted replaced
37993:e446184da25e 38051:d092550d625d
  2969 
  2969 
  2970     StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit    = StubRoutines::_oop_disjoint_arraycopy_uninit;
  2970     StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit    = StubRoutines::_oop_disjoint_arraycopy_uninit;
  2971     StubRoutines::_arrayof_oop_arraycopy_uninit             = StubRoutines::_oop_arraycopy_uninit;
  2971     StubRoutines::_arrayof_oop_arraycopy_uninit             = StubRoutines::_oop_arraycopy_uninit;
  2972   }
  2972   }
  2973 
  2973 
  2974   void generate_math_stubs() {
       
  2975     {
       
  2976       StubCodeMark mark(this, "StubRoutines", "log10");
       
  2977       StubRoutines::_intrinsic_log10 = (double (*)(double)) __ pc();
       
  2978 
       
  2979       __ subq(rsp, 8);
       
  2980       __ movdbl(Address(rsp, 0), xmm0);
       
  2981       __ fld_d(Address(rsp, 0));
       
  2982       __ flog10();
       
  2983       __ fstp_d(Address(rsp, 0));
       
  2984       __ movdbl(xmm0, Address(rsp, 0));
       
  2985       __ addq(rsp, 8);
       
  2986       __ ret(0);
       
  2987     }
       
  2988     {
       
  2989       StubCodeMark mark(this, "StubRoutines", "tan");
       
  2990       StubRoutines::_intrinsic_tan = (double (*)(double)) __ pc();
       
  2991 
       
  2992       __ subq(rsp, 8);
       
  2993       __ movdbl(Address(rsp, 0), xmm0);
       
  2994       __ fld_d(Address(rsp, 0));
       
  2995       __ trigfunc('t');
       
  2996       __ fstp_d(Address(rsp, 0));
       
  2997       __ movdbl(xmm0, Address(rsp, 0));
       
  2998       __ addq(rsp, 8);
       
  2999       __ ret(0);
       
  3000     }
       
  3001   }
       
  3002 
       
  3003   // AES intrinsic stubs
  2974   // AES intrinsic stubs
  3004   enum {AESBlockSize = 16};
  2975   enum {AESBlockSize = 16};
  3005 
  2976 
  3006   address generate_key_shuffle_mask() {
  2977   address generate_key_shuffle_mask() {
  3007     __ align(16);
  2978     __ align(16);
  4742 
  4713 
  4743     return start;
  4714     return start;
  4744 
  4715 
  4745   }
  4716   }
  4746 
  4717 
  4747   address generate_libmPow() {
  4718   address generate_libmLog10() {
  4748     address start = __ pc();
  4719     address start = __ pc();
  4749 
  4720 
  4750     const XMMRegister x0 = xmm0;
  4721     const XMMRegister x0 = xmm0;
  4751     const XMMRegister x1 = xmm1;
  4722     const XMMRegister x1 = xmm1;
  4752     const XMMRegister x2 = xmm2;
  4723     const XMMRegister x2 = xmm2;
  4755     const XMMRegister x4 = xmm4;
  4726     const XMMRegister x4 = xmm4;
  4756     const XMMRegister x5 = xmm5;
  4727     const XMMRegister x5 = xmm5;
  4757     const XMMRegister x6 = xmm6;
  4728     const XMMRegister x6 = xmm6;
  4758     const XMMRegister x7 = xmm7;
  4729     const XMMRegister x7 = xmm7;
  4759 
  4730 
  4760     const Register tmp1 = r8;
  4731     const Register tmp = r11;
  4761     const Register tmp2 = r9;
       
  4762     const Register tmp3 = r10;
       
  4763     const Register tmp4 = r11;
       
  4764 
  4732 
  4765     BLOCK_COMMENT("Entry:");
  4733     BLOCK_COMMENT("Entry:");
  4766     __ enter(); // required for proper stackwalking of RuntimeStub frame
  4734     __ enter(); // required for proper stackwalking of RuntimeStub frame
  4767 
  4735 
  4768 #ifdef _WIN64
  4736 #ifdef _WIN64
  4769     // save the xmm registers which must be preserved 6-7
  4737     // save the xmm registers which must be preserved 6-7
  4770     __ subptr(rsp, 4 * wordSize);
  4738     __ subptr(rsp, 4 * wordSize);
  4771     __ movdqu(Address(rsp, 0), xmm6);
  4739     __ movdqu(Address(rsp, 0), xmm6);
  4772     __ movdqu(Address(rsp, 2 * wordSize), xmm7);
  4740     __ movdqu(Address(rsp, 2 * wordSize), xmm7);
  4773 #endif
  4741 #endif
  4774     __ fast_pow(x0, x1, x2, x3, x4, x5, x6, x7, rax, rcx, rdx, tmp1, tmp2, tmp3, tmp4);
  4742     __ fast_log10(x0, x1, x2, x3, x4, x5, x6, x7, rax, rcx, rdx, tmp);
  4775 
  4743 
  4776 #ifdef _WIN64
  4744 #ifdef _WIN64
  4777     // restore xmm regs belonging to calling function
  4745     // restore xmm regs belonging to calling function
  4778     __ movdqu(xmm6, Address(rsp, 0));
  4746     __ movdqu(xmm6, Address(rsp, 0));
  4779     __ movdqu(xmm7, Address(rsp, 2 * wordSize));
  4747     __ movdqu(xmm7, Address(rsp, 2 * wordSize));
  4785 
  4753 
  4786     return start;
  4754     return start;
  4787 
  4755 
  4788   }
  4756   }
  4789 
  4757 
  4790   address generate_libmSin() {
  4758   address generate_libmPow() {
  4791     address start = __ pc();
  4759     address start = __ pc();
  4792 
  4760 
  4793     const XMMRegister x0 = xmm0;
  4761     const XMMRegister x0 = xmm0;
  4794     const XMMRegister x1 = xmm1;
  4762     const XMMRegister x1 = xmm1;
  4795     const XMMRegister x2 = xmm2;
  4763     const XMMRegister x2 = xmm2;
  4812     // save the xmm registers which must be preserved 6-7
  4780     // save the xmm registers which must be preserved 6-7
  4813     __ subptr(rsp, 4 * wordSize);
  4781     __ subptr(rsp, 4 * wordSize);
  4814     __ movdqu(Address(rsp, 0), xmm6);
  4782     __ movdqu(Address(rsp, 0), xmm6);
  4815     __ movdqu(Address(rsp, 2 * wordSize), xmm7);
  4783     __ movdqu(Address(rsp, 2 * wordSize), xmm7);
  4816 #endif
  4784 #endif
  4817     __ fast_sin(x0, x1, x2, x3, x4, x5, x6, x7, rax, rbx, rcx, rdx, tmp1, tmp2, tmp3, tmp4);
  4785     __ fast_pow(x0, x1, x2, x3, x4, x5, x6, x7, rax, rcx, rdx, tmp1, tmp2, tmp3, tmp4);
  4818 
  4786 
  4819 #ifdef _WIN64
  4787 #ifdef _WIN64
  4820     // restore xmm regs belonging to calling function
  4788     // restore xmm regs belonging to calling function
  4821     __ movdqu(xmm6, Address(rsp, 0));
  4789     __ movdqu(xmm6, Address(rsp, 0));
  4822     __ movdqu(xmm7, Address(rsp, 2 * wordSize));
  4790     __ movdqu(xmm7, Address(rsp, 2 * wordSize));
  4828 
  4796 
  4829     return start;
  4797     return start;
  4830 
  4798 
  4831   }
  4799   }
  4832 
  4800 
  4833   address generate_libmCos() {
  4801   address generate_libmSin() {
  4834     address start = __ pc();
  4802     address start = __ pc();
  4835 
  4803 
  4836     const XMMRegister x0 = xmm0;
  4804     const XMMRegister x0 = xmm0;
  4837     const XMMRegister x1 = xmm1;
  4805     const XMMRegister x1 = xmm1;
  4838     const XMMRegister x2 = xmm2;
  4806     const XMMRegister x2 = xmm2;
  4850 
  4818 
  4851     BLOCK_COMMENT("Entry:");
  4819     BLOCK_COMMENT("Entry:");
  4852     __ enter(); // required for proper stackwalking of RuntimeStub frame
  4820     __ enter(); // required for proper stackwalking of RuntimeStub frame
  4853 
  4821 
  4854 #ifdef _WIN64
  4822 #ifdef _WIN64
       
  4823     __ push(rsi);
       
  4824     __ push(rdi);
  4855     // save the xmm registers which must be preserved 6-7
  4825     // save the xmm registers which must be preserved 6-7
  4856     __ subptr(rsp, 4 * wordSize);
  4826     __ subptr(rsp, 4 * wordSize);
  4857     __ movdqu(Address(rsp, 0), xmm6);
  4827     __ movdqu(Address(rsp, 0), xmm6);
  4858     __ movdqu(Address(rsp, 2 * wordSize), xmm7);
  4828     __ movdqu(Address(rsp, 2 * wordSize), xmm7);
  4859 #endif
  4829 #endif
  4860     __ fast_cos(x0, x1, x2, x3, x4, x5, x6, x7, rax, rcx, rdx, tmp1, tmp2, tmp3, tmp4);
  4830     __ fast_sin(x0, x1, x2, x3, x4, x5, x6, x7, rax, rbx, rcx, rdx, tmp1, tmp2, tmp3, tmp4);
  4861 
  4831 
  4862 #ifdef _WIN64
  4832 #ifdef _WIN64
  4863     // restore xmm regs belonging to calling function
  4833     // restore xmm regs belonging to calling function
  4864     __ movdqu(xmm6, Address(rsp, 0));
  4834     __ movdqu(xmm6, Address(rsp, 0));
  4865     __ movdqu(xmm7, Address(rsp, 2 * wordSize));
  4835     __ movdqu(xmm7, Address(rsp, 2 * wordSize));
  4866     __ addptr(rsp, 4 * wordSize);
  4836     __ addptr(rsp, 4 * wordSize);
       
  4837     __ pop(rdi);
       
  4838     __ pop(rsi);
       
  4839 #endif
       
  4840 
       
  4841     __ leave(); // required for proper stackwalking of RuntimeStub frame
       
  4842     __ ret(0);
       
  4843 
       
  4844     return start;
       
  4845 
       
  4846   }
       
  4847 
       
  4848   address generate_libmCos() {
       
  4849     address start = __ pc();
       
  4850 
       
  4851     const XMMRegister x0 = xmm0;
       
  4852     const XMMRegister x1 = xmm1;
       
  4853     const XMMRegister x2 = xmm2;
       
  4854     const XMMRegister x3 = xmm3;
       
  4855 
       
  4856     const XMMRegister x4 = xmm4;
       
  4857     const XMMRegister x5 = xmm5;
       
  4858     const XMMRegister x6 = xmm6;
       
  4859     const XMMRegister x7 = xmm7;
       
  4860 
       
  4861     const Register tmp1 = r8;
       
  4862     const Register tmp2 = r9;
       
  4863     const Register tmp3 = r10;
       
  4864     const Register tmp4 = r11;
       
  4865 
       
  4866     BLOCK_COMMENT("Entry:");
       
  4867     __ enter(); // required for proper stackwalking of RuntimeStub frame
       
  4868 
       
  4869 #ifdef _WIN64
       
  4870     __ push(rsi);
       
  4871     __ push(rdi);
       
  4872     // save the xmm registers which must be preserved 6-7
       
  4873     __ subptr(rsp, 4 * wordSize);
       
  4874     __ movdqu(Address(rsp, 0), xmm6);
       
  4875     __ movdqu(Address(rsp, 2 * wordSize), xmm7);
       
  4876 #endif
       
  4877     __ fast_cos(x0, x1, x2, x3, x4, x5, x6, x7, rax, rcx, rdx, tmp1, tmp2, tmp3, tmp4);
       
  4878 
       
  4879 #ifdef _WIN64
       
  4880     // restore xmm regs belonging to calling function
       
  4881     __ movdqu(xmm6, Address(rsp, 0));
       
  4882     __ movdqu(xmm7, Address(rsp, 2 * wordSize));
       
  4883     __ addptr(rsp, 4 * wordSize);
       
  4884     __ pop(rdi);
       
  4885     __ pop(rsi);
       
  4886 #endif
       
  4887 
       
  4888     __ leave(); // required for proper stackwalking of RuntimeStub frame
       
  4889     __ ret(0);
       
  4890 
       
  4891     return start;
       
  4892 
       
  4893   }
       
  4894 
       
  4895   address generate_libmTan() {
       
  4896     address start = __ pc();
       
  4897 
       
  4898     const XMMRegister x0 = xmm0;
       
  4899     const XMMRegister x1 = xmm1;
       
  4900     const XMMRegister x2 = xmm2;
       
  4901     const XMMRegister x3 = xmm3;
       
  4902 
       
  4903     const XMMRegister x4 = xmm4;
       
  4904     const XMMRegister x5 = xmm5;
       
  4905     const XMMRegister x6 = xmm6;
       
  4906     const XMMRegister x7 = xmm7;
       
  4907 
       
  4908     const Register tmp1 = r8;
       
  4909     const Register tmp2 = r9;
       
  4910     const Register tmp3 = r10;
       
  4911     const Register tmp4 = r11;
       
  4912 
       
  4913     BLOCK_COMMENT("Entry:");
       
  4914     __ enter(); // required for proper stackwalking of RuntimeStub frame
       
  4915 
       
  4916 #ifdef _WIN64
       
  4917     __ push(rsi);
       
  4918     __ push(rdi);
       
  4919     // save the xmm registers which must be preserved 6-7
       
  4920     __ subptr(rsp, 4 * wordSize);
       
  4921     __ movdqu(Address(rsp, 0), xmm6);
       
  4922     __ movdqu(Address(rsp, 2 * wordSize), xmm7);
       
  4923 #endif
       
  4924     __ fast_tan(x0, x1, x2, x3, x4, x5, x6, x7, rax, rcx, rdx, tmp1, tmp2, tmp3, tmp4);
       
  4925 
       
  4926 #ifdef _WIN64
       
  4927     // restore xmm regs belonging to calling function
       
  4928     __ movdqu(xmm6, Address(rsp, 0));
       
  4929     __ movdqu(xmm7, Address(rsp, 2 * wordSize));
       
  4930     __ addptr(rsp, 4 * wordSize);
       
  4931     __ pop(rdi);
       
  4932     __ pop(rsi);
  4867 #endif
  4933 #endif
  4868 
  4934 
  4869     __ leave(); // required for proper stackwalking of RuntimeStub frame
  4935     __ leave(); // required for proper stackwalking of RuntimeStub frame
  4870     __ ret(0);
  4936     __ ret(0);
  4871 
  4937 
  5062       bool supports_clmul = VM_Version::supports_clmul();
  5128       bool supports_clmul = VM_Version::supports_clmul();
  5063       StubRoutines::x86::generate_CRC32C_table(supports_clmul);
  5129       StubRoutines::x86::generate_CRC32C_table(supports_clmul);
  5064       StubRoutines::_crc32c_table_addr = (address)StubRoutines::x86::_crc32c_table;
  5130       StubRoutines::_crc32c_table_addr = (address)StubRoutines::x86::_crc32c_table;
  5065       StubRoutines::_updateBytesCRC32C = generate_updateBytesCRC32C(supports_clmul);
  5131       StubRoutines::_updateBytesCRC32C = generate_updateBytesCRC32C(supports_clmul);
  5066     }
  5132     }
  5067     if (VM_Version::supports_sse2()) {
  5133     if (VM_Version::supports_sse2() && UseLibmIntrinsic) {
       
  5134       StubRoutines::x86::_ONEHALF_adr = (address)StubRoutines::x86::_ONEHALF;
       
  5135       StubRoutines::x86::_P_2_adr = (address)StubRoutines::x86::_P_2;
       
  5136       StubRoutines::x86::_SC_4_adr = (address)StubRoutines::x86::_SC_4;
       
  5137       StubRoutines::x86::_Ctable_adr = (address)StubRoutines::x86::_Ctable;
       
  5138       StubRoutines::x86::_SC_2_adr = (address)StubRoutines::x86::_SC_2;
       
  5139       StubRoutines::x86::_SC_3_adr = (address)StubRoutines::x86::_SC_3;
       
  5140       StubRoutines::x86::_SC_1_adr = (address)StubRoutines::x86::_SC_1;
       
  5141       StubRoutines::x86::_PI_INV_TABLE_adr = (address)StubRoutines::x86::_PI_INV_TABLE;
       
  5142       StubRoutines::x86::_PI_4_adr = (address)StubRoutines::x86::_PI_4;
       
  5143       StubRoutines::x86::_PI32INV_adr = (address)StubRoutines::x86::_PI32INV;
       
  5144       StubRoutines::x86::_SIGN_MASK_adr = (address)StubRoutines::x86::_SIGN_MASK;
       
  5145       StubRoutines::x86::_P_1_adr = (address)StubRoutines::x86::_P_1;
       
  5146       StubRoutines::x86::_P_3_adr = (address)StubRoutines::x86::_P_3;
       
  5147       StubRoutines::x86::_NEG_ZERO_adr = (address)StubRoutines::x86::_NEG_ZERO;
  5068       StubRoutines::_dexp = generate_libmExp();
  5148       StubRoutines::_dexp = generate_libmExp();
  5069       StubRoutines::_dlog = generate_libmLog();
  5149       StubRoutines::_dlog = generate_libmLog();
       
  5150       StubRoutines::_dlog10 = generate_libmLog10();
  5070       StubRoutines::_dpow = generate_libmPow();
  5151       StubRoutines::_dpow = generate_libmPow();
  5071       if (UseLibmSinIntrinsic) {
  5152       StubRoutines::_dtan = generate_libmTan();
  5072         StubRoutines::_dsin = generate_libmSin();
  5153       StubRoutines::_dsin = generate_libmSin();
  5073       }
  5154       StubRoutines::_dcos = generate_libmCos();
  5074       if (UseLibmCosIntrinsic) {
       
  5075         StubRoutines::_dcos = generate_libmCos();
       
  5076       }
       
  5077     }
  5155     }
  5078   }
  5156   }
  5079 
  5157 
  5080   void generate_all() {
  5158   void generate_all() {
  5081     // Generates all stubs and initializes the entry points
  5159     // Generates all stubs and initializes the entry points
  5115     // support for verify_oop (must happen after universe_init)
  5193     // support for verify_oop (must happen after universe_init)
  5116     StubRoutines::_verify_oop_subroutine_entry = generate_verify_oop();
  5194     StubRoutines::_verify_oop_subroutine_entry = generate_verify_oop();
  5117 
  5195 
  5118     // arraycopy stubs used by compilers
  5196     // arraycopy stubs used by compilers
  5119     generate_arraycopy_stubs();
  5197     generate_arraycopy_stubs();
  5120 
       
  5121     generate_math_stubs();
       
  5122 
  5198 
  5123     // don't bother generating these AES intrinsic stubs unless global flag is set
  5199     // don't bother generating these AES intrinsic stubs unless global flag is set
  5124     if (UseAESIntrinsics) {
  5200     if (UseAESIntrinsics) {
  5125       StubRoutines::x86::_key_shuffle_mask_addr = generate_key_shuffle_mask();  // needed by the others
  5201       StubRoutines::x86::_key_shuffle_mask_addr = generate_key_shuffle_mask();  // needed by the others
  5126       StubRoutines::_aescrypt_encryptBlock = generate_aescrypt_encryptBlock();
  5202       StubRoutines::_aescrypt_encryptBlock = generate_aescrypt_encryptBlock();