relocInfo_sparc.cpp revision 9111:a41fe5ffa839
1/*
2 * Copyright (c) 1998, 2013, 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#include "precompiled.hpp"
26#include "asm/assembler.hpp"
27#include "code/relocInfo.hpp"
28#include "nativeInst_sparc.hpp"
29#include "oops/klass.inline.hpp"
30#include "oops/oop.inline.hpp"
31#include "runtime/safepoint.hpp"
32
33void Relocation::pd_set_data_value(address x, intptr_t o, bool verify_only) {
34  NativeInstruction* ip = nativeInstruction_at(addr());
35  jint inst = ip->long_at(0);
36  assert(inst != NativeInstruction::illegal_instruction(), "no breakpoint");
37  switch (Assembler::inv_op(inst)) {
38
39  case Assembler::ldst_op:
40    #ifdef ASSERT
41      switch (Assembler::inv_op3(inst)) {
42        case Assembler::lduw_op3:
43        case Assembler::ldub_op3:
44        case Assembler::lduh_op3:
45        case Assembler::ldd_op3:
46        case Assembler::ldsw_op3:
47        case Assembler::ldsb_op3:
48        case Assembler::ldsh_op3:
49        case Assembler::ldx_op3:
50        case Assembler::ldf_op3:
51        case Assembler::lddf_op3:
52        case Assembler::stw_op3:
53        case Assembler::stb_op3:
54        case Assembler::sth_op3:
55        case Assembler::std_op3:
56        case Assembler::stx_op3:
57        case Assembler::stf_op3:
58        case Assembler::stdf_op3:
59        case Assembler::casa_op3:
60        case Assembler::casxa_op3:
61          break;
62        default:
63          ShouldNotReachHere();
64      }
65      goto do_non_sethi;
66    #endif
67
68  case Assembler::arith_op:
69    #ifdef ASSERT
70      switch (Assembler::inv_op3(inst)) {
71        case Assembler::or_op3:
72        case Assembler::add_op3:
73        case Assembler::jmpl_op3:
74          break;
75        default:
76          ShouldNotReachHere();
77      }
78    do_non_sethi:;
79    #endif
80    {
81    guarantee(Assembler::inv_immed(inst), "must have a simm13 field");
82    int simm13 = Assembler::low10((intptr_t)x) + o;
83    guarantee(Assembler::is_simm13(simm13), "offset can't overflow simm13");
84    inst &= ~Assembler::simm(    -1, 13);
85    inst |=  Assembler::simm(simm13, 13);
86    if (verify_only) {
87      assert(ip->long_at(0) == inst, "instructions must match");
88    } else {
89      ip->set_long_at(0, inst);
90    }
91    }
92    break;
93
94  case Assembler::branch_op:
95    {
96#ifdef _LP64
97    jint inst2;
98    guarantee(Assembler::inv_op2(inst)==Assembler::sethi_op2, "must be sethi");
99    if (format() != 0) {
100      assert(type() == relocInfo::oop_type || type() == relocInfo::metadata_type, "only narrow oops or klasses case");
101      jint np = type() == relocInfo::oop_type ? oopDesc::encode_heap_oop((oop)x) : Klass::encode_klass((Klass*)x);
102      inst &= ~Assembler::hi22(-1);
103      inst |=  Assembler::hi22((intptr_t)np);
104      if (verify_only) {
105        assert(ip->long_at(0) == inst, "instructions must match");
106      } else {
107        ip->set_long_at(0, inst);
108      }
109      inst2 = ip->long_at( NativeInstruction::nop_instruction_size );
110      guarantee(Assembler::inv_op(inst2)==Assembler::arith_op, "arith op");
111      if (verify_only) {
112        assert(ip->long_at(NativeInstruction::nop_instruction_size) == NativeInstruction::set_data32_simm13( inst2, (intptr_t)np),
113               "instructions must match");
114      } else {
115        ip->set_long_at(NativeInstruction::nop_instruction_size, NativeInstruction::set_data32_simm13( inst2, (intptr_t)np));
116      }
117      break;
118    }
119    if (verify_only) {
120      ip->verify_data64_sethi( ip->addr_at(0), (intptr_t)x );
121    } else {
122      ip->set_data64_sethi( ip->addr_at(0), (intptr_t)x );
123    }
124#else
125    guarantee(Assembler::inv_op2(inst)==Assembler::sethi_op2, "must be sethi");
126    inst &= ~Assembler::hi22(     -1);
127    inst |=  Assembler::hi22((intptr_t)x);
128    // (ignore offset; it doesn't play into the sethi)
129    if (verify_only) {
130      assert(ip->long_at(0) == inst, "instructions must match");
131    } else {
132      ip->set_long_at(0, inst);
133    }
134#endif
135    }
136    break;
137
138  default:
139    guarantee(false, "instruction must perform arithmetic or memory access");
140  }
141}
142
143
144address Relocation::pd_call_destination(address orig_addr) {
145  intptr_t adj = 0;
146  if (orig_addr != NULL) {
147    // We just moved this call instruction from orig_addr to addr().
148    // This means its target will appear to have grown by addr() - orig_addr.
149    adj = -( addr() - orig_addr );
150  }
151  if (NativeCall::is_call_at(addr())) {
152    NativeCall* call = nativeCall_at(addr());
153    return call->destination() + adj;
154  }
155  if (NativeFarCall::is_call_at(addr())) {
156    NativeFarCall* call = nativeFarCall_at(addr());
157    return call->destination() + adj;
158  }
159  // Special case:  Patchable branch local to the code cache.
160  // This will break badly if the code cache grows larger than a few Mb.
161  NativeGeneralJump* br = nativeGeneralJump_at(addr());
162  return br->jump_destination() + adj;
163}
164
165
166void Relocation::pd_set_call_destination(address x) {
167  if (NativeCall::is_call_at(addr())) {
168    NativeCall* call = nativeCall_at(addr());
169    call->set_destination(x);
170    return;
171  }
172  if (NativeFarCall::is_call_at(addr())) {
173    NativeFarCall* call = nativeFarCall_at(addr());
174    call->set_destination(x);
175    return;
176  }
177  // Special case:  Patchable branch local to the code cache.
178  // This will break badly if the code cache grows larger than a few Mb.
179  NativeGeneralJump* br = nativeGeneralJump_at(addr());
180  br->set_jump_destination(x);
181}
182
183
184address* Relocation::pd_address_in_code() {
185  // SPARC never embeds addresses in code, at present.
186  //assert(type() == relocInfo::oop_type, "only oops are inlined at present");
187  return (address*)addr();
188}
189
190
191address Relocation::pd_get_address_from_code() {
192  // SPARC never embeds addresses in code, at present.
193  //assert(type() == relocInfo::oop_type, "only oops are inlined at present");
194  return *(address*)addr();
195}
196
197void poll_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) {
198}
199
200void metadata_Relocation::pd_fix_value(address x) {
201}
202