1 /* 2 * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #ifndef CPU_ARM_VM_MACROASSEMBLER_ARM_HPP 26 #define CPU_ARM_VM_MACROASSEMBLER_ARM_HPP 27 28 #include "code/relocInfo.hpp" 29 #include "code/relocInfo_ext.hpp" 30 31 class BiasedLockingCounters; 32 33 // Introduced AddressLiteral and its subclasses to ease portability from 34 // x86 and avoid relocation issues 35 class AddressLiteral { 36 RelocationHolder _rspec; 37 // Typically we use AddressLiterals we want to use their rval 38 // However in some situations we want the lval (effect address) of the item. 39 // We provide a special factory for making those lvals. 40 bool _is_lval; 41 42 address _target; 43 44 private: 45 static relocInfo::relocType reloc_for_target(address target) { 46 // Used for ExternalAddress or when the type is not specified 47 // Sometimes ExternalAddress is used for values which aren't 48 // exactly addresses, like the card table base. 49 // external_word_type can't be used for values in the first page 50 // so just skip the reloc in that case. 51 return external_word_Relocation::can_be_relocated(target) ? relocInfo::external_word_type : relocInfo::none; 52 } 53 54 void set_rspec(relocInfo::relocType rtype); 55 56 protected: 57 // creation 58 AddressLiteral() 59 : _is_lval(false), 60 _target(NULL) 61 {} 62 63 public: 64 65 AddressLiteral(address target, relocInfo::relocType rtype) { 66 _is_lval = false; 67 _target = target; 68 set_rspec(rtype); 69 } 70 71 AddressLiteral(address target, RelocationHolder const& rspec) 72 : _rspec(rspec), 73 _is_lval(false), 74 _target(target) 75 {} 76 77 AddressLiteral(address target) { 78 _is_lval = false; 79 _target = target; 80 set_rspec(reloc_for_target(target)); 81 } 82 83 AddressLiteral addr() { 84 AddressLiteral ret = *this; 85 ret._is_lval = true; 86 return ret; 87 } 88 89 private: 90 91 address target() { return _target; } 92 bool is_lval() { return _is_lval; } 93 94 relocInfo::relocType reloc() const { return _rspec.type(); } 95 const RelocationHolder& rspec() const { return _rspec; } 96 97 friend class Assembler; 98 friend class MacroAssembler; 99 friend class Address; 100 friend class LIR_Assembler; 101 friend class InlinedAddress; 102 }; 103 104 class ExternalAddress: public AddressLiteral { 105 106 public: 107 108 ExternalAddress(address target) : AddressLiteral(target) {} 109 110 }; 111 112 class InternalAddress: public AddressLiteral { 113 114 public: 115 116 InternalAddress(address target) : AddressLiteral(target, relocInfo::internal_word_type) {} 117 118 }; 119 120 // Inlined constants, for use with ldr_literal / bind_literal 121 // Note: InlinedInteger not supported (use move_slow(Register,int[,cond])) 122 class InlinedLiteral: StackObj { 123 public: 124 Label label; // need to be public for direct access with & 125 InlinedLiteral() { 126 } 127 }; 128 129 class InlinedMetadata: public InlinedLiteral { 130 private: 131 Metadata *_data; 132 133 public: 134 InlinedMetadata(Metadata *data): InlinedLiteral() { 135 _data = data; 136 } 137 Metadata *data() { return _data; } 138 }; 139 140 // Currently unused 141 // class InlinedOop: public InlinedLiteral { 142 // private: 143 // jobject _jobject; 144 // 145 // public: 146 // InlinedOop(jobject target): InlinedLiteral() { 147 // _jobject = target; 148 // } 149 // jobject jobject() { return _jobject; } 150 // }; 151 152 class InlinedAddress: public InlinedLiteral { 153 private: 154 AddressLiteral _literal; 155 156 public: 157 158 InlinedAddress(jobject object): InlinedLiteral(), _literal((address)object, relocInfo::oop_type) { 159 ShouldNotReachHere(); // use mov_oop (or implement InlinedOop) 160 } 161 162 InlinedAddress(Metadata *data): InlinedLiteral(), _literal((address)data, relocInfo::metadata_type) { 163 ShouldNotReachHere(); // use InlinedMetadata or mov_metadata 164 } 165 166 InlinedAddress(address target, const RelocationHolder &rspec): InlinedLiteral(), _literal(target, rspec) { 167 assert(rspec.type() != relocInfo::oop_type, "Do not use InlinedAddress for oops"); 168 assert(rspec.type() != relocInfo::metadata_type, "Do not use InlinedAddress for metadatas"); 169 } 170 171 InlinedAddress(address target, relocInfo::relocType rtype): InlinedLiteral(), _literal(target, rtype) { 172 assert(rtype != relocInfo::oop_type, "Do not use InlinedAddress for oops"); 173 assert(rtype != relocInfo::metadata_type, "Do not use InlinedAddress for metadatas"); 174 } 175 176 // Note: default is relocInfo::none for InlinedAddress 177 InlinedAddress(address target): InlinedLiteral(), _literal(target, relocInfo::none) { 178 } 179 180 address target() { return _literal.target(); } 181 182 const RelocationHolder& rspec() const { return _literal.rspec(); } 183 }; 184 185 class InlinedString: public InlinedLiteral { 186 private: 187 const char* _msg; 188 189 public: 190 InlinedString(const char* msg): InlinedLiteral() { 191 _msg = msg; 192 } 193 const char* msg() { return _msg; } 194 }; 195 196 class MacroAssembler: public Assembler { 197 protected: 198 199 // Support for VM calls 200 // 201 202 // This is the base routine called by the different versions of call_VM_leaf. 203 void call_VM_leaf_helper(address entry_point, int number_of_arguments); 204 205 // This is the base routine called by the different versions of call_VM. The interpreter 206 // may customize this version by overriding it for its purposes (e.g., to save/restore 207 // additional registers when doing a VM call). 208 virtual void call_VM_helper(Register oop_result, address entry_point, int number_of_arguments, bool check_exceptions); 209 public: 210 211 MacroAssembler(CodeBuffer* code) : Assembler(code) {} 212 213 // These routines should emit JVMTI PopFrame and ForceEarlyReturn handling code. 214 // The implementation is only non-empty for the InterpreterMacroAssembler, 215 // as only the interpreter handles PopFrame and ForceEarlyReturn requests. 216 virtual void check_and_handle_popframe() {} 217 virtual void check_and_handle_earlyret() {} 218 219 // By default, we do not need relocation information for non 220 // patchable absolute addresses. However, when needed by some 221 // extensions, ignore_non_patchable_relocations can be modified, 222 // returning false to preserve all relocation information. 223 inline bool ignore_non_patchable_relocations() { return true; } 224 225 // Initially added to the Assembler interface as a pure virtual: 226 // RegisterConstant delayed_value(..) 227 // for: 228 // 6812678 macro assembler needs delayed binding of a few constants (for 6655638) 229 // this was subsequently modified to its present name and return type 230 virtual RegisterOrConstant delayed_value_impl(intptr_t* delayed_value_addr, Register tmp, int offset); 231 232 #ifdef AARCH64 233 # define NOT_IMPLEMENTED() unimplemented("NYI at " __FILE__ ":" XSTR(__LINE__)) 234 # define NOT_TESTED() warn("Not tested at " __FILE__ ":" XSTR(__LINE__)) 235 #endif 236 237 void align(int modulus); 238 239 // Support for VM calls 240 // 241 // It is imperative that all calls into the VM are handled via the call_VM methods. 242 // They make sure that the stack linkage is setup correctly. call_VM's correspond 243 // to ENTRY/ENTRY_X entry points while call_VM_leaf's correspond to LEAF entry points. 244 245 void call_VM(Register oop_result, address entry_point, bool check_exceptions = true); 246 void call_VM(Register oop_result, address entry_point, Register arg_1, bool check_exceptions = true); 247 void call_VM(Register oop_result, address entry_point, Register arg_1, Register arg_2, bool check_exceptions = true); 248 void call_VM(Register oop_result, address entry_point, Register arg_1, Register arg_2, Register arg_3, bool check_exceptions = true); 249 250 // The following methods are required by templateTable.cpp, 251 // but not used on ARM. 252 void call_VM(Register oop_result, Register last_java_sp, address entry_point, int number_of_arguments = 0, bool check_exceptions = true); 253 void call_VM(Register oop_result, Register last_java_sp, address entry_point, Register arg_1, bool check_exceptions = true); 254 void call_VM(Register oop_result, Register last_java_sp, address entry_point, Register arg_1, Register arg_2, bool check_exceptions = true); 255 void call_VM(Register oop_result, Register last_java_sp, address entry_point, Register arg_1, Register arg_2, Register arg_3, bool check_exceptions = true); 256 257 // Note: The super_call_VM calls are not used on ARM 258 259 // Raw call, without saving/restoring registers, exception handling, etc. 260 // Mainly used from various stubs. 261 // Note: if 'save_R9_if_scratched' is true, call_VM may on some 262 // platforms save values on the stack. Set it to false (and handle 263 // R9 in the callers) if the top of the stack must not be modified 264 // by call_VM. 265 void call_VM(address entry_point, bool save_R9_if_scratched); 266 267 void call_VM_leaf(address entry_point); 268 void call_VM_leaf(address entry_point, Register arg_1); 269 void call_VM_leaf(address entry_point, Register arg_1, Register arg_2); 270 void call_VM_leaf(address entry_point, Register arg_1, Register arg_2, Register arg_3); 271 void call_VM_leaf(address entry_point, Register arg_1, Register arg_2, Register arg_3, Register arg_4); 272 273 void get_vm_result(Register oop_result, Register tmp); 274 void get_vm_result_2(Register metadata_result, Register tmp); 275 276 // Always sets/resets sp, which default to SP if (last_sp == noreg) 277 // Optionally sets/resets fp (use noreg to avoid setting it) 278 // Always sets/resets pc on AArch64; optionally sets/resets pc on 32-bit ARM depending on save_last_java_pc flag 279 // Note: when saving PC, set_last_Java_frame returns PC's offset in the code section 280 // (for oop_maps offset computation) 281 int set_last_Java_frame(Register last_sp, Register last_fp, bool save_last_java_pc, Register tmp); 282 void reset_last_Java_frame(Register tmp); 283 // status set in set_last_Java_frame for reset_last_Java_frame 284 bool _fp_saved; 285 bool _pc_saved; 286 287 #ifdef PRODUCT 288 #define BLOCK_COMMENT(str) /* nothing */ 289 #define STOP(error) __ stop(error) 290 #else 291 #define BLOCK_COMMENT(str) __ block_comment(str) 292 #define STOP(error) __ block_comment(error); __ stop(error) 293 #endif 294 295 void lookup_virtual_method(Register recv_klass, 296 Register vtable_index, 297 Register method_result); 298 299 // Test sub_klass against super_klass, with fast and slow paths. 300 301 // The fast path produces a tri-state answer: yes / no / maybe-slow. 302 // One of the three labels can be NULL, meaning take the fall-through. 303 // No registers are killed, except temp_regs. 304 void check_klass_subtype_fast_path(Register sub_klass, 305 Register super_klass, 306 Register temp_reg, 307 Register temp_reg2, 308 Label* L_success, 309 Label* L_failure, 310 Label* L_slow_path); 311 312 // The rest of the type check; must be wired to a corresponding fast path. 313 // It does not repeat the fast path logic, so don't use it standalone. 314 // temp_reg3 can be noreg, if no temps are available. 315 // Updates the sub's secondary super cache as necessary. 316 // If set_cond_codes: 317 // - condition codes will be Z on success, NZ on failure. 318 // - temp_reg will be 0 on success, non-0 on failure 319 void check_klass_subtype_slow_path(Register sub_klass, 320 Register super_klass, 321 Register temp_reg, 322 Register temp_reg2, 323 Register temp_reg3, // auto assigned if noreg 324 Label* L_success, 325 Label* L_failure, 326 bool set_cond_codes = false); 327 328 // Simplified, combined version, good for typical uses. 329 // temp_reg3 can be noreg, if no temps are available. It is used only on slow path. 330 // Falls through on failure. 331 void check_klass_subtype(Register sub_klass, 332 Register super_klass, 333 Register temp_reg, 334 Register temp_reg2, 335 Register temp_reg3, // auto assigned on slow path if noreg 336 Label& L_success); 337 338 // Returns address of receiver parameter, using tmp as base register. tmp and params_count can be the same. 339 Address receiver_argument_address(Register params_base, Register params_count, Register tmp); 340 341 void _verify_oop(Register reg, const char* s, const char* file, int line); 342 void _verify_oop_addr(Address addr, const char * s, const char* file, int line); 343 344 // TODO: verify method and klass metadata (compare against vptr?) 345 void _verify_method_ptr(Register reg, const char * msg, const char * file, int line) {} 346 void _verify_klass_ptr(Register reg, const char * msg, const char * file, int line) {} 347 348 #define verify_oop(reg) _verify_oop(reg, "broken oop " #reg, __FILE__, __LINE__) 349 #define verify_oop_addr(addr) _verify_oop_addr(addr, "broken oop ", __FILE__, __LINE__) 350 #define verify_method_ptr(reg) _verify_method_ptr(reg, "broken method " #reg, __FILE__, __LINE__) 351 #define verify_klass_ptr(reg) _verify_klass_ptr(reg, "broken klass " #reg, __FILE__, __LINE__) 352 353 void null_check(Register reg, Register tmp, int offset = -1); 354 inline void null_check(Register reg) { null_check(reg, noreg, -1); } // for C1 lir_null_check 355 356 // Puts address of allocated object into register `obj` and end of allocated object into register `obj_end`. 357 void eden_allocate(Register obj, Register obj_end, Register tmp1, Register tmp2, 358 RegisterOrConstant size_expression, Label& slow_case); 359 void tlab_allocate(Register obj, Register obj_end, Register tmp1, 360 RegisterOrConstant size_expression, Label& slow_case); 361 362 void zero_memory(Register start, Register end, Register tmp); 363 364 void incr_allocated_bytes(RegisterOrConstant size_in_bytes, Register tmp); 365 366 static bool needs_explicit_null_check(intptr_t offset); 367 368 void arm_stack_overflow_check(int frame_size_in_bytes, Register tmp); 369 void arm_stack_overflow_check(Register Rsize, Register tmp); 370 371 void bang_stack_with_offset(int offset) { 372 ShouldNotReachHere(); 373 } 374 375 // Biased locking support 376 // lock_reg and obj_reg must be loaded up with the appropriate values. 377 // swap_reg must be supplied. 378 // tmp_reg must be supplied. 379 // Optional slow case is for implementations (interpreter and C1) which branch to 380 // slow case directly. If slow_case is NULL, then leaves condition 381 // codes set (for C2's Fast_Lock node) and jumps to done label. 382 // Falls through for the fast locking attempt. 383 // Returns offset of first potentially-faulting instruction for null 384 // check info (currently consumed only by C1). If 385 // swap_reg_contains_mark is true then returns -1 as it is assumed 386 // the calling code has already passed any potential faults. 387 // Notes: 388 // - swap_reg and tmp_reg are scratched 389 // - Rtemp was (implicitly) scratched and can now be specified as the tmp2 390 int biased_locking_enter(Register obj_reg, Register swap_reg, Register tmp_reg, 391 bool swap_reg_contains_mark, 392 Register tmp2, 393 Label& done, Label& slow_case, 394 BiasedLockingCounters* counters = NULL); 395 void biased_locking_exit(Register obj_reg, Register temp_reg, Label& done); 396 397 // Building block for CAS cases of biased locking: makes CAS and records statistics. 398 // Optional slow_case label is used to transfer control if CAS fails. Otherwise leaves condition codes set. 399 void biased_locking_enter_with_cas(Register obj_reg, Register old_mark_reg, Register new_mark_reg, 400 Register tmp, Label& slow_case, int* counter_addr); 401 402 void resolve_jobject(Register value, Register tmp1, Register tmp2); 403 404 #ifndef AARCH64 405 void nop() { 406 mov(R0, R0); 407 } 408 409 void push(Register rd, AsmCondition cond = al) { 410 assert(rd != SP, "unpredictable instruction"); 411 str(rd, Address(SP, -wordSize, pre_indexed), cond); 412 } 413 414 void push(RegisterSet reg_set, AsmCondition cond = al) { 415 assert(!reg_set.contains(SP), "unpredictable instruction"); 416 stmdb(SP, reg_set, writeback, cond); 417 } 418 419 void pop(Register rd, AsmCondition cond = al) { 420 assert(rd != SP, "unpredictable instruction"); 421 ldr(rd, Address(SP, wordSize, post_indexed), cond); 422 } 423 424 void pop(RegisterSet reg_set, AsmCondition cond = al) { 425 assert(!reg_set.contains(SP), "unpredictable instruction"); 426 ldmia(SP, reg_set, writeback, cond); 427 } 428 429 void fpushd(FloatRegister fd, AsmCondition cond = al) { 430 fstmdbd(SP, FloatRegisterSet(fd), writeback, cond); 431 } 432 433 void fpushs(FloatRegister fd, AsmCondition cond = al) { 434 fstmdbs(SP, FloatRegisterSet(fd), writeback, cond); 435 } 436 437 void fpopd(FloatRegister fd, AsmCondition cond = al) { 438 fldmiad(SP, FloatRegisterSet(fd), writeback, cond); 439 } 440 441 void fpops(FloatRegister fd, AsmCondition cond = al) { 442 fldmias(SP, FloatRegisterSet(fd), writeback, cond); 443 } 444 #endif // !AARCH64 445 446 void fpush(FloatRegisterSet reg_set) { 447 fstmdbd(SP, reg_set, writeback); 448 } 449 450 void fpop(FloatRegisterSet reg_set) { 451 fldmiad(SP, reg_set, writeback); 452 } 453 454 void fpush_hardfp(FloatRegisterSet reg_set) { 455 #ifndef __SOFTFP__ 456 fpush(reg_set); 457 #endif 458 } 459 460 void fpop_hardfp(FloatRegisterSet reg_set) { 461 #ifndef __SOFTFP__ 462 fpop(reg_set); 463 #endif 464 } 465 466 // Order access primitives 467 enum Membar_mask_bits { 468 StoreStore = 1 << 3, 469 LoadStore = 1 << 2, 470 StoreLoad = 1 << 1, 471 LoadLoad = 1 << 0 472 }; 473 474 #ifdef AARCH64 475 // tmp register is not used on AArch64, this parameter is provided solely for better compatibility with 32-bit ARM 476 void membar(Membar_mask_bits order_constraint, Register tmp = noreg); 477 #else 478 void membar(Membar_mask_bits mask, 479 Register tmp, 480 bool preserve_flags = true, 481 Register load_tgt = noreg); 482 #endif 483 484 void breakpoint(AsmCondition cond = al); 485 void stop(const char* msg); 486 // prints msg and continues 487 void warn(const char* msg); 488 void unimplemented(const char* what = ""); 489 void should_not_reach_here() { stop("should not reach here"); } 490 static void debug(const char* msg, const intx* registers); 491 492 // Create a walkable frame to help tracking down who called this code. 493 // Returns the frame size in words. 494 int should_not_call_this() { 495 raw_push(FP, LR); 496 should_not_reach_here(); 497 flush(); 498 return 2; // frame_size_in_words (FP+LR) 499 } 500 501 int save_all_registers(); 502 void restore_all_registers(); 503 int save_caller_save_registers(); 504 void restore_caller_save_registers(); 505 506 void add_rc(Register dst, Register arg1, RegisterOrConstant arg2); 507 508 // add_slow and mov_slow are used to manipulate offsets larger than 1024, 509 // these functions are not expected to handle all possible constants, 510 // only those that can really occur during compilation 511 void add_slow(Register rd, Register rn, int c); 512 void sub_slow(Register rd, Register rn, int c); 513 514 #ifdef AARCH64 515 static int mov_slow_helper(Register rd, intptr_t c, MacroAssembler* masm /* optional */); 516 #endif 517 518 void mov_slow(Register rd, intptr_t c NOT_AARCH64_ARG(AsmCondition cond = al)); 519 void mov_slow(Register rd, const char *string); 520 void mov_slow(Register rd, address addr); 521 522 void patchable_mov_oop(Register rd, jobject o, int oop_index) { 523 mov_oop(rd, o, oop_index AARCH64_ONLY_ARG(true)); 524 } 525 void mov_oop(Register rd, jobject o, int index = 0 526 AARCH64_ONLY_ARG(bool patchable = false) 527 NOT_AARCH64_ARG(AsmCondition cond = al)); 528 529 530 void patchable_mov_metadata(Register rd, Metadata* o, int index) { 531 mov_metadata(rd, o, index AARCH64_ONLY_ARG(true)); 532 } 533 void mov_metadata(Register rd, Metadata* o, int index = 0 AARCH64_ONLY_ARG(bool patchable = false)); 534 535 void mov_float(FloatRegister fd, jfloat c NOT_AARCH64_ARG(AsmCondition cond = al)); 536 void mov_double(FloatRegister fd, jdouble c NOT_AARCH64_ARG(AsmCondition cond = al)); 537 538 #ifdef AARCH64 539 int mov_pc_to(Register rd) { 540 Label L; 541 adr(rd, L); 542 bind(L); 543 return offset(); 544 } 545 #endif 546 547 // Note: this variant of mov_address assumes the address moves with 548 // the code. Do *not* implement it with non-relocated instructions, 549 // unless PC-relative. 550 #ifdef AARCH64 551 void mov_relative_address(Register rd, address addr) { 552 adr(rd, addr); 553 } 554 #else 555 void mov_relative_address(Register rd, address addr, AsmCondition cond = al) { 556 int offset = addr - pc() - 8; 557 assert((offset & 3) == 0, "bad alignment"); 558 if (offset >= 0) { 559 assert(AsmOperand::is_rotated_imm(offset), "addr too far"); 560 add(rd, PC, offset, cond); 561 } else { 562 assert(AsmOperand::is_rotated_imm(-offset), "addr too far"); 563 sub(rd, PC, -offset, cond); 564 } 565 } 566 #endif // AARCH64 567 568 // Runtime address that may vary from one execution to another. The 569 // symbolic_reference describes what the address is, allowing 570 // the address to be resolved in a different execution context. 571 // Warning: do not implement as a PC relative address. 572 void mov_address(Register rd, address addr, symbolic_Relocation::symbolic_reference t) { 573 mov_address(rd, addr, RelocationHolder::none); 574 } 575 576 // rspec can be RelocationHolder::none (for ignored symbolic_Relocation). 577 // In that case, the address is absolute and the generated code need 578 // not be relocable. 579 void mov_address(Register rd, address addr, RelocationHolder const& rspec) { 580 assert(rspec.type() != relocInfo::runtime_call_type, "do not use mov_address for runtime calls"); 581 assert(rspec.type() != relocInfo::static_call_type, "do not use mov_address for relocable calls"); 582 if (rspec.type() == relocInfo::none) { 583 // absolute address, relocation not needed 584 mov_slow(rd, (intptr_t)addr); 585 return; 586 } 587 #ifndef AARCH64 588 if (VM_Version::supports_movw()) { 589 relocate(rspec); 590 int c = (int)addr; 591 movw(rd, c & 0xffff); 592 if ((unsigned int)c >> 16) { 593 movt(rd, (unsigned int)c >> 16); 594 } 595 return; 596 } 597 #endif 598 Label skip_literal; 599 InlinedAddress addr_literal(addr, rspec); 600 ldr_literal(rd, addr_literal); 601 b(skip_literal); 602 bind_literal(addr_literal); 603 // AARCH64 WARNING: because of alignment padding, extra padding 604 // may be required to get a consistent size for C2, or rules must 605 // overestimate size see MachEpilogNode::size 606 bind(skip_literal); 607 } 608 609 // Note: Do not define mov_address for a Label 610 // 611 // Load from addresses potentially within the code are now handled 612 // InlinedLiteral subclasses (to allow more flexibility on how the 613 // ldr_literal is performed). 614 615 void ldr_literal(Register rd, InlinedAddress& L) { 616 assert(L.rspec().type() != relocInfo::runtime_call_type, "avoid ldr_literal for calls"); 617 assert(L.rspec().type() != relocInfo::static_call_type, "avoid ldr_literal for calls"); 618 relocate(L.rspec()); 619 #ifdef AARCH64 620 ldr(rd, target(L.label)); 621 #else 622 ldr(rd, Address(PC, target(L.label) - pc() - 8)); 623 #endif 624 } 625 626 void ldr_literal(Register rd, InlinedString& L) { 627 const char* msg = L.msg(); 628 if (code()->consts()->contains((address)msg)) { 629 // string address moves with the code 630 #ifdef AARCH64 631 ldr(rd, (address)msg); 632 #else 633 ldr(rd, Address(PC, ((address)msg) - pc() - 8)); 634 #endif 635 return; 636 } 637 // Warning: use external strings with care. They are not relocated 638 // if the code moves. If needed, use code_string to move them 639 // to the consts section. 640 #ifdef AARCH64 641 ldr(rd, target(L.label)); 642 #else 643 ldr(rd, Address(PC, target(L.label) - pc() - 8)); 644 #endif 645 } 646 647 void ldr_literal(Register rd, InlinedMetadata& L) { 648 // relocation done in the bind_literal for metadatas 649 #ifdef AARCH64 650 ldr(rd, target(L.label)); 651 #else 652 ldr(rd, Address(PC, target(L.label) - pc() - 8)); 653 #endif 654 } 655 656 void bind_literal(InlinedAddress& L) { 657 AARCH64_ONLY(align(wordSize)); 658 bind(L.label); 659 assert(L.rspec().type() != relocInfo::metadata_type, "Must use InlinedMetadata"); 660 // We currently do not use oop 'bound' literals. 661 // If the code evolves and the following assert is triggered, 662 // we need to implement InlinedOop (see InlinedMetadata). 663 assert(L.rspec().type() != relocInfo::oop_type, "Inlined oops not supported"); 664 // Note: relocation is handled by relocate calls in ldr_literal 665 AbstractAssembler::emit_address((address)L.target()); 666 } 667 668 void bind_literal(InlinedString& L) { 669 const char* msg = L.msg(); 670 if (code()->consts()->contains((address)msg)) { 671 // The Label should not be used; avoid binding it 672 // to detect errors. 673 return; 674 } 675 AARCH64_ONLY(align(wordSize)); 676 bind(L.label); 677 AbstractAssembler::emit_address((address)L.msg()); 678 } 679 680 void bind_literal(InlinedMetadata& L) { 681 AARCH64_ONLY(align(wordSize)); 682 bind(L.label); 683 relocate(metadata_Relocation::spec_for_immediate()); 684 AbstractAssembler::emit_address((address)L.data()); 685 } 686 687 void resolve_oop_handle(Register result); 688 void load_mirror(Register mirror, Register method, Register tmp); 689 690 // Porting layer between 32-bit ARM and AArch64 691 692 #define COMMON_INSTR_1(common_mnemonic, aarch64_mnemonic, arm32_mnemonic, arg_type) \ 693 void common_mnemonic(arg_type arg) { \ 694 AARCH64_ONLY(aarch64_mnemonic) NOT_AARCH64(arm32_mnemonic) (arg); \ 695 } 696 697 #define COMMON_INSTR_2(common_mnemonic, aarch64_mnemonic, arm32_mnemonic, arg1_type, arg2_type) \ 698 void common_mnemonic(arg1_type arg1, arg2_type arg2) { \ 699 AARCH64_ONLY(aarch64_mnemonic) NOT_AARCH64(arm32_mnemonic) (arg1, arg2); \ 700 } 701 702 #define COMMON_INSTR_3(common_mnemonic, aarch64_mnemonic, arm32_mnemonic, arg1_type, arg2_type, arg3_type) \ 703 void common_mnemonic(arg1_type arg1, arg2_type arg2, arg3_type arg3) { \ 704 AARCH64_ONLY(aarch64_mnemonic) NOT_AARCH64(arm32_mnemonic) (arg1, arg2, arg3); \ 705 } 706 707 COMMON_INSTR_1(jump, br, bx, Register) 708 COMMON_INSTR_1(call, blr, blx, Register) 709 710 COMMON_INSTR_2(cbz_32, cbz_w, cbz, Register, Label&) 711 COMMON_INSTR_2(cbnz_32, cbnz_w, cbnz, Register, Label&) 712 713 COMMON_INSTR_2(ldr_u32, ldr_w, ldr, Register, Address) 714 COMMON_INSTR_2(ldr_s32, ldrsw, ldr, Register, Address) 715 COMMON_INSTR_2(str_32, str_w, str, Register, Address) 716 717 COMMON_INSTR_2(mvn_32, mvn_w, mvn, Register, Register) 718 COMMON_INSTR_2(cmp_32, cmp_w, cmp, Register, Register) 719 COMMON_INSTR_2(neg_32, neg_w, neg, Register, Register) 720 COMMON_INSTR_2(clz_32, clz_w, clz, Register, Register) 721 COMMON_INSTR_2(rbit_32, rbit_w, rbit, Register, Register) 722 723 COMMON_INSTR_2(cmp_32, cmp_w, cmp, Register, int) 724 COMMON_INSTR_2(cmn_32, cmn_w, cmn, Register, int) 725 726 COMMON_INSTR_3(add_32, add_w, add, Register, Register, Register) 727 COMMON_INSTR_3(sub_32, sub_w, sub, Register, Register, Register) 728 COMMON_INSTR_3(subs_32, subs_w, subs, Register, Register, Register) 729 COMMON_INSTR_3(mul_32, mul_w, mul, Register, Register, Register) 730 COMMON_INSTR_3(and_32, andr_w, andr, Register, Register, Register) 731 COMMON_INSTR_3(orr_32, orr_w, orr, Register, Register, Register) 732 COMMON_INSTR_3(eor_32, eor_w, eor, Register, Register, Register) 733 734 COMMON_INSTR_3(add_32, add_w, add, Register, Register, AsmOperand) 735 COMMON_INSTR_3(sub_32, sub_w, sub, Register, Register, AsmOperand) 736 COMMON_INSTR_3(orr_32, orr_w, orr, Register, Register, AsmOperand) 737 COMMON_INSTR_3(eor_32, eor_w, eor, Register, Register, AsmOperand) 738 COMMON_INSTR_3(and_32, andr_w, andr, Register, Register, AsmOperand) 739 740 741 COMMON_INSTR_3(add_32, add_w, add, Register, Register, int) 742 COMMON_INSTR_3(adds_32, adds_w, adds, Register, Register, int) 743 COMMON_INSTR_3(sub_32, sub_w, sub, Register, Register, int) 744 COMMON_INSTR_3(subs_32, subs_w, subs, Register, Register, int) 745 746 COMMON_INSTR_2(tst_32, tst_w, tst, Register, unsigned int) 747 COMMON_INSTR_2(tst_32, tst_w, tst, Register, AsmOperand) 748 749 COMMON_INSTR_3(and_32, andr_w, andr, Register, Register, uint) 750 COMMON_INSTR_3(orr_32, orr_w, orr, Register, Register, uint) 751 COMMON_INSTR_3(eor_32, eor_w, eor, Register, Register, uint) 752 753 COMMON_INSTR_1(cmp_zero_float, fcmp0_s, fcmpzs, FloatRegister) 754 COMMON_INSTR_1(cmp_zero_double, fcmp0_d, fcmpzd, FloatRegister) 755 756 COMMON_INSTR_2(ldr_float, ldr_s, flds, FloatRegister, Address) 757 COMMON_INSTR_2(str_float, str_s, fsts, FloatRegister, Address) 758 COMMON_INSTR_2(mov_float, fmov_s, fcpys, FloatRegister, FloatRegister) 759 COMMON_INSTR_2(neg_float, fneg_s, fnegs, FloatRegister, FloatRegister) 760 COMMON_INSTR_2(abs_float, fabs_s, fabss, FloatRegister, FloatRegister) 761 COMMON_INSTR_2(sqrt_float, fsqrt_s, fsqrts, FloatRegister, FloatRegister) 762 COMMON_INSTR_2(cmp_float, fcmp_s, fcmps, FloatRegister, FloatRegister) 763 764 COMMON_INSTR_3(add_float, fadd_s, fadds, FloatRegister, FloatRegister, FloatRegister) 765 COMMON_INSTR_3(sub_float, fsub_s, fsubs, FloatRegister, FloatRegister, FloatRegister) 766 COMMON_INSTR_3(mul_float, fmul_s, fmuls, FloatRegister, FloatRegister, FloatRegister) 767 COMMON_INSTR_3(div_float, fdiv_s, fdivs, FloatRegister, FloatRegister, FloatRegister) 768 769 COMMON_INSTR_2(ldr_double, ldr_d, fldd, FloatRegister, Address) 770 COMMON_INSTR_2(str_double, str_d, fstd, FloatRegister, Address) 771 COMMON_INSTR_2(mov_double, fmov_d, fcpyd, FloatRegister, FloatRegister) 772 COMMON_INSTR_2(neg_double, fneg_d, fnegd, FloatRegister, FloatRegister) 773 COMMON_INSTR_2(cmp_double, fcmp_d, fcmpd, FloatRegister, FloatRegister) 774 COMMON_INSTR_2(abs_double, fabs_d, fabsd, FloatRegister, FloatRegister) 775 COMMON_INSTR_2(sqrt_double, fsqrt_d, fsqrtd, FloatRegister, FloatRegister) 776 777 COMMON_INSTR_3(add_double, fadd_d, faddd, FloatRegister, FloatRegister, FloatRegister) 778 COMMON_INSTR_3(sub_double, fsub_d, fsubd, FloatRegister, FloatRegister, FloatRegister) 779 COMMON_INSTR_3(mul_double, fmul_d, fmuld, FloatRegister, FloatRegister, FloatRegister) 780 COMMON_INSTR_3(div_double, fdiv_d, fdivd, FloatRegister, FloatRegister, FloatRegister) 781 782 COMMON_INSTR_2(convert_f2d, fcvt_ds, fcvtds, FloatRegister, FloatRegister) 783 COMMON_INSTR_2(convert_d2f, fcvt_sd, fcvtsd, FloatRegister, FloatRegister) 784 785 COMMON_INSTR_2(mov_fpr2gpr_float, fmov_ws, fmrs, Register, FloatRegister) 786 787 #undef COMMON_INSTR_1 788 #undef COMMON_INSTR_2 789 #undef COMMON_INSTR_3 790 791 792 #ifdef AARCH64 793 794 void mov(Register dst, Register src, AsmCondition cond) { 795 if (cond == al) { 796 mov(dst, src); 797 } else { 798 csel(dst, src, dst, cond); 799 } 800 } 801 802 // Propagate other overloaded "mov" methods from Assembler. 803 void mov(Register dst, Register src) { Assembler::mov(dst, src); } 804 void mov(Register rd, int imm) { Assembler::mov(rd, imm); } 805 806 void mov(Register dst, int imm, AsmCondition cond) { 807 assert(imm == 0 || imm == 1, ""); 808 if (imm == 0) { 809 mov(dst, ZR, cond); 810 } else if (imm == 1) { 811 csinc(dst, dst, ZR, inverse(cond)); 812 } else if (imm == -1) { 813 csinv(dst, dst, ZR, inverse(cond)); 814 } else { 815 fatal("illegal mov(R%d,%d,cond)", dst->encoding(), imm); 816 } 817 } 818 819 void movs(Register dst, Register src) { adds(dst, src, 0); } 820 821 #else // AARCH64 822 823 void tbz(Register rt, int bit, Label& L) { 824 assert(0 <= bit && bit < BitsPerWord, "bit number is out of range"); 825 tst(rt, 1 << bit); 826 b(L, eq); 827 } 828 829 void tbnz(Register rt, int bit, Label& L) { 830 assert(0 <= bit && bit < BitsPerWord, "bit number is out of range"); 831 tst(rt, 1 << bit); 832 b(L, ne); 833 } 834 835 void cbz(Register rt, Label& L) { 836 cmp(rt, 0); 837 b(L, eq); 838 } 839 840 void cbz(Register rt, address target) { 841 cmp(rt, 0); 842 b(target, eq); 843 } 844 845 void cbnz(Register rt, Label& L) { 846 cmp(rt, 0); 847 b(L, ne); 848 } 849 850 void ret(Register dst = LR) { 851 bx(dst); 852 } 853 854 #endif // AARCH64 855 856 Register zero_register(Register tmp) { 857 #ifdef AARCH64 858 return ZR; 859 #else 860 mov(tmp, 0); 861 return tmp; 862 #endif 863 } 864 865 void logical_shift_left(Register dst, Register src, int shift) { 866 #ifdef AARCH64 867 _lsl(dst, src, shift); 868 #else 869 mov(dst, AsmOperand(src, lsl, shift)); 870 #endif 871 } 872 873 void logical_shift_left_32(Register dst, Register src, int shift) { 874 #ifdef AARCH64 875 _lsl_w(dst, src, shift); 876 #else 877 mov(dst, AsmOperand(src, lsl, shift)); 878 #endif 879 } 880 881 void logical_shift_right(Register dst, Register src, int shift) { 882 #ifdef AARCH64 883 _lsr(dst, src, shift); 884 #else 885 mov(dst, AsmOperand(src, lsr, shift)); 886 #endif 887 } 888 889 void arith_shift_right(Register dst, Register src, int shift) { 890 #ifdef AARCH64 891 _asr(dst, src, shift); 892 #else 893 mov(dst, AsmOperand(src, asr, shift)); 894 #endif 895 } 896 897 void asr_32(Register dst, Register src, int shift) { 898 #ifdef AARCH64 899 _asr_w(dst, src, shift); 900 #else 901 mov(dst, AsmOperand(src, asr, shift)); 902 #endif 903 } 904 905 // If <cond> holds, compares r1 and r2. Otherwise, flags are set so that <cond> does not hold. 906 void cond_cmp(Register r1, Register r2, AsmCondition cond) { 907 #ifdef AARCH64 908 ccmp(r1, r2, flags_for_condition(inverse(cond)), cond); 909 #else 910 cmp(r1, r2, cond); 911 #endif 912 } 913 914 // If <cond> holds, compares r and imm. Otherwise, flags are set so that <cond> does not hold. 915 void cond_cmp(Register r, int imm, AsmCondition cond) { 916 #ifdef AARCH64 917 ccmp(r, imm, flags_for_condition(inverse(cond)), cond); 918 #else 919 cmp(r, imm, cond); 920 #endif 921 } 922 923 void align_reg(Register dst, Register src, int align) { 924 assert (is_power_of_2(align), "should be"); 925 #ifdef AARCH64 926 andr(dst, src, ~(uintx)(align-1)); 927 #else 928 bic(dst, src, align-1); 929 #endif 930 } 931 932 void prefetch_read(Address addr) { 933 #ifdef AARCH64 934 prfm(pldl1keep, addr); 935 #else 936 pld(addr); 937 #endif 938 } 939 940 void raw_push(Register r1, Register r2) { 941 #ifdef AARCH64 942 stp(r1, r2, Address(SP, -2*wordSize, pre_indexed)); 943 #else 944 assert(r1->encoding() < r2->encoding(), "should be ordered"); 945 push(RegisterSet(r1) | RegisterSet(r2)); 946 #endif 947 } 948 949 void raw_pop(Register r1, Register r2) { 950 #ifdef AARCH64 951 ldp(r1, r2, Address(SP, 2*wordSize, post_indexed)); 952 #else 953 assert(r1->encoding() < r2->encoding(), "should be ordered"); 954 pop(RegisterSet(r1) | RegisterSet(r2)); 955 #endif 956 } 957 958 void raw_push(Register r1, Register r2, Register r3) { 959 #ifdef AARCH64 960 raw_push(r1, r2); 961 raw_push(r3, ZR); 962 #else 963 assert(r1->encoding() < r2->encoding() && r2->encoding() < r3->encoding(), "should be ordered"); 964 push(RegisterSet(r1) | RegisterSet(r2) | RegisterSet(r3)); 965 #endif 966 } 967 968 void raw_pop(Register r1, Register r2, Register r3) { 969 #ifdef AARCH64 970 raw_pop(r3, ZR); 971 raw_pop(r1, r2); 972 #else 973 assert(r1->encoding() < r2->encoding() && r2->encoding() < r3->encoding(), "should be ordered"); 974 pop(RegisterSet(r1) | RegisterSet(r2) | RegisterSet(r3)); 975 #endif 976 } 977 978 // Restores registers r1 and r2 previously saved by raw_push(r1, r2, ret_addr) and returns by ret_addr. Clobbers LR. 979 void raw_pop_and_ret(Register r1, Register r2) { 980 #ifdef AARCH64 981 raw_pop(r1, r2, LR); 982 ret(); 983 #else 984 raw_pop(r1, r2, PC); 985 #endif 986 } 987 988 void indirect_jump(Address addr, Register scratch) { 989 #ifdef AARCH64 990 ldr(scratch, addr); 991 br(scratch); 992 #else 993 ldr(PC, addr); 994 #endif 995 } 996 997 void indirect_jump(InlinedAddress& literal, Register scratch) { 998 #ifdef AARCH64 999 ldr_literal(scratch, literal); 1000 br(scratch); 1001 #else 1002 ldr_literal(PC, literal); 1003 #endif 1004 } 1005 1006 #ifndef AARCH64 1007 void neg(Register dst, Register src) { 1008 rsb(dst, src, 0); 1009 } 1010 #endif 1011 1012 void branch_if_negative_32(Register r, Label& L) { 1013 // Note about branch_if_negative_32() / branch_if_any_negative_32() implementation for AArch64: 1014 // tbnz is not used instead of tst & b.mi because destination may be out of tbnz range (+-32KB) 1015 // since these methods are used in LIR_Assembler::emit_arraycopy() to jump to stub entry. 1016 tst_32(r, r); 1017 b(L, mi); 1018 } 1019 1020 void branch_if_any_negative_32(Register r1, Register r2, Register tmp, Label& L) { 1021 #ifdef AARCH64 1022 orr_32(tmp, r1, r2); 1023 tst_32(tmp, tmp); 1024 #else 1025 orrs(tmp, r1, r2); 1026 #endif 1027 b(L, mi); 1028 } 1029 1030 void branch_if_any_negative_32(Register r1, Register r2, Register r3, Register tmp, Label& L) { 1031 orr_32(tmp, r1, r2); 1032 #ifdef AARCH64 1033 orr_32(tmp, tmp, r3); 1034 tst_32(tmp, tmp); 1035 #else 1036 orrs(tmp, tmp, r3); 1037 #endif 1038 b(L, mi); 1039 } 1040 1041 void add_ptr_scaled_int32(Register dst, Register r1, Register r2, int shift) { 1042 #ifdef AARCH64 1043 add(dst, r1, r2, ex_sxtw, shift); 1044 #else 1045 add(dst, r1, AsmOperand(r2, lsl, shift)); 1046 #endif 1047 } 1048 1049 void sub_ptr_scaled_int32(Register dst, Register r1, Register r2, int shift) { 1050 #ifdef AARCH64 1051 sub(dst, r1, r2, ex_sxtw, shift); 1052 #else 1053 sub(dst, r1, AsmOperand(r2, lsl, shift)); 1054 #endif 1055 } 1056 1057 // C 'boolean' to Java boolean: x == 0 ? 0 : 1 1058 void c2bool(Register x); 1059 1060 // klass oop manipulations if compressed 1061 1062 #ifdef AARCH64 1063 void load_klass(Register dst_klass, Register src_oop); 1064 #else 1065 void load_klass(Register dst_klass, Register src_oop, AsmCondition cond = al); 1066 #endif // AARCH64 1067 1068 void store_klass(Register src_klass, Register dst_oop); 1069 1070 #ifdef AARCH64 1071 void store_klass_gap(Register dst); 1072 #endif // AARCH64 1073 1074 // oop manipulations 1075 1076 void load_heap_oop(Register dst, Address src, Register tmp1 = noreg, Register tmp2 = noreg, Register tmp3 = noreg, DecoratorSet decorators = 0); 1077 void store_heap_oop(Address obj, Register new_val, Register tmp1 = noreg, Register tmp2 = noreg, Register tmp3 = noreg, DecoratorSet decorators = 0); 1078 void store_heap_oop_null(Address obj, Register new_val, Register tmp1 = noreg, Register tmp2 = noreg, Register tmp3 = noreg, DecoratorSet decorators = 0); 1079 1080 void access_load_at(BasicType type, DecoratorSet decorators, Address src, Register dst, Register tmp1, Register tmp2, Register tmp3); 1081 void access_store_at(BasicType type, DecoratorSet decorators, Address obj, Register new_val, Register tmp1, Register tmp2, Register tmp3, bool is_null); 1082 1083 #ifdef AARCH64 1084 void encode_heap_oop(Register dst, Register src); 1085 void encode_heap_oop(Register r) { 1086 encode_heap_oop(r, r); 1087 } 1088 void decode_heap_oop(Register dst, Register src); 1089 void decode_heap_oop(Register r) { 1090 decode_heap_oop(r, r); 1091 } 1092 1093 #ifdef COMPILER2 1094 void encode_heap_oop_not_null(Register dst, Register src); 1095 void decode_heap_oop_not_null(Register dst, Register src); 1096 1097 void set_narrow_klass(Register dst, Klass* k); 1098 void set_narrow_oop(Register dst, jobject obj); 1099 #endif 1100 1101 void encode_klass_not_null(Register r); 1102 void encode_klass_not_null(Register dst, Register src); 1103 void decode_klass_not_null(Register r); 1104 void decode_klass_not_null(Register dst, Register src); 1105 1106 void reinit_heapbase(); 1107 1108 #ifdef ASSERT 1109 void verify_heapbase(const char* msg); 1110 #endif // ASSERT 1111 1112 static int instr_count_for_mov_slow(intptr_t c); 1113 static int instr_count_for_mov_slow(address addr); 1114 static int instr_count_for_decode_klass_not_null(); 1115 #endif // AARCH64 1116 1117 void ldr_global_ptr(Register reg, address address_of_global); 1118 void ldr_global_s32(Register reg, address address_of_global); 1119 void ldrb_global(Register reg, address address_of_global); 1120 1121 // address_placeholder_instruction is invalid instruction and is used 1122 // as placeholder in code for address of label 1123 enum { address_placeholder_instruction = 0xFFFFFFFF }; 1124 1125 void emit_address(Label& L) { 1126 assert(!L.is_bound(), "otherwise address will not be patched"); 1127 target(L); // creates relocation which will be patched later 1128 1129 assert ((offset() & (wordSize-1)) == 0, "should be aligned by word size"); 1130 1131 #ifdef AARCH64 1132 emit_int32(address_placeholder_instruction); 1133 emit_int32(address_placeholder_instruction); 1134 #else 1135 AbstractAssembler::emit_address((address)address_placeholder_instruction); 1136 #endif 1137 } 1138 1139 void b(address target, AsmCondition cond = al) { 1140 Assembler::b(target, cond); \ 1141 } 1142 void b(Label& L, AsmCondition cond = al) { 1143 // internal jumps 1144 Assembler::b(target(L), cond); 1145 } 1146 1147 void bl(address target NOT_AARCH64_ARG(AsmCondition cond = al)) { 1148 Assembler::bl(target NOT_AARCH64_ARG(cond)); 1149 } 1150 void bl(Label& L NOT_AARCH64_ARG(AsmCondition cond = al)) { 1151 // internal calls 1152 Assembler::bl(target(L) NOT_AARCH64_ARG(cond)); 1153 } 1154 1155 #ifndef AARCH64 1156 void adr(Register dest, Label& L, AsmCondition cond = al) { 1157 int delta = target(L) - pc() - 8; 1158 if (delta >= 0) { 1159 add(dest, PC, delta, cond); 1160 } else { 1161 sub(dest, PC, -delta, cond); 1162 } 1163 } 1164 #endif // !AARCH64 1165 1166 // Variable-length jump and calls. We now distinguish only the 1167 // patchable case from the other cases. Patchable must be 1168 // distinguised from relocable. Relocable means the generated code 1169 // containing the jump/call may move. Patchable means that the 1170 // targeted address may be changed later. 1171 1172 // Non patchable versions. 1173 // - used only for relocInfo::runtime_call_type and relocInfo::none 1174 // - may use relative or absolute format (do not use relocInfo::none 1175 // if the generated code may move) 1176 // - the implementation takes into account switch to THUMB mode if the 1177 // destination is a THUMB address 1178 // - the implementation supports far targets 1179 // 1180 // To reduce regression risk, scratch still defaults to noreg on 1181 // arm32. This results in patchable instructions. However, if 1182 // patching really matters, the call sites should be modified and 1183 // use patchable_call or patchable_jump. If patching is not required 1184 // and if a register can be cloberred, it should be explicitly 1185 // specified to allow future optimizations. 1186 void jump(address target, 1187 relocInfo::relocType rtype = relocInfo::runtime_call_type, 1188 Register scratch = AARCH64_ONLY(Rtemp) NOT_AARCH64(noreg) 1189 #ifndef AARCH64 1190 , AsmCondition cond = al 1191 #endif 1192 ); 1193 1194 void call(address target, 1195 RelocationHolder rspec 1196 NOT_AARCH64_ARG(AsmCondition cond = al)); 1197 1198 void call(address target, 1199 relocInfo::relocType rtype = relocInfo::runtime_call_type 1200 NOT_AARCH64_ARG(AsmCondition cond = al)) { 1201 call(target, Relocation::spec_simple(rtype) NOT_AARCH64_ARG(cond)); 1202 } 1203 1204 void jump(AddressLiteral dest) { 1205 jump(dest.target(), dest.reloc()); 1206 } 1207 #ifndef AARCH64 1208 void jump(address dest, relocInfo::relocType rtype, AsmCondition cond) { 1209 jump(dest, rtype, Rtemp, cond); 1210 } 1211 #endif 1212 1213 void call(AddressLiteral dest) { 1214 call(dest.target(), dest.reloc()); 1215 } 1216 1217 // Patchable version: 1218 // - set_destination can be used to atomically change the target 1219 // 1220 // The targets for patchable_jump and patchable_call must be in the 1221 // code cache. 1222 // [ including possible extensions of the code cache, like AOT code ] 1223 // 1224 // To reduce regression risk, scratch still defaults to noreg on 1225 // arm32. If a register can be cloberred, it should be explicitly 1226 // specified to allow future optimizations. 1227 void patchable_jump(address target, 1228 relocInfo::relocType rtype = relocInfo::runtime_call_type, 1229 Register scratch = AARCH64_ONLY(Rtemp) NOT_AARCH64(noreg) 1230 #ifndef AARCH64 1231 , AsmCondition cond = al 1232 #endif 1233 ); 1234 1235 // patchable_call may scratch Rtemp 1236 int patchable_call(address target, 1237 RelocationHolder const& rspec, 1238 bool c2 = false); 1239 1240 int patchable_call(address target, 1241 relocInfo::relocType rtype, 1242 bool c2 = false) { 1243 return patchable_call(target, Relocation::spec_simple(rtype), c2); 1244 } 1245 1246 #if defined(AARCH64) && defined(COMPILER2) 1247 static int call_size(address target, bool far, bool patchable); 1248 #endif 1249 1250 #ifdef AARCH64 1251 static bool page_reachable_from_cache(address target); 1252 #endif 1253 static bool _reachable_from_cache(address target); 1254 static bool _cache_fully_reachable(); 1255 bool cache_fully_reachable(); 1256 bool reachable_from_cache(address target); 1257 1258 void zero_extend(Register rd, Register rn, int bits); 1259 void sign_extend(Register rd, Register rn, int bits); 1260 1261 inline void zap_high_non_significant_bits(Register r) { 1262 #ifdef AARCH64 1263 if(ZapHighNonSignificantBits) { 1264 movk(r, 0xBAAD, 48); 1265 movk(r, 0xF00D, 32); 1266 } 1267 #endif 1268 } 1269 1270 #ifndef AARCH64 1271 void long_move(Register rd_lo, Register rd_hi, 1272 Register rn_lo, Register rn_hi, 1273 AsmCondition cond = al); 1274 void long_shift(Register rd_lo, Register rd_hi, 1275 Register rn_lo, Register rn_hi, 1276 AsmShift shift, Register count); 1277 void long_shift(Register rd_lo, Register rd_hi, 1278 Register rn_lo, Register rn_hi, 1279 AsmShift shift, int count); 1280 1281 void atomic_cas(Register tmpreg1, Register tmpreg2, Register oldval, Register newval, Register base, int offset); 1282 void atomic_cas_bool(Register oldval, Register newval, Register base, int offset, Register tmpreg); 1283 void atomic_cas64(Register temp_lo, Register temp_hi, Register temp_result, Register oldval_lo, Register oldval_hi, Register newval_lo, Register newval_hi, Register base, int offset); 1284 #endif // !AARCH64 1285 1286 void cas_for_lock_acquire(Register oldval, Register newval, Register base, Register tmp, Label &slow_case, bool allow_fallthrough_on_failure = false, bool one_shot = false); 1287 void cas_for_lock_release(Register oldval, Register newval, Register base, Register tmp, Label &slow_case, bool allow_fallthrough_on_failure = false, bool one_shot = false); 1288 1289 #ifndef PRODUCT 1290 // Preserves flags and all registers. 1291 // On SMP the updated value might not be visible to external observers without a sychronization barrier 1292 void cond_atomic_inc32(AsmCondition cond, int* counter_addr); 1293 #endif // !PRODUCT 1294 1295 // unconditional non-atomic increment 1296 void inc_counter(address counter_addr, Register tmpreg1, Register tmpreg2); 1297 void inc_counter(int* counter_addr, Register tmpreg1, Register tmpreg2) { 1298 inc_counter((address) counter_addr, tmpreg1, tmpreg2); 1299 } 1300 1301 void pd_patch_instruction(address branch, address target); 1302 1303 // Loading and storing values by size and signed-ness; 1304 // size must not exceed wordSize (i.e. 8-byte values are not supported on 32-bit ARM); 1305 // each of these calls generates exactly one load or store instruction, 1306 // so src can be pre- or post-indexed address. 1307 #ifdef AARCH64 1308 void load_sized_value(Register dst, Address src, size_t size_in_bytes, bool is_signed); 1309 void store_sized_value(Register src, Address dst, size_t size_in_bytes); 1310 #else 1311 // 32-bit ARM variants also support conditional execution 1312 void load_sized_value(Register dst, Address src, size_t size_in_bytes, bool is_signed, AsmCondition cond = al); 1313 void store_sized_value(Register src, Address dst, size_t size_in_bytes, AsmCondition cond = al); 1314 #endif 1315 1316 void lookup_interface_method(Register recv_klass, 1317 Register intf_klass, 1318 RegisterOrConstant itable_index, 1319 Register method_result, 1320 Register temp_reg1, 1321 Register temp_reg2, 1322 Label& L_no_such_interface); 1323 1324 // Compare char[] arrays aligned to 4 bytes. 1325 void char_arrays_equals(Register ary1, Register ary2, 1326 Register limit, Register result, 1327 Register chr1, Register chr2, Label& Ldone); 1328 1329 1330 void floating_cmp(Register dst); 1331 1332 // improved x86 portability (minimizing source code changes) 1333 1334 void ldr_literal(Register rd, AddressLiteral addr) { 1335 relocate(addr.rspec()); 1336 #ifdef AARCH64 1337 ldr(rd, addr.target()); 1338 #else 1339 ldr(rd, Address(PC, addr.target() - pc() - 8)); 1340 #endif 1341 } 1342 1343 void lea(Register Rd, AddressLiteral addr) { 1344 // Never dereferenced, as on x86 (lval status ignored) 1345 mov_address(Rd, addr.target(), addr.rspec()); 1346 } 1347 1348 void restore_default_fp_mode(); 1349 1350 #ifdef COMPILER2 1351 #ifdef AARCH64 1352 // Code used by cmpFastLock and cmpFastUnlock mach instructions in .ad file. 1353 void fast_lock(Register obj, Register box, Register scratch, Register scratch2, Register scratch3); 1354 void fast_unlock(Register obj, Register box, Register scratch, Register scratch2, Register scratch3); 1355 #else 1356 void fast_lock(Register obj, Register box, Register scratch, Register scratch2); 1357 void fast_unlock(Register obj, Register box, Register scratch, Register scratch2); 1358 #endif 1359 #endif 1360 1361 #ifdef AARCH64 1362 1363 #define F(mnemonic) \ 1364 void mnemonic(Register rt, address target) { \ 1365 Assembler::mnemonic(rt, target); \ 1366 } \ 1367 void mnemonic(Register rt, Label& L) { \ 1368 Assembler::mnemonic(rt, target(L)); \ 1369 } 1370 1371 F(cbz_w); 1372 F(cbnz_w); 1373 F(cbz); 1374 F(cbnz); 1375 1376 #undef F 1377 1378 #define F(mnemonic) \ 1379 void mnemonic(Register rt, int bit, address target) { \ 1380 Assembler::mnemonic(rt, bit, target); \ 1381 } \ 1382 void mnemonic(Register rt, int bit, Label& L) { \ 1383 Assembler::mnemonic(rt, bit, target(L)); \ 1384 } 1385 1386 F(tbz); 1387 F(tbnz); 1388 #undef F 1389 1390 #endif // AARCH64 1391 1392 }; 1393 1394 1395 // The purpose of this class is to build several code fragments of the same size 1396 // in order to allow fast table branch. 1397 1398 class FixedSizeCodeBlock { 1399 public: 1400 FixedSizeCodeBlock(MacroAssembler* masm, int size_in_instrs, bool enabled); 1401 ~FixedSizeCodeBlock(); 1402 1403 private: 1404 MacroAssembler* _masm; 1405 address _start; 1406 int _size_in_instrs; 1407 bool _enabled; 1408 }; 1409 1410 1411 #endif // CPU_ARM_VM_MACROASSEMBLER_ARM_HPP 1412