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