1 /*
   2  * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright (c) 2012, 2015 SAP SE. All rights reserved.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  *
  24  */
  25 
  26 #ifndef CPU_PPC_VM_MACROASSEMBLER_PPC_INLINE_HPP
  27 #define CPU_PPC_VM_MACROASSEMBLER_PPC_INLINE_HPP
  28 
  29 #include "asm/assembler.inline.hpp"
  30 #include "asm/macroAssembler.hpp"
  31 #include "asm/codeBuffer.hpp"
  32 #include "code/codeCache.hpp"
  33 #include "gc/shared/barrierSet.hpp"
  34 #include "gc/shared/barrierSetAssembler.hpp"
  35 #include "oops/accessDecorators.hpp"
  36 #include "runtime/safepointMechanism.hpp"
  37 
  38 inline bool MacroAssembler::is_ld_largeoffset(address a) {
  39   const int inst1 = *(int *)a;
  40   const int inst2 = *(int *)(a+4);
  41   return (is_ld(inst1)) ||
  42          (is_addis(inst1) && is_ld(inst2) && inv_ra_field(inst2) == inv_rt_field(inst1));
  43 }
  44 
  45 inline int MacroAssembler::get_ld_largeoffset_offset(address a) {
  46   assert(MacroAssembler::is_ld_largeoffset(a), "must be ld with large offset");
  47 
  48   const int inst1 = *(int *)a;
  49   if (is_ld(inst1)) {
  50     return inv_d1_field(inst1);
  51   } else {
  52     const int inst2 = *(int *)(a+4);
  53     return (inv_d1_field(inst1) << 16) + inv_d1_field(inst2);
  54   }
  55 }
  56 
  57 inline void MacroAssembler::round_to(Register r, int modulus) {
  58   assert(is_power_of_2_long((jlong)modulus), "must be power of 2");
  59   addi(r, r, modulus-1);
  60   clrrdi(r, r, log2_long((jlong)modulus));
  61 }
  62 
  63 // Move register if destination register and target register are different.
  64 inline void MacroAssembler::mr_if_needed(Register rd, Register rs) {
  65   if (rs != rd) mr(rd, rs);
  66 }
  67 inline void MacroAssembler::fmr_if_needed(FloatRegister rd, FloatRegister rs) {
  68   if (rs != rd) fmr(rd, rs);
  69 }
  70 inline void MacroAssembler::endgroup_if_needed(bool needed) {
  71   if (needed) {
  72     endgroup();
  73   }
  74 }
  75 
  76 inline void MacroAssembler::membar(int bits) {
  77   // Comment: Usage of elemental_membar(bits) is not recommended for Power 8.
  78   // If elemental_membar(bits) is used, disable optimization of acquire-release
  79   // (Matcher::post_membar_release where we use PPC64_ONLY(xop == Op_MemBarRelease ||))!
  80   if (bits & StoreLoad) { sync(); }
  81   else if (bits) { lwsync(); }
  82 }
  83 inline void MacroAssembler::release() { membar(LoadStore | StoreStore); }
  84 inline void MacroAssembler::acquire() { membar(LoadLoad | LoadStore); }
  85 inline void MacroAssembler::fence()   { membar(LoadLoad | LoadStore | StoreLoad | StoreStore); }
  86 
  87 // Address of the global TOC.
  88 inline address MacroAssembler::global_toc() {
  89   return CodeCache::low_bound();
  90 }
  91 
  92 // Offset of given address to the global TOC.
  93 inline int MacroAssembler::offset_to_global_toc(const address addr) {
  94   intptr_t offset = (intptr_t)addr - (intptr_t)MacroAssembler::global_toc();
  95   assert(Assembler::is_uimm((long)offset, 31), "must be in range");
  96   return (int)offset;
  97 }
  98 
  99 // Address of current method's TOC.
 100 inline address MacroAssembler::method_toc() {
 101   return code()->consts()->start();
 102 }
 103 
 104 // Offset of given address to current method's TOC.
 105 inline int MacroAssembler::offset_to_method_toc(address addr) {
 106   intptr_t offset = (intptr_t)addr - (intptr_t)method_toc();
 107   assert(Assembler::is_uimm((long)offset, 31), "must be in range");
 108   return (int)offset;
 109 }
 110 
 111 inline bool MacroAssembler::is_calculate_address_from_global_toc_at(address a, address bound) {
 112   const address inst2_addr = a;
 113   const int inst2 = *(int *) a;
 114 
 115   // The relocation points to the second instruction, the addi.
 116   if (!is_addi(inst2)) return false;
 117 
 118   // The addi reads and writes the same register dst.
 119   const int dst = inv_rt_field(inst2);
 120   if (inv_ra_field(inst2) != dst) return false;
 121 
 122   // Now, find the preceding addis which writes to dst.
 123   int inst1 = 0;
 124   address inst1_addr = inst2_addr - BytesPerInstWord;
 125   while (inst1_addr >= bound) {
 126     inst1 = *(int *) inst1_addr;
 127     if (is_addis(inst1) && inv_rt_field(inst1) == dst) {
 128       // stop, found the addis which writes dst
 129       break;
 130     }
 131     inst1_addr -= BytesPerInstWord;
 132   }
 133 
 134   if (!(inst1 == 0 || inv_ra_field(inst1) == 29 /* R29 */)) return false;
 135   return is_addis(inst1);
 136 }
 137 
 138 #ifdef _LP64
 139 // Detect narrow oop constants.
 140 inline bool MacroAssembler::is_set_narrow_oop(address a, address bound) {
 141   const address inst2_addr = a;
 142   const int inst2 = *(int *)a;
 143   // The relocation points to the second instruction, the ori.
 144   if (!is_ori(inst2)) return false;
 145 
 146   // The ori reads and writes the same register dst.
 147   const int dst = inv_rta_field(inst2);
 148   if (inv_rs_field(inst2) != dst) return false;
 149 
 150   // Now, find the preceding addis which writes to dst.
 151   int inst1 = 0;
 152   address inst1_addr = inst2_addr - BytesPerInstWord;
 153   while (inst1_addr >= bound) {
 154     inst1 = *(int *) inst1_addr;
 155     if (is_lis(inst1) && inv_rs_field(inst1) == dst) return true;
 156     inst1_addr -= BytesPerInstWord;
 157   }
 158   return false;
 159 }
 160 #endif
 161 
 162 
 163 inline bool MacroAssembler::is_load_const_at(address a) {
 164   const int* p_inst = (int *) a;
 165   bool b = is_lis(*p_inst++);
 166   if (is_ori(*p_inst)) {
 167     p_inst++;
 168     b = b && is_rldicr(*p_inst++); // TODO: could be made more precise: `sldi'!
 169     b = b && is_oris(*p_inst++);
 170     b = b && is_ori(*p_inst);
 171   } else if (is_lis(*p_inst)) {
 172     p_inst++;
 173     b = b && is_ori(*p_inst++);
 174     b = b && is_ori(*p_inst);
 175     // TODO: could enhance reliability by adding is_insrdi
 176   } else return false;
 177   return b;
 178 }
 179 
 180 inline void MacroAssembler::set_oop_constant(jobject obj, Register d) {
 181   set_oop(constant_oop_address(obj), d);
 182 }
 183 
 184 inline void MacroAssembler::set_oop(AddressLiteral obj_addr, Register d) {
 185   assert(obj_addr.rspec().type() == relocInfo::oop_type, "must be an oop reloc");
 186   load_const(d, obj_addr);
 187 }
 188 
 189 inline void MacroAssembler::pd_patch_instruction(address branch, address target) {
 190   jint& stub_inst = *(jint*) branch;
 191   stub_inst = patched_branch(target - branch, stub_inst, 0);
 192 }
 193 
 194 // Relocation of conditional far branches.
 195 inline bool MacroAssembler::is_bc_far_variant1_at(address instruction_addr) {
 196   // Variant 1, the 1st instruction contains the destination address:
 197   //
 198   //    bcxx  DEST
 199   //    nop
 200   //
 201   const int instruction_1 = *(int*)(instruction_addr);
 202   const int instruction_2 = *(int*)(instruction_addr + 4);
 203   return is_bcxx(instruction_1) &&
 204          (inv_bd_field(instruction_1, (intptr_t)instruction_addr) != (intptr_t)(instruction_addr + 2*4)) &&
 205          is_nop(instruction_2);
 206 }
 207 
 208 // Relocation of conditional far branches.
 209 inline bool MacroAssembler::is_bc_far_variant2_at(address instruction_addr) {
 210   // Variant 2, the 2nd instruction contains the destination address:
 211   //
 212   //    b!cxx SKIP
 213   //    bxx   DEST
 214   //  SKIP:
 215   //
 216   const int instruction_1 = *(int*)(instruction_addr);
 217   const int instruction_2 = *(int*)(instruction_addr + 4);
 218   return is_bcxx(instruction_1) &&
 219          (inv_bd_field(instruction_1, (intptr_t)instruction_addr) == (intptr_t)(instruction_addr + 2*4)) &&
 220          is_bxx(instruction_2);
 221 }
 222 
 223 // Relocation for conditional branches
 224 inline bool MacroAssembler::is_bc_far_variant3_at(address instruction_addr) {
 225   // Variant 3, far cond branch to the next instruction, already patched to nops:
 226   //
 227   //    nop
 228   //    endgroup
 229   //  SKIP/DEST:
 230   //
 231   const int instruction_1 = *(int*)(instruction_addr);
 232   const int instruction_2 = *(int*)(instruction_addr + 4);
 233   return is_nop(instruction_1) &&
 234          is_endgroup(instruction_2);
 235 }
 236 
 237 
 238 // Convenience bc_far versions
 239 inline void MacroAssembler::blt_far(ConditionRegister crx, Label& L, int optimize) { MacroAssembler::bc_far(bcondCRbiIs1, bi0(crx, less), L, optimize); }
 240 inline void MacroAssembler::bgt_far(ConditionRegister crx, Label& L, int optimize) { MacroAssembler::bc_far(bcondCRbiIs1, bi0(crx, greater), L, optimize); }
 241 inline void MacroAssembler::beq_far(ConditionRegister crx, Label& L, int optimize) { MacroAssembler::bc_far(bcondCRbiIs1, bi0(crx, equal), L, optimize); }
 242 inline void MacroAssembler::bso_far(ConditionRegister crx, Label& L, int optimize) { MacroAssembler::bc_far(bcondCRbiIs1, bi0(crx, summary_overflow), L, optimize); }
 243 inline void MacroAssembler::bge_far(ConditionRegister crx, Label& L, int optimize) { MacroAssembler::bc_far(bcondCRbiIs0, bi0(crx, less), L, optimize); }
 244 inline void MacroAssembler::ble_far(ConditionRegister crx, Label& L, int optimize) { MacroAssembler::bc_far(bcondCRbiIs0, bi0(crx, greater), L, optimize); }
 245 inline void MacroAssembler::bne_far(ConditionRegister crx, Label& L, int optimize) { MacroAssembler::bc_far(bcondCRbiIs0, bi0(crx, equal), L, optimize); }
 246 inline void MacroAssembler::bns_far(ConditionRegister crx, Label& L, int optimize) { MacroAssembler::bc_far(bcondCRbiIs0, bi0(crx, summary_overflow), L, optimize); }
 247 
 248 inline address MacroAssembler::call_stub(Register function_entry) {
 249   mtctr(function_entry);
 250   bctrl();
 251   return pc();
 252 }
 253 
 254 inline void MacroAssembler::call_stub_and_return_to(Register function_entry, Register return_pc) {
 255   assert_different_registers(function_entry, return_pc);
 256   mtlr(return_pc);
 257   mtctr(function_entry);
 258   bctr();
 259 }
 260 
 261 // Get the pc where the last emitted call will return to.
 262 inline address MacroAssembler::last_calls_return_pc() {
 263   return _last_calls_return_pc;
 264 }
 265 
 266 // Read from the polling page, its address is already in a register.
 267 inline void MacroAssembler::load_from_polling_page(Register polling_page_address, int offset) {
 268   if (SafepointMechanism::uses_thread_local_poll() && USE_POLL_BIT_ONLY) {
 269     int encoding = SafepointMechanism::poll_bit();
 270     tdi(traptoGreaterThanUnsigned | traptoEqual, polling_page_address, encoding);
 271   } else {
 272     ld(R0, offset, polling_page_address);
 273   }
 274 }
 275 
 276 // Trap-instruction-based checks.
 277 
 278 inline void MacroAssembler::trap_null_check(Register a, trap_to_bits cmp) {
 279   assert(TrapBasedNullChecks, "sanity");
 280   tdi(cmp, a/*reg a*/, 0);
 281 }
 282 inline void MacroAssembler::trap_zombie_not_entrant() {
 283   tdi(traptoUnconditional, 0/*reg 0*/, 1);
 284 }
 285 inline void MacroAssembler::trap_should_not_reach_here() {
 286   tdi_unchecked(traptoUnconditional, 0/*reg 0*/, 2);
 287 }
 288 
 289 inline void MacroAssembler::trap_ic_miss_check(Register a, Register b) {
 290   td(traptoGreaterThanUnsigned | traptoLessThanUnsigned, a, b);
 291 }
 292 
 293 // Do an explicit null check if access to a+offset will not raise a SIGSEGV.
 294 // Either issue a trap instruction that raises SIGTRAP, or do a compare that
 295 // branches to exception_entry.
 296 // No support for compressed oops (base page of heap). Does not distinguish
 297 // loads and stores.
 298 inline void MacroAssembler::null_check_throw(Register a, int offset, Register temp_reg,
 299                                              address exception_entry) {
 300   if (!ImplicitNullChecks || needs_explicit_null_check(offset) || !os::zero_page_read_protected()) {
 301     if (TrapBasedNullChecks) {
 302       assert(UseSIGTRAP, "sanity");
 303       trap_null_check(a);
 304     } else {
 305       Label ok;
 306       cmpdi(CCR0, a, 0);
 307       bne(CCR0, ok);
 308       load_const_optimized(temp_reg, exception_entry);
 309       mtctr(temp_reg);
 310       bctr();
 311       bind(ok);
 312     }
 313   }
 314 }
 315 
 316 inline void MacroAssembler::null_check(Register a, int offset, Label *Lis_null) {
 317   if (!ImplicitNullChecks || needs_explicit_null_check(offset) || !os::zero_page_read_protected()) {
 318     if (TrapBasedNullChecks) {
 319       assert(UseSIGTRAP, "sanity");
 320       trap_null_check(a);
 321     } else if (Lis_null){
 322       Label ok;
 323       cmpdi(CCR0, a, 0);
 324       beq(CCR0, *Lis_null);
 325     }
 326   }
 327 }
 328 
 329 inline void MacroAssembler::access_store_at(BasicType type, DecoratorSet decorators,
 330                                             Register base, RegisterOrConstant ind_or_offs, Register val,
 331                                             Register tmp1, Register tmp2, Register tmp3, bool needs_frame) {
 332   assert((decorators & ~(AS_RAW | IN_HEAP | IN_HEAP_ARRAY | IN_ROOT | OOP_NOT_NULL |
 333                          ON_UNKNOWN_OOP_REF)) == 0, "unsupported decorator");
 334   BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
 335   bool as_raw = (decorators & AS_RAW) != 0;
 336   decorators = AccessInternal::decorator_fixup(decorators);
 337   if (as_raw) {
 338     bs->BarrierSetAssembler::store_at(this, decorators, type,
 339                                       base, ind_or_offs, val,
 340                                       tmp1, tmp2, tmp3, needs_frame);
 341   } else {
 342     bs->store_at(this, decorators, type,
 343                  base, ind_or_offs, val,
 344                  tmp1, tmp2, tmp3, needs_frame);
 345   }
 346 }
 347 
 348 inline void MacroAssembler::access_load_at(BasicType type, DecoratorSet decorators,
 349                                            Register base, RegisterOrConstant ind_or_offs, Register dst,
 350                                            Register tmp1, Register tmp2, bool needs_frame, Label *L_handle_null) {
 351   assert((decorators & ~(AS_RAW | IN_HEAP | IN_HEAP_ARRAY | IN_ROOT | OOP_NOT_NULL |
 352                          ON_PHANTOM_OOP_REF | ON_WEAK_OOP_REF)) == 0, "unsupported decorator");
 353   BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
 354   decorators = AccessInternal::decorator_fixup(decorators);
 355   bool as_raw = (decorators & AS_RAW) != 0;
 356   if (as_raw) {
 357     bs->BarrierSetAssembler::load_at(this, decorators, type,
 358                                      base, ind_or_offs, dst,
 359                                      tmp1, tmp2, needs_frame, L_handle_null);
 360   } else {
 361     bs->load_at(this, decorators, type,
 362                 base, ind_or_offs, dst,
 363                 tmp1, tmp2, needs_frame, L_handle_null);
 364   }
 365 }
 366 
 367 inline void MacroAssembler::load_heap_oop(Register d, RegisterOrConstant offs, Register s1,
 368                                           Register tmp1, Register tmp2,
 369                                           bool needs_frame, DecoratorSet decorators, Label *L_handle_null) {
 370   access_load_at(T_OBJECT, IN_HEAP | decorators, s1, offs, d, tmp1, tmp2, needs_frame, L_handle_null);
 371 }
 372 
 373 inline void MacroAssembler::store_heap_oop(Register d, RegisterOrConstant offs, Register s1,
 374                                            Register tmp1, Register tmp2, Register tmp3,
 375                                            bool needs_frame, DecoratorSet decorators) {
 376   access_store_at(T_OBJECT, IN_HEAP | decorators, s1, offs, d, tmp1, tmp2, tmp3, needs_frame);
 377 }
 378 
 379 inline Register MacroAssembler::encode_heap_oop_not_null(Register d, Register src) {
 380   Register current = (src != noreg) ? src : d; // Oop to be compressed is in d if no src provided.
 381   if (Universe::narrow_oop_base_overlaps()) {
 382     sub_const_optimized(d, current, Universe::narrow_oop_base(), R0);
 383     current = d;
 384   }
 385   if (Universe::narrow_oop_shift() != 0) {
 386     rldicl(d, current, 64-Universe::narrow_oop_shift(), 32);  // Clears the upper bits.
 387     current = d;
 388   }
 389   return current; // Encoded oop is in this register.
 390 }
 391 
 392 inline Register MacroAssembler::encode_heap_oop(Register d, Register src) {
 393   if (Universe::narrow_oop_base() != NULL) {
 394     if (VM_Version::has_isel()) {
 395       cmpdi(CCR0, src, 0);
 396       Register co = encode_heap_oop_not_null(d, src);
 397       assert(co == d, "sanity");
 398       isel_0(d, CCR0, Assembler::equal);
 399     } else {
 400       Label isNull;
 401       or_(d, src, src); // move and compare 0
 402       beq(CCR0, isNull);
 403       encode_heap_oop_not_null(d, src);
 404       bind(isNull);
 405     }
 406     return d;
 407   } else {
 408     return encode_heap_oop_not_null(d, src);
 409   }
 410 }
 411 
 412 inline Register MacroAssembler::decode_heap_oop_not_null(Register d, Register src) {
 413   if (Universe::narrow_oop_base_disjoint() && src != noreg && src != d &&
 414       Universe::narrow_oop_shift() != 0) {
 415     load_const_optimized(d, Universe::narrow_oop_base(), R0);
 416     rldimi(d, src, Universe::narrow_oop_shift(), 32-Universe::narrow_oop_shift());
 417     return d;
 418   }
 419 
 420   Register current = (src != noreg) ? src : d; // Compressed oop is in d if no src provided.
 421   if (Universe::narrow_oop_shift() != 0) {
 422     sldi(d, current, Universe::narrow_oop_shift());
 423     current = d;
 424   }
 425   if (Universe::narrow_oop_base() != NULL) {
 426     add_const_optimized(d, current, Universe::narrow_oop_base(), R0);
 427     current = d;
 428   }
 429   return current; // Decoded oop is in this register.
 430 }
 431 
 432 inline void MacroAssembler::decode_heap_oop(Register d) {
 433   Label isNull;
 434   bool use_isel = false;
 435   if (Universe::narrow_oop_base() != NULL) {
 436     cmpwi(CCR0, d, 0);
 437     if (VM_Version::has_isel()) {
 438       use_isel = true;
 439     } else {
 440       beq(CCR0, isNull);
 441     }
 442   }
 443   decode_heap_oop_not_null(d);
 444   if (use_isel) {
 445     isel_0(d, CCR0, Assembler::equal);
 446   }
 447   bind(isNull);
 448 }
 449 
 450 // SIGTRAP-based range checks for arrays.
 451 inline void MacroAssembler::trap_range_check_l(Register a, Register b) {
 452   tw (traptoLessThanUnsigned,                  a/*reg a*/, b/*reg b*/);
 453 }
 454 inline void MacroAssembler::trap_range_check_l(Register a, int si16) {
 455   twi(traptoLessThanUnsigned,                  a/*reg a*/, si16);
 456 }
 457 inline void MacroAssembler::trap_range_check_le(Register a, int si16) {
 458   twi(traptoEqual | traptoLessThanUnsigned,    a/*reg a*/, si16);
 459 }
 460 inline void MacroAssembler::trap_range_check_g(Register a, int si16) {
 461   twi(traptoGreaterThanUnsigned,               a/*reg a*/, si16);
 462 }
 463 inline void MacroAssembler::trap_range_check_ge(Register a, Register b) {
 464   tw (traptoEqual | traptoGreaterThanUnsigned, a/*reg a*/, b/*reg b*/);
 465 }
 466 inline void MacroAssembler::trap_range_check_ge(Register a, int si16) {
 467   twi(traptoEqual | traptoGreaterThanUnsigned, a/*reg a*/, si16);
 468 }
 469 
 470 // unsigned integer multiplication 64*64 -> 128 bits
 471 inline void MacroAssembler::multiply64(Register dest_hi, Register dest_lo,
 472                                        Register x, Register y) {
 473   mulld(dest_lo, x, y);
 474   mulhdu(dest_hi, x, y);
 475 }
 476 
 477 #if defined(ABI_ELFv2)
 478 inline address MacroAssembler::function_entry() { return pc(); }
 479 #else
 480 inline address MacroAssembler::function_entry() { return emit_fd(); }
 481 #endif
 482 
 483 #endif // CPU_PPC_VM_MACROASSEMBLER_PPC_INLINE_HPP