src/cpu/ppc/vm/macroAssembler_ppc.hpp

changeset 0
f90c822e73f8
child 6876
710a3c8b516e
     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

mercurial