Wed, 24 Apr 2013 20:55:28 -0400
8003853: specify offset of IC load in java_to_interp stub
Summary: refactored code to allow platform-specific differences
Reviewed-by: dlong, twisti
Contributed-by: Goetz Lindenmaier <goetz.lindenmaier@sap.com>
twisti@4323 | 1 | /* |
twisti@4323 | 2 | * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. |
twisti@4323 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
twisti@4323 | 4 | * |
twisti@4323 | 5 | * This code is free software; you can redistribute it and/or modify it |
twisti@4323 | 6 | * under the terms of the GNU General Public License version 2 only, as |
twisti@4323 | 7 | * published by the Free Software Foundation. |
twisti@4323 | 8 | * |
twisti@4323 | 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
twisti@4323 | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
twisti@4323 | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
twisti@4323 | 12 | * version 2 for more details (a copy is included in the LICENSE file that |
twisti@4323 | 13 | * accompanied this code). |
twisti@4323 | 14 | * |
twisti@4323 | 15 | * You should have received a copy of the GNU General Public License version |
twisti@4323 | 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
twisti@4323 | 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
twisti@4323 | 18 | * |
twisti@4323 | 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
twisti@4323 | 20 | * or visit www.oracle.com if you need additional information or have any |
twisti@4323 | 21 | * questions. |
twisti@4323 | 22 | * |
twisti@4323 | 23 | */ |
twisti@4323 | 24 | |
twisti@4323 | 25 | #ifndef CPU_SPARC_VM_MACROASSEMBLER_SPARC_INLINE_HPP |
twisti@4323 | 26 | #define CPU_SPARC_VM_MACROASSEMBLER_SPARC_INLINE_HPP |
twisti@4323 | 27 | |
twisti@4323 | 28 | #include "asm/assembler.inline.hpp" |
twisti@4323 | 29 | #include "asm/macroAssembler.hpp" |
twisti@4323 | 30 | #include "asm/codeBuffer.hpp" |
twisti@4323 | 31 | #include "code/codeCache.hpp" |
twisti@4323 | 32 | |
twisti@4323 | 33 | inline bool Address::is_simm13(int offset) { return Assembler::is_simm13(disp() + offset); } |
twisti@4323 | 34 | |
twisti@4323 | 35 | |
twisti@4323 | 36 | inline int AddressLiteral::low10() const { |
twisti@4323 | 37 | return Assembler::low10(value()); |
twisti@4323 | 38 | } |
twisti@4323 | 39 | |
twisti@4323 | 40 | |
twisti@4323 | 41 | inline void MacroAssembler::pd_patch_instruction(address branch, address target) { |
twisti@4323 | 42 | jint& stub_inst = *(jint*) branch; |
twisti@4323 | 43 | stub_inst = patched_branch(target - branch, stub_inst, 0); |
twisti@4323 | 44 | } |
twisti@4323 | 45 | |
twisti@4323 | 46 | // Use the right loads/stores for the platform |
twisti@4323 | 47 | inline void MacroAssembler::ld_ptr( Register s1, Register s2, Register d ) { |
twisti@4323 | 48 | #ifdef _LP64 |
twisti@4323 | 49 | Assembler::ldx(s1, s2, d); |
twisti@4323 | 50 | #else |
twisti@4323 | 51 | ld( s1, s2, d); |
twisti@4323 | 52 | #endif |
twisti@4323 | 53 | } |
twisti@4323 | 54 | |
twisti@4323 | 55 | inline void MacroAssembler::ld_ptr( Register s1, int simm13a, Register d ) { |
twisti@4323 | 56 | #ifdef _LP64 |
twisti@4323 | 57 | Assembler::ldx(s1, simm13a, d); |
twisti@4323 | 58 | #else |
twisti@4323 | 59 | ld( s1, simm13a, d); |
twisti@4323 | 60 | #endif |
twisti@4323 | 61 | } |
twisti@4323 | 62 | |
twisti@4323 | 63 | #ifdef ASSERT |
twisti@4323 | 64 | // ByteSize is only a class when ASSERT is defined, otherwise it's an int. |
twisti@4323 | 65 | inline void MacroAssembler::ld_ptr( Register s1, ByteSize simm13a, Register d ) { |
twisti@4323 | 66 | ld_ptr(s1, in_bytes(simm13a), d); |
twisti@4323 | 67 | } |
twisti@4323 | 68 | #endif |
twisti@4323 | 69 | |
twisti@4323 | 70 | inline void MacroAssembler::ld_ptr( Register s1, RegisterOrConstant s2, Register d ) { |
twisti@4323 | 71 | #ifdef _LP64 |
twisti@4323 | 72 | ldx(s1, s2, d); |
twisti@4323 | 73 | #else |
twisti@4323 | 74 | ld( s1, s2, d); |
twisti@4323 | 75 | #endif |
twisti@4323 | 76 | } |
twisti@4323 | 77 | |
twisti@4323 | 78 | inline void MacroAssembler::ld_ptr(const Address& a, Register d, int offset) { |
twisti@4323 | 79 | #ifdef _LP64 |
twisti@4323 | 80 | ldx(a, d, offset); |
twisti@4323 | 81 | #else |
twisti@4323 | 82 | ld( a, d, offset); |
twisti@4323 | 83 | #endif |
twisti@4323 | 84 | } |
twisti@4323 | 85 | |
twisti@4323 | 86 | inline void MacroAssembler::st_ptr( Register d, Register s1, Register s2 ) { |
twisti@4323 | 87 | #ifdef _LP64 |
twisti@4323 | 88 | Assembler::stx(d, s1, s2); |
twisti@4323 | 89 | #else |
twisti@4323 | 90 | st( d, s1, s2); |
twisti@4323 | 91 | #endif |
twisti@4323 | 92 | } |
twisti@4323 | 93 | |
twisti@4323 | 94 | inline void MacroAssembler::st_ptr( Register d, Register s1, int simm13a ) { |
twisti@4323 | 95 | #ifdef _LP64 |
twisti@4323 | 96 | Assembler::stx(d, s1, simm13a); |
twisti@4323 | 97 | #else |
twisti@4323 | 98 | st( d, s1, simm13a); |
twisti@4323 | 99 | #endif |
twisti@4323 | 100 | } |
twisti@4323 | 101 | |
twisti@4323 | 102 | #ifdef ASSERT |
twisti@4323 | 103 | // ByteSize is only a class when ASSERT is defined, otherwise it's an int. |
twisti@4323 | 104 | inline void MacroAssembler::st_ptr( Register d, Register s1, ByteSize simm13a ) { |
twisti@4323 | 105 | st_ptr(d, s1, in_bytes(simm13a)); |
twisti@4323 | 106 | } |
twisti@4323 | 107 | #endif |
twisti@4323 | 108 | |
twisti@4323 | 109 | inline void MacroAssembler::st_ptr( Register d, Register s1, RegisterOrConstant s2 ) { |
twisti@4323 | 110 | #ifdef _LP64 |
twisti@4323 | 111 | stx(d, s1, s2); |
twisti@4323 | 112 | #else |
twisti@4323 | 113 | st( d, s1, s2); |
twisti@4323 | 114 | #endif |
twisti@4323 | 115 | } |
twisti@4323 | 116 | |
twisti@4323 | 117 | inline void MacroAssembler::st_ptr(Register d, const Address& a, int offset) { |
twisti@4323 | 118 | #ifdef _LP64 |
twisti@4323 | 119 | stx(d, a, offset); |
twisti@4323 | 120 | #else |
twisti@4323 | 121 | st( d, a, offset); |
twisti@4323 | 122 | #endif |
twisti@4323 | 123 | } |
twisti@4323 | 124 | |
twisti@4323 | 125 | // Use the right loads/stores for the platform |
twisti@4323 | 126 | inline void MacroAssembler::ld_long( Register s1, Register s2, Register d ) { |
twisti@4323 | 127 | #ifdef _LP64 |
twisti@4323 | 128 | Assembler::ldx(s1, s2, d); |
twisti@4323 | 129 | #else |
twisti@4323 | 130 | Assembler::ldd(s1, s2, d); |
twisti@4323 | 131 | #endif |
twisti@4323 | 132 | } |
twisti@4323 | 133 | |
twisti@4323 | 134 | inline void MacroAssembler::ld_long( Register s1, int simm13a, Register d ) { |
twisti@4323 | 135 | #ifdef _LP64 |
twisti@4323 | 136 | Assembler::ldx(s1, simm13a, d); |
twisti@4323 | 137 | #else |
twisti@4323 | 138 | Assembler::ldd(s1, simm13a, d); |
twisti@4323 | 139 | #endif |
twisti@4323 | 140 | } |
twisti@4323 | 141 | |
twisti@4323 | 142 | inline void MacroAssembler::ld_long( Register s1, RegisterOrConstant s2, Register d ) { |
twisti@4323 | 143 | #ifdef _LP64 |
twisti@4323 | 144 | ldx(s1, s2, d); |
twisti@4323 | 145 | #else |
twisti@4323 | 146 | ldd(s1, s2, d); |
twisti@4323 | 147 | #endif |
twisti@4323 | 148 | } |
twisti@4323 | 149 | |
twisti@4323 | 150 | inline void MacroAssembler::ld_long(const Address& a, Register d, int offset) { |
twisti@4323 | 151 | #ifdef _LP64 |
twisti@4323 | 152 | ldx(a, d, offset); |
twisti@4323 | 153 | #else |
twisti@4323 | 154 | ldd(a, d, offset); |
twisti@4323 | 155 | #endif |
twisti@4323 | 156 | } |
twisti@4323 | 157 | |
twisti@4323 | 158 | inline void MacroAssembler::st_long( Register d, Register s1, Register s2 ) { |
twisti@4323 | 159 | #ifdef _LP64 |
twisti@4323 | 160 | Assembler::stx(d, s1, s2); |
twisti@4323 | 161 | #else |
twisti@4323 | 162 | Assembler::std(d, s1, s2); |
twisti@4323 | 163 | #endif |
twisti@4323 | 164 | } |
twisti@4323 | 165 | |
twisti@4323 | 166 | inline void MacroAssembler::st_long( Register d, Register s1, int simm13a ) { |
twisti@4323 | 167 | #ifdef _LP64 |
twisti@4323 | 168 | Assembler::stx(d, s1, simm13a); |
twisti@4323 | 169 | #else |
twisti@4323 | 170 | Assembler::std(d, s1, simm13a); |
twisti@4323 | 171 | #endif |
twisti@4323 | 172 | } |
twisti@4323 | 173 | |
twisti@4323 | 174 | inline void MacroAssembler::st_long( Register d, Register s1, RegisterOrConstant s2 ) { |
twisti@4323 | 175 | #ifdef _LP64 |
twisti@4323 | 176 | stx(d, s1, s2); |
twisti@4323 | 177 | #else |
twisti@4323 | 178 | std(d, s1, s2); |
twisti@4323 | 179 | #endif |
twisti@4323 | 180 | } |
twisti@4323 | 181 | |
twisti@4323 | 182 | inline void MacroAssembler::st_long( Register d, const Address& a, int offset ) { |
twisti@4323 | 183 | #ifdef _LP64 |
twisti@4323 | 184 | stx(d, a, offset); |
twisti@4323 | 185 | #else |
twisti@4323 | 186 | std(d, a, offset); |
twisti@4323 | 187 | #endif |
twisti@4323 | 188 | } |
twisti@4323 | 189 | |
twisti@4323 | 190 | // Functions for isolating 64 bit shifts for LP64 |
twisti@4323 | 191 | |
twisti@4323 | 192 | inline void MacroAssembler::sll_ptr( Register s1, Register s2, Register d ) { |
twisti@4323 | 193 | #ifdef _LP64 |
twisti@4323 | 194 | Assembler::sllx(s1, s2, d); |
twisti@4323 | 195 | #else |
twisti@4323 | 196 | Assembler::sll( s1, s2, d); |
twisti@4323 | 197 | #endif |
twisti@4323 | 198 | } |
twisti@4323 | 199 | |
twisti@4323 | 200 | inline void MacroAssembler::sll_ptr( Register s1, int imm6a, Register d ) { |
twisti@4323 | 201 | #ifdef _LP64 |
twisti@4323 | 202 | Assembler::sllx(s1, imm6a, d); |
twisti@4323 | 203 | #else |
twisti@4323 | 204 | Assembler::sll( s1, imm6a, d); |
twisti@4323 | 205 | #endif |
twisti@4323 | 206 | } |
twisti@4323 | 207 | |
twisti@4323 | 208 | inline void MacroAssembler::srl_ptr( Register s1, Register s2, Register d ) { |
twisti@4323 | 209 | #ifdef _LP64 |
twisti@4323 | 210 | Assembler::srlx(s1, s2, d); |
twisti@4323 | 211 | #else |
twisti@4323 | 212 | Assembler::srl( s1, s2, d); |
twisti@4323 | 213 | #endif |
twisti@4323 | 214 | } |
twisti@4323 | 215 | |
twisti@4323 | 216 | inline void MacroAssembler::srl_ptr( Register s1, int imm6a, Register d ) { |
twisti@4323 | 217 | #ifdef _LP64 |
twisti@4323 | 218 | Assembler::srlx(s1, imm6a, d); |
twisti@4323 | 219 | #else |
twisti@4323 | 220 | Assembler::srl( s1, imm6a, d); |
twisti@4323 | 221 | #endif |
twisti@4323 | 222 | } |
twisti@4323 | 223 | |
twisti@4323 | 224 | inline void MacroAssembler::sll_ptr( Register s1, RegisterOrConstant s2, Register d ) { |
twisti@4323 | 225 | if (s2.is_register()) sll_ptr(s1, s2.as_register(), d); |
twisti@4323 | 226 | else sll_ptr(s1, s2.as_constant(), d); |
twisti@4323 | 227 | } |
twisti@4323 | 228 | |
twisti@4323 | 229 | // Use the right branch for the platform |
twisti@4323 | 230 | |
twisti@4323 | 231 | inline void MacroAssembler::br( Condition c, bool a, Predict p, address d, relocInfo::relocType rt ) { |
twisti@4323 | 232 | if (VM_Version::v9_instructions_work()) |
twisti@4323 | 233 | Assembler::bp(c, a, icc, p, d, rt); |
twisti@4323 | 234 | else |
twisti@4323 | 235 | Assembler::br(c, a, d, rt); |
twisti@4323 | 236 | } |
twisti@4323 | 237 | |
twisti@4323 | 238 | inline void MacroAssembler::br( Condition c, bool a, Predict p, Label& L ) { |
twisti@4323 | 239 | br(c, a, p, target(L)); |
twisti@4323 | 240 | } |
twisti@4323 | 241 | |
twisti@4323 | 242 | |
twisti@4323 | 243 | // Branch that tests either xcc or icc depending on the |
twisti@4323 | 244 | // architecture compiled (LP64 or not) |
twisti@4323 | 245 | inline void MacroAssembler::brx( Condition c, bool a, Predict p, address d, relocInfo::relocType rt ) { |
twisti@4323 | 246 | #ifdef _LP64 |
twisti@4323 | 247 | Assembler::bp(c, a, xcc, p, d, rt); |
twisti@4323 | 248 | #else |
twisti@4323 | 249 | MacroAssembler::br(c, a, p, d, rt); |
twisti@4323 | 250 | #endif |
twisti@4323 | 251 | } |
twisti@4323 | 252 | |
twisti@4323 | 253 | inline void MacroAssembler::brx( Condition c, bool a, Predict p, Label& L ) { |
twisti@4323 | 254 | brx(c, a, p, target(L)); |
twisti@4323 | 255 | } |
twisti@4323 | 256 | |
twisti@4323 | 257 | inline void MacroAssembler::ba( Label& L ) { |
twisti@4323 | 258 | br(always, false, pt, L); |
twisti@4323 | 259 | } |
twisti@4323 | 260 | |
twisti@4323 | 261 | // Warning: V9 only functions |
twisti@4323 | 262 | inline void MacroAssembler::bp( Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt ) { |
twisti@4323 | 263 | Assembler::bp(c, a, cc, p, d, rt); |
twisti@4323 | 264 | } |
twisti@4323 | 265 | |
twisti@4323 | 266 | inline void MacroAssembler::bp( Condition c, bool a, CC cc, Predict p, Label& L ) { |
twisti@4323 | 267 | Assembler::bp(c, a, cc, p, L); |
twisti@4323 | 268 | } |
twisti@4323 | 269 | |
twisti@4323 | 270 | inline void MacroAssembler::fb( Condition c, bool a, Predict p, address d, relocInfo::relocType rt ) { |
twisti@4323 | 271 | if (VM_Version::v9_instructions_work()) |
twisti@4323 | 272 | fbp(c, a, fcc0, p, d, rt); |
twisti@4323 | 273 | else |
twisti@4323 | 274 | Assembler::fb(c, a, d, rt); |
twisti@4323 | 275 | } |
twisti@4323 | 276 | |
twisti@4323 | 277 | inline void MacroAssembler::fb( Condition c, bool a, Predict p, Label& L ) { |
twisti@4323 | 278 | fb(c, a, p, target(L)); |
twisti@4323 | 279 | } |
twisti@4323 | 280 | |
twisti@4323 | 281 | inline void MacroAssembler::fbp( Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt ) { |
twisti@4323 | 282 | Assembler::fbp(c, a, cc, p, d, rt); |
twisti@4323 | 283 | } |
twisti@4323 | 284 | |
twisti@4323 | 285 | inline void MacroAssembler::fbp( Condition c, bool a, CC cc, Predict p, Label& L ) { |
twisti@4323 | 286 | Assembler::fbp(c, a, cc, p, L); |
twisti@4323 | 287 | } |
twisti@4323 | 288 | |
twisti@4323 | 289 | inline void MacroAssembler::jmp( Register s1, Register s2 ) { jmpl( s1, s2, G0 ); } |
twisti@4323 | 290 | inline void MacroAssembler::jmp( Register s1, int simm13a, RelocationHolder const& rspec ) { jmpl( s1, simm13a, G0, rspec); } |
twisti@4323 | 291 | |
twisti@4323 | 292 | inline bool MacroAssembler::is_far_target(address d) { |
twisti@4323 | 293 | if (ForceUnreachable) { |
twisti@4323 | 294 | // References outside the code cache should be treated as far |
twisti@4323 | 295 | return d < CodeCache::low_bound() || d > CodeCache::high_bound(); |
twisti@4323 | 296 | } |
twisti@4323 | 297 | return !is_in_wdisp30_range(d, CodeCache::low_bound()) || !is_in_wdisp30_range(d, CodeCache::high_bound()); |
twisti@4323 | 298 | } |
twisti@4323 | 299 | |
twisti@4323 | 300 | // Call with a check to see if we need to deal with the added |
twisti@4323 | 301 | // expense of relocation and if we overflow the displacement |
twisti@4323 | 302 | // of the quick call instruction. |
twisti@4323 | 303 | inline void MacroAssembler::call( address d, relocInfo::relocType rt ) { |
twisti@4323 | 304 | #ifdef _LP64 |
twisti@4323 | 305 | intptr_t disp; |
twisti@4323 | 306 | // NULL is ok because it will be relocated later. |
twisti@4323 | 307 | // Must change NULL to a reachable address in order to |
twisti@4323 | 308 | // pass asserts here and in wdisp. |
twisti@4323 | 309 | if ( d == NULL ) |
twisti@4323 | 310 | d = pc(); |
twisti@4323 | 311 | |
twisti@4323 | 312 | // Is this address within range of the call instruction? |
twisti@4323 | 313 | // If not, use the expensive instruction sequence |
twisti@4323 | 314 | if (is_far_target(d)) { |
twisti@4323 | 315 | relocate(rt); |
twisti@4323 | 316 | AddressLiteral dest(d); |
twisti@4323 | 317 | jumpl_to(dest, O7, O7); |
twisti@4323 | 318 | } else { |
twisti@4323 | 319 | Assembler::call(d, rt); |
twisti@4323 | 320 | } |
twisti@4323 | 321 | #else |
twisti@4323 | 322 | Assembler::call( d, rt ); |
twisti@4323 | 323 | #endif |
twisti@4323 | 324 | } |
twisti@4323 | 325 | |
twisti@4323 | 326 | inline void MacroAssembler::call( Label& L, relocInfo::relocType rt ) { |
twisti@4323 | 327 | MacroAssembler::call( target(L), rt); |
twisti@4323 | 328 | } |
twisti@4323 | 329 | |
twisti@4323 | 330 | |
twisti@4323 | 331 | |
twisti@4323 | 332 | inline void MacroAssembler::callr( Register s1, Register s2 ) { jmpl( s1, s2, O7 ); } |
twisti@4323 | 333 | inline void MacroAssembler::callr( Register s1, int simm13a, RelocationHolder const& rspec ) { jmpl( s1, simm13a, O7, rspec); } |
twisti@4323 | 334 | |
twisti@4323 | 335 | // prefetch instruction |
twisti@4323 | 336 | inline void MacroAssembler::iprefetch( address d, relocInfo::relocType rt ) { |
twisti@4323 | 337 | if (VM_Version::v9_instructions_work()) |
twisti@4323 | 338 | Assembler::bp( never, true, xcc, pt, d, rt ); |
twisti@4323 | 339 | } |
twisti@4323 | 340 | inline void MacroAssembler::iprefetch( Label& L) { iprefetch( target(L) ); } |
twisti@4323 | 341 | |
twisti@4323 | 342 | |
twisti@4323 | 343 | // clobbers o7 on V8!! |
twisti@4323 | 344 | // returns delta from gotten pc to addr after |
twisti@4323 | 345 | inline int MacroAssembler::get_pc( Register d ) { |
twisti@4323 | 346 | int x = offset(); |
twisti@4323 | 347 | if (VM_Version::v9_instructions_work()) |
twisti@4323 | 348 | rdpc(d); |
twisti@4323 | 349 | else { |
twisti@4323 | 350 | Label lbl; |
twisti@4323 | 351 | Assembler::call(lbl, relocInfo::none); // No relocation as this is call to pc+0x8 |
twisti@4323 | 352 | if (d == O7) delayed()->nop(); |
twisti@4323 | 353 | else delayed()->mov(O7, d); |
twisti@4323 | 354 | bind(lbl); |
twisti@4323 | 355 | } |
twisti@4323 | 356 | return offset() - x; |
twisti@4323 | 357 | } |
twisti@4323 | 358 | |
twisti@4323 | 359 | |
twisti@4323 | 360 | // Note: All MacroAssembler::set_foo functions are defined out-of-line. |
twisti@4323 | 361 | |
twisti@4323 | 362 | |
twisti@4323 | 363 | // Loads the current PC of the following instruction as an immediate value in |
twisti@4323 | 364 | // 2 instructions. All PCs in the CodeCache are within 2 Gig of each other. |
twisti@4323 | 365 | inline intptr_t MacroAssembler::load_pc_address( Register reg, int bytes_to_skip ) { |
twisti@4323 | 366 | intptr_t thepc = (intptr_t)pc() + 2*BytesPerInstWord + bytes_to_skip; |
twisti@4323 | 367 | #ifdef _LP64 |
twisti@4323 | 368 | Unimplemented(); |
twisti@4323 | 369 | #else |
twisti@4323 | 370 | Assembler::sethi( thepc & ~0x3ff, reg, internal_word_Relocation::spec((address)thepc)); |
twisti@4323 | 371 | add(reg, thepc & 0x3ff, reg, internal_word_Relocation::spec((address)thepc)); |
twisti@4323 | 372 | #endif |
twisti@4323 | 373 | return thepc; |
twisti@4323 | 374 | } |
twisti@4323 | 375 | |
twisti@4323 | 376 | |
twisti@4323 | 377 | inline void MacroAssembler::load_contents(const AddressLiteral& addrlit, Register d, int offset) { |
twisti@4323 | 378 | assert_not_delayed(); |
twisti@4323 | 379 | if (ForceUnreachable) { |
twisti@4323 | 380 | patchable_sethi(addrlit, d); |
twisti@4323 | 381 | } else { |
twisti@4323 | 382 | sethi(addrlit, d); |
twisti@4323 | 383 | } |
twisti@4323 | 384 | ld(d, addrlit.low10() + offset, d); |
twisti@4323 | 385 | } |
twisti@4323 | 386 | |
twisti@4323 | 387 | |
twisti@4323 | 388 | inline void MacroAssembler::load_bool_contents(const AddressLiteral& addrlit, Register d, int offset) { |
twisti@4323 | 389 | assert_not_delayed(); |
twisti@4323 | 390 | if (ForceUnreachable) { |
twisti@4323 | 391 | patchable_sethi(addrlit, d); |
twisti@4323 | 392 | } else { |
twisti@4323 | 393 | sethi(addrlit, d); |
twisti@4323 | 394 | } |
twisti@4323 | 395 | ldub(d, addrlit.low10() + offset, d); |
twisti@4323 | 396 | } |
twisti@4323 | 397 | |
twisti@4323 | 398 | |
twisti@4323 | 399 | inline void MacroAssembler::load_ptr_contents(const AddressLiteral& addrlit, Register d, int offset) { |
twisti@4323 | 400 | assert_not_delayed(); |
twisti@4323 | 401 | if (ForceUnreachable) { |
twisti@4323 | 402 | patchable_sethi(addrlit, d); |
twisti@4323 | 403 | } else { |
twisti@4323 | 404 | sethi(addrlit, d); |
twisti@4323 | 405 | } |
twisti@4323 | 406 | ld_ptr(d, addrlit.low10() + offset, d); |
twisti@4323 | 407 | } |
twisti@4323 | 408 | |
twisti@4323 | 409 | |
twisti@4323 | 410 | inline void MacroAssembler::store_contents(Register s, const AddressLiteral& addrlit, Register temp, int offset) { |
twisti@4323 | 411 | assert_not_delayed(); |
twisti@4323 | 412 | if (ForceUnreachable) { |
twisti@4323 | 413 | patchable_sethi(addrlit, temp); |
twisti@4323 | 414 | } else { |
twisti@4323 | 415 | sethi(addrlit, temp); |
twisti@4323 | 416 | } |
twisti@4323 | 417 | st(s, temp, addrlit.low10() + offset); |
twisti@4323 | 418 | } |
twisti@4323 | 419 | |
twisti@4323 | 420 | |
twisti@4323 | 421 | inline void MacroAssembler::store_ptr_contents(Register s, const AddressLiteral& addrlit, Register temp, int offset) { |
twisti@4323 | 422 | assert_not_delayed(); |
twisti@4323 | 423 | if (ForceUnreachable) { |
twisti@4323 | 424 | patchable_sethi(addrlit, temp); |
twisti@4323 | 425 | } else { |
twisti@4323 | 426 | sethi(addrlit, temp); |
twisti@4323 | 427 | } |
twisti@4323 | 428 | st_ptr(s, temp, addrlit.low10() + offset); |
twisti@4323 | 429 | } |
twisti@4323 | 430 | |
twisti@4323 | 431 | |
twisti@4323 | 432 | // This code sequence is relocatable to any address, even on LP64. |
twisti@4323 | 433 | inline void MacroAssembler::jumpl_to(const AddressLiteral& addrlit, Register temp, Register d, int offset) { |
twisti@4323 | 434 | assert_not_delayed(); |
twisti@4323 | 435 | // Force fixed length sethi because NativeJump and NativeFarCall don't handle |
twisti@4323 | 436 | // variable length instruction streams. |
twisti@4323 | 437 | patchable_sethi(addrlit, temp); |
twisti@4323 | 438 | jmpl(temp, addrlit.low10() + offset, d); |
twisti@4323 | 439 | } |
twisti@4323 | 440 | |
twisti@4323 | 441 | |
twisti@4323 | 442 | inline void MacroAssembler::jump_to(const AddressLiteral& addrlit, Register temp, int offset) { |
twisti@4323 | 443 | jumpl_to(addrlit, temp, G0, offset); |
twisti@4323 | 444 | } |
twisti@4323 | 445 | |
twisti@4323 | 446 | |
twisti@4323 | 447 | inline void MacroAssembler::jump_indirect_to(Address& a, Register temp, |
twisti@4323 | 448 | int ld_offset, int jmp_offset) { |
twisti@4323 | 449 | assert_not_delayed(); |
twisti@4323 | 450 | //sethi(al); // sethi is caller responsibility for this one |
twisti@4323 | 451 | ld_ptr(a, temp, ld_offset); |
twisti@4323 | 452 | jmp(temp, jmp_offset); |
twisti@4323 | 453 | } |
twisti@4323 | 454 | |
twisti@4323 | 455 | |
twisti@4323 | 456 | inline void MacroAssembler::set_metadata(Metadata* obj, Register d) { |
twisti@4323 | 457 | set_metadata(allocate_metadata_address(obj), d); |
twisti@4323 | 458 | } |
twisti@4323 | 459 | |
twisti@4323 | 460 | inline void MacroAssembler::set_metadata_constant(Metadata* obj, Register d) { |
twisti@4323 | 461 | set_metadata(constant_metadata_address(obj), d); |
twisti@4323 | 462 | } |
twisti@4323 | 463 | |
twisti@4323 | 464 | inline void MacroAssembler::set_metadata(const AddressLiteral& obj_addr, Register d) { |
twisti@4323 | 465 | assert(obj_addr.rspec().type() == relocInfo::metadata_type, "must be a metadata reloc"); |
twisti@4323 | 466 | set(obj_addr, d); |
twisti@4323 | 467 | } |
twisti@4323 | 468 | |
twisti@4323 | 469 | inline void MacroAssembler::set_oop(jobject obj, Register d) { |
twisti@4323 | 470 | set_oop(allocate_oop_address(obj), d); |
twisti@4323 | 471 | } |
twisti@4323 | 472 | |
twisti@4323 | 473 | |
twisti@4323 | 474 | inline void MacroAssembler::set_oop_constant(jobject obj, Register d) { |
twisti@4323 | 475 | set_oop(constant_oop_address(obj), d); |
twisti@4323 | 476 | } |
twisti@4323 | 477 | |
twisti@4323 | 478 | |
twisti@4323 | 479 | inline void MacroAssembler::set_oop(const AddressLiteral& obj_addr, Register d) { |
twisti@4323 | 480 | assert(obj_addr.rspec().type() == relocInfo::oop_type, "must be an oop reloc"); |
twisti@4323 | 481 | set(obj_addr, d); |
twisti@4323 | 482 | } |
twisti@4323 | 483 | |
twisti@4323 | 484 | |
twisti@4323 | 485 | inline void MacroAssembler::load_argument( Argument& a, Register d ) { |
twisti@4323 | 486 | if (a.is_register()) |
twisti@4323 | 487 | mov(a.as_register(), d); |
twisti@4323 | 488 | else |
twisti@4323 | 489 | ld (a.as_address(), d); |
twisti@4323 | 490 | } |
twisti@4323 | 491 | |
twisti@4323 | 492 | inline void MacroAssembler::store_argument( Register s, Argument& a ) { |
twisti@4323 | 493 | if (a.is_register()) |
twisti@4323 | 494 | mov(s, a.as_register()); |
twisti@4323 | 495 | else |
twisti@4323 | 496 | st_ptr (s, a.as_address()); // ABI says everything is right justified. |
twisti@4323 | 497 | } |
twisti@4323 | 498 | |
twisti@4323 | 499 | inline void MacroAssembler::store_ptr_argument( Register s, Argument& a ) { |
twisti@4323 | 500 | if (a.is_register()) |
twisti@4323 | 501 | mov(s, a.as_register()); |
twisti@4323 | 502 | else |
twisti@4323 | 503 | st_ptr (s, a.as_address()); |
twisti@4323 | 504 | } |
twisti@4323 | 505 | |
twisti@4323 | 506 | |
twisti@4323 | 507 | #ifdef _LP64 |
twisti@4323 | 508 | inline void MacroAssembler::store_float_argument( FloatRegister s, Argument& a ) { |
twisti@4323 | 509 | if (a.is_float_register()) |
twisti@4323 | 510 | // V9 ABI has F1, F3, F5 are used to pass instead of O0, O1, O2 |
twisti@4323 | 511 | fmov(FloatRegisterImpl::S, s, a.as_float_register() ); |
twisti@4323 | 512 | else |
twisti@4323 | 513 | // Floats are stored in the high half of the stack entry |
twisti@4323 | 514 | // The low half is undefined per the ABI. |
twisti@4323 | 515 | stf(FloatRegisterImpl::S, s, a.as_address(), sizeof(jfloat)); |
twisti@4323 | 516 | } |
twisti@4323 | 517 | |
twisti@4323 | 518 | inline void MacroAssembler::store_double_argument( FloatRegister s, Argument& a ) { |
twisti@4323 | 519 | if (a.is_float_register()) |
twisti@4323 | 520 | // V9 ABI has D0, D2, D4 are used to pass instead of O0, O1, O2 |
twisti@4323 | 521 | fmov(FloatRegisterImpl::D, s, a.as_double_register() ); |
twisti@4323 | 522 | else |
twisti@4323 | 523 | stf(FloatRegisterImpl::D, s, a.as_address()); |
twisti@4323 | 524 | } |
twisti@4323 | 525 | |
twisti@4323 | 526 | inline void MacroAssembler::store_long_argument( Register s, Argument& a ) { |
twisti@4323 | 527 | if (a.is_register()) |
twisti@4323 | 528 | mov(s, a.as_register()); |
twisti@4323 | 529 | else |
twisti@4323 | 530 | stx(s, a.as_address()); |
twisti@4323 | 531 | } |
twisti@4323 | 532 | #endif |
twisti@4323 | 533 | |
twisti@4323 | 534 | inline void MacroAssembler::add(Register s1, int simm13a, Register d, relocInfo::relocType rtype) { |
twisti@4323 | 535 | relocate(rtype); |
twisti@4323 | 536 | add(s1, simm13a, d); |
twisti@4323 | 537 | } |
twisti@4323 | 538 | inline void MacroAssembler::add(Register s1, int simm13a, Register d, RelocationHolder const& rspec) { |
twisti@4323 | 539 | relocate(rspec); |
twisti@4323 | 540 | add(s1, simm13a, d); |
twisti@4323 | 541 | } |
twisti@4323 | 542 | |
twisti@4323 | 543 | // form effective addresses this way: |
twisti@4323 | 544 | inline void MacroAssembler::add(const Address& a, Register d, int offset) { |
twisti@4323 | 545 | if (a.has_index()) add(a.base(), a.index(), d); |
twisti@4323 | 546 | else { add(a.base(), a.disp() + offset, d, a.rspec(offset)); offset = 0; } |
twisti@4323 | 547 | if (offset != 0) add(d, offset, d); |
twisti@4323 | 548 | } |
twisti@4323 | 549 | inline void MacroAssembler::add(Register s1, RegisterOrConstant s2, Register d, int offset) { |
twisti@4323 | 550 | if (s2.is_register()) add(s1, s2.as_register(), d); |
twisti@4323 | 551 | else { add(s1, s2.as_constant() + offset, d); offset = 0; } |
twisti@4323 | 552 | if (offset != 0) add(d, offset, d); |
twisti@4323 | 553 | } |
twisti@4323 | 554 | |
twisti@4323 | 555 | inline void MacroAssembler::andn(Register s1, RegisterOrConstant s2, Register d) { |
twisti@4323 | 556 | if (s2.is_register()) andn(s1, s2.as_register(), d); |
twisti@4323 | 557 | else andn(s1, s2.as_constant(), d); |
twisti@4323 | 558 | } |
twisti@4323 | 559 | |
twisti@4323 | 560 | inline void MacroAssembler::clrb( Register s1, Register s2) { stb( G0, s1, s2 ); } |
twisti@4323 | 561 | inline void MacroAssembler::clrh( Register s1, Register s2) { sth( G0, s1, s2 ); } |
twisti@4323 | 562 | inline void MacroAssembler::clr( Register s1, Register s2) { stw( G0, s1, s2 ); } |
twisti@4323 | 563 | inline void MacroAssembler::clrx( Register s1, Register s2) { stx( G0, s1, s2 ); } |
twisti@4323 | 564 | |
twisti@4323 | 565 | inline void MacroAssembler::clrb( Register s1, int simm13a) { stb( G0, s1, simm13a); } |
twisti@4323 | 566 | inline void MacroAssembler::clrh( Register s1, int simm13a) { sth( G0, s1, simm13a); } |
twisti@4323 | 567 | inline void MacroAssembler::clr( Register s1, int simm13a) { stw( G0, s1, simm13a); } |
twisti@4323 | 568 | inline void MacroAssembler::clrx( Register s1, int simm13a) { stx( G0, s1, simm13a); } |
twisti@4323 | 569 | |
twisti@4323 | 570 | #ifdef _LP64 |
twisti@4323 | 571 | // Make all 32 bit loads signed so 64 bit registers maintain proper sign |
twisti@4323 | 572 | inline void MacroAssembler::ld( Register s1, Register s2, Register d) { ldsw( s1, s2, d); } |
twisti@4323 | 573 | inline void MacroAssembler::ld( Register s1, int simm13a, Register d) { ldsw( s1, simm13a, d); } |
twisti@4323 | 574 | #else |
twisti@4323 | 575 | inline void MacroAssembler::ld( Register s1, Register s2, Register d) { lduw( s1, s2, d); } |
twisti@4323 | 576 | inline void MacroAssembler::ld( Register s1, int simm13a, Register d) { lduw( s1, simm13a, d); } |
twisti@4323 | 577 | #endif |
twisti@4323 | 578 | |
twisti@4323 | 579 | #ifdef ASSERT |
twisti@4323 | 580 | // ByteSize is only a class when ASSERT is defined, otherwise it's an int. |
twisti@4323 | 581 | # ifdef _LP64 |
twisti@4323 | 582 | inline void MacroAssembler::ld(Register s1, ByteSize simm13a, Register d) { ldsw( s1, in_bytes(simm13a), d); } |
twisti@4323 | 583 | # else |
twisti@4323 | 584 | inline void MacroAssembler::ld(Register s1, ByteSize simm13a, Register d) { lduw( s1, in_bytes(simm13a), d); } |
twisti@4323 | 585 | # endif |
twisti@4323 | 586 | #endif |
twisti@4323 | 587 | |
twisti@4323 | 588 | inline void MacroAssembler::ld( const Address& a, Register d, int offset) { |
twisti@4323 | 589 | if (a.has_index()) { assert(offset == 0, ""); ld( a.base(), a.index(), d); } |
twisti@4323 | 590 | else { ld( a.base(), a.disp() + offset, d); } |
twisti@4323 | 591 | } |
twisti@4323 | 592 | |
twisti@4323 | 593 | inline void MacroAssembler::ldsb(const Address& a, Register d, int offset) { |
twisti@4323 | 594 | if (a.has_index()) { assert(offset == 0, ""); ldsb(a.base(), a.index(), d); } |
twisti@4323 | 595 | else { ldsb(a.base(), a.disp() + offset, d); } |
twisti@4323 | 596 | } |
twisti@4323 | 597 | inline void MacroAssembler::ldsh(const Address& a, Register d, int offset) { |
twisti@4323 | 598 | if (a.has_index()) { assert(offset == 0, ""); ldsh(a.base(), a.index(), d); } |
twisti@4323 | 599 | else { ldsh(a.base(), a.disp() + offset, d); } |
twisti@4323 | 600 | } |
twisti@4323 | 601 | inline void MacroAssembler::ldsw(const Address& a, Register d, int offset) { |
twisti@4323 | 602 | if (a.has_index()) { assert(offset == 0, ""); ldsw(a.base(), a.index(), d); } |
twisti@4323 | 603 | else { ldsw(a.base(), a.disp() + offset, d); } |
twisti@4323 | 604 | } |
twisti@4323 | 605 | inline void MacroAssembler::ldub(const Address& a, Register d, int offset) { |
twisti@4323 | 606 | if (a.has_index()) { assert(offset == 0, ""); ldub(a.base(), a.index(), d); } |
twisti@4323 | 607 | else { ldub(a.base(), a.disp() + offset, d); } |
twisti@4323 | 608 | } |
twisti@4323 | 609 | inline void MacroAssembler::lduh(const Address& a, Register d, int offset) { |
twisti@4323 | 610 | if (a.has_index()) { assert(offset == 0, ""); lduh(a.base(), a.index(), d); } |
twisti@4323 | 611 | else { lduh(a.base(), a.disp() + offset, d); } |
twisti@4323 | 612 | } |
twisti@4323 | 613 | inline void MacroAssembler::lduw(const Address& a, Register d, int offset) { |
twisti@4323 | 614 | if (a.has_index()) { assert(offset == 0, ""); lduw(a.base(), a.index(), d); } |
twisti@4323 | 615 | else { lduw(a.base(), a.disp() + offset, d); } |
twisti@4323 | 616 | } |
twisti@4323 | 617 | inline void MacroAssembler::ldd( const Address& a, Register d, int offset) { |
twisti@4323 | 618 | if (a.has_index()) { assert(offset == 0, ""); ldd( a.base(), a.index(), d); } |
twisti@4323 | 619 | else { ldd( a.base(), a.disp() + offset, d); } |
twisti@4323 | 620 | } |
twisti@4323 | 621 | inline void MacroAssembler::ldx( const Address& a, Register d, int offset) { |
twisti@4323 | 622 | if (a.has_index()) { assert(offset == 0, ""); ldx( a.base(), a.index(), d); } |
twisti@4323 | 623 | else { ldx( a.base(), a.disp() + offset, d); } |
twisti@4323 | 624 | } |
twisti@4323 | 625 | |
twisti@4323 | 626 | inline void MacroAssembler::ldub(Register s1, RegisterOrConstant s2, Register d) { ldub(Address(s1, s2), d); } |
twisti@4323 | 627 | inline void MacroAssembler::ldsb(Register s1, RegisterOrConstant s2, Register d) { ldsb(Address(s1, s2), d); } |
twisti@4323 | 628 | inline void MacroAssembler::lduh(Register s1, RegisterOrConstant s2, Register d) { lduh(Address(s1, s2), d); } |
twisti@4323 | 629 | inline void MacroAssembler::ldsh(Register s1, RegisterOrConstant s2, Register d) { ldsh(Address(s1, s2), d); } |
twisti@4323 | 630 | inline void MacroAssembler::lduw(Register s1, RegisterOrConstant s2, Register d) { lduw(Address(s1, s2), d); } |
twisti@4323 | 631 | inline void MacroAssembler::ldsw(Register s1, RegisterOrConstant s2, Register d) { ldsw(Address(s1, s2), d); } |
twisti@4323 | 632 | inline void MacroAssembler::ldx( Register s1, RegisterOrConstant s2, Register d) { ldx( Address(s1, s2), d); } |
twisti@4323 | 633 | inline void MacroAssembler::ld( Register s1, RegisterOrConstant s2, Register d) { ld( Address(s1, s2), d); } |
twisti@4323 | 634 | inline void MacroAssembler::ldd( Register s1, RegisterOrConstant s2, Register d) { ldd( Address(s1, s2), d); } |
twisti@4323 | 635 | |
twisti@4323 | 636 | inline void MacroAssembler::ldf(FloatRegisterImpl::Width w, Register s1, RegisterOrConstant s2, FloatRegister d) { |
twisti@4323 | 637 | if (s2.is_register()) ldf(w, s1, s2.as_register(), d); |
twisti@4323 | 638 | else ldf(w, s1, s2.as_constant(), d); |
twisti@4323 | 639 | } |
twisti@4323 | 640 | |
twisti@4323 | 641 | inline void MacroAssembler::ldf(FloatRegisterImpl::Width w, const Address& a, FloatRegister d, int offset) { |
twisti@4323 | 642 | relocate(a.rspec(offset)); |
twisti@4323 | 643 | ldf(w, a.base(), a.disp() + offset, d); |
twisti@4323 | 644 | } |
twisti@4323 | 645 | |
twisti@4323 | 646 | // returns if membar generates anything, obviously this code should mirror |
twisti@4323 | 647 | // membar below. |
twisti@4323 | 648 | inline bool MacroAssembler::membar_has_effect( Membar_mask_bits const7a ) { |
twisti@4323 | 649 | if( !os::is_MP() ) return false; // Not needed on single CPU |
twisti@4323 | 650 | if( VM_Version::v9_instructions_work() ) { |
twisti@4323 | 651 | const Membar_mask_bits effective_mask = |
twisti@4323 | 652 | Membar_mask_bits(const7a & ~(LoadLoad | LoadStore | StoreStore)); |
twisti@4323 | 653 | return (effective_mask != 0); |
twisti@4323 | 654 | } else { |
twisti@4323 | 655 | return true; |
twisti@4323 | 656 | } |
twisti@4323 | 657 | } |
twisti@4323 | 658 | |
twisti@4323 | 659 | inline void MacroAssembler::membar( Membar_mask_bits const7a ) { |
twisti@4323 | 660 | // Uniprocessors do not need memory barriers |
twisti@4323 | 661 | if (!os::is_MP()) return; |
twisti@4323 | 662 | // Weakened for current Sparcs and TSO. See the v9 manual, sections 8.4.3, |
twisti@4323 | 663 | // 8.4.4.3, a.31 and a.50. |
twisti@4323 | 664 | if( VM_Version::v9_instructions_work() ) { |
twisti@4323 | 665 | // Under TSO, setting bit 3, 2, or 0 is redundant, so the only value |
twisti@4323 | 666 | // of the mmask subfield of const7a that does anything that isn't done |
twisti@4323 | 667 | // implicitly is StoreLoad. |
twisti@4323 | 668 | const Membar_mask_bits effective_mask = |
twisti@4323 | 669 | Membar_mask_bits(const7a & ~(LoadLoad | LoadStore | StoreStore)); |
twisti@4323 | 670 | if ( effective_mask != 0 ) { |
twisti@4323 | 671 | Assembler::membar( effective_mask ); |
twisti@4323 | 672 | } |
twisti@4323 | 673 | } else { |
twisti@4323 | 674 | // stbar is the closest there is on v8. Equivalent to membar(StoreStore). We |
twisti@4323 | 675 | // do not issue the stbar because to my knowledge all v8 machines implement TSO, |
twisti@4323 | 676 | // which guarantees that all stores behave as if an stbar were issued just after |
twisti@4323 | 677 | // each one of them. On these machines, stbar ought to be a nop. There doesn't |
twisti@4323 | 678 | // appear to be an equivalent of membar(StoreLoad) on v8: TSO doesn't require it, |
twisti@4323 | 679 | // it can't be specified by stbar, nor have I come up with a way to simulate it. |
twisti@4323 | 680 | // |
twisti@4323 | 681 | // Addendum. Dave says that ldstub guarantees a write buffer flush to coherent |
twisti@4323 | 682 | // space. Put one here to be on the safe side. |
twisti@4323 | 683 | Assembler::ldstub(SP, 0, G0); |
twisti@4323 | 684 | } |
twisti@4323 | 685 | } |
twisti@4323 | 686 | |
twisti@4323 | 687 | inline void MacroAssembler::prefetch(const Address& a, PrefetchFcn f, int offset) { |
twisti@4323 | 688 | relocate(a.rspec(offset)); |
twisti@4323 | 689 | assert(!a.has_index(), ""); |
twisti@4323 | 690 | prefetch(a.base(), a.disp() + offset, f); |
twisti@4323 | 691 | } |
twisti@4323 | 692 | |
twisti@4323 | 693 | inline void MacroAssembler::st(Register d, Register s1, Register s2) { stw(d, s1, s2); } |
twisti@4323 | 694 | inline void MacroAssembler::st(Register d, Register s1, int simm13a) { stw(d, s1, simm13a); } |
twisti@4323 | 695 | |
twisti@4323 | 696 | #ifdef ASSERT |
twisti@4323 | 697 | // ByteSize is only a class when ASSERT is defined, otherwise it's an int. |
twisti@4323 | 698 | inline void MacroAssembler::st(Register d, Register s1, ByteSize simm13a) { stw(d, s1, in_bytes(simm13a)); } |
twisti@4323 | 699 | #endif |
twisti@4323 | 700 | |
twisti@4323 | 701 | inline void MacroAssembler::st(Register d, const Address& a, int offset) { |
twisti@4323 | 702 | if (a.has_index()) { assert(offset == 0, ""); st( d, a.base(), a.index() ); } |
twisti@4323 | 703 | else { st( d, a.base(), a.disp() + offset); } |
twisti@4323 | 704 | } |
twisti@4323 | 705 | |
twisti@4323 | 706 | inline void MacroAssembler::stb(Register d, const Address& a, int offset) { |
twisti@4323 | 707 | if (a.has_index()) { assert(offset == 0, ""); stb(d, a.base(), a.index() ); } |
twisti@4323 | 708 | else { stb(d, a.base(), a.disp() + offset); } |
twisti@4323 | 709 | } |
twisti@4323 | 710 | inline void MacroAssembler::sth(Register d, const Address& a, int offset) { |
twisti@4323 | 711 | if (a.has_index()) { assert(offset == 0, ""); sth(d, a.base(), a.index() ); } |
twisti@4323 | 712 | else { sth(d, a.base(), a.disp() + offset); } |
twisti@4323 | 713 | } |
twisti@4323 | 714 | inline void MacroAssembler::stw(Register d, const Address& a, int offset) { |
twisti@4323 | 715 | if (a.has_index()) { assert(offset == 0, ""); stw(d, a.base(), a.index() ); } |
twisti@4323 | 716 | else { stw(d, a.base(), a.disp() + offset); } |
twisti@4323 | 717 | } |
twisti@4323 | 718 | inline void MacroAssembler::std(Register d, const Address& a, int offset) { |
twisti@4323 | 719 | if (a.has_index()) { assert(offset == 0, ""); std(d, a.base(), a.index() ); } |
twisti@4323 | 720 | else { std(d, a.base(), a.disp() + offset); } |
twisti@4323 | 721 | } |
twisti@4323 | 722 | inline void MacroAssembler::stx(Register d, const Address& a, int offset) { |
twisti@4323 | 723 | if (a.has_index()) { assert(offset == 0, ""); stx(d, a.base(), a.index() ); } |
twisti@4323 | 724 | else { stx(d, a.base(), a.disp() + offset); } |
twisti@4323 | 725 | } |
twisti@4323 | 726 | |
twisti@4323 | 727 | inline void MacroAssembler::stb(Register d, Register s1, RegisterOrConstant s2) { stb(d, Address(s1, s2)); } |
twisti@4323 | 728 | inline void MacroAssembler::sth(Register d, Register s1, RegisterOrConstant s2) { sth(d, Address(s1, s2)); } |
twisti@4323 | 729 | inline void MacroAssembler::stw(Register d, Register s1, RegisterOrConstant s2) { stw(d, Address(s1, s2)); } |
twisti@4323 | 730 | inline void MacroAssembler::stx(Register d, Register s1, RegisterOrConstant s2) { stx(d, Address(s1, s2)); } |
twisti@4323 | 731 | inline void MacroAssembler::std(Register d, Register s1, RegisterOrConstant s2) { std(d, Address(s1, s2)); } |
twisti@4323 | 732 | inline void MacroAssembler::st( Register d, Register s1, RegisterOrConstant s2) { st( d, Address(s1, s2)); } |
twisti@4323 | 733 | |
twisti@4323 | 734 | inline void MacroAssembler::stf(FloatRegisterImpl::Width w, FloatRegister d, Register s1, RegisterOrConstant s2) { |
twisti@4323 | 735 | if (s2.is_register()) stf(w, d, s1, s2.as_register()); |
twisti@4323 | 736 | else stf(w, d, s1, s2.as_constant()); |
twisti@4323 | 737 | } |
twisti@4323 | 738 | |
twisti@4323 | 739 | inline void MacroAssembler::stf(FloatRegisterImpl::Width w, FloatRegister d, const Address& a, int offset) { |
twisti@4323 | 740 | relocate(a.rspec(offset)); |
twisti@4323 | 741 | if (a.has_index()) { assert(offset == 0, ""); stf(w, d, a.base(), a.index() ); } |
twisti@4323 | 742 | else { stf(w, d, a.base(), a.disp() + offset); } |
twisti@4323 | 743 | } |
twisti@4323 | 744 | |
twisti@4323 | 745 | inline void MacroAssembler::sub(Register s1, RegisterOrConstant s2, Register d, int offset) { |
twisti@4323 | 746 | if (s2.is_register()) sub(s1, s2.as_register(), d); |
twisti@4323 | 747 | else { sub(s1, s2.as_constant() + offset, d); offset = 0; } |
twisti@4323 | 748 | if (offset != 0) sub(d, offset, d); |
twisti@4323 | 749 | } |
twisti@4323 | 750 | |
twisti@4323 | 751 | inline void MacroAssembler::swap(Address& a, Register d, int offset) { |
twisti@4323 | 752 | relocate(a.rspec(offset)); |
twisti@4323 | 753 | if (a.has_index()) { assert(offset == 0, ""); swap(a.base(), a.index(), d ); } |
twisti@4323 | 754 | else { swap(a.base(), a.disp() + offset, d); } |
twisti@4323 | 755 | } |
twisti@4323 | 756 | |
twisti@4323 | 757 | #endif // CPU_SPARC_VM_MACROASSEMBLER_SPARC_INLINE_HPP |