1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/cpu/ppc/vm/macroAssembler_ppc.hpp Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,716 @@ 1.4 +/* 1.5 + * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright 2012, 2014 SAP AG. All rights reserved. 1.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 + * 1.9 + * This code is free software; you can redistribute it and/or modify it 1.10 + * under the terms of the GNU General Public License version 2 only, as 1.11 + * published by the Free Software Foundation. 1.12 + * 1.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.16 + * version 2 for more details (a copy is included in the LICENSE file that 1.17 + * accompanied this code). 1.18 + * 1.19 + * You should have received a copy of the GNU General Public License version 1.20 + * 2 along with this work; if not, write to the Free Software Foundation, 1.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.22 + * 1.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.24 + * or visit www.oracle.com if you need additional information or have any 1.25 + * questions. 1.26 + * 1.27 + */ 1.28 + 1.29 +#ifndef CPU_PPC_VM_MACROASSEMBLER_PPC_HPP 1.30 +#define CPU_PPC_VM_MACROASSEMBLER_PPC_HPP 1.31 + 1.32 +#include "asm/assembler.hpp" 1.33 + 1.34 +// MacroAssembler extends Assembler by a few frequently used macros. 1.35 + 1.36 +class ciTypeArray; 1.37 + 1.38 +class MacroAssembler: public Assembler { 1.39 + public: 1.40 + MacroAssembler(CodeBuffer* code) : Assembler(code) {} 1.41 + 1.42 + // 1.43 + // Optimized instruction emitters 1.44 + // 1.45 + 1.46 + inline static int largeoffset_si16_si16_hi(int si31) { return (si31 + (1<<15)) >> 16; } 1.47 + inline static int largeoffset_si16_si16_lo(int si31) { return si31 - (((si31 + (1<<15)) >> 16) << 16); } 1.48 + 1.49 + // load d = *[a+si31] 1.50 + // Emits several instructions if the offset is not encodable in one instruction. 1.51 + void ld_largeoffset_unchecked(Register d, int si31, Register a, int emit_filler_nop); 1.52 + void ld_largeoffset (Register d, int si31, Register a, int emit_filler_nop); 1.53 + inline static bool is_ld_largeoffset(address a); 1.54 + inline static int get_ld_largeoffset_offset(address a); 1.55 + 1.56 + inline void round_to(Register r, int modulus); 1.57 + 1.58 + // Load/store with type given by parameter. 1.59 + void load_sized_value( Register dst, RegisterOrConstant offs, Register base, size_t size_in_bytes, bool is_signed); 1.60 + void store_sized_value(Register dst, RegisterOrConstant offs, Register base, size_t size_in_bytes); 1.61 + 1.62 + // Move register if destination register and target register are different 1.63 + inline void mr_if_needed(Register rd, Register rs); 1.64 + inline void fmr_if_needed(FloatRegister rd, FloatRegister rs); 1.65 + // This is dedicated for emitting scheduled mach nodes. For better 1.66 + // readability of the ad file I put it here. 1.67 + // Endgroups are not needed if 1.68 + // - the scheduler is off 1.69 + // - the scheduler found that there is a natural group end, in that 1.70 + // case it reduced the size of the instruction used in the test 1.71 + // yielding 'needed'. 1.72 + inline void endgroup_if_needed(bool needed); 1.73 + 1.74 + // Memory barriers. 1.75 + inline void membar(int bits); 1.76 + inline void release(); 1.77 + inline void acquire(); 1.78 + inline void fence(); 1.79 + 1.80 + // nop padding 1.81 + void align(int modulus, int max = 252, int rem = 0); 1.82 + 1.83 + // 1.84 + // Constants, loading constants, TOC support 1.85 + // 1.86 + 1.87 + // Address of the global TOC. 1.88 + inline static address global_toc(); 1.89 + // Offset of given address to the global TOC. 1.90 + inline static int offset_to_global_toc(const address addr); 1.91 + 1.92 + // Address of TOC of the current method. 1.93 + inline address method_toc(); 1.94 + // Offset of given address to TOC of the current method. 1.95 + inline int offset_to_method_toc(const address addr); 1.96 + 1.97 + // Global TOC. 1.98 + void calculate_address_from_global_toc(Register dst, address addr, 1.99 + bool hi16 = true, bool lo16 = true, 1.100 + bool add_relocation = true, bool emit_dummy_addr = false); 1.101 + inline void calculate_address_from_global_toc_hi16only(Register dst, address addr) { 1.102 + calculate_address_from_global_toc(dst, addr, true, false); 1.103 + }; 1.104 + inline void calculate_address_from_global_toc_lo16only(Register dst, address addr) { 1.105 + calculate_address_from_global_toc(dst, addr, false, true); 1.106 + }; 1.107 + 1.108 + inline static bool is_calculate_address_from_global_toc_at(address a, address bound); 1.109 + static int patch_calculate_address_from_global_toc_at(address a, address addr, address bound); 1.110 + static address get_address_of_calculate_address_from_global_toc_at(address a, address addr); 1.111 + 1.112 +#ifdef _LP64 1.113 + // Patch narrow oop constant. 1.114 + inline static bool is_set_narrow_oop(address a, address bound); 1.115 + static int patch_set_narrow_oop(address a, address bound, narrowOop data); 1.116 + static narrowOop get_narrow_oop(address a, address bound); 1.117 +#endif 1.118 + 1.119 + inline static bool is_load_const_at(address a); 1.120 + 1.121 + // Emits an oop const to the constant pool, loads the constant, and 1.122 + // sets a relocation info with address current_pc. 1.123 + void load_const_from_method_toc(Register dst, AddressLiteral& a, Register toc); 1.124 + void load_toc_from_toc(Register dst, AddressLiteral& a, Register toc) { 1.125 + assert(dst == R2_TOC, "base register must be TOC"); 1.126 + load_const_from_method_toc(dst, a, toc); 1.127 + } 1.128 + 1.129 + static bool is_load_const_from_method_toc_at(address a); 1.130 + static int get_offset_of_load_const_from_method_toc_at(address a); 1.131 + 1.132 + // Get the 64 bit constant from a `load_const' sequence. 1.133 + static long get_const(address load_const); 1.134 + 1.135 + // Patch the 64 bit constant of a `load_const' sequence. This is a 1.136 + // low level procedure. It neither flushes the instruction cache nor 1.137 + // is it atomic. 1.138 + static void patch_const(address load_const, long x); 1.139 + 1.140 + // Metadata in code that we have to keep track of. 1.141 + AddressLiteral allocate_metadata_address(Metadata* obj); // allocate_index 1.142 + AddressLiteral constant_metadata_address(Metadata* obj); // find_index 1.143 + // Oops used directly in compiled code are stored in the constant pool, 1.144 + // and loaded from there. 1.145 + // Allocate new entry for oop in constant pool. Generate relocation. 1.146 + AddressLiteral allocate_oop_address(jobject obj); 1.147 + // Find oop obj in constant pool. Return relocation with it's index. 1.148 + AddressLiteral constant_oop_address(jobject obj); 1.149 + 1.150 + // Find oop in constant pool and emit instructions to load it. 1.151 + // Uses constant_oop_address. 1.152 + inline void set_oop_constant(jobject obj, Register d); 1.153 + // Same as load_address. 1.154 + inline void set_oop (AddressLiteral obj_addr, Register d); 1.155 + 1.156 + // Read runtime constant: Issue load if constant not yet established, 1.157 + // else use real constant. 1.158 + virtual RegisterOrConstant delayed_value_impl(intptr_t* delayed_value_addr, 1.159 + Register tmp, 1.160 + int offset); 1.161 + 1.162 + // 1.163 + // branch, jump 1.164 + // 1.165 + 1.166 + inline void pd_patch_instruction(address branch, address target); 1.167 + NOT_PRODUCT(static void pd_print_patched_instruction(address branch);) 1.168 + 1.169 + // Conditional far branch for destinations encodable in 24+2 bits. 1.170 + // Same interface as bc, e.g. no inverse boint-field. 1.171 + enum { 1.172 + bc_far_optimize_not = 0, 1.173 + bc_far_optimize_on_relocate = 1 1.174 + }; 1.175 + // optimize: flag for telling the conditional far branch to optimize 1.176 + // itself when relocated. 1.177 + void bc_far(int boint, int biint, Label& dest, int optimize); 1.178 + // Relocation of conditional far branches. 1.179 + static bool is_bc_far_at(address instruction_addr); 1.180 + static address get_dest_of_bc_far_at(address instruction_addr); 1.181 + static void set_dest_of_bc_far_at(address instruction_addr, address dest); 1.182 + private: 1.183 + static bool inline is_bc_far_variant1_at(address instruction_addr); 1.184 + static bool inline is_bc_far_variant2_at(address instruction_addr); 1.185 + static bool inline is_bc_far_variant3_at(address instruction_addr); 1.186 + public: 1.187 + 1.188 + // Convenience bc_far versions. 1.189 + inline void blt_far(ConditionRegister crx, Label& L, int optimize); 1.190 + inline void bgt_far(ConditionRegister crx, Label& L, int optimize); 1.191 + inline void beq_far(ConditionRegister crx, Label& L, int optimize); 1.192 + inline void bso_far(ConditionRegister crx, Label& L, int optimize); 1.193 + inline void bge_far(ConditionRegister crx, Label& L, int optimize); 1.194 + inline void ble_far(ConditionRegister crx, Label& L, int optimize); 1.195 + inline void bne_far(ConditionRegister crx, Label& L, int optimize); 1.196 + inline void bns_far(ConditionRegister crx, Label& L, int optimize); 1.197 + 1.198 + // Emit, identify and patch a NOT mt-safe patchable 64 bit absolute call/jump. 1.199 + private: 1.200 + enum { 1.201 + bxx64_patchable_instruction_count = (2/*load_codecache_const*/ + 3/*5load_const*/ + 1/*mtctr*/ + 1/*bctrl*/), 1.202 + bxx64_patchable_size = bxx64_patchable_instruction_count * BytesPerInstWord, 1.203 + bxx64_patchable_ret_addr_offset = bxx64_patchable_size 1.204 + }; 1.205 + void bxx64_patchable(address target, relocInfo::relocType rt, bool link); 1.206 + static bool is_bxx64_patchable_at( address instruction_addr, bool link); 1.207 + // Does the instruction use a pc-relative encoding of the destination? 1.208 + static bool is_bxx64_patchable_pcrelative_at( address instruction_addr, bool link); 1.209 + static bool is_bxx64_patchable_variant1_at( address instruction_addr, bool link); 1.210 + // Load destination relative to global toc. 1.211 + static bool is_bxx64_patchable_variant1b_at( address instruction_addr, bool link); 1.212 + static bool is_bxx64_patchable_variant2_at( address instruction_addr, bool link); 1.213 + static void set_dest_of_bxx64_patchable_at( address instruction_addr, address target, bool link); 1.214 + static address get_dest_of_bxx64_patchable_at(address instruction_addr, bool link); 1.215 + 1.216 + public: 1.217 + // call 1.218 + enum { 1.219 + bl64_patchable_instruction_count = bxx64_patchable_instruction_count, 1.220 + bl64_patchable_size = bxx64_patchable_size, 1.221 + bl64_patchable_ret_addr_offset = bxx64_patchable_ret_addr_offset 1.222 + }; 1.223 + inline void bl64_patchable(address target, relocInfo::relocType rt) { 1.224 + bxx64_patchable(target, rt, /*link=*/true); 1.225 + } 1.226 + inline static bool is_bl64_patchable_at(address instruction_addr) { 1.227 + return is_bxx64_patchable_at(instruction_addr, /*link=*/true); 1.228 + } 1.229 + inline static bool is_bl64_patchable_pcrelative_at(address instruction_addr) { 1.230 + return is_bxx64_patchable_pcrelative_at(instruction_addr, /*link=*/true); 1.231 + } 1.232 + inline static void set_dest_of_bl64_patchable_at(address instruction_addr, address target) { 1.233 + set_dest_of_bxx64_patchable_at(instruction_addr, target, /*link=*/true); 1.234 + } 1.235 + inline static address get_dest_of_bl64_patchable_at(address instruction_addr) { 1.236 + return get_dest_of_bxx64_patchable_at(instruction_addr, /*link=*/true); 1.237 + } 1.238 + // jump 1.239 + enum { 1.240 + b64_patchable_instruction_count = bxx64_patchable_instruction_count, 1.241 + b64_patchable_size = bxx64_patchable_size, 1.242 + }; 1.243 + inline void b64_patchable(address target, relocInfo::relocType rt) { 1.244 + bxx64_patchable(target, rt, /*link=*/false); 1.245 + } 1.246 + inline static bool is_b64_patchable_at(address instruction_addr) { 1.247 + return is_bxx64_patchable_at(instruction_addr, /*link=*/false); 1.248 + } 1.249 + inline static bool is_b64_patchable_pcrelative_at(address instruction_addr) { 1.250 + return is_bxx64_patchable_pcrelative_at(instruction_addr, /*link=*/false); 1.251 + } 1.252 + inline static void set_dest_of_b64_patchable_at(address instruction_addr, address target) { 1.253 + set_dest_of_bxx64_patchable_at(instruction_addr, target, /*link=*/false); 1.254 + } 1.255 + inline static address get_dest_of_b64_patchable_at(address instruction_addr) { 1.256 + return get_dest_of_bxx64_patchable_at(instruction_addr, /*link=*/false); 1.257 + } 1.258 + 1.259 + // 1.260 + // Support for frame handling 1.261 + // 1.262 + 1.263 + // some ABI-related functions 1.264 + void save_nonvolatile_gprs( Register dst_base, int offset); 1.265 + void restore_nonvolatile_gprs(Register src_base, int offset); 1.266 + void save_volatile_gprs( Register dst_base, int offset); 1.267 + void restore_volatile_gprs(Register src_base, int offset); 1.268 + void save_LR_CR( Register tmp); // tmp contains LR on return. 1.269 + void restore_LR_CR(Register tmp); 1.270 + 1.271 + // Get current PC using bl-next-instruction trick. 1.272 + address get_PC_trash_LR(Register result); 1.273 + 1.274 + // Resize current frame either relatively wrt to current SP or absolute. 1.275 + void resize_frame(Register offset, Register tmp); 1.276 + void resize_frame(int offset, Register tmp); 1.277 + void resize_frame_absolute(Register addr, Register tmp1, Register tmp2); 1.278 + 1.279 + // Push a frame of size bytes. 1.280 + void push_frame(Register bytes, Register tmp); 1.281 + 1.282 + // Push a frame of size `bytes'. No abi space provided. 1.283 + void push_frame(unsigned int bytes, Register tmp); 1.284 + 1.285 + // Push a frame of size `bytes' plus abi_reg_args on top. 1.286 + void push_frame_reg_args(unsigned int bytes, Register tmp); 1.287 + 1.288 + // Setup up a new C frame with a spill area for non-volatile GPRs and additional 1.289 + // space for local variables 1.290 + void push_frame_reg_args_nonvolatiles(unsigned int bytes, Register tmp); 1.291 + 1.292 + // pop current C frame 1.293 + void pop_frame(); 1.294 + 1.295 + // 1.296 + // Calls 1.297 + // 1.298 + 1.299 + private: 1.300 + address _last_calls_return_pc; 1.301 + 1.302 +#if defined(ABI_ELFv2) 1.303 + // Generic version of a call to C function. 1.304 + // Updates and returns _last_calls_return_pc. 1.305 + address branch_to(Register function_entry, bool and_link); 1.306 +#else 1.307 + // Generic version of a call to C function via a function descriptor 1.308 + // with variable support for C calling conventions (TOC, ENV, etc.). 1.309 + // updates and returns _last_calls_return_pc. 1.310 + address branch_to(Register function_descriptor, bool and_link, bool save_toc_before_call, 1.311 + bool restore_toc_after_call, bool load_toc_of_callee, bool load_env_of_callee); 1.312 +#endif 1.313 + 1.314 + public: 1.315 + 1.316 + // Get the pc where the last call will return to. returns _last_calls_return_pc. 1.317 + inline address last_calls_return_pc(); 1.318 + 1.319 +#if defined(ABI_ELFv2) 1.320 + // Call a C function via a function descriptor and use full C 1.321 + // calling conventions. Updates and returns _last_calls_return_pc. 1.322 + address call_c(Register function_entry); 1.323 + // For tail calls: only branch, don't link, so callee returns to caller of this function. 1.324 + address call_c_and_return_to_caller(Register function_entry); 1.325 + address call_c(address function_entry, relocInfo::relocType rt); 1.326 +#else 1.327 + // Call a C function via a function descriptor and use full C 1.328 + // calling conventions. Updates and returns _last_calls_return_pc. 1.329 + address call_c(Register function_descriptor); 1.330 + // For tail calls: only branch, don't link, so callee returns to caller of this function. 1.331 + address call_c_and_return_to_caller(Register function_descriptor); 1.332 + address call_c(const FunctionDescriptor* function_descriptor, relocInfo::relocType rt); 1.333 + address call_c_using_toc(const FunctionDescriptor* function_descriptor, relocInfo::relocType rt, 1.334 + Register toc); 1.335 +#endif 1.336 + 1.337 + protected: 1.338 + 1.339 + // It is imperative that all calls into the VM are handled via the 1.340 + // call_VM macros. They make sure that the stack linkage is setup 1.341 + // correctly. call_VM's correspond to ENTRY/ENTRY_X entry points 1.342 + // while call_VM_leaf's correspond to LEAF entry points. 1.343 + // 1.344 + // This is the base routine called by the different versions of 1.345 + // call_VM. The interpreter may customize this version by overriding 1.346 + // it for its purposes (e.g., to save/restore additional registers 1.347 + // when doing a VM call). 1.348 + // 1.349 + // If no last_java_sp is specified (noreg) then SP will be used instead. 1.350 + virtual void call_VM_base( 1.351 + // where an oop-result ends up if any; use noreg otherwise 1.352 + Register oop_result, 1.353 + // to set up last_Java_frame in stubs; use noreg otherwise 1.354 + Register last_java_sp, 1.355 + // the entry point 1.356 + address entry_point, 1.357 + // flag which indicates if exception should be checked 1.358 + bool check_exception = true 1.359 + ); 1.360 + 1.361 + // Support for VM calls. This is the base routine called by the 1.362 + // different versions of call_VM_leaf. The interpreter may customize 1.363 + // this version by overriding it for its purposes (e.g., to 1.364 + // save/restore additional registers when doing a VM call). 1.365 + void call_VM_leaf_base(address entry_point); 1.366 + 1.367 + public: 1.368 + // Call into the VM. 1.369 + // Passes the thread pointer (in R3_ARG1) as a prepended argument. 1.370 + // Makes sure oop return values are visible to the GC. 1.371 + void call_VM(Register oop_result, address entry_point, bool check_exceptions = true); 1.372 + void call_VM(Register oop_result, address entry_point, Register arg_1, bool check_exceptions = true); 1.373 + void call_VM(Register oop_result, address entry_point, Register arg_1, Register arg_2, bool check_exceptions = true); 1.374 + void call_VM_leaf(address entry_point); 1.375 + void call_VM_leaf(address entry_point, Register arg_1); 1.376 + void call_VM_leaf(address entry_point, Register arg_1, Register arg_2); 1.377 + void call_VM_leaf(address entry_point, Register arg_1, Register arg_2, Register arg_3); 1.378 + 1.379 + // Call a stub function via a function descriptor, but don't save 1.380 + // TOC before call, don't setup TOC and ENV for call, and don't 1.381 + // restore TOC after call. Updates and returns _last_calls_return_pc. 1.382 + inline address call_stub(Register function_entry); 1.383 + inline void call_stub_and_return_to(Register function_entry, Register return_pc); 1.384 + 1.385 + // 1.386 + // Java utilities 1.387 + // 1.388 + 1.389 + // Read from the polling page, its address is already in a register. 1.390 + inline void load_from_polling_page(Register polling_page_address, int offset = 0); 1.391 + // Check whether instruction is a read access to the polling page 1.392 + // which was emitted by load_from_polling_page(..). 1.393 + static bool is_load_from_polling_page(int instruction, void* ucontext/*may be NULL*/, 1.394 + address* polling_address_ptr = NULL); 1.395 + 1.396 + // Check whether instruction is a write access to the memory 1.397 + // serialization page realized by one of the instructions stw, stwu, 1.398 + // stwx, or stwux. 1.399 + static bool is_memory_serialization(int instruction, JavaThread* thread, void* ucontext); 1.400 + 1.401 + // Support for NULL-checks 1.402 + // 1.403 + // Generates code that causes a NULL OS exception if the content of reg is NULL. 1.404 + // If the accessed location is M[reg + offset] and the offset is known, provide the 1.405 + // offset. No explicit code generation is needed if the offset is within a certain 1.406 + // range (0 <= offset <= page_size). 1.407 + 1.408 + // Stack overflow checking 1.409 + void bang_stack_with_offset(int offset); 1.410 + 1.411 + // If instruction is a stack bang of the form ld, stdu, or 1.412 + // stdux, return the banged address. Otherwise, return 0. 1.413 + static address get_stack_bang_address(int instruction, void* ucontext); 1.414 + 1.415 + // Atomics 1.416 + // CmpxchgX sets condition register to cmpX(current, compare). 1.417 + // (flag == ne) => (dest_current_value != compare_value), (!swapped) 1.418 + // (flag == eq) => (dest_current_value == compare_value), ( swapped) 1.419 + static inline bool cmpxchgx_hint_acquire_lock() { return true; } 1.420 + // The stxcx will probably not be succeeded by a releasing store. 1.421 + static inline bool cmpxchgx_hint_release_lock() { return false; } 1.422 + static inline bool cmpxchgx_hint_atomic_update() { return false; } 1.423 + 1.424 + // Cmpxchg semantics 1.425 + enum { 1.426 + MemBarNone = 0, 1.427 + MemBarRel = 1, 1.428 + MemBarAcq = 2, 1.429 + MemBarFenceAfter = 4 // use powers of 2 1.430 + }; 1.431 + void cmpxchgw(ConditionRegister flag, 1.432 + Register dest_current_value, Register compare_value, Register exchange_value, Register addr_base, 1.433 + int semantics, bool cmpxchgx_hint = false, 1.434 + Register int_flag_success = noreg, bool contention_hint = false); 1.435 + void cmpxchgd(ConditionRegister flag, 1.436 + Register dest_current_value, Register compare_value, Register exchange_value, Register addr_base, 1.437 + int semantics, bool cmpxchgx_hint = false, 1.438 + Register int_flag_success = noreg, Label* failed = NULL, bool contention_hint = false); 1.439 + 1.440 + // interface method calling 1.441 + void lookup_interface_method(Register recv_klass, 1.442 + Register intf_klass, 1.443 + RegisterOrConstant itable_index, 1.444 + Register method_result, 1.445 + Register temp_reg, Register temp2_reg, 1.446 + Label& no_such_interface); 1.447 + 1.448 + // virtual method calling 1.449 + void lookup_virtual_method(Register recv_klass, 1.450 + RegisterOrConstant vtable_index, 1.451 + Register method_result); 1.452 + 1.453 + // Test sub_klass against super_klass, with fast and slow paths. 1.454 + 1.455 + // The fast path produces a tri-state answer: yes / no / maybe-slow. 1.456 + // One of the three labels can be NULL, meaning take the fall-through. 1.457 + // If super_check_offset is -1, the value is loaded up from super_klass. 1.458 + // No registers are killed, except temp_reg and temp2_reg. 1.459 + // If super_check_offset is not -1, temp2_reg is not used and can be noreg. 1.460 + void check_klass_subtype_fast_path(Register sub_klass, 1.461 + Register super_klass, 1.462 + Register temp1_reg, 1.463 + Register temp2_reg, 1.464 + Label& L_success, 1.465 + Label& L_failure); 1.466 + 1.467 + // The rest of the type check; must be wired to a corresponding fast path. 1.468 + // It does not repeat the fast path logic, so don't use it standalone. 1.469 + // The temp_reg can be noreg, if no temps are available. 1.470 + // It can also be sub_klass or super_klass, meaning it's OK to kill that one. 1.471 + // Updates the sub's secondary super cache as necessary. 1.472 + void check_klass_subtype_slow_path(Register sub_klass, 1.473 + Register super_klass, 1.474 + Register temp1_reg, 1.475 + Register temp2_reg, 1.476 + Label* L_success = NULL, 1.477 + Register result_reg = noreg); 1.478 + 1.479 + // Simplified, combined version, good for typical uses. 1.480 + // Falls through on failure. 1.481 + void check_klass_subtype(Register sub_klass, 1.482 + Register super_klass, 1.483 + Register temp1_reg, 1.484 + Register temp2_reg, 1.485 + Label& L_success); 1.486 + 1.487 + // Method handle support (JSR 292). 1.488 + void check_method_handle_type(Register mtype_reg, Register mh_reg, Register temp_reg, Label& wrong_method_type); 1.489 + 1.490 + RegisterOrConstant argument_offset(RegisterOrConstant arg_slot, Register temp_reg, int extra_slot_offset = 0); 1.491 + 1.492 + // Biased locking support 1.493 + // Upon entry,obj_reg must contain the target object, and mark_reg 1.494 + // must contain the target object's header. 1.495 + // Destroys mark_reg if an attempt is made to bias an anonymously 1.496 + // biased lock. In this case a failure will go either to the slow 1.497 + // case or fall through with the notEqual condition code set with 1.498 + // the expectation that the slow case in the runtime will be called. 1.499 + // In the fall-through case where the CAS-based lock is done, 1.500 + // mark_reg is not destroyed. 1.501 + void biased_locking_enter(ConditionRegister cr_reg, Register obj_reg, Register mark_reg, Register temp_reg, 1.502 + Register temp2_reg, Label& done, Label* slow_case = NULL); 1.503 + // Upon entry, the base register of mark_addr must contain the oop. 1.504 + // Destroys temp_reg. 1.505 + // If allow_delay_slot_filling is set to true, the next instruction 1.506 + // emitted after this one will go in an annulled delay slot if the 1.507 + // biased locking exit case failed. 1.508 + void biased_locking_exit(ConditionRegister cr_reg, Register mark_addr, Register temp_reg, Label& done); 1.509 + 1.510 + void compiler_fast_lock_object( ConditionRegister flag, Register oop, Register box, Register tmp1, Register tmp2, Register tmp3); 1.511 + void compiler_fast_unlock_object(ConditionRegister flag, Register oop, Register box, Register tmp1, Register tmp2, Register tmp3); 1.512 + 1.513 + // Support for serializing memory accesses between threads 1.514 + void serialize_memory(Register thread, Register tmp1, Register tmp2); 1.515 + 1.516 + // GC barrier support. 1.517 + void card_write_barrier_post(Register Rstore_addr, Register Rnew_val, Register Rtmp); 1.518 + void card_table_write(jbyte* byte_map_base, Register Rtmp, Register Robj); 1.519 + 1.520 +#if INCLUDE_ALL_GCS 1.521 + // General G1 pre-barrier generator. 1.522 + void g1_write_barrier_pre(Register Robj, RegisterOrConstant offset, Register Rpre_val, 1.523 + Register Rtmp1, Register Rtmp2, bool needs_frame = false); 1.524 + // General G1 post-barrier generator 1.525 + void g1_write_barrier_post(Register Rstore_addr, Register Rnew_val, Register Rtmp1, 1.526 + Register Rtmp2, Register Rtmp3, Label *filtered_ext = NULL); 1.527 +#endif 1.528 + 1.529 + // Support for managing the JavaThread pointer (i.e.; the reference to 1.530 + // thread-local information). 1.531 + 1.532 + // Support for last Java frame (but use call_VM instead where possible): 1.533 + // access R16_thread->last_Java_sp. 1.534 + void set_last_Java_frame(Register last_java_sp, Register last_Java_pc); 1.535 + void reset_last_Java_frame(void); 1.536 + void set_top_ijava_frame_at_SP_as_last_Java_frame(Register sp, Register tmp1); 1.537 + 1.538 + // Read vm result from thread: oop_result = R16_thread->result; 1.539 + void get_vm_result (Register oop_result); 1.540 + void get_vm_result_2(Register metadata_result); 1.541 + 1.542 + static bool needs_explicit_null_check(intptr_t offset); 1.543 + 1.544 + // Trap-instruction-based checks. 1.545 + // Range checks can be distinguished from zero checks as they check 32 bit, 1.546 + // zero checks all 64 bits (tw, td). 1.547 + inline void trap_null_check(Register a, trap_to_bits cmp = traptoEqual); 1.548 + static bool is_trap_null_check(int x) { 1.549 + return is_tdi(x, traptoEqual, -1/*any reg*/, 0) || 1.550 + is_tdi(x, traptoGreaterThanUnsigned, -1/*any reg*/, 0); 1.551 + } 1.552 + 1.553 + inline void trap_zombie_not_entrant(); 1.554 + static bool is_trap_zombie_not_entrant(int x) { return is_tdi(x, traptoUnconditional, 0/*reg 0*/, 1); } 1.555 + 1.556 + inline void trap_should_not_reach_here(); 1.557 + static bool is_trap_should_not_reach_here(int x) { return is_tdi(x, traptoUnconditional, 0/*reg 0*/, 2); } 1.558 + 1.559 + inline void trap_ic_miss_check(Register a, Register b); 1.560 + static bool is_trap_ic_miss_check(int x) { 1.561 + return is_td(x, traptoGreaterThanUnsigned | traptoLessThanUnsigned, -1/*any reg*/, -1/*any reg*/); 1.562 + } 1.563 + 1.564 + // Implicit or explicit null check, jumps to static address exception_entry. 1.565 + inline void null_check_throw(Register a, int offset, Register temp_reg, address exception_entry); 1.566 + 1.567 + // Check accessed object for null. Use SIGTRAP-based null checks on AIX. 1.568 + inline void load_with_trap_null_check(Register d, int si16, Register s1); 1.569 + 1.570 + // Load heap oop and decompress. Loaded oop may not be null. 1.571 + inline void load_heap_oop_not_null(Register d, RegisterOrConstant offs, Register s1 = noreg); 1.572 + inline void store_heap_oop_not_null(Register d, RegisterOrConstant offs, Register s1, 1.573 + /*specify if d must stay uncompressed*/ Register tmp = noreg); 1.574 + 1.575 + // Null allowed. 1.576 + inline void load_heap_oop(Register d, RegisterOrConstant offs, Register s1 = noreg); 1.577 + 1.578 + // Encode/decode heap oop. Oop may not be null, else en/decoding goes wrong. 1.579 + inline Register encode_heap_oop_not_null(Register d, Register src = noreg); 1.580 + inline void decode_heap_oop_not_null(Register d); 1.581 + 1.582 + // Null allowed. 1.583 + inline void decode_heap_oop(Register d); 1.584 + 1.585 + // Load/Store klass oop from klass field. Compress. 1.586 + void load_klass(Register dst, Register src); 1.587 + void load_klass_with_trap_null_check(Register dst, Register src); 1.588 + void store_klass(Register dst_oop, Register klass, Register tmp = R0); 1.589 + void store_klass_gap(Register dst_oop, Register val = noreg); // Will store 0 if val not specified. 1.590 + static int instr_size_for_decode_klass_not_null(); 1.591 + void decode_klass_not_null(Register dst, Register src = noreg); 1.592 + void encode_klass_not_null(Register dst, Register src = noreg); 1.593 + 1.594 + // Load common heap base into register. 1.595 + void reinit_heapbase(Register d, Register tmp = noreg); 1.596 + 1.597 + // SIGTRAP-based range checks for arrays. 1.598 + inline void trap_range_check_l(Register a, Register b); 1.599 + inline void trap_range_check_l(Register a, int si16); 1.600 + static bool is_trap_range_check_l(int x) { 1.601 + return (is_tw (x, traptoLessThanUnsigned, -1/*any reg*/, -1/*any reg*/) || 1.602 + is_twi(x, traptoLessThanUnsigned, -1/*any reg*/) ); 1.603 + } 1.604 + inline void trap_range_check_le(Register a, int si16); 1.605 + static bool is_trap_range_check_le(int x) { 1.606 + return is_twi(x, traptoEqual | traptoLessThanUnsigned, -1/*any reg*/); 1.607 + } 1.608 + inline void trap_range_check_g(Register a, int si16); 1.609 + static bool is_trap_range_check_g(int x) { 1.610 + return is_twi(x, traptoGreaterThanUnsigned, -1/*any reg*/); 1.611 + } 1.612 + inline void trap_range_check_ge(Register a, Register b); 1.613 + inline void trap_range_check_ge(Register a, int si16); 1.614 + static bool is_trap_range_check_ge(int x) { 1.615 + return (is_tw (x, traptoEqual | traptoGreaterThanUnsigned, -1/*any reg*/, -1/*any reg*/) || 1.616 + is_twi(x, traptoEqual | traptoGreaterThanUnsigned, -1/*any reg*/) ); 1.617 + } 1.618 + static bool is_trap_range_check(int x) { 1.619 + return is_trap_range_check_l(x) || is_trap_range_check_le(x) || 1.620 + is_trap_range_check_g(x) || is_trap_range_check_ge(x); 1.621 + } 1.622 + 1.623 + void clear_memory_doubleword(Register base_ptr, Register cnt_dwords, Register tmp = R0); 1.624 + 1.625 + // Needle of length 1. 1.626 + void string_indexof_1(Register result, Register haystack, Register haycnt, 1.627 + Register needle, jchar needleChar, 1.628 + Register tmp1, Register tmp2); 1.629 + // General indexof, eventually with constant needle length. 1.630 + void string_indexof(Register result, Register haystack, Register haycnt, 1.631 + Register needle, ciTypeArray* needle_values, Register needlecnt, int needlecntval, 1.632 + Register tmp1, Register tmp2, Register tmp3, Register tmp4); 1.633 + void string_compare(Register str1_reg, Register str2_reg, Register cnt1_reg, Register cnt2_reg, 1.634 + Register result_reg, Register tmp_reg); 1.635 + void char_arrays_equals(Register str1_reg, Register str2_reg, Register cnt_reg, Register result_reg, 1.636 + Register tmp1_reg, Register tmp2_reg, Register tmp3_reg, Register tmp4_reg, 1.637 + Register tmp5_reg); 1.638 + void char_arrays_equalsImm(Register str1_reg, Register str2_reg, int cntval, Register result_reg, 1.639 + Register tmp1_reg, Register tmp2_reg); 1.640 + 1.641 + // 1.642 + // Debugging 1.643 + // 1.644 + 1.645 + // assert on cr0 1.646 + void asm_assert(bool check_equal, const char* msg, int id); 1.647 + void asm_assert_eq(const char* msg, int id) { asm_assert(true, msg, id); } 1.648 + void asm_assert_ne(const char* msg, int id) { asm_assert(false, msg, id); } 1.649 + 1.650 + private: 1.651 + void asm_assert_mems_zero(bool check_equal, int size, int mem_offset, Register mem_base, 1.652 + const char* msg, int id); 1.653 + 1.654 + public: 1.655 + 1.656 + void asm_assert_mem8_is_zero(int mem_offset, Register mem_base, const char* msg, int id) { 1.657 + asm_assert_mems_zero(true, 8, mem_offset, mem_base, msg, id); 1.658 + } 1.659 + void asm_assert_mem8_isnot_zero(int mem_offset, Register mem_base, const char* msg, int id) { 1.660 + asm_assert_mems_zero(false, 8, mem_offset, mem_base, msg, id); 1.661 + } 1.662 + 1.663 + // Verify R16_thread contents. 1.664 + void verify_thread(); 1.665 + 1.666 + // Emit code to verify that reg contains a valid oop if +VerifyOops is set. 1.667 + void verify_oop(Register reg, const char* s = "broken oop"); 1.668 + 1.669 + // TODO: verify method and klass metadata (compare against vptr?) 1.670 + void _verify_method_ptr(Register reg, const char * msg, const char * file, int line) {} 1.671 + void _verify_klass_ptr(Register reg, const char * msg, const char * file, int line) {} 1.672 + 1.673 + // Convenience method returning function entry. For the ELFv1 case 1.674 + // creates function descriptor at the current address and returs 1.675 + // the pointer to it. For the ELFv2 case returns the current address. 1.676 + inline address function_entry(); 1.677 + 1.678 +#define verify_method_ptr(reg) _verify_method_ptr(reg, "broken method " #reg, __FILE__, __LINE__) 1.679 +#define verify_klass_ptr(reg) _verify_klass_ptr(reg, "broken klass " #reg, __FILE__, __LINE__) 1.680 + 1.681 + private: 1.682 + 1.683 + enum { 1.684 + stop_stop = 0, 1.685 + stop_untested = 1, 1.686 + stop_unimplemented = 2, 1.687 + stop_shouldnotreachhere = 3, 1.688 + stop_end = 4 1.689 + }; 1.690 + void stop(int type, const char* msg, int id); 1.691 + 1.692 + public: 1.693 + // Prints msg, dumps registers and stops execution. 1.694 + void stop (const char* msg = "", int id = 0) { stop(stop_stop, msg, id); } 1.695 + void untested (const char* msg = "", int id = 0) { stop(stop_untested, msg, id); } 1.696 + void unimplemented(const char* msg = "", int id = 0) { stop(stop_unimplemented, msg, id); } 1.697 + void should_not_reach_here() { stop(stop_shouldnotreachhere, "", -1); } 1.698 + 1.699 + void zap_from_to(Register low, int before, Register high, int after, Register val, Register addr) PRODUCT_RETURN; 1.700 +}; 1.701 + 1.702 +// class SkipIfEqualZero: 1.703 +// 1.704 +// Instantiating this class will result in assembly code being output that will 1.705 +// jump around any code emitted between the creation of the instance and it's 1.706 +// automatic destruction at the end of a scope block, depending on the value of 1.707 +// the flag passed to the constructor, which will be checked at run-time. 1.708 +class SkipIfEqualZero : public StackObj { 1.709 + private: 1.710 + MacroAssembler* _masm; 1.711 + Label _label; 1.712 + 1.713 + public: 1.714 + // 'Temp' is a temp register that this object can use (and trash). 1.715 + explicit SkipIfEqualZero(MacroAssembler*, Register temp, const bool* flag_addr); 1.716 + ~SkipIfEqualZero(); 1.717 +}; 1.718 + 1.719 +#endif // CPU_PPC_VM_MACROASSEMBLER_PPC_HPP