1 /* 2 * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. 3 * Copyright (c) 2016 SAP SE. All rights reserved. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 * 24 */ 25 26 // Major contributions by AHa, JL, LS 27 28 #ifndef CPU_S390_VM_NATIVEINST_S390_HPP 29 #define CPU_S390_VM_NATIVEINST_S390_HPP 30 31 #include "asm/macroAssembler.hpp" 32 #include "runtime/icache.hpp" 33 #include "runtime/os.hpp" 34 35 class NativeCall; 36 class NativeFarCall; 37 class NativeMovConstReg; 38 class NativeJump; 39 #ifndef COMPILER2 40 class NativeGeneralJump; 41 class NativeMovRegMem; 42 #endif 43 class NativeInstruction; 44 45 NativeCall* nativeCall_before(address return_address); 46 NativeCall* nativeCall_at(address instr); 47 NativeFarCall* nativeFarCall_before(address return_address); 48 NativeFarCall* nativeFarCall_at(address instr); 49 NativeMovConstReg* nativeMovConstReg_at(address address); 50 NativeMovConstReg* nativeMovConstReg_before(address address); 51 NativeJump* nativeJump_at(address address); 52 #ifndef COMPILER2 53 NativeMovRegMem* nativeMovRegMem_at (address address); 54 NativeGeneralJump* nativeGeneralJump_at(address address); 55 #endif 56 NativeInstruction* nativeInstruction_at(address address); 57 58 // We have interface for the following instructions: 59 // - NativeInstruction 60 // - NativeCall 61 // - NativeFarCall 62 // - NativeMovConstReg 63 // - NativeMovRegMem 64 // - NativeJump 65 // - NativeGeneralJump 66 // - NativeIllegalInstruction 67 // The base class for different kinds of native instruction abstractions. 68 // Provides the primitive operations to manipulate code relative to this. 69 70 //------------------------------------- 71 // N a t i v e I n s t r u c t i o n 72 //------------------------------------- 73 74 class NativeInstruction { 75 friend class Relocation; 76 77 public: 78 79 enum z_specific_constants { 80 nop_instruction_size = 2 81 }; 82 83 bool is_illegal(); 84 85 // Bcrl is currently the only accepted instruction here. 86 bool is_jump(); 87 88 // We use an illtrap for marking a method as not_entrant or zombie. 89 bool is_sigill_zombie_not_entrant(); 90 91 bool is_safepoint_poll() { 92 // Is the current instruction a POTENTIAL read access to the polling page? 93 // The instruction's current arguments are not checked! 94 return MacroAssembler::is_load_from_polling_page(addr_at(0)); 95 } 96 97 address get_poll_address(void *ucontext) { 98 // Extract poll address from instruction and ucontext. 99 return MacroAssembler::get_poll_address(addr_at(0), ucontext); 100 } 101 102 uint get_poll_register() { 103 // Extract poll register from instruction. 104 return MacroAssembler::get_poll_register(addr_at(0)); 105 } 106 107 bool is_memory_serialization(JavaThread *thread, void *ucontext) { 108 // Is the current instruction a write access of thread to the 109 // memory serialization page? 110 return MacroAssembler::is_memory_serialization(long_at(0), thread, ucontext); 111 } 112 113 public: 114 115 // The output of __ breakpoint_trap(). 116 static int illegal_instruction(); 117 118 // The address of the currently processed instruction. 119 address instruction_address() const { return addr_at(0); } 120 121 protected: 122 address addr_at(int offset) const { return address(this) + offset; } 123 124 // z/Architecture terminology 125 // halfword = 2 bytes 126 // word = 4 bytes 127 // doubleword = 8 bytes 128 unsigned short halfword_at(int offset) const { return *(unsigned short*)addr_at(offset); } 129 int word_at(int offset) const { return *(jint*)addr_at(offset); } 130 long long_at(int offset) const { return *(jlong*)addr_at(offset); } 131 void set_halfword_at(int offset, short i); // Deals with I-cache. 132 void set_word_at(int offset, int i); // Deals with I-cache. 133 void set_jlong_at(int offset, jlong i); // Deals with I-cache. 134 void set_addr_at(int offset, address x); // Deals with I-cache. 135 136 void print() const; 137 void print(const char* msg) const; 138 void dump() const; 139 void dump(const unsigned int range) const; 140 void dump(const unsigned int range, const char* msg) const; 141 142 public: 143 144 void verify(); 145 146 // unit test stuff 147 static void test() {} // Override for testing. 148 149 friend NativeInstruction* nativeInstruction_at(address address) { 150 NativeInstruction* inst = (NativeInstruction*)address; 151 #ifdef ASSERT 152 inst->verify(); 153 #endif 154 return inst; 155 } 156 }; 157 158 //--------------------------------------------------- 159 // N a t i v e I l l e g a l I n s t r u c t i o n 160 //--------------------------------------------------- 161 162 class NativeIllegalInstruction: public NativeInstruction { 163 public: 164 enum z_specific_constants { 165 instruction_size = 2 166 }; 167 168 // Insert illegal opcode at specific address. 169 static void insert(address code_pos); 170 }; 171 172 //----------------------- 173 // N a t i v e C a l l 174 //----------------------- 175 176 // The NativeCall is an abstraction for accessing/manipulating call 177 // instructions. It is used to manipulate inline caches, primitive & 178 // dll calls, etc. 179 180 // A native call, as defined by this abstraction layer, consists of 181 // all instructions required to set up for and actually make the call. 182 // 183 // On z/Architecture, there exist three different forms of native calls: 184 // 1) Call with pc-relative address, 1 instruction 185 // The location of the target function is encoded as relative address 186 // in the call instruction. The short form (BRAS) allows for a 187 // 16-bit signed relative address (in 2-byte units). The long form 188 // (BRASL) allows for a 32-bit signed relative address (in 2-byte units). 189 // 2) Call with immediate address, 3 or 5 instructions. 190 // The location of the target function is given by an immediate 191 // constant which is loaded into a (scratch) register. Depending on 192 // the hardware capabilities, this takes 2 or 4 instructions. 193 // The call itself is then a "call by register"(BASR) instruction. 194 // 3) Call with address from constant pool, 2(3) instructions (with dynamic TOC) 195 // The location of the target function is stored in the constant pool 196 // during compilation. From there it is loaded into a (scratch) register. 197 // The call itself is then a "call by register"(BASR) instruction. 198 // 199 // When initially generating a call, the compiler uses form 2) (not 200 // patchable, target address constant, e.g. runtime calls) or 3) (patchable, 201 // target address might eventually get relocated). Later in the process, 202 // a call could be transformed into form 1) (also patchable) during ShortenBranches. 203 // 204 // If a call is/has to be patchable, the instruction sequence generated for it 205 // has to be constant in length. Excessive space, created e.g. by ShortenBranches, 206 // is allocated to lower addresses and filled with nops. That is necessary to 207 // keep the return address constant, no matter what form the call has. 208 // Methods dealing with such calls have "patchable" as part of their name. 209 210 class NativeCall: public NativeInstruction { 211 public: 212 213 static int get_IC_pos_in_java_to_interp_stub() { 214 return 0; 215 } 216 217 enum z_specific_constants { 218 instruction_size = 18, // Used in shared code for calls with reloc_info: 219 // value correct if !has_long_displacement_fast(). 220 call_far_pcrelative_displacement_offset = 4, // Includes 2 bytes for the nop. 221 call_far_pcrelative_displacement_alignment = 4 222 }; 223 224 225 // Maximum size (in bytes) of a call to an absolute address. 226 // Used when emitting call to deopt handler blob, which is a 227 // "load_const_call". The code pattern is: 228 // tmpReg := load_const(address); (* depends on CPU ArchLvl, but is otherwise constant *) 229 // call(tmpReg); (* basr, 2 bytes *) 230 static unsigned int max_instruction_size() { 231 return MacroAssembler::load_const_size() + MacroAssembler::call_byregister_size(); 232 } 233 234 // address instruction_address() const { return addr_at(0); } 235 236 // For the ordering of the checks see note at nativeCall_before. 237 address next_instruction_address() const { 238 address iaddr = instruction_address(); 239 240 if (MacroAssembler::is_load_const_call(iaddr)) { 241 // Form 2): load_const, BASR 242 return addr_at(MacroAssembler::load_const_call_size()); 243 } 244 245 if (MacroAssembler::is_load_const_from_toc_call(iaddr)) { 246 // Form 3): load_const_from_toc (LARL+LG/LGRL), BASR. 247 return addr_at(MacroAssembler::load_const_from_toc_call_size()); 248 } 249 250 if (MacroAssembler::is_call_far_pcrelative(iaddr)) { 251 // Form 1): NOP, BRASL 252 // The BRASL (Branch Relative And Save Long) is patched into the space created 253 // by the load_const_from_toc_call sequence (typically (LARL-LG)/LGRL - BASR. 254 // The BRASL must be positioned such that it's end is FW (4-byte) aligned (for atomic patching). 255 // It is achieved by aligning the end of the entire sequence on a 4byte boundary, by inserting 256 // a nop, if required, at the very beginning of the instruction sequence. The nop needs to 257 // be accounted for when calculating the next instruction address. The alignment takes place 258 // already when generating the original instruction sequence. The alignment requirement 259 // makes the size depend on location. 260 // The return address of the call must always be at the end of the instruction sequence. 261 // Inserting the extra alignment nop (or anything else) at the end is not an option. 262 // The patched-in brasl instruction is prepended with a nop to make it easier to 263 // distinguish from a load_const_from_toc_call sequence. 264 return addr_at(MacroAssembler::call_far_pcrelative_size()); 265 } 266 267 ((NativeCall*)iaddr)->print(); 268 guarantee(false, "Not a NativeCall site"); 269 return NULL; 270 } 271 272 address return_address() const { 273 return next_instruction_address(); 274 } 275 276 address destination() const; 277 278 void set_destination_mt_safe(address dest); 279 280 void verify_alignment() {} // Yet another real do nothing guy :) 281 void verify(); 282 283 // unit test stuff 284 static void test(); 285 286 // Creation. 287 friend NativeCall* nativeCall_at(address instr) { 288 NativeCall* call; 289 290 // Make sure not to return garbage. 291 if (NativeCall::is_call_at(instr)) { 292 call = (NativeCall*)instr; 293 } else { 294 call = (NativeCall*)instr; 295 call->print(); 296 guarantee(false, "Not a NativeCall site"); 297 } 298 299 #ifdef ASSERT 300 call->verify(); 301 #endif 302 return call; 303 } 304 305 // This is a very tricky function to implement. It involves stepping 306 // backwards in the instruction stream. On architectures with variable 307 // instruction length, this is a risky endeavor. From the return address, 308 // you do not know how far to step back to be at a location (your starting 309 // point) that will eventually bring you back to the return address. 310 // Furthermore, it may happen that there are multiple starting points. 311 // 312 // With only a few possible (allowed) code patterns, the risk is lower but 313 // does not diminish completely. Experience shows that there are code patterns 314 // which look like a load_const_from_toc_call @(return address-8), but in 315 // fact are a call_far_pcrelative @(return address-6). The other way around 316 // is possible as well, but was not knowingly observed so far. 317 // 318 // The unpredictability is caused by the pc-relative address field in both 319 // the call_far_pcrelative (BASR) and the load_const_from_toc (LGRL) 320 // instructions. This field can contain an arbitrary bit pattern. 321 // 322 // Here is a real-world example: 323 // Mnemonics: <not a valid sequence> LGRL r10,<addr> BASR r14,r10 324 // Hex code: eb01 9008 007a c498 ffff c4a8 c0e5 ffc1 0dea 325 // Mnemonics: AGSI <mem>,I8 LGRL r9,<addr> BRASL r14,<addr> correct 326 // 327 // If you first check for a load_const_from_toc_call @(-8), you will find 328 // a false positive. In this example, it is obviously false, because the 329 // preceding bytes do not form a valid instruction pattern. If you first 330 // check for call_far_pcrelative @(-6), you get a true positive - in this 331 // case. 332 // 333 // The following remedy has been implemented/enforced: 334 // 1) Everywhere, the permissible code patterns are checked in the same 335 // sequence: Form 2) - Form 3) - Form 1). 336 // 2) The call_far_pcrelative, which would ideally be just one BRASL 337 // instruction, is always prepended with a NOP. This measure avoids 338 // ambiguities with load_const_from_toc_call. 339 friend NativeCall* nativeCall_before(address return_address) { 340 NativeCall *call = NULL; 341 342 // Make sure not to return garbage 343 address instp = return_address - MacroAssembler::load_const_call_size(); 344 if (MacroAssembler::is_load_const_call(instp)) { // Form 2) 345 call = (NativeCall*)(instp); // load_const + basr 346 } else { 347 instp = return_address - MacroAssembler::load_const_from_toc_call_size(); 348 if (MacroAssembler::is_load_const_from_toc_call(instp)) { // Form 3) 349 call = (NativeCall*)(instp); // load_const_from_toc + basr 350 } else { 351 instp = return_address - MacroAssembler::call_far_pcrelative_size(); 352 if (MacroAssembler::is_call_far_pcrelative(instp)) { // Form 1) 353 call = (NativeCall*)(instp); // brasl (or nop + brasl) 354 } else { 355 call = (NativeCall*)(instp); 356 call->print(); 357 guarantee(false, "Not a NativeCall site"); 358 } 359 } 360 } 361 362 #ifdef ASSERT 363 call->verify(); 364 #endif 365 return call; 366 } 367 368 // Ordering of checks 2) 3) 1) is relevant! 369 static bool is_call_at(address a) { 370 // Check plain instruction sequence. Do not care about filler or alignment nops. 371 bool b = MacroAssembler::is_load_const_call(a) || // load_const + basr 372 MacroAssembler::is_load_const_from_toc_call(a) || // load_const_from_toc + basr 373 MacroAssembler::is_call_far_pcrelative(a); // nop + brasl 374 return b; 375 } 376 377 // Ordering of checks 2) 3) 1) is relevant! 378 static bool is_call_before(address a) { 379 // check plain instruction sequence. Do not care about filler or alignment nops. 380 bool b = MacroAssembler::is_load_const_call( a - MacroAssembler::load_const_call_size()) || // load_const + basr 381 MacroAssembler::is_load_const_from_toc_call(a - MacroAssembler::load_const_from_toc_call_size()) || // load_const_from_toc + basr 382 MacroAssembler::is_call_far_pcrelative( a - MacroAssembler::call_far_pcrelative_size()); // nop+brasl 383 return b; 384 } 385 386 static bool is_call_to(address instr, address target) { 387 // Check whether there is a `NativeCall' at the address `instr' 388 // calling to the address `target'. 389 return is_call_at(instr) && target == ((NativeCall *)instr)->destination(); 390 } 391 392 bool is_pcrelative() { 393 return MacroAssembler::is_call_far_pcrelative((address)this); 394 } 395 }; 396 397 //----------------------------- 398 // N a t i v e F a r C a l l 399 //----------------------------- 400 401 // The NativeFarCall is an abstraction for accessing/manipulating native 402 // call-anywhere instructions. 403 // Used to call native methods which may be loaded anywhere in the address 404 // space, possibly out of reach of a call instruction. 405 406 // Refer to NativeCall for a description of the supported call forms. 407 408 class NativeFarCall: public NativeInstruction { 409 410 public: 411 // We use MacroAssembler::call_far_patchable() for implementing a 412 // call-anywhere instruction. 413 414 static int instruction_size() { return MacroAssembler::call_far_patchable_size(); } 415 static int return_address_offset() { return MacroAssembler::call_far_patchable_ret_addr_offset(); } 416 417 // address instruction_address() const { return addr_at(0); } 418 419 address next_instruction_address() const { 420 return addr_at(instruction_size()); 421 } 422 423 address return_address() const { 424 return addr_at(return_address_offset()); 425 } 426 427 // Returns the NativeFarCall's destination. 428 address destination(); 429 430 // Sets the NativeCall's destination, not necessarily mt-safe. 431 // Used when relocating code. 432 void set_destination(address dest, int toc_offset); 433 434 // Checks whether instr points at a NativeFarCall instruction. 435 static bool is_far_call_at(address instr) { 436 // Use compound inspection function which, in addition to instruction sequence, 437 // also checks for expected nops and for instruction alignment. 438 return MacroAssembler::is_call_far_patchable_at(instr); 439 } 440 441 // Does the NativeFarCall implementation use a pc-relative encoding 442 // of the call destination? 443 // Used when relocating code. 444 bool is_pcrelative() { 445 address iaddr = (address)this; 446 assert(is_far_call_at(iaddr), "unexpected call type"); 447 return MacroAssembler::is_call_far_patchable_pcrelative_at(iaddr); 448 } 449 450 void verify(); 451 452 // Unit tests 453 static void test(); 454 455 // Instantiates a NativeFarCall object starting at the given instruction 456 // address and returns the NativeFarCall object. 457 inline friend NativeFarCall* nativeFarCall_at(address instr) { 458 NativeFarCall* call = (NativeFarCall*)instr; 459 #ifdef ASSERT 460 call->verify(); 461 #endif 462 return call; 463 } 464 }; 465 466 467 //------------------------------------- 468 // N a t i v e M o v C o n s t R e g 469 //------------------------------------- 470 471 // An interface for accessing/manipulating native set_oop imm, reg instructions. 472 // (Used to manipulate inlined data references, etc.) 473 474 // A native move of a constant into a register, as defined by this abstraction layer, 475 // deals with instruction sequences that load "quasi constant" oops into registers 476 // for addressing. For multiple causes, those "quasi constant" oops eventually need 477 // to be changed (i.e. patched). The reason is quite simple: objects might get moved 478 // around in storage. Pc-relative oop addresses have to be patched also if the 479 // reference location is moved. That happens when executable code is relocated. 480 481 class NativeMovConstReg: public NativeInstruction { 482 public: 483 484 enum z_specific_constants { 485 instruction_size = 10 // Used in shared code for calls with reloc_info. 486 }; 487 488 // address instruction_address() const { return addr_at(0); } 489 490 // The current instruction might be located at an offset. 491 address next_instruction_address(int offset = 0) const; 492 493 // (The [set_]data accessor respects oop_type relocs also.) 494 intptr_t data() const; 495 496 // Patch data in code stream. 497 address set_data_plain(intptr_t x, CodeBlob *code); 498 // Patch data in code stream and oop pool if necessary. 499 void set_data(intptr_t x); 500 501 // Patch narrow oop constant in code stream. 502 void set_narrow_oop(intptr_t data); 503 void set_narrow_klass(intptr_t data); 504 void set_pcrel_addr(intptr_t addr, CompiledMethod *nm = NULL, bool copy_back_to_oop_pool=false); 505 void set_pcrel_data(intptr_t data, CompiledMethod *nm = NULL, bool copy_back_to_oop_pool=false); 506 507 void verify(); 508 509 // unit test stuff 510 static void test(); 511 512 // Creation. 513 friend NativeMovConstReg* nativeMovConstReg_at(address address) { 514 NativeMovConstReg* test = (NativeMovConstReg*)address; 515 #ifdef ASSERT 516 test->verify(); 517 #endif 518 return test; 519 } 520 }; 521 522 523 #ifdef COMPILER1 524 //--------------------------------- 525 // N a t i v e M o v R e g M e m 526 //--------------------------------- 527 528 // Interface to manipulate a code sequence that performs a memory access (load/store). 529 // The code is the patchable version of memory accesses generated by 530 // LIR_Assembler::reg2mem() and LIR_Assembler::mem2reg(). 531 // 532 // Loading the offset for the mem access is target of the manipulation. 533 // 534 // The instruction sequence looks like this: 535 // iihf %r1,$bits1 ; load offset for mem access 536 // iilf %r1,$bits2 537 // [compress oop] ; optional, load only 538 // load/store %r2,0(%r1,%r2) ; memory access 539 540 class NativeMovRegMem; 541 inline NativeMovRegMem* nativeMovRegMem_at (address address); 542 class NativeMovRegMem: public NativeInstruction { 543 public: 544 intptr_t offset() const { 545 return nativeMovConstReg_at(addr_at(0))->data(); 546 } 547 void set_offset(intptr_t x) { 548 nativeMovConstReg_at(addr_at(0))->set_data(x); 549 } 550 void add_offset_in_bytes(intptr_t radd_offset) { 551 set_offset(offset() + radd_offset); 552 } 553 void verify(); 554 555 private: 556 friend inline NativeMovRegMem* nativeMovRegMem_at(address address) { 557 NativeMovRegMem* test = (NativeMovRegMem*)address; 558 #ifdef ASSERT 559 test->verify(); 560 #endif 561 return test; 562 } 563 }; 564 #endif // COMPILER1 565 566 567 //----------------------- 568 // N a t i v e J u m p 569 //----------------------- 570 571 572 // An interface for accessing/manipulating native jumps 573 class NativeJump: public NativeInstruction { 574 public: 575 enum z_constants { 576 instruction_size = 2 // Size of z_illtrap(). 577 }; 578 579 // Maximum size (in bytes) of a jump to an absolute address. 580 // Used when emitting branch to an exception handler which is a "load_const_optimized_branch". 581 // Thus, a pessimistic estimate is obtained when using load_const. 582 // code pattern is: 583 // tmpReg := load_const(address); (* varying size *) 584 // jumpTo(tmpReg); (* bcr, 2 bytes *) 585 // 586 static unsigned int max_instruction_size() { 587 return MacroAssembler::load_const_size() + MacroAssembler::jump_byregister_size(); 588 } 589 590 591 // address instruction_address() const { return addr_at(0); } 592 593 address jump_destination() const { 594 return (address)nativeMovConstReg_at(instruction_address())->data(); 595 } 596 597 void set_jump_destination(address dest) { 598 nativeMovConstReg_at(instruction_address())->set_data(((intptr_t)dest)); 599 } 600 601 // Creation 602 friend NativeJump* nativeJump_at(address address) { 603 NativeJump* jump = (NativeJump*)address; 604 #ifdef ASSERT 605 jump->verify(); 606 #endif 607 return jump; 608 } 609 610 static bool is_jump_at(address a) { 611 int off = 0; 612 bool b = (MacroAssembler::is_load_const_from_toc(a+off) && 613 Assembler::is_z_br(*(short*)(a+off + MacroAssembler::load_const_from_toc_size()))); 614 b = b || (MacroAssembler::is_load_const(a+off) && 615 Assembler::is_z_br(*(short*)(a+off + MacroAssembler::load_const_size()))); 616 return b; 617 } 618 619 void verify(); 620 621 // Unit testing stuff 622 static void test(); 623 624 // Insertion of native jump instruction. 625 static void insert(address code_pos, address entry); 626 627 // MT-safe insertion of native jump at verified method entry. 628 static void check_verified_entry_alignment(address entry, address verified_entry) { } 629 630 static void patch_verified_entry(address entry, address verified_entry, address dest); 631 }; 632 633 //------------------------------------- 634 // N a t i v e G e n e r a l J u m p 635 //------------------------------------- 636 637 // Despite the name, handles only simple branches. 638 // On ZARCH_64 BRCL only. 639 class NativeGeneralJump; 640 inline NativeGeneralJump* nativeGeneralJump_at(address address); 641 class NativeGeneralJump: public NativeInstruction { 642 public: 643 enum ZARCH_specific_constants { 644 instruction_size = 6 645 }; 646 647 address instruction_address() const { return addr_at(0); } 648 address jump_destination() const { return addr_at(0) + MacroAssembler::get_pcrel_offset(addr_at(0)); } 649 650 // Creation 651 friend inline NativeGeneralJump* nativeGeneralJump_at(address addr) { 652 NativeGeneralJump* jump = (NativeGeneralJump*)(addr); 653 #ifdef ASSERT 654 jump->verify(); 655 #endif 656 return jump; 657 } 658 659 // Insertion of native general jump instruction. 660 static void insert_unconditional(address code_pos, address entry); 661 662 void set_jump_destination(address dest) { 663 Unimplemented(); 664 // set_word_at(MacroAssembler::call_far_pcrelative_size()-4, Assembler::z_pcrel_off(dest, addr_at(0))); 665 } 666 667 static void replace_mt_safe(address instr_addr, address code_buffer); 668 669 void verify() PRODUCT_RETURN; 670 }; 671 672 #endif // CPU_S390_VM_NATIVEINST_S390_HPP