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