Mercurial > hg > graal-jvmci-8
diff 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 |
line wrap: on
line diff
--- a/src/cpu/x86/vm/stubGenerator_x86_64.cpp Tue Jul 30 13:03:28 2013 -0700 +++ b/src/cpu/x86/vm/stubGenerator_x86_64.cpp Wed Jul 31 11:00:54 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -81,7 +81,7 @@ private: #ifdef PRODUCT -#define inc_counter_np(counter) (0) +#define inc_counter_np(counter) ((void)0) #else void inc_counter_np_(int& counter) { // This can destroy rscratch1 if counter is far from the code cache @@ -279,7 +279,7 @@ __ stmxcsr(mxcsr_save); __ movl(rax, mxcsr_save); __ andl(rax, MXCSR_MASK); // Only check control and mask bits - ExternalAddress mxcsr_std(StubRoutines::x86::mxcsr_std()); + ExternalAddress mxcsr_std(StubRoutines::addr_mxcsr_std()); __ cmp32(rax, mxcsr_std); __ jcc(Assembler::equal, skip_ldmx); __ ldmxcsr(mxcsr_std); @@ -729,17 +729,18 @@ if (CheckJNICalls) { Label ok_ret; + ExternalAddress mxcsr_std(StubRoutines::addr_mxcsr_std()); __ push(rax); __ subptr(rsp, wordSize); // allocate a temp location __ stmxcsr(mxcsr_save); __ movl(rax, mxcsr_save); __ andl(rax, MXCSR_MASK); // Only check control and mask bits - __ cmpl(rax, *(int *)(StubRoutines::x86::mxcsr_std())); + __ cmp32(rax, mxcsr_std); __ jcc(Assembler::equal, ok_ret); __ warn("MXCSR changed by native JNI code, use -XX:+RestoreMXCSROnJNICall"); - __ ldmxcsr(ExternalAddress(StubRoutines::x86::mxcsr_std())); + __ ldmxcsr(mxcsr_std); __ bind(ok_ret); __ addptr(rsp, wordSize); @@ -3357,7 +3358,45 @@ return start; } - + // Safefetch stubs. + void generate_safefetch(const char* name, int size, address* entry, + address* fault_pc, address* continuation_pc) { + // safefetch signatures: + // int SafeFetch32(int* adr, int errValue); + // intptr_t SafeFetchN (intptr_t* adr, intptr_t errValue); + // + // arguments: + // c_rarg0 = adr + // c_rarg1 = errValue + // + // result: + // PPC_RET = *adr or errValue + + StubCodeMark mark(this, "StubRoutines", name); + + // Entry point, pc or function descriptor. + *entry = __ pc(); + + // Load *adr into c_rarg1, may fault. + *fault_pc = __ pc(); + switch (size) { + case 4: + // int32_t + __ movl(c_rarg1, Address(c_rarg0, 0)); + break; + case 8: + // int64_t + __ movq(c_rarg1, Address(c_rarg0, 0)); + break; + default: + ShouldNotReachHere(); + } + + // return errValue or *adr + *continuation_pc = __ pc(); + __ movq(rax, c_rarg1); + __ ret(0); + } // This is a version of CBC/AES Decrypt which does 4 blocks in a loop at a time // to hide instruction latency @@ -3584,7 +3623,45 @@ return start; } - + /** + * Arguments: + * + * Inputs: + * c_rarg0 - int crc + * c_rarg1 - byte* buf + * c_rarg2 - int length + * + * Ouput: + * rax - int crc result + */ + address generate_updateBytesCRC32() { + assert(UseCRC32Intrinsics, "need AVX and CLMUL instructions"); + + __ align(CodeEntryAlignment); + StubCodeMark mark(this, "StubRoutines", "updateBytesCRC32"); + + address start = __ pc(); + // Win64: rcx, rdx, r8, r9 (c_rarg0, c_rarg1, ...) + // Unix: rdi, rsi, rdx, rcx, r8, r9 (c_rarg0, c_rarg1, ...) + // rscratch1: r10 + const Register crc = c_rarg0; // crc + const Register buf = c_rarg1; // source java byte array address + const Register len = c_rarg2; // length + const Register table = c_rarg3; // crc_table address (reuse register) + const Register tmp = r11; + assert_different_registers(crc, buf, len, table, tmp, rax); + + BLOCK_COMMENT("Entry:"); + __ enter(); // required for proper stackwalking of RuntimeStub frame + + __ kernel_crc32(crc, buf, len, table, tmp); + + __ movl(rax, crc); + __ leave(); // required for proper stackwalking of RuntimeStub frame + __ ret(0); + + return start; + } #undef __ #define __ masm-> @@ -3691,12 +3768,35 @@ return stub->entry_point(); } + void create_control_words() { + // Round to nearest, 53-bit mode, exceptions masked + StubRoutines::_fpu_cntrl_wrd_std = 0x027F; + // Round to zero, 53-bit mode, exception mased + StubRoutines::_fpu_cntrl_wrd_trunc = 0x0D7F; + // Round to nearest, 24-bit mode, exceptions masked + StubRoutines::_fpu_cntrl_wrd_24 = 0x007F; + // Round to nearest, 64-bit mode, exceptions masked + StubRoutines::_fpu_cntrl_wrd_64 = 0x037F; + // Round to nearest, 64-bit mode, exceptions masked + StubRoutines::_mxcsr_std = 0x1F80; + // Note: the following two constants are 80-bit values + // layout is critical for correct loading by FPU. + // Bias for strict fp multiply/divide + StubRoutines::_fpu_subnormal_bias1[0]= 0x00000000; // 2^(-15360) == 0x03ff 8000 0000 0000 0000 + StubRoutines::_fpu_subnormal_bias1[1]= 0x80000000; + StubRoutines::_fpu_subnormal_bias1[2]= 0x03ff; + // Un-Bias for strict fp multiply/divide + StubRoutines::_fpu_subnormal_bias2[0]= 0x00000000; // 2^(+15360) == 0x7bff 8000 0000 0000 0000 + StubRoutines::_fpu_subnormal_bias2[1]= 0x80000000; + StubRoutines::_fpu_subnormal_bias2[2]= 0x7bff; + } + // Initialization void generate_initial() { // Generates all stubs and initializes the entry points - // This platform-specific stub is needed by generate_call_stub() - StubRoutines::x86::_mxcsr_std = generate_fp_mask("mxcsr_std", 0x0000000000001F80); + // This platform-specific settings are needed by generate_call_stub() + create_control_words(); // entry points that exist in all platforms Note: This is code // that could be shared among different platforms - however the @@ -3736,6 +3836,11 @@ CAST_FROM_FN_PTR(address, SharedRuntime:: throw_StackOverflowError)); + if (UseCRC32Intrinsics) { + // set table address before stub generation which use it + StubRoutines::_crc_table_adr = (address)StubRoutines::x86::_crc_table; + StubRoutines::_updateBytesCRC32 = generate_updateBytesCRC32(); + } } void generate_all() { @@ -3796,6 +3901,14 @@ StubRoutines::_cipherBlockChaining_encryptAESCrypt = generate_cipherBlockChaining_encryptAESCrypt(); StubRoutines::_cipherBlockChaining_decryptAESCrypt = generate_cipherBlockChaining_decryptAESCrypt_Parallel(); } + + // Safefetch stubs. + generate_safefetch("SafeFetch32", sizeof(int), &StubRoutines::_safefetch32_entry, + &StubRoutines::_safefetch32_fault_pc, + &StubRoutines::_safefetch32_continuation_pc); + generate_safefetch("SafeFetchN", sizeof(intptr_t), &StubRoutines::_safefetchN_entry, + &StubRoutines::_safefetchN_fault_pc, + &StubRoutines::_safefetchN_continuation_pc); } public: