1 /*
   2  * Copyright (c) 1997, 2010, 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_X86_VM_ASSEMBLER_X86_INLINE_HPP
  26 #define CPU_X86_VM_ASSEMBLER_X86_INLINE_HPP
  27 
  28 #include "asm/assembler.inline.hpp"
  29 #include "asm/codeBuffer.hpp"
  30 #include "code/codeCache.hpp"
  31 #include "runtime/handles.inline.hpp"
  32 
  33 inline void MacroAssembler::pd_patch_instruction(address branch, address target) {
  34   unsigned char op = branch[0];
  35   assert(op == 0xE8 /* call */ ||
  36          op == 0xE9 /* jmp */ ||
  37          op == 0xEB /* short jmp */ ||
  38          (op & 0xF0) == 0x70 /* short jcc */ ||
  39          op == 0x0F && (branch[1] & 0xF0) == 0x80 /* jcc */,
  40          "Invalid opcode at patch point");
  41 
  42   if (op == 0xEB || (op & 0xF0) == 0x70) {
  43     // short offset operators (jmp and jcc)
  44     char* disp = (char*) &branch[1];
  45     int imm8 = target - (address) &disp[1];
  46     guarantee(this->is8bit(imm8), "Short forward jump exceeds 8-bit offset");
  47     *disp = imm8;
  48   } else {
  49     int* disp = (int*) &branch[(op == 0x0F)? 2: 1];
  50     int imm32 = target - (address) &disp[1];
  51     *disp = imm32;
  52   }
  53 }
  54 
  55 #ifndef PRODUCT
  56 inline void MacroAssembler::pd_print_patched_instruction(address branch) {
  57   const char* s;
  58   unsigned char op = branch[0];
  59   if (op == 0xE8) {
  60     s = "call";
  61   } else if (op == 0xE9 || op == 0xEB) {
  62     s = "jmp";
  63   } else if ((op & 0xF0) == 0x70) {
  64     s = "jcc";
  65   } else if (op == 0x0F) {
  66     s = "jcc";
  67   } else {
  68     s = "????";
  69   }
  70   tty->print("%s (unresolved)", s);
  71 }
  72 #endif // ndef PRODUCT
  73 
  74 #ifndef _LP64
  75 inline int Assembler::prefix_and_encode(int reg_enc, bool byteinst) { return reg_enc; }
  76 inline int Assembler::prefixq_and_encode(int reg_enc) { return reg_enc; }
  77 
  78 inline int Assembler::prefix_and_encode(int dst_enc, int src_enc, bool byteinst) { return dst_enc << 3 | src_enc; }
  79 inline int Assembler::prefixq_and_encode(int dst_enc, int src_enc) { return dst_enc << 3 | src_enc; }
  80 
  81 inline void Assembler::prefix(Register reg) {}
  82 inline void Assembler::prefix(Address adr) {}
  83 inline void Assembler::prefixq(Address adr) {}
  84 
  85 inline void Assembler::prefix(Address adr, Register reg,  bool byteinst) {}
  86 inline void Assembler::prefixq(Address adr, Register reg) {}
  87 
  88 inline void Assembler::prefix(Address adr, XMMRegister reg) {}
  89 #else
  90 inline void Assembler::emit_long64(jlong x) {
  91   *(jlong*) _code_pos = x;
  92   _code_pos += sizeof(jlong);
  93   code_section()->set_end(_code_pos);
  94 }
  95 #endif // _LP64
  96 
  97 #endif // CPU_X86_VM_ASSEMBLER_X86_INLINE_HPP