comparison src/cpu/x86/vm/stubGenerator_x86_64.cpp @ 11173:6b0fd0964b87

Merge with http://hg.openjdk.java.net/hsx/hsx25/hotspot/
author Doug Simon <doug.simon@oracle.com>
date Wed, 31 Jul 2013 11:00:54 +0200
parents 40b8c383bc31 46a90f83df31
children 2d4df4c43ae2
comparison
equal deleted inserted replaced
10912:4ea54634f03e 11173:6b0fd0964b87
1 /* 1 /*
2 * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
79 79
80 class StubGenerator: public StubCodeGenerator { 80 class StubGenerator: public StubCodeGenerator {
81 private: 81 private:
82 82
83 #ifdef PRODUCT 83 #ifdef PRODUCT
84 #define inc_counter_np(counter) (0) 84 #define inc_counter_np(counter) ((void)0)
85 #else 85 #else
86 void inc_counter_np_(int& counter) { 86 void inc_counter_np_(int& counter) {
87 // This can destroy rscratch1 if counter is far from the code cache 87 // This can destroy rscratch1 if counter is far from the code cache
88 __ incrementl(ExternalAddress((address)&counter)); 88 __ incrementl(ExternalAddress((address)&counter));
89 } 89 }
277 { 277 {
278 Label skip_ldmx; 278 Label skip_ldmx;
279 __ stmxcsr(mxcsr_save); 279 __ stmxcsr(mxcsr_save);
280 __ movl(rax, mxcsr_save); 280 __ movl(rax, mxcsr_save);
281 __ andl(rax, MXCSR_MASK); // Only check control and mask bits 281 __ andl(rax, MXCSR_MASK); // Only check control and mask bits
282 ExternalAddress mxcsr_std(StubRoutines::x86::mxcsr_std()); 282 ExternalAddress mxcsr_std(StubRoutines::addr_mxcsr_std());
283 __ cmp32(rax, mxcsr_std); 283 __ cmp32(rax, mxcsr_std);
284 __ jcc(Assembler::equal, skip_ldmx); 284 __ jcc(Assembler::equal, skip_ldmx);
285 __ ldmxcsr(mxcsr_std); 285 __ ldmxcsr(mxcsr_std);
286 __ bind(skip_ldmx); 286 __ bind(skip_ldmx);
287 } 287 }
727 727
728 const Address mxcsr_save(rsp, 0); 728 const Address mxcsr_save(rsp, 0);
729 729
730 if (CheckJNICalls) { 730 if (CheckJNICalls) {
731 Label ok_ret; 731 Label ok_ret;
732 ExternalAddress mxcsr_std(StubRoutines::addr_mxcsr_std());
732 __ push(rax); 733 __ push(rax);
733 __ subptr(rsp, wordSize); // allocate a temp location 734 __ subptr(rsp, wordSize); // allocate a temp location
734 __ stmxcsr(mxcsr_save); 735 __ stmxcsr(mxcsr_save);
735 __ movl(rax, mxcsr_save); 736 __ movl(rax, mxcsr_save);
736 __ andl(rax, MXCSR_MASK); // Only check control and mask bits 737 __ andl(rax, MXCSR_MASK); // Only check control and mask bits
737 __ cmpl(rax, *(int *)(StubRoutines::x86::mxcsr_std())); 738 __ cmp32(rax, mxcsr_std);
738 __ jcc(Assembler::equal, ok_ret); 739 __ jcc(Assembler::equal, ok_ret);
739 740
740 __ warn("MXCSR changed by native JNI code, use -XX:+RestoreMXCSROnJNICall"); 741 __ warn("MXCSR changed by native JNI code, use -XX:+RestoreMXCSROnJNICall");
741 742
742 __ ldmxcsr(ExternalAddress(StubRoutines::x86::mxcsr_std())); 743 __ ldmxcsr(mxcsr_std);
743 744
744 __ bind(ok_ret); 745 __ bind(ok_ret);
745 __ addptr(rsp, wordSize); 746 __ addptr(rsp, wordSize);
746 __ pop(rax); 747 __ pop(rax);
747 } 748 }
3355 __ jmp(L_exit); 3356 __ jmp(L_exit);
3356 3357
3357 return start; 3358 return start;
3358 } 3359 }
3359 3360
3360 3361 // Safefetch stubs.
3362 void generate_safefetch(const char* name, int size, address* entry,
3363 address* fault_pc, address* continuation_pc) {
3364 // safefetch signatures:
3365 // int SafeFetch32(int* adr, int errValue);
3366 // intptr_t SafeFetchN (intptr_t* adr, intptr_t errValue);
3367 //
3368 // arguments:
3369 // c_rarg0 = adr
3370 // c_rarg1 = errValue
3371 //
3372 // result:
3373 // PPC_RET = *adr or errValue
3374
3375 StubCodeMark mark(this, "StubRoutines", name);
3376
3377 // Entry point, pc or function descriptor.
3378 *entry = __ pc();
3379
3380 // Load *adr into c_rarg1, may fault.
3381 *fault_pc = __ pc();
3382 switch (size) {
3383 case 4:
3384 // int32_t
3385 __ movl(c_rarg1, Address(c_rarg0, 0));
3386 break;
3387 case 8:
3388 // int64_t
3389 __ movq(c_rarg1, Address(c_rarg0, 0));
3390 break;
3391 default:
3392 ShouldNotReachHere();
3393 }
3394
3395 // return errValue or *adr
3396 *continuation_pc = __ pc();
3397 __ movq(rax, c_rarg1);
3398 __ ret(0);
3399 }
3361 3400
3362 // This is a version of CBC/AES Decrypt which does 4 blocks in a loop at a time 3401 // This is a version of CBC/AES Decrypt which does 4 blocks in a loop at a time
3363 // to hide instruction latency 3402 // to hide instruction latency
3364 // 3403 //
3365 // Arguments: 3404 // Arguments:
3582 __ jmp(L_exit); 3621 __ jmp(L_exit);
3583 3622
3584 return start; 3623 return start;
3585 } 3624 }
3586 3625
3587 3626 /**
3627 * Arguments:
3628 *
3629 * Inputs:
3630 * c_rarg0 - int crc
3631 * c_rarg1 - byte* buf
3632 * c_rarg2 - int length
3633 *
3634 * Ouput:
3635 * rax - int crc result
3636 */
3637 address generate_updateBytesCRC32() {
3638 assert(UseCRC32Intrinsics, "need AVX and CLMUL instructions");
3639
3640 __ align(CodeEntryAlignment);
3641 StubCodeMark mark(this, "StubRoutines", "updateBytesCRC32");
3642
3643 address start = __ pc();
3644 // Win64: rcx, rdx, r8, r9 (c_rarg0, c_rarg1, ...)
3645 // Unix: rdi, rsi, rdx, rcx, r8, r9 (c_rarg0, c_rarg1, ...)
3646 // rscratch1: r10
3647 const Register crc = c_rarg0; // crc
3648 const Register buf = c_rarg1; // source java byte array address
3649 const Register len = c_rarg2; // length
3650 const Register table = c_rarg3; // crc_table address (reuse register)
3651 const Register tmp = r11;
3652 assert_different_registers(crc, buf, len, table, tmp, rax);
3653
3654 BLOCK_COMMENT("Entry:");
3655 __ enter(); // required for proper stackwalking of RuntimeStub frame
3656
3657 __ kernel_crc32(crc, buf, len, table, tmp);
3658
3659 __ movl(rax, crc);
3660 __ leave(); // required for proper stackwalking of RuntimeStub frame
3661 __ ret(0);
3662
3663 return start;
3664 }
3588 3665
3589 #undef __ 3666 #undef __
3590 #define __ masm-> 3667 #define __ masm->
3591 3668
3592 // Continuation point for throwing of implicit exceptions that are 3669 // Continuation point for throwing of implicit exceptions that are
3689 (framesize >> (LogBytesPerWord - LogBytesPerInt)), 3766 (framesize >> (LogBytesPerWord - LogBytesPerInt)),
3690 oop_maps, false); 3767 oop_maps, false);
3691 return stub->entry_point(); 3768 return stub->entry_point();
3692 } 3769 }
3693 3770
3771 void create_control_words() {
3772 // Round to nearest, 53-bit mode, exceptions masked
3773 StubRoutines::_fpu_cntrl_wrd_std = 0x027F;
3774 // Round to zero, 53-bit mode, exception mased
3775 StubRoutines::_fpu_cntrl_wrd_trunc = 0x0D7F;
3776 // Round to nearest, 24-bit mode, exceptions masked
3777 StubRoutines::_fpu_cntrl_wrd_24 = 0x007F;
3778 // Round to nearest, 64-bit mode, exceptions masked
3779 StubRoutines::_fpu_cntrl_wrd_64 = 0x037F;
3780 // Round to nearest, 64-bit mode, exceptions masked
3781 StubRoutines::_mxcsr_std = 0x1F80;
3782 // Note: the following two constants are 80-bit values
3783 // layout is critical for correct loading by FPU.
3784 // Bias for strict fp multiply/divide
3785 StubRoutines::_fpu_subnormal_bias1[0]= 0x00000000; // 2^(-15360) == 0x03ff 8000 0000 0000 0000
3786 StubRoutines::_fpu_subnormal_bias1[1]= 0x80000000;
3787 StubRoutines::_fpu_subnormal_bias1[2]= 0x03ff;
3788 // Un-Bias for strict fp multiply/divide
3789 StubRoutines::_fpu_subnormal_bias2[0]= 0x00000000; // 2^(+15360) == 0x7bff 8000 0000 0000 0000
3790 StubRoutines::_fpu_subnormal_bias2[1]= 0x80000000;
3791 StubRoutines::_fpu_subnormal_bias2[2]= 0x7bff;
3792 }
3793
3694 // Initialization 3794 // Initialization
3695 void generate_initial() { 3795 void generate_initial() {
3696 // Generates all stubs and initializes the entry points 3796 // Generates all stubs and initializes the entry points
3697 3797
3698 // This platform-specific stub is needed by generate_call_stub() 3798 // This platform-specific settings are needed by generate_call_stub()
3699 StubRoutines::x86::_mxcsr_std = generate_fp_mask("mxcsr_std", 0x0000000000001F80); 3799 create_control_words();
3700 3800
3701 // entry points that exist in all platforms Note: This is code 3801 // entry points that exist in all platforms Note: This is code
3702 // that could be shared among different platforms - however the 3802 // that could be shared among different platforms - however the
3703 // benefit seems to be smaller than the disadvantage of having a 3803 // benefit seems to be smaller than the disadvantage of having a
3704 // much more complicated generator structure. See also comment in 3804 // much more complicated generator structure. See also comment in
3734 StubRoutines::_throw_StackOverflowError_entry = 3834 StubRoutines::_throw_StackOverflowError_entry =
3735 generate_throw_exception("StackOverflowError throw_exception", 3835 generate_throw_exception("StackOverflowError throw_exception",
3736 CAST_FROM_FN_PTR(address, 3836 CAST_FROM_FN_PTR(address,
3737 SharedRuntime:: 3837 SharedRuntime::
3738 throw_StackOverflowError)); 3838 throw_StackOverflowError));
3839 if (UseCRC32Intrinsics) {
3840 // set table address before stub generation which use it
3841 StubRoutines::_crc_table_adr = (address)StubRoutines::x86::_crc_table;
3842 StubRoutines::_updateBytesCRC32 = generate_updateBytesCRC32();
3843 }
3739 } 3844 }
3740 3845
3741 void generate_all() { 3846 void generate_all() {
3742 // Generates all stubs and initializes the entry points 3847 // Generates all stubs and initializes the entry points
3743 3848
3794 StubRoutines::_aescrypt_encryptBlock = generate_aescrypt_encryptBlock(); 3899 StubRoutines::_aescrypt_encryptBlock = generate_aescrypt_encryptBlock();
3795 StubRoutines::_aescrypt_decryptBlock = generate_aescrypt_decryptBlock(); 3900 StubRoutines::_aescrypt_decryptBlock = generate_aescrypt_decryptBlock();
3796 StubRoutines::_cipherBlockChaining_encryptAESCrypt = generate_cipherBlockChaining_encryptAESCrypt(); 3901 StubRoutines::_cipherBlockChaining_encryptAESCrypt = generate_cipherBlockChaining_encryptAESCrypt();
3797 StubRoutines::_cipherBlockChaining_decryptAESCrypt = generate_cipherBlockChaining_decryptAESCrypt_Parallel(); 3902 StubRoutines::_cipherBlockChaining_decryptAESCrypt = generate_cipherBlockChaining_decryptAESCrypt_Parallel();
3798 } 3903 }
3904
3905 // Safefetch stubs.
3906 generate_safefetch("SafeFetch32", sizeof(int), &StubRoutines::_safefetch32_entry,
3907 &StubRoutines::_safefetch32_fault_pc,
3908 &StubRoutines::_safefetch32_continuation_pc);
3909 generate_safefetch("SafeFetchN", sizeof(intptr_t), &StubRoutines::_safefetchN_entry,
3910 &StubRoutines::_safefetchN_fault_pc,
3911 &StubRoutines::_safefetchN_continuation_pc);
3799 } 3912 }
3800 3913
3801 public: 3914 public:
3802 StubGenerator(CodeBuffer* code, bool all) : StubCodeGenerator(code) { 3915 StubGenerator(CodeBuffer* code, bool all) : StubCodeGenerator(code) {
3803 if (all) { 3916 if (all) {