src/cpu/sparc/vm/assembler_sparc.hpp

Thu, 07 Apr 2011 09:53:20 -0700

author
johnc
date
Thu, 07 Apr 2011 09:53:20 -0700
changeset 2781
e1162778c1c8
parent 2565
28bf941f445e
child 2950
cba7b5c2d53f
permissions
-rw-r--r--

7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
Summary: A referent object that is only weakly reachable at the start of concurrent marking but is re-attached to the strongly reachable object graph during marking may not be marked as live. This can cause the reference object to be processed prematurely and leave dangling pointers to the referent object. Implement a read barrier for the java.lang.ref.Reference::referent field by intrinsifying the Reference.get() method, and intercepting accesses though JNI, reflection, and Unsafe, so that when a non-null referent object is read it is also logged in an SATB buffer.
Reviewed-by: kvn, iveresov, never, tonyp, dholmes

duke@435 1 /*
phh@2423 2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
duke@435 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@435 4 *
duke@435 5 * This code is free software; you can redistribute it and/or modify it
duke@435 6 * under the terms of the GNU General Public License version 2 only, as
duke@435 7 * published by the Free Software Foundation.
duke@435 8 *
duke@435 9 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@435 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@435 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@435 12 * version 2 for more details (a copy is included in the LICENSE file that
duke@435 13 * accompanied this code).
duke@435 14 *
duke@435 15 * You should have received a copy of the GNU General Public License version
duke@435 16 * 2 along with this work; if not, write to the Free Software Foundation,
duke@435 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@435 18 *
trims@1907 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
trims@1907 20 * or visit www.oracle.com if you need additional information or have any
trims@1907 21 * questions.
duke@435 22 *
duke@435 23 */
duke@435 24
stefank@2314 25 #ifndef CPU_SPARC_VM_ASSEMBLER_SPARC_HPP
stefank@2314 26 #define CPU_SPARC_VM_ASSEMBLER_SPARC_HPP
stefank@2314 27
duke@435 28 class BiasedLockingCounters;
duke@435 29
duke@435 30 // <sys/trap.h> promises that the system will not use traps 16-31
duke@435 31 #define ST_RESERVED_FOR_USER_0 0x10
duke@435 32
duke@435 33 /* Written: David Ungar 4/19/97 */
duke@435 34
duke@435 35 // Contains all the definitions needed for sparc assembly code generation.
duke@435 36
duke@435 37 // Register aliases for parts of the system:
duke@435 38
duke@435 39 // 64 bit values can be kept in g1-g5, o1-o5 and o7 and all 64 bits are safe
duke@435 40 // across context switches in V8+ ABI. Of course, there are no 64 bit regs
duke@435 41 // in V8 ABI. All 64 bits are preserved in V9 ABI for all registers.
duke@435 42
duke@435 43 // g2-g4 are scratch registers called "application globals". Their
duke@435 44 // meaning is reserved to the "compilation system"--which means us!
duke@435 45 // They are are not supposed to be touched by ordinary C code, although
duke@435 46 // highly-optimized C code might steal them for temps. They are safe
duke@435 47 // across thread switches, and the ABI requires that they be safe
duke@435 48 // across function calls.
duke@435 49 //
duke@435 50 // g1 and g3 are touched by more modules. V8 allows g1 to be clobbered
duke@435 51 // across func calls, and V8+ also allows g5 to be clobbered across
duke@435 52 // func calls. Also, g1 and g5 can get touched while doing shared
duke@435 53 // library loading.
duke@435 54 //
duke@435 55 // We must not touch g7 (it is the thread-self register) and g6 is
duke@435 56 // reserved for certain tools. g0, of course, is always zero.
duke@435 57 //
duke@435 58 // (Sources: SunSoft Compilers Group, thread library engineers.)
duke@435 59
duke@435 60 // %%%% The interpreter should be revisited to reduce global scratch regs.
duke@435 61
duke@435 62 // This global always holds the current JavaThread pointer:
duke@435 63
duke@435 64 REGISTER_DECLARATION(Register, G2_thread , G2);
coleenp@548 65 REGISTER_DECLARATION(Register, G6_heapbase , G6);
duke@435 66
duke@435 67 // The following globals are part of the Java calling convention:
duke@435 68
duke@435 69 REGISTER_DECLARATION(Register, G5_method , G5);
duke@435 70 REGISTER_DECLARATION(Register, G5_megamorphic_method , G5_method);
duke@435 71 REGISTER_DECLARATION(Register, G5_inline_cache_reg , G5_method);
duke@435 72
duke@435 73 // The following globals are used for the new C1 & interpreter calling convention:
duke@435 74 REGISTER_DECLARATION(Register, Gargs , G4); // pointing to the last argument
duke@435 75
duke@435 76 // This local is used to preserve G2_thread in the interpreter and in stubs:
duke@435 77 REGISTER_DECLARATION(Register, L7_thread_cache , L7);
duke@435 78
duke@435 79 // These globals are used as scratch registers in the interpreter:
duke@435 80
duke@435 81 REGISTER_DECLARATION(Register, Gframe_size , G1); // SAME REG as G1_scratch
duke@435 82 REGISTER_DECLARATION(Register, G1_scratch , G1); // also SAME
duke@435 83 REGISTER_DECLARATION(Register, G3_scratch , G3);
duke@435 84 REGISTER_DECLARATION(Register, G4_scratch , G4);
duke@435 85
duke@435 86 // These globals are used as short-lived scratch registers in the compiler:
duke@435 87
duke@435 88 REGISTER_DECLARATION(Register, Gtemp , G5);
duke@435 89
jrose@1145 90 // JSR 292 fixed register usages:
jrose@1145 91 REGISTER_DECLARATION(Register, G5_method_type , G5);
jrose@1145 92 REGISTER_DECLARATION(Register, G3_method_handle , G3);
twisti@1919 93 REGISTER_DECLARATION(Register, L7_mh_SP_save , L7);
jrose@1145 94
duke@435 95 // The compiler requires that G5_megamorphic_method is G5_inline_cache_klass,
duke@435 96 // because a single patchable "set" instruction (NativeMovConstReg,
duke@435 97 // or NativeMovConstPatching for compiler1) instruction
duke@435 98 // serves to set up either quantity, depending on whether the compiled
duke@435 99 // call site is an inline cache or is megamorphic. See the function
duke@435 100 // CompiledIC::set_to_megamorphic.
duke@435 101 //
jrose@1145 102 // If a inline cache targets an interpreted method, then the
jrose@1145 103 // G5 register will be used twice during the call. First,
jrose@1145 104 // the call site will be patched to load a compiledICHolder
jrose@1145 105 // into G5. (This is an ordered pair of ic_klass, method.)
jrose@1145 106 // The c2i adapter will first check the ic_klass, then load
jrose@1145 107 // G5_method with the method part of the pair just before
jrose@1145 108 // jumping into the interpreter.
duke@435 109 //
duke@435 110 // Note that G5_method is only the method-self for the interpreter,
duke@435 111 // and is logically unrelated to G5_megamorphic_method.
duke@435 112 //
duke@435 113 // Invariants on G2_thread (the JavaThread pointer):
duke@435 114 // - it should not be used for any other purpose anywhere
duke@435 115 // - it must be re-initialized by StubRoutines::call_stub()
duke@435 116 // - it must be preserved around every use of call_VM
duke@435 117
duke@435 118 // We can consider using g2/g3/g4 to cache more values than the
duke@435 119 // JavaThread, such as the card-marking base or perhaps pointers into
duke@435 120 // Eden. It's something of a waste to use them as scratch temporaries,
duke@435 121 // since they are not supposed to be volatile. (Of course, if we find
duke@435 122 // that Java doesn't benefit from application globals, then we can just
duke@435 123 // use them as ordinary temporaries.)
duke@435 124 //
duke@435 125 // Since g1 and g5 (and/or g6) are the volatile (caller-save) registers,
duke@435 126 // it makes sense to use them routinely for procedure linkage,
duke@435 127 // whenever the On registers are not applicable. Examples: G5_method,
duke@435 128 // G5_inline_cache_klass, and a double handful of miscellaneous compiler
duke@435 129 // stubs. This means that compiler stubs, etc., should be kept to a
duke@435 130 // maximum of two or three G-register arguments.
duke@435 131
duke@435 132
duke@435 133 // stub frames
duke@435 134
duke@435 135 REGISTER_DECLARATION(Register, Lentry_args , L0); // pointer to args passed to callee (interpreter) not stub itself
duke@435 136
duke@435 137 // Interpreter frames
duke@435 138
duke@435 139 #ifdef CC_INTERP
duke@435 140 REGISTER_DECLARATION(Register, Lstate , L0); // interpreter state object pointer
duke@435 141 REGISTER_DECLARATION(Register, L1_scratch , L1); // scratch
duke@435 142 REGISTER_DECLARATION(Register, Lmirror , L1); // mirror (for native methods only)
duke@435 143 REGISTER_DECLARATION(Register, L2_scratch , L2);
duke@435 144 REGISTER_DECLARATION(Register, L3_scratch , L3);
duke@435 145 REGISTER_DECLARATION(Register, L4_scratch , L4);
duke@435 146 REGISTER_DECLARATION(Register, Lscratch , L5); // C1 uses
duke@435 147 REGISTER_DECLARATION(Register, Lscratch2 , L6); // C1 uses
duke@435 148 REGISTER_DECLARATION(Register, L7_scratch , L7); // constant pool cache
duke@435 149 REGISTER_DECLARATION(Register, O5_savedSP , O5);
duke@435 150 REGISTER_DECLARATION(Register, I5_savedSP , I5); // Saved SP before bumping for locals. This is simply
duke@435 151 // a copy SP, so in 64-bit it's a biased value. The bias
duke@435 152 // is added and removed as needed in the frame code.
duke@435 153 // Interface to signature handler
duke@435 154 REGISTER_DECLARATION(Register, Llocals , L7); // pointer to locals for signature handler
duke@435 155 REGISTER_DECLARATION(Register, Lmethod , L6); // methodOop when calling signature handler
duke@435 156
duke@435 157 #else
duke@435 158 REGISTER_DECLARATION(Register, Lesp , L0); // expression stack pointer
duke@435 159 REGISTER_DECLARATION(Register, Lbcp , L1); // pointer to next bytecode
duke@435 160 REGISTER_DECLARATION(Register, Lmethod , L2);
duke@435 161 REGISTER_DECLARATION(Register, Llocals , L3);
duke@435 162 REGISTER_DECLARATION(Register, Largs , L3); // pointer to locals for signature handler
duke@435 163 // must match Llocals in asm interpreter
duke@435 164 REGISTER_DECLARATION(Register, Lmonitors , L4);
duke@435 165 REGISTER_DECLARATION(Register, Lbyte_code , L5);
duke@435 166 // When calling out from the interpreter we record SP so that we can remove any extra stack
duke@435 167 // space allocated during adapter transitions. This register is only live from the point
duke@435 168 // of the call until we return.
duke@435 169 REGISTER_DECLARATION(Register, Llast_SP , L5);
duke@435 170 REGISTER_DECLARATION(Register, Lscratch , L5);
duke@435 171 REGISTER_DECLARATION(Register, Lscratch2 , L6);
duke@435 172 REGISTER_DECLARATION(Register, LcpoolCache , L6); // constant pool cache
duke@435 173
duke@435 174 REGISTER_DECLARATION(Register, O5_savedSP , O5);
duke@435 175 REGISTER_DECLARATION(Register, I5_savedSP , I5); // Saved SP before bumping for locals. This is simply
duke@435 176 // a copy SP, so in 64-bit it's a biased value. The bias
duke@435 177 // is added and removed as needed in the frame code.
duke@435 178 REGISTER_DECLARATION(Register, IdispatchTables , I4); // Base address of the bytecode dispatch tables
duke@435 179 REGISTER_DECLARATION(Register, IdispatchAddress , I3); // Register which saves the dispatch address for each bytecode
duke@435 180 REGISTER_DECLARATION(Register, ImethodDataPtr , I2); // Pointer to the current method data
duke@435 181 #endif /* CC_INTERP */
duke@435 182
duke@435 183 // NOTE: Lscratch2 and LcpoolCache point to the same registers in
duke@435 184 // the interpreter code. If Lscratch2 needs to be used for some
duke@435 185 // purpose than LcpoolCache should be restore after that for
duke@435 186 // the interpreter to work right
duke@435 187 // (These assignments must be compatible with L7_thread_cache; see above.)
duke@435 188
duke@435 189 // Since Lbcp points into the middle of the method object,
duke@435 190 // it is temporarily converted into a "bcx" during GC.
duke@435 191
duke@435 192 // Exception processing
duke@435 193 // These registers are passed into exception handlers.
duke@435 194 // All exception handlers require the exception object being thrown.
duke@435 195 // In addition, an nmethod's exception handler must be passed
duke@435 196 // the address of the call site within the nmethod, to allow
duke@435 197 // proper selection of the applicable catch block.
duke@435 198 // (Interpreter frames use their own bcp() for this purpose.)
duke@435 199 //
duke@435 200 // The Oissuing_pc value is not always needed. When jumping to a
duke@435 201 // handler that is known to be interpreted, the Oissuing_pc value can be
duke@435 202 // omitted. An actual catch block in compiled code receives (from its
duke@435 203 // nmethod's exception handler) the thrown exception in the Oexception,
duke@435 204 // but it doesn't need the Oissuing_pc.
duke@435 205 //
duke@435 206 // If an exception handler (either interpreted or compiled)
duke@435 207 // discovers there is no applicable catch block, it updates
duke@435 208 // the Oissuing_pc to the continuation PC of its own caller,
duke@435 209 // pops back to that caller's stack frame, and executes that
duke@435 210 // caller's exception handler. Obviously, this process will
duke@435 211 // iterate until the control stack is popped back to a method
duke@435 212 // containing an applicable catch block. A key invariant is
duke@435 213 // that the Oissuing_pc value is always a value local to
duke@435 214 // the method whose exception handler is currently executing.
duke@435 215 //
duke@435 216 // Note: The issuing PC value is __not__ a raw return address (I7 value).
duke@435 217 // It is a "return pc", the address __following__ the call.
duke@435 218 // Raw return addresses are converted to issuing PCs by frame::pc(),
duke@435 219 // or by stubs. Issuing PCs can be used directly with PC range tables.
duke@435 220 //
duke@435 221 REGISTER_DECLARATION(Register, Oexception , O0); // exception being thrown
duke@435 222 REGISTER_DECLARATION(Register, Oissuing_pc , O1); // where the exception is coming from
duke@435 223
duke@435 224
duke@435 225 // These must occur after the declarations above
duke@435 226 #ifndef DONT_USE_REGISTER_DEFINES
duke@435 227
duke@435 228 #define Gthread AS_REGISTER(Register, Gthread)
duke@435 229 #define Gmethod AS_REGISTER(Register, Gmethod)
duke@435 230 #define Gmegamorphic_method AS_REGISTER(Register, Gmegamorphic_method)
duke@435 231 #define Ginline_cache_reg AS_REGISTER(Register, Ginline_cache_reg)
duke@435 232 #define Gargs AS_REGISTER(Register, Gargs)
duke@435 233 #define Lthread_cache AS_REGISTER(Register, Lthread_cache)
duke@435 234 #define Gframe_size AS_REGISTER(Register, Gframe_size)
duke@435 235 #define Gtemp AS_REGISTER(Register, Gtemp)
duke@435 236
duke@435 237 #ifdef CC_INTERP
duke@435 238 #define Lstate AS_REGISTER(Register, Lstate)
duke@435 239 #define Lesp AS_REGISTER(Register, Lesp)
duke@435 240 #define L1_scratch AS_REGISTER(Register, L1_scratch)
duke@435 241 #define Lmirror AS_REGISTER(Register, Lmirror)
duke@435 242 #define L2_scratch AS_REGISTER(Register, L2_scratch)
duke@435 243 #define L3_scratch AS_REGISTER(Register, L3_scratch)
duke@435 244 #define L4_scratch AS_REGISTER(Register, L4_scratch)
duke@435 245 #define Lscratch AS_REGISTER(Register, Lscratch)
duke@435 246 #define Lscratch2 AS_REGISTER(Register, Lscratch2)
duke@435 247 #define L7_scratch AS_REGISTER(Register, L7_scratch)
duke@435 248 #define Ostate AS_REGISTER(Register, Ostate)
duke@435 249 #else
duke@435 250 #define Lesp AS_REGISTER(Register, Lesp)
duke@435 251 #define Lbcp AS_REGISTER(Register, Lbcp)
duke@435 252 #define Lmethod AS_REGISTER(Register, Lmethod)
duke@435 253 #define Llocals AS_REGISTER(Register, Llocals)
duke@435 254 #define Lmonitors AS_REGISTER(Register, Lmonitors)
duke@435 255 #define Lbyte_code AS_REGISTER(Register, Lbyte_code)
duke@435 256 #define Lscratch AS_REGISTER(Register, Lscratch)
duke@435 257 #define Lscratch2 AS_REGISTER(Register, Lscratch2)
duke@435 258 #define LcpoolCache AS_REGISTER(Register, LcpoolCache)
duke@435 259 #endif /* ! CC_INTERP */
duke@435 260
duke@435 261 #define Lentry_args AS_REGISTER(Register, Lentry_args)
duke@435 262 #define I5_savedSP AS_REGISTER(Register, I5_savedSP)
duke@435 263 #define O5_savedSP AS_REGISTER(Register, O5_savedSP)
duke@435 264 #define IdispatchAddress AS_REGISTER(Register, IdispatchAddress)
duke@435 265 #define ImethodDataPtr AS_REGISTER(Register, ImethodDataPtr)
duke@435 266 #define IdispatchTables AS_REGISTER(Register, IdispatchTables)
duke@435 267
duke@435 268 #define Oexception AS_REGISTER(Register, Oexception)
duke@435 269 #define Oissuing_pc AS_REGISTER(Register, Oissuing_pc)
duke@435 270
duke@435 271
duke@435 272 #endif
duke@435 273
duke@435 274 // Address is an abstraction used to represent a memory location.
duke@435 275 //
duke@435 276 // Note: A register location is represented via a Register, not
duke@435 277 // via an address for efficiency & simplicity reasons.
duke@435 278
duke@435 279 class Address VALUE_OBJ_CLASS_SPEC {
duke@435 280 private:
twisti@1162 281 Register _base; // Base register.
twisti@1162 282 RegisterOrConstant _index_or_disp; // Index register or constant displacement.
twisti@1162 283 RelocationHolder _rspec;
twisti@1162 284
twisti@1162 285 public:
twisti@1162 286 Address() : _base(noreg), _index_or_disp(noreg) {}
twisti@1162 287
twisti@1162 288 Address(Register base, RegisterOrConstant index_or_disp)
twisti@1162 289 : _base(base),
twisti@1162 290 _index_or_disp(index_or_disp) {
twisti@1162 291 }
twisti@1162 292
twisti@1162 293 Address(Register base, Register index)
twisti@1162 294 : _base(base),
twisti@1162 295 _index_or_disp(index) {
twisti@1162 296 }
twisti@1162 297
twisti@1162 298 Address(Register base, int disp)
twisti@1162 299 : _base(base),
twisti@1162 300 _index_or_disp(disp) {
twisti@1162 301 }
twisti@1162 302
twisti@1162 303 #ifdef ASSERT
twisti@1162 304 // ByteSize is only a class when ASSERT is defined, otherwise it's an int.
twisti@1162 305 Address(Register base, ByteSize disp)
twisti@1162 306 : _base(base),
twisti@1162 307 _index_or_disp(in_bytes(disp)) {
twisti@1162 308 }
duke@435 309 #endif
twisti@1162 310
twisti@1162 311 // accessors
twisti@1162 312 Register base() const { return _base; }
twisti@1162 313 Register index() const { return _index_or_disp.as_register(); }
twisti@1162 314 int disp() const { return _index_or_disp.as_constant(); }
twisti@1162 315
twisti@1162 316 bool has_index() const { return _index_or_disp.is_register(); }
twisti@1162 317 bool has_disp() const { return _index_or_disp.is_constant(); }
twisti@1162 318
twisti@1162 319 const relocInfo::relocType rtype() { return _rspec.type(); }
twisti@1162 320 const RelocationHolder& rspec() { return _rspec; }
twisti@1162 321
twisti@1162 322 RelocationHolder rspec(int offset) const {
twisti@1162 323 return offset == 0 ? _rspec : _rspec.plus(offset);
twisti@1162 324 }
twisti@1162 325
twisti@1162 326 inline bool is_simm13(int offset = 0); // check disp+offset for overflow
twisti@1162 327
twisti@1162 328 Address plus_disp(int plusdisp) const { // bump disp by a small amount
twisti@1162 329 assert(_index_or_disp.is_constant(), "must have a displacement");
twisti@1162 330 Address a(base(), disp() + plusdisp);
twisti@1162 331 return a;
twisti@1162 332 }
twisti@1162 333
twisti@1162 334 Address after_save() const {
twisti@1162 335 Address a = (*this);
twisti@1162 336 a._base = a._base->after_save();
twisti@1162 337 return a;
twisti@1162 338 }
twisti@1162 339
twisti@1162 340 Address after_restore() const {
twisti@1162 341 Address a = (*this);
twisti@1162 342 a._base = a._base->after_restore();
twisti@1162 343 return a;
twisti@1162 344 }
twisti@1162 345
twisti@1162 346 // Convert the raw encoding form into the form expected by the
twisti@1162 347 // constructor for Address.
twisti@1162 348 static Address make_raw(int base, int index, int scale, int disp, bool disp_is_oop);
twisti@1162 349
twisti@1162 350 friend class Assembler;
twisti@1162 351 };
twisti@1162 352
twisti@1162 353
twisti@1162 354 class AddressLiteral VALUE_OBJ_CLASS_SPEC {
twisti@1162 355 private:
twisti@1162 356 address _address;
twisti@1162 357 RelocationHolder _rspec;
twisti@1162 358
twisti@1162 359 RelocationHolder rspec_from_rtype(relocInfo::relocType rtype, address addr) {
twisti@1162 360 switch (rtype) {
duke@435 361 case relocInfo::external_word_type:
twisti@1162 362 return external_word_Relocation::spec(addr);
duke@435 363 case relocInfo::internal_word_type:
twisti@1162 364 return internal_word_Relocation::spec(addr);
duke@435 365 #ifdef _LP64
duke@435 366 case relocInfo::opt_virtual_call_type:
duke@435 367 return opt_virtual_call_Relocation::spec();
duke@435 368 case relocInfo::static_call_type:
duke@435 369 return static_call_Relocation::spec();
duke@435 370 case relocInfo::runtime_call_type:
duke@435 371 return runtime_call_Relocation::spec();
duke@435 372 #endif
duke@435 373 case relocInfo::none:
duke@435 374 return RelocationHolder();
duke@435 375 default:
duke@435 376 ShouldNotReachHere();
duke@435 377 return RelocationHolder();
duke@435 378 }
duke@435 379 }
duke@435 380
twisti@1162 381 protected:
twisti@1162 382 // creation
twisti@1162 383 AddressLiteral() : _address(NULL), _rspec(NULL) {}
twisti@1162 384
duke@435 385 public:
twisti@1162 386 AddressLiteral(address addr, RelocationHolder const& rspec)
twisti@1162 387 : _address(addr),
twisti@1162 388 _rspec(rspec) {}
twisti@1162 389
twisti@1162 390 // Some constructors to avoid casting at the call site.
twisti@1162 391 AddressLiteral(jobject obj, RelocationHolder const& rspec)
twisti@1162 392 : _address((address) obj),
twisti@1162 393 _rspec(rspec) {}
twisti@1162 394
twisti@1162 395 AddressLiteral(intptr_t value, RelocationHolder const& rspec)
twisti@1162 396 : _address((address) value),
twisti@1162 397 _rspec(rspec) {}
twisti@1162 398
twisti@1162 399 AddressLiteral(address addr, relocInfo::relocType rtype = relocInfo::none)
twisti@1162 400 : _address((address) addr),
twisti@1162 401 _rspec(rspec_from_rtype(rtype, (address) addr)) {}
twisti@1162 402
twisti@1162 403 // Some constructors to avoid casting at the call site.
twisti@1162 404 AddressLiteral(address* addr, relocInfo::relocType rtype = relocInfo::none)
twisti@1162 405 : _address((address) addr),
twisti@1162 406 _rspec(rspec_from_rtype(rtype, (address) addr)) {}
twisti@1162 407
twisti@1162 408 AddressLiteral(bool* addr, relocInfo::relocType rtype = relocInfo::none)
twisti@1162 409 : _address((address) addr),
twisti@1162 410 _rspec(rspec_from_rtype(rtype, (address) addr)) {}
twisti@1162 411
twisti@1162 412 AddressLiteral(const bool* addr, relocInfo::relocType rtype = relocInfo::none)
twisti@1162 413 : _address((address) addr),
twisti@1162 414 _rspec(rspec_from_rtype(rtype, (address) addr)) {}
twisti@1162 415
twisti@1162 416 AddressLiteral(signed char* addr, relocInfo::relocType rtype = relocInfo::none)
twisti@1162 417 : _address((address) addr),
twisti@1162 418 _rspec(rspec_from_rtype(rtype, (address) addr)) {}
twisti@1162 419
twisti@1162 420 AddressLiteral(int* addr, relocInfo::relocType rtype = relocInfo::none)
twisti@1162 421 : _address((address) addr),
twisti@1162 422 _rspec(rspec_from_rtype(rtype, (address) addr)) {}
twisti@1162 423
twisti@1162 424 AddressLiteral(intptr_t addr, relocInfo::relocType rtype = relocInfo::none)
twisti@1162 425 : _address((address) addr),
twisti@1162 426 _rspec(rspec_from_rtype(rtype, (address) addr)) {}
twisti@1162 427
duke@435 428 #ifdef _LP64
twisti@1162 429 // 32-bit complains about a multiple declaration for int*.
twisti@1162 430 AddressLiteral(intptr_t* addr, relocInfo::relocType rtype = relocInfo::none)
twisti@1162 431 : _address((address) addr),
twisti@1162 432 _rspec(rspec_from_rtype(rtype, (address) addr)) {}
duke@435 433 #endif
twisti@1162 434
twisti@1162 435 AddressLiteral(oop addr, relocInfo::relocType rtype = relocInfo::none)
twisti@1162 436 : _address((address) addr),
twisti@1162 437 _rspec(rspec_from_rtype(rtype, (address) addr)) {}
twisti@1162 438
twisti@1162 439 AddressLiteral(float* addr, relocInfo::relocType rtype = relocInfo::none)
twisti@1162 440 : _address((address) addr),
twisti@1162 441 _rspec(rspec_from_rtype(rtype, (address) addr)) {}
twisti@1162 442
twisti@1162 443 AddressLiteral(double* addr, relocInfo::relocType rtype = relocInfo::none)
twisti@1162 444 : _address((address) addr),
twisti@1162 445 _rspec(rspec_from_rtype(rtype, (address) addr)) {}
twisti@1162 446
twisti@1162 447 intptr_t value() const { return (intptr_t) _address; }
twisti@1162 448 int low10() const;
twisti@1162 449
twisti@1162 450 const relocInfo::relocType rtype() const { return _rspec.type(); }
twisti@1162 451 const RelocationHolder& rspec() const { return _rspec; }
twisti@1162 452
twisti@1162 453 RelocationHolder rspec(int offset) const {
duke@435 454 return offset == 0 ? _rspec : _rspec.plus(offset);
duke@435 455 }
duke@435 456 };
duke@435 457
duke@435 458
duke@435 459 inline Address RegisterImpl::address_in_saved_window() const {
twisti@1162 460 return (Address(SP, (sp_offset_in_saved_window() * wordSize) + STACK_BIAS));
duke@435 461 }
duke@435 462
duke@435 463
duke@435 464
duke@435 465 // Argument is an abstraction used to represent an outgoing
duke@435 466 // actual argument or an incoming formal parameter, whether
duke@435 467 // it resides in memory or in a register, in a manner consistent
duke@435 468 // with the SPARC Application Binary Interface, or ABI. This is
duke@435 469 // often referred to as the native or C calling convention.
duke@435 470
duke@435 471 class Argument VALUE_OBJ_CLASS_SPEC {
duke@435 472 private:
duke@435 473 int _number;
duke@435 474 bool _is_in;
duke@435 475
duke@435 476 public:
duke@435 477 #ifdef _LP64
duke@435 478 enum {
duke@435 479 n_register_parameters = 6, // only 6 registers may contain integer parameters
duke@435 480 n_float_register_parameters = 16 // Can have up to 16 floating registers
duke@435 481 };
duke@435 482 #else
duke@435 483 enum {
duke@435 484 n_register_parameters = 6 // only 6 registers may contain integer parameters
duke@435 485 };
duke@435 486 #endif
duke@435 487
duke@435 488 // creation
duke@435 489 Argument(int number, bool is_in) : _number(number), _is_in(is_in) {}
duke@435 490
duke@435 491 int number() const { return _number; }
duke@435 492 bool is_in() const { return _is_in; }
duke@435 493 bool is_out() const { return !is_in(); }
duke@435 494
duke@435 495 Argument successor() const { return Argument(number() + 1, is_in()); }
duke@435 496 Argument as_in() const { return Argument(number(), true ); }
duke@435 497 Argument as_out() const { return Argument(number(), false); }
duke@435 498
duke@435 499 // locating register-based arguments:
duke@435 500 bool is_register() const { return _number < n_register_parameters; }
duke@435 501
duke@435 502 #ifdef _LP64
duke@435 503 // locating Floating Point register-based arguments:
duke@435 504 bool is_float_register() const { return _number < n_float_register_parameters; }
duke@435 505
duke@435 506 FloatRegister as_float_register() const {
duke@435 507 assert(is_float_register(), "must be a register argument");
duke@435 508 return as_FloatRegister(( number() *2 ) + 1);
duke@435 509 }
duke@435 510 FloatRegister as_double_register() const {
duke@435 511 assert(is_float_register(), "must be a register argument");
duke@435 512 return as_FloatRegister(( number() *2 ));
duke@435 513 }
duke@435 514 #endif
duke@435 515
duke@435 516 Register as_register() const {
duke@435 517 assert(is_register(), "must be a register argument");
duke@435 518 return is_in() ? as_iRegister(number()) : as_oRegister(number());
duke@435 519 }
duke@435 520
duke@435 521 // locating memory-based arguments
duke@435 522 Address as_address() const {
duke@435 523 assert(!is_register(), "must be a memory argument");
duke@435 524 return address_in_frame();
duke@435 525 }
duke@435 526
duke@435 527 // When applied to a register-based argument, give the corresponding address
duke@435 528 // into the 6-word area "into which callee may store register arguments"
duke@435 529 // (This is a different place than the corresponding register-save area location.)
twisti@1162 530 Address address_in_frame() const;
duke@435 531
duke@435 532 // debugging
duke@435 533 const char* name() const;
duke@435 534
duke@435 535 friend class Assembler;
duke@435 536 };
duke@435 537
duke@435 538
duke@435 539 // The SPARC Assembler: Pure assembler doing NO optimizations on the instruction
duke@435 540 // level; i.e., what you write
duke@435 541 // is what you get. The Assembler is generating code into a CodeBuffer.
duke@435 542
duke@435 543 class Assembler : public AbstractAssembler {
duke@435 544 protected:
duke@435 545
duke@435 546 static void print_instruction(int inst);
duke@435 547 static int patched_branch(int dest_pos, int inst, int inst_pos);
duke@435 548 static int branch_destination(int inst, int pos);
duke@435 549
duke@435 550
duke@435 551 friend class AbstractAssembler;
twisti@1162 552 friend class AddressLiteral;
duke@435 553
duke@435 554 // code patchers need various routines like inv_wdisp()
duke@435 555 friend class NativeInstruction;
duke@435 556 friend class NativeGeneralJump;
duke@435 557 friend class Relocation;
duke@435 558 friend class Label;
duke@435 559
duke@435 560 public:
duke@435 561 // op carries format info; see page 62 & 267
duke@435 562
duke@435 563 enum ops {
duke@435 564 call_op = 1, // fmt 1
duke@435 565 branch_op = 0, // also sethi (fmt2)
duke@435 566 arith_op = 2, // fmt 3, arith & misc
duke@435 567 ldst_op = 3 // fmt 3, load/store
duke@435 568 };
duke@435 569
duke@435 570 enum op2s {
duke@435 571 bpr_op2 = 3,
duke@435 572 fb_op2 = 6,
duke@435 573 fbp_op2 = 5,
duke@435 574 br_op2 = 2,
duke@435 575 bp_op2 = 1,
duke@435 576 cb_op2 = 7, // V8
duke@435 577 sethi_op2 = 4
duke@435 578 };
duke@435 579
duke@435 580 enum op3s {
duke@435 581 // selected op3s
duke@435 582 add_op3 = 0x00,
duke@435 583 and_op3 = 0x01,
duke@435 584 or_op3 = 0x02,
duke@435 585 xor_op3 = 0x03,
duke@435 586 sub_op3 = 0x04,
duke@435 587 andn_op3 = 0x05,
duke@435 588 orn_op3 = 0x06,
duke@435 589 xnor_op3 = 0x07,
duke@435 590 addc_op3 = 0x08,
duke@435 591 mulx_op3 = 0x09,
duke@435 592 umul_op3 = 0x0a,
duke@435 593 smul_op3 = 0x0b,
duke@435 594 subc_op3 = 0x0c,
duke@435 595 udivx_op3 = 0x0d,
duke@435 596 udiv_op3 = 0x0e,
duke@435 597 sdiv_op3 = 0x0f,
duke@435 598
duke@435 599 addcc_op3 = 0x10,
duke@435 600 andcc_op3 = 0x11,
duke@435 601 orcc_op3 = 0x12,
duke@435 602 xorcc_op3 = 0x13,
duke@435 603 subcc_op3 = 0x14,
duke@435 604 andncc_op3 = 0x15,
duke@435 605 orncc_op3 = 0x16,
duke@435 606 xnorcc_op3 = 0x17,
duke@435 607 addccc_op3 = 0x18,
duke@435 608 umulcc_op3 = 0x1a,
duke@435 609 smulcc_op3 = 0x1b,
duke@435 610 subccc_op3 = 0x1c,
duke@435 611 udivcc_op3 = 0x1e,
duke@435 612 sdivcc_op3 = 0x1f,
duke@435 613
duke@435 614 taddcc_op3 = 0x20,
duke@435 615 tsubcc_op3 = 0x21,
duke@435 616 taddcctv_op3 = 0x22,
duke@435 617 tsubcctv_op3 = 0x23,
duke@435 618 mulscc_op3 = 0x24,
duke@435 619 sll_op3 = 0x25,
duke@435 620 sllx_op3 = 0x25,
duke@435 621 srl_op3 = 0x26,
duke@435 622 srlx_op3 = 0x26,
duke@435 623 sra_op3 = 0x27,
duke@435 624 srax_op3 = 0x27,
duke@435 625 rdreg_op3 = 0x28,
duke@435 626 membar_op3 = 0x28,
duke@435 627
duke@435 628 flushw_op3 = 0x2b,
duke@435 629 movcc_op3 = 0x2c,
duke@435 630 sdivx_op3 = 0x2d,
duke@435 631 popc_op3 = 0x2e,
duke@435 632 movr_op3 = 0x2f,
duke@435 633
duke@435 634 sir_op3 = 0x30,
duke@435 635 wrreg_op3 = 0x30,
duke@435 636 saved_op3 = 0x31,
duke@435 637
duke@435 638 fpop1_op3 = 0x34,
duke@435 639 fpop2_op3 = 0x35,
duke@435 640 impdep1_op3 = 0x36,
duke@435 641 impdep2_op3 = 0x37,
duke@435 642 jmpl_op3 = 0x38,
duke@435 643 rett_op3 = 0x39,
duke@435 644 trap_op3 = 0x3a,
duke@435 645 flush_op3 = 0x3b,
duke@435 646 save_op3 = 0x3c,
duke@435 647 restore_op3 = 0x3d,
duke@435 648 done_op3 = 0x3e,
duke@435 649 retry_op3 = 0x3e,
duke@435 650
duke@435 651 lduw_op3 = 0x00,
duke@435 652 ldub_op3 = 0x01,
duke@435 653 lduh_op3 = 0x02,
duke@435 654 ldd_op3 = 0x03,
duke@435 655 stw_op3 = 0x04,
duke@435 656 stb_op3 = 0x05,
duke@435 657 sth_op3 = 0x06,
duke@435 658 std_op3 = 0x07,
duke@435 659 ldsw_op3 = 0x08,
duke@435 660 ldsb_op3 = 0x09,
duke@435 661 ldsh_op3 = 0x0a,
duke@435 662 ldx_op3 = 0x0b,
duke@435 663
duke@435 664 ldstub_op3 = 0x0d,
duke@435 665 stx_op3 = 0x0e,
duke@435 666 swap_op3 = 0x0f,
duke@435 667
duke@435 668 stwa_op3 = 0x14,
duke@435 669 stxa_op3 = 0x1e,
duke@435 670
duke@435 671 ldf_op3 = 0x20,
duke@435 672 ldfsr_op3 = 0x21,
duke@435 673 ldqf_op3 = 0x22,
duke@435 674 lddf_op3 = 0x23,
duke@435 675 stf_op3 = 0x24,
duke@435 676 stfsr_op3 = 0x25,
duke@435 677 stqf_op3 = 0x26,
duke@435 678 stdf_op3 = 0x27,
duke@435 679
duke@435 680 prefetch_op3 = 0x2d,
duke@435 681
duke@435 682
duke@435 683 ldc_op3 = 0x30,
duke@435 684 ldcsr_op3 = 0x31,
duke@435 685 lddc_op3 = 0x33,
duke@435 686 stc_op3 = 0x34,
duke@435 687 stcsr_op3 = 0x35,
duke@435 688 stdcq_op3 = 0x36,
duke@435 689 stdc_op3 = 0x37,
duke@435 690
duke@435 691 casa_op3 = 0x3c,
duke@435 692 casxa_op3 = 0x3e,
duke@435 693
duke@435 694 alt_bit_op3 = 0x10,
duke@435 695 cc_bit_op3 = 0x10
duke@435 696 };
duke@435 697
duke@435 698 enum opfs {
duke@435 699 // selected opfs
duke@435 700 fmovs_opf = 0x01,
duke@435 701 fmovd_opf = 0x02,
duke@435 702
duke@435 703 fnegs_opf = 0x05,
duke@435 704 fnegd_opf = 0x06,
duke@435 705
duke@435 706 fadds_opf = 0x41,
duke@435 707 faddd_opf = 0x42,
duke@435 708 fsubs_opf = 0x45,
duke@435 709 fsubd_opf = 0x46,
duke@435 710
duke@435 711 fmuls_opf = 0x49,
duke@435 712 fmuld_opf = 0x4a,
duke@435 713 fdivs_opf = 0x4d,
duke@435 714 fdivd_opf = 0x4e,
duke@435 715
duke@435 716 fcmps_opf = 0x51,
duke@435 717 fcmpd_opf = 0x52,
duke@435 718
duke@435 719 fstox_opf = 0x81,
duke@435 720 fdtox_opf = 0x82,
duke@435 721 fxtos_opf = 0x84,
duke@435 722 fxtod_opf = 0x88,
duke@435 723 fitos_opf = 0xc4,
duke@435 724 fdtos_opf = 0xc6,
duke@435 725 fitod_opf = 0xc8,
duke@435 726 fstod_opf = 0xc9,
duke@435 727 fstoi_opf = 0xd1,
duke@435 728 fdtoi_opf = 0xd2
duke@435 729 };
duke@435 730
duke@435 731 enum RCondition { rc_z = 1, rc_lez = 2, rc_lz = 3, rc_nz = 5, rc_gz = 6, rc_gez = 7 };
duke@435 732
duke@435 733 enum Condition {
duke@435 734 // for FBfcc & FBPfcc instruction
duke@435 735 f_never = 0,
duke@435 736 f_notEqual = 1,
duke@435 737 f_notZero = 1,
duke@435 738 f_lessOrGreater = 2,
duke@435 739 f_unorderedOrLess = 3,
duke@435 740 f_less = 4,
duke@435 741 f_unorderedOrGreater = 5,
duke@435 742 f_greater = 6,
duke@435 743 f_unordered = 7,
duke@435 744 f_always = 8,
duke@435 745 f_equal = 9,
duke@435 746 f_zero = 9,
duke@435 747 f_unorderedOrEqual = 10,
duke@435 748 f_greaterOrEqual = 11,
duke@435 749 f_unorderedOrGreaterOrEqual = 12,
duke@435 750 f_lessOrEqual = 13,
duke@435 751 f_unorderedOrLessOrEqual = 14,
duke@435 752 f_ordered = 15,
duke@435 753
duke@435 754 // V8 coproc, pp 123 v8 manual
duke@435 755
duke@435 756 cp_always = 8,
duke@435 757 cp_never = 0,
duke@435 758 cp_3 = 7,
duke@435 759 cp_2 = 6,
duke@435 760 cp_2or3 = 5,
duke@435 761 cp_1 = 4,
duke@435 762 cp_1or3 = 3,
duke@435 763 cp_1or2 = 2,
duke@435 764 cp_1or2or3 = 1,
duke@435 765 cp_0 = 9,
duke@435 766 cp_0or3 = 10,
duke@435 767 cp_0or2 = 11,
duke@435 768 cp_0or2or3 = 12,
duke@435 769 cp_0or1 = 13,
duke@435 770 cp_0or1or3 = 14,
duke@435 771 cp_0or1or2 = 15,
duke@435 772
duke@435 773
duke@435 774 // for integers
duke@435 775
duke@435 776 never = 0,
duke@435 777 equal = 1,
duke@435 778 zero = 1,
duke@435 779 lessEqual = 2,
duke@435 780 less = 3,
duke@435 781 lessEqualUnsigned = 4,
duke@435 782 lessUnsigned = 5,
duke@435 783 carrySet = 5,
duke@435 784 negative = 6,
duke@435 785 overflowSet = 7,
duke@435 786 always = 8,
duke@435 787 notEqual = 9,
duke@435 788 notZero = 9,
duke@435 789 greater = 10,
duke@435 790 greaterEqual = 11,
duke@435 791 greaterUnsigned = 12,
duke@435 792 greaterEqualUnsigned = 13,
duke@435 793 carryClear = 13,
duke@435 794 positive = 14,
duke@435 795 overflowClear = 15
duke@435 796 };
duke@435 797
duke@435 798 enum CC {
duke@435 799 icc = 0, xcc = 2,
duke@435 800 // ptr_cc is the correct condition code for a pointer or intptr_t:
duke@435 801 ptr_cc = NOT_LP64(icc) LP64_ONLY(xcc),
duke@435 802 fcc0 = 0, fcc1 = 1, fcc2 = 2, fcc3 = 3
duke@435 803 };
duke@435 804
duke@435 805 enum PrefetchFcn {
duke@435 806 severalReads = 0, oneRead = 1, severalWritesAndPossiblyReads = 2, oneWrite = 3, page = 4
duke@435 807 };
duke@435 808
duke@435 809 public:
duke@435 810 // Helper functions for groups of instructions
duke@435 811
duke@435 812 enum Predict { pt = 1, pn = 0 }; // pt = predict taken
duke@435 813
duke@435 814 enum Membar_mask_bits { // page 184, v9
duke@435 815 StoreStore = 1 << 3,
duke@435 816 LoadStore = 1 << 2,
duke@435 817 StoreLoad = 1 << 1,
duke@435 818 LoadLoad = 1 << 0,
duke@435 819
duke@435 820 Sync = 1 << 6,
duke@435 821 MemIssue = 1 << 5,
duke@435 822 Lookaside = 1 << 4
duke@435 823 };
duke@435 824
duke@435 825 // test if x is within signed immediate range for nbits
iveresov@2441 826 static bool is_simm(intptr_t x, int nbits) { return -( intptr_t(1) << nbits-1 ) <= x && x < ( intptr_t(1) << nbits-1 ); }
duke@435 827
duke@435 828 // test if -4096 <= x <= 4095
iveresov@2441 829 static bool is_simm13(intptr_t x) { return is_simm(x, 13); }
iveresov@2441 830
iveresov@2441 831 static bool is_in_wdisp_range(address a, address b, int nbits) {
iveresov@2441 832 intptr_t d = intptr_t(b) - intptr_t(a);
iveresov@2441 833 return is_simm(d, nbits + 2);
iveresov@2441 834 }
duke@435 835
iveresov@2203 836 // test if label is in simm16 range in words (wdisp16).
iveresov@2203 837 bool is_in_wdisp16_range(Label& L) {
iveresov@2441 838 return is_in_wdisp_range(target(L), pc(), 16);
iveresov@2441 839 }
iveresov@2441 840 // test if the distance between two addresses fits in simm30 range in words
iveresov@2441 841 static bool is_in_wdisp30_range(address a, address b) {
iveresov@2441 842 return is_in_wdisp_range(a, b, 30);
iveresov@2203 843 }
iveresov@2203 844
duke@435 845 enum ASIs { // page 72, v9
duke@435 846 ASI_PRIMARY = 0x80,
duke@435 847 ASI_PRIMARY_LITTLE = 0x88
duke@435 848 // add more from book as needed
duke@435 849 };
duke@435 850
duke@435 851 protected:
duke@435 852 // helpers
duke@435 853
duke@435 854 // x is supposed to fit in a field "nbits" wide
duke@435 855 // and be sign-extended. Check the range.
duke@435 856
duke@435 857 static void assert_signed_range(intptr_t x, int nbits) {
duke@435 858 assert( nbits == 32
duke@435 859 || -(1 << nbits-1) <= x && x < ( 1 << nbits-1),
duke@435 860 "value out of range");
duke@435 861 }
duke@435 862
duke@435 863 static void assert_signed_word_disp_range(intptr_t x, int nbits) {
duke@435 864 assert( (x & 3) == 0, "not word aligned");
duke@435 865 assert_signed_range(x, nbits + 2);
duke@435 866 }
duke@435 867
duke@435 868 static void assert_unsigned_const(int x, int nbits) {
duke@435 869 assert( juint(x) < juint(1 << nbits), "unsigned constant out of range");
duke@435 870 }
duke@435 871
duke@435 872 // fields: note bits numbered from LSB = 0,
duke@435 873 // fields known by inclusive bit range
duke@435 874
duke@435 875 static int fmask(juint hi_bit, juint lo_bit) {
duke@435 876 assert( hi_bit >= lo_bit && 0 <= lo_bit && hi_bit < 32, "bad bits");
duke@435 877 return (1 << ( hi_bit-lo_bit + 1 )) - 1;
duke@435 878 }
duke@435 879
duke@435 880 // inverse of u_field
duke@435 881
duke@435 882 static int inv_u_field(int x, int hi_bit, int lo_bit) {
duke@435 883 juint r = juint(x) >> lo_bit;
duke@435 884 r &= fmask( hi_bit, lo_bit);
duke@435 885 return int(r);
duke@435 886 }
duke@435 887
duke@435 888
duke@435 889 // signed version: extract from field and sign-extend
duke@435 890
duke@435 891 static int inv_s_field(int x, int hi_bit, int lo_bit) {
duke@435 892 int sign_shift = 31 - hi_bit;
duke@435 893 return inv_u_field( ((x << sign_shift) >> sign_shift), hi_bit, lo_bit);
duke@435 894 }
duke@435 895
duke@435 896 // given a field that ranges from hi_bit to lo_bit (inclusive,
duke@435 897 // LSB = 0), and an unsigned value for the field,
duke@435 898 // shift it into the field
duke@435 899
duke@435 900 #ifdef ASSERT
duke@435 901 static int u_field(int x, int hi_bit, int lo_bit) {
duke@435 902 assert( ( x & ~fmask(hi_bit, lo_bit)) == 0,
duke@435 903 "value out of range");
duke@435 904 int r = x << lo_bit;
duke@435 905 assert( inv_u_field(r, hi_bit, lo_bit) == x, "just checking");
duke@435 906 return r;
duke@435 907 }
duke@435 908 #else
duke@435 909 // make sure this is inlined as it will reduce code size significantly
duke@435 910 #define u_field(x, hi_bit, lo_bit) ((x) << (lo_bit))
duke@435 911 #endif
duke@435 912
duke@435 913 static int inv_op( int x ) { return inv_u_field(x, 31, 30); }
duke@435 914 static int inv_op2( int x ) { return inv_u_field(x, 24, 22); }
duke@435 915 static int inv_op3( int x ) { return inv_u_field(x, 24, 19); }
duke@435 916 static int inv_cond( int x ){ return inv_u_field(x, 28, 25); }
duke@435 917
duke@435 918 static bool inv_immed( int x ) { return (x & Assembler::immed(true)) != 0; }
duke@435 919
duke@435 920 static Register inv_rd( int x ) { return as_Register(inv_u_field(x, 29, 25)); }
duke@435 921 static Register inv_rs1( int x ) { return as_Register(inv_u_field(x, 18, 14)); }
duke@435 922 static Register inv_rs2( int x ) { return as_Register(inv_u_field(x, 4, 0)); }
duke@435 923
duke@435 924 static int op( int x) { return u_field(x, 31, 30); }
duke@435 925 static int rd( Register r) { return u_field(r->encoding(), 29, 25); }
duke@435 926 static int fcn( int x) { return u_field(x, 29, 25); }
duke@435 927 static int op3( int x) { return u_field(x, 24, 19); }
duke@435 928 static int rs1( Register r) { return u_field(r->encoding(), 18, 14); }
duke@435 929 static int rs2( Register r) { return u_field(r->encoding(), 4, 0); }
duke@435 930 static int annul( bool a) { return u_field(a ? 1 : 0, 29, 29); }
duke@435 931 static int cond( int x) { return u_field(x, 28, 25); }
duke@435 932 static int cond_mov( int x) { return u_field(x, 17, 14); }
duke@435 933 static int rcond( RCondition x) { return u_field(x, 12, 10); }
duke@435 934 static int op2( int x) { return u_field(x, 24, 22); }
duke@435 935 static int predict( bool p) { return u_field(p ? 1 : 0, 19, 19); }
duke@435 936 static int branchcc( CC fcca) { return u_field(fcca, 21, 20); }
duke@435 937 static int cmpcc( CC fcca) { return u_field(fcca, 26, 25); }
duke@435 938 static int imm_asi( int x) { return u_field(x, 12, 5); }
duke@435 939 static int immed( bool i) { return u_field(i ? 1 : 0, 13, 13); }
duke@435 940 static int opf_low6( int w) { return u_field(w, 10, 5); }
duke@435 941 static int opf_low5( int w) { return u_field(w, 9, 5); }
duke@435 942 static int trapcc( CC cc) { return u_field(cc, 12, 11); }
duke@435 943 static int sx( int i) { return u_field(i, 12, 12); } // shift x=1 means 64-bit
duke@435 944 static int opf( int x) { return u_field(x, 13, 5); }
duke@435 945
duke@435 946 static int opf_cc( CC c, bool useFloat ) { return u_field((useFloat ? 0 : 4) + c, 13, 11); }
duke@435 947 static int mov_cc( CC c, bool useFloat ) { return u_field(useFloat ? 0 : 1, 18, 18) | u_field(c, 12, 11); }
duke@435 948
duke@435 949 static int fd( FloatRegister r, FloatRegisterImpl::Width fwa) { return u_field(r->encoding(fwa), 29, 25); };
duke@435 950 static int fs1(FloatRegister r, FloatRegisterImpl::Width fwa) { return u_field(r->encoding(fwa), 18, 14); };
duke@435 951 static int fs2(FloatRegister r, FloatRegisterImpl::Width fwa) { return u_field(r->encoding(fwa), 4, 0); };
duke@435 952
duke@435 953 // some float instructions use this encoding on the op3 field
duke@435 954 static int alt_op3(int op, FloatRegisterImpl::Width w) {
duke@435 955 int r;
duke@435 956 switch(w) {
duke@435 957 case FloatRegisterImpl::S: r = op + 0; break;
duke@435 958 case FloatRegisterImpl::D: r = op + 3; break;
duke@435 959 case FloatRegisterImpl::Q: r = op + 2; break;
duke@435 960 default: ShouldNotReachHere(); break;
duke@435 961 }
duke@435 962 return op3(r);
duke@435 963 }
duke@435 964
duke@435 965
duke@435 966 // compute inverse of simm
duke@435 967 static int inv_simm(int x, int nbits) {
duke@435 968 return (int)(x << (32 - nbits)) >> (32 - nbits);
duke@435 969 }
duke@435 970
duke@435 971 static int inv_simm13( int x ) { return inv_simm(x, 13); }
duke@435 972
duke@435 973 // signed immediate, in low bits, nbits long
duke@435 974 static int simm(int x, int nbits) {
duke@435 975 assert_signed_range(x, nbits);
duke@435 976 return x & (( 1 << nbits ) - 1);
duke@435 977 }
duke@435 978
duke@435 979 // compute inverse of wdisp16
duke@435 980 static intptr_t inv_wdisp16(int x, intptr_t pos) {
duke@435 981 int lo = x & (( 1 << 14 ) - 1);
duke@435 982 int hi = (x >> 20) & 3;
duke@435 983 if (hi >= 2) hi |= ~1;
duke@435 984 return (((hi << 14) | lo) << 2) + pos;
duke@435 985 }
duke@435 986
duke@435 987 // word offset, 14 bits at LSend, 2 bits at B21, B20
duke@435 988 static int wdisp16(intptr_t x, intptr_t off) {
duke@435 989 intptr_t xx = x - off;
duke@435 990 assert_signed_word_disp_range(xx, 16);
duke@435 991 int r = (xx >> 2) & ((1 << 14) - 1)
duke@435 992 | ( ( (xx>>(2+14)) & 3 ) << 20 );
duke@435 993 assert( inv_wdisp16(r, off) == x, "inverse is not inverse");
duke@435 994 return r;
duke@435 995 }
duke@435 996
duke@435 997
duke@435 998 // word displacement in low-order nbits bits
duke@435 999
duke@435 1000 static intptr_t inv_wdisp( int x, intptr_t pos, int nbits ) {
duke@435 1001 int pre_sign_extend = x & (( 1 << nbits ) - 1);
duke@435 1002 int r = pre_sign_extend >= ( 1 << (nbits-1) )
duke@435 1003 ? pre_sign_extend | ~(( 1 << nbits ) - 1)
duke@435 1004 : pre_sign_extend;
duke@435 1005 return (r << 2) + pos;
duke@435 1006 }
duke@435 1007
duke@435 1008 static int wdisp( intptr_t x, intptr_t off, int nbits ) {
duke@435 1009 intptr_t xx = x - off;
duke@435 1010 assert_signed_word_disp_range(xx, nbits);
duke@435 1011 int r = (xx >> 2) & (( 1 << nbits ) - 1);
duke@435 1012 assert( inv_wdisp( r, off, nbits ) == x, "inverse not inverse");
duke@435 1013 return r;
duke@435 1014 }
duke@435 1015
duke@435 1016
duke@435 1017 // Extract the top 32 bits in a 64 bit word
duke@435 1018 static int32_t hi32( int64_t x ) {
duke@435 1019 int32_t r = int32_t( (uint64_t)x >> 32 );
duke@435 1020 return r;
duke@435 1021 }
duke@435 1022
duke@435 1023 // given a sethi instruction, extract the constant, left-justified
duke@435 1024 static int inv_hi22( int x ) {
duke@435 1025 return x << 10;
duke@435 1026 }
duke@435 1027
duke@435 1028 // create an imm22 field, given a 32-bit left-justified constant
duke@435 1029 static int hi22( int x ) {
duke@435 1030 int r = int( juint(x) >> 10 );
duke@435 1031 assert( (r & ~((1 << 22) - 1)) == 0, "just checkin'");
duke@435 1032 return r;
duke@435 1033 }
duke@435 1034
duke@435 1035 // create a low10 __value__ (not a field) for a given a 32-bit constant
duke@435 1036 static int low10( int x ) {
duke@435 1037 return x & ((1 << 10) - 1);
duke@435 1038 }
duke@435 1039
duke@435 1040 // instruction only in v9
duke@435 1041 static void v9_only() { assert( VM_Version::v9_instructions_work(), "This instruction only works on SPARC V9"); }
duke@435 1042
duke@435 1043 // instruction only in v8
duke@435 1044 static void v8_only() { assert( VM_Version::v8_instructions_work(), "This instruction only works on SPARC V8"); }
duke@435 1045
duke@435 1046 // instruction deprecated in v9
duke@435 1047 static void v9_dep() { } // do nothing for now
duke@435 1048
duke@435 1049 // some float instructions only exist for single prec. on v8
duke@435 1050 static void v8_s_only(FloatRegisterImpl::Width w) { if (w != FloatRegisterImpl::S) v9_only(); }
duke@435 1051
duke@435 1052 // v8 has no CC field
duke@435 1053 static void v8_no_cc(CC cc) { if (cc) v9_only(); }
duke@435 1054
duke@435 1055 protected:
duke@435 1056 // Simple delay-slot scheme:
duke@435 1057 // In order to check the programmer, the assembler keeps track of deley slots.
duke@435 1058 // It forbids CTIs in delay slots (conservative, but should be OK).
duke@435 1059 // Also, when putting an instruction into a delay slot, you must say
duke@435 1060 // asm->delayed()->add(...), in order to check that you don't omit
duke@435 1061 // delay-slot instructions.
duke@435 1062 // To implement this, we use a simple FSA
duke@435 1063
duke@435 1064 #ifdef ASSERT
duke@435 1065 #define CHECK_DELAY
duke@435 1066 #endif
duke@435 1067 #ifdef CHECK_DELAY
duke@435 1068 enum Delay_state { no_delay, at_delay_slot, filling_delay_slot } delay_state;
duke@435 1069 #endif
duke@435 1070
duke@435 1071 public:
duke@435 1072 // Tells assembler next instruction must NOT be in delay slot.
duke@435 1073 // Use at start of multinstruction macros.
duke@435 1074 void assert_not_delayed() {
duke@435 1075 // This is a separate overloading to avoid creation of string constants
duke@435 1076 // in non-asserted code--with some compilers this pollutes the object code.
duke@435 1077 #ifdef CHECK_DELAY
duke@435 1078 assert_not_delayed("next instruction should not be a delay slot");
duke@435 1079 #endif
duke@435 1080 }
duke@435 1081 void assert_not_delayed(const char* msg) {
duke@435 1082 #ifdef CHECK_DELAY
jcoomes@1845 1083 assert(delay_state == no_delay, msg);
duke@435 1084 #endif
duke@435 1085 }
duke@435 1086
duke@435 1087 protected:
duke@435 1088 // Delay slot helpers
duke@435 1089 // cti is called when emitting control-transfer instruction,
duke@435 1090 // BEFORE doing the emitting.
duke@435 1091 // Only effective when assertion-checking is enabled.
duke@435 1092 void cti() {
duke@435 1093 #ifdef CHECK_DELAY
duke@435 1094 assert_not_delayed("cti should not be in delay slot");
duke@435 1095 #endif
duke@435 1096 }
duke@435 1097
duke@435 1098 // called when emitting cti with a delay slot, AFTER emitting
duke@435 1099 void has_delay_slot() {
duke@435 1100 #ifdef CHECK_DELAY
duke@435 1101 assert_not_delayed("just checking");
duke@435 1102 delay_state = at_delay_slot;
duke@435 1103 #endif
duke@435 1104 }
duke@435 1105
duke@435 1106 public:
duke@435 1107 // Tells assembler you know that next instruction is delayed
duke@435 1108 Assembler* delayed() {
duke@435 1109 #ifdef CHECK_DELAY
duke@435 1110 assert ( delay_state == at_delay_slot, "delayed instruction is not in delay slot");
duke@435 1111 delay_state = filling_delay_slot;
duke@435 1112 #endif
duke@435 1113 return this;
duke@435 1114 }
duke@435 1115
duke@435 1116 void flush() {
duke@435 1117 #ifdef CHECK_DELAY
duke@435 1118 assert ( delay_state == no_delay, "ending code with a delay slot");
duke@435 1119 #endif
duke@435 1120 AbstractAssembler::flush();
duke@435 1121 }
duke@435 1122
duke@435 1123 inline void emit_long(int); // shadows AbstractAssembler::emit_long
duke@435 1124 inline void emit_data(int x) { emit_long(x); }
duke@435 1125 inline void emit_data(int, RelocationHolder const&);
duke@435 1126 inline void emit_data(int, relocInfo::relocType rtype);
duke@435 1127 // helper for above fcns
duke@435 1128 inline void check_delay();
duke@435 1129
duke@435 1130
duke@435 1131 public:
duke@435 1132 // instructions, refer to page numbers in the SPARC Architecture Manual, V9
duke@435 1133
duke@435 1134 // pp 135 (addc was addx in v8)
duke@435 1135
twisti@1162 1136 inline void add(Register s1, Register s2, Register d );
twisti@1162 1137 inline void add(Register s1, int simm13a, Register d, relocInfo::relocType rtype = relocInfo::none);
twisti@1162 1138 inline void add(Register s1, int simm13a, Register d, RelocationHolder const& rspec);
twisti@1162 1139 inline void add(Register s1, RegisterOrConstant s2, Register d, int offset = 0);
jrose@2266 1140 inline void add(const Address& a, Register d, int offset = 0);
duke@435 1141
duke@435 1142 void addcc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(add_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); }
duke@435 1143 void addcc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(add_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1144 void addc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(addc_op3 ) | rs1(s1) | rs2(s2) ); }
duke@435 1145 void addc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(addc_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1146 void addccc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(addc_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); }
duke@435 1147 void addccc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(addc_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1148
duke@435 1149 // pp 136
duke@435 1150
duke@435 1151 inline void bpr( RCondition c, bool a, Predict p, Register s1, address d, relocInfo::relocType rt = relocInfo::none );
duke@435 1152 inline void bpr( RCondition c, bool a, Predict p, Register s1, Label& L);
duke@435 1153
duke@435 1154 protected: // use MacroAssembler::br instead
duke@435 1155
duke@435 1156 // pp 138
duke@435 1157
duke@435 1158 inline void fb( Condition c, bool a, address d, relocInfo::relocType rt = relocInfo::none );
duke@435 1159 inline void fb( Condition c, bool a, Label& L );
duke@435 1160
duke@435 1161 // pp 141
duke@435 1162
duke@435 1163 inline void fbp( Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt = relocInfo::none );
duke@435 1164 inline void fbp( Condition c, bool a, CC cc, Predict p, Label& L );
duke@435 1165
duke@435 1166 public:
duke@435 1167
duke@435 1168 // pp 144
duke@435 1169
duke@435 1170 inline void br( Condition c, bool a, address d, relocInfo::relocType rt = relocInfo::none );
duke@435 1171 inline void br( Condition c, bool a, Label& L );
duke@435 1172
duke@435 1173 // pp 146
duke@435 1174
duke@435 1175 inline void bp( Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt = relocInfo::none );
duke@435 1176 inline void bp( Condition c, bool a, CC cc, Predict p, Label& L );
duke@435 1177
duke@435 1178 // pp 121 (V8)
duke@435 1179
duke@435 1180 inline void cb( Condition c, bool a, address d, relocInfo::relocType rt = relocInfo::none );
duke@435 1181 inline void cb( Condition c, bool a, Label& L );
duke@435 1182
duke@435 1183 // pp 149
duke@435 1184
duke@435 1185 inline void call( address d, relocInfo::relocType rt = relocInfo::runtime_call_type );
duke@435 1186 inline void call( Label& L, relocInfo::relocType rt = relocInfo::runtime_call_type );
duke@435 1187
duke@435 1188 // pp 150
duke@435 1189
duke@435 1190 // These instructions compare the contents of s2 with the contents of
duke@435 1191 // memory at address in s1. If the values are equal, the contents of memory
duke@435 1192 // at address s1 is swapped with the data in d. If the values are not equal,
duke@435 1193 // the the contents of memory at s1 is loaded into d, without the swap.
duke@435 1194
duke@435 1195 void casa( Register s1, Register s2, Register d, int ia = -1 ) { v9_only(); emit_long( op(ldst_op) | rd(d) | op3(casa_op3 ) | rs1(s1) | (ia == -1 ? immed(true) : imm_asi(ia)) | rs2(s2)); }
duke@435 1196 void casxa( Register s1, Register s2, Register d, int ia = -1 ) { v9_only(); emit_long( op(ldst_op) | rd(d) | op3(casxa_op3) | rs1(s1) | (ia == -1 ? immed(true) : imm_asi(ia)) | rs2(s2)); }
duke@435 1197
duke@435 1198 // pp 152
duke@435 1199
duke@435 1200 void udiv( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(udiv_op3 ) | rs1(s1) | rs2(s2)); }
duke@435 1201 void udiv( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(udiv_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1202 void sdiv( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(sdiv_op3 ) | rs1(s1) | rs2(s2)); }
duke@435 1203 void sdiv( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(sdiv_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1204 void udivcc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(udiv_op3 | cc_bit_op3) | rs1(s1) | rs2(s2)); }
duke@435 1205 void udivcc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(udiv_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1206 void sdivcc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(sdiv_op3 | cc_bit_op3) | rs1(s1) | rs2(s2)); }
duke@435 1207 void sdivcc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(sdiv_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1208
duke@435 1209 // pp 155
duke@435 1210
duke@435 1211 void done() { v9_only(); cti(); emit_long( op(arith_op) | fcn(0) | op3(done_op3) ); }
duke@435 1212 void retry() { v9_only(); cti(); emit_long( op(arith_op) | fcn(1) | op3(retry_op3) ); }
duke@435 1213
duke@435 1214 // pp 156
duke@435 1215
duke@435 1216 void fadd( FloatRegisterImpl::Width w, FloatRegister s1, FloatRegister s2, FloatRegister d ) { emit_long( op(arith_op) | fd(d, w) | op3(fpop1_op3) | fs1(s1, w) | opf(0x40 + w) | fs2(s2, w)); }
duke@435 1217 void fsub( FloatRegisterImpl::Width w, FloatRegister s1, FloatRegister s2, FloatRegister d ) { emit_long( op(arith_op) | fd(d, w) | op3(fpop1_op3) | fs1(s1, w) | opf(0x44 + w) | fs2(s2, w)); }
duke@435 1218
duke@435 1219 // pp 157
duke@435 1220
duke@435 1221 void fcmp( FloatRegisterImpl::Width w, CC cc, FloatRegister s1, FloatRegister s2) { v8_no_cc(cc); emit_long( op(arith_op) | cmpcc(cc) | op3(fpop2_op3) | fs1(s1, w) | opf(0x50 + w) | fs2(s2, w)); }
duke@435 1222 void fcmpe( FloatRegisterImpl::Width w, CC cc, FloatRegister s1, FloatRegister s2) { v8_no_cc(cc); emit_long( op(arith_op) | cmpcc(cc) | op3(fpop2_op3) | fs1(s1, w) | opf(0x54 + w) | fs2(s2, w)); }
duke@435 1223
duke@435 1224 // pp 159
duke@435 1225
duke@435 1226 void ftox( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { v9_only(); emit_long( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0x80 + w) | fs2(s, w)); }
duke@435 1227 void ftoi( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { emit_long( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0xd0 + w) | fs2(s, w)); }
duke@435 1228
duke@435 1229 // pp 160
duke@435 1230
duke@435 1231 void ftof( FloatRegisterImpl::Width sw, FloatRegisterImpl::Width dw, FloatRegister s, FloatRegister d ) { emit_long( op(arith_op) | fd(d, dw) | op3(fpop1_op3) | opf(0xc0 + sw + dw*4) | fs2(s, sw)); }
duke@435 1232
duke@435 1233 // pp 161
duke@435 1234
duke@435 1235 void fxtof( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { v9_only(); emit_long( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0x80 + w*4) | fs2(s, w)); }
duke@435 1236 void fitof( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { emit_long( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0xc0 + w*4) | fs2(s, w)); }
duke@435 1237
duke@435 1238 // pp 162
duke@435 1239
duke@435 1240 void fmov( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { v8_s_only(w); emit_long( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0x00 + w) | fs2(s, w)); }
duke@435 1241
duke@435 1242 void fneg( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { v8_s_only(w); emit_long( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0x04 + w) | fs2(s, w)); }
duke@435 1243
duke@435 1244 // page 144 sparc v8 architecture (double prec works on v8 if the source and destination registers are the same). fnegs is the only instruction available
duke@435 1245 // on v8 to do negation of single, double and quad precision floats.
duke@435 1246
duke@435 1247 void fneg( FloatRegisterImpl::Width w, FloatRegister sd ) { if (VM_Version::v9_instructions_work()) emit_long( op(arith_op) | fd(sd, w) | op3(fpop1_op3) | opf(0x04 + w) | fs2(sd, w)); else emit_long( op(arith_op) | fd(sd, w) | op3(fpop1_op3) | opf(0x05) | fs2(sd, w)); }
duke@435 1248
duke@435 1249 void fabs( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { v8_s_only(w); emit_long( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0x08 + w) | fs2(s, w)); }
duke@435 1250
duke@435 1251 // page 144 sparc v8 architecture (double prec works on v8 if the source and destination registers are the same). fabss is the only instruction available
duke@435 1252 // on v8 to do abs operation on single/double/quad precision floats.
duke@435 1253
duke@435 1254 void fabs( FloatRegisterImpl::Width w, FloatRegister sd ) { if (VM_Version::v9_instructions_work()) emit_long( op(arith_op) | fd(sd, w) | op3(fpop1_op3) | opf(0x08 + w) | fs2(sd, w)); else emit_long( op(arith_op) | fd(sd, w) | op3(fpop1_op3) | opf(0x09) | fs2(sd, w)); }
duke@435 1255
duke@435 1256 // pp 163
duke@435 1257
duke@435 1258 void fmul( FloatRegisterImpl::Width w, FloatRegister s1, FloatRegister s2, FloatRegister d ) { emit_long( op(arith_op) | fd(d, w) | op3(fpop1_op3) | fs1(s1, w) | opf(0x48 + w) | fs2(s2, w)); }
duke@435 1259 void fmul( FloatRegisterImpl::Width sw, FloatRegisterImpl::Width dw, FloatRegister s1, FloatRegister s2, FloatRegister d ) { emit_long( op(arith_op) | fd(d, dw) | op3(fpop1_op3) | fs1(s1, sw) | opf(0x60 + sw + dw*4) | fs2(s2, sw)); }
duke@435 1260 void fdiv( FloatRegisterImpl::Width w, FloatRegister s1, FloatRegister s2, FloatRegister d ) { emit_long( op(arith_op) | fd(d, w) | op3(fpop1_op3) | fs1(s1, w) | opf(0x4c + w) | fs2(s2, w)); }
duke@435 1261
duke@435 1262 // pp 164
duke@435 1263
duke@435 1264 void fsqrt( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { emit_long( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0x28 + w) | fs2(s, w)); }
duke@435 1265
duke@435 1266 // pp 165
duke@435 1267
duke@435 1268 inline void flush( Register s1, Register s2 );
duke@435 1269 inline void flush( Register s1, int simm13a);
duke@435 1270
duke@435 1271 // pp 167
duke@435 1272
duke@435 1273 void flushw() { v9_only(); emit_long( op(arith_op) | op3(flushw_op3) ); }
duke@435 1274
duke@435 1275 // pp 168
duke@435 1276
duke@435 1277 void illtrap( int const22a) { if (const22a != 0) v9_only(); emit_long( op(branch_op) | u_field(const22a, 21, 0) ); }
duke@435 1278 // v8 unimp == illtrap(0)
duke@435 1279
duke@435 1280 // pp 169
duke@435 1281
duke@435 1282 void impdep1( int id1, int const19a ) { v9_only(); emit_long( op(arith_op) | fcn(id1) | op3(impdep1_op3) | u_field(const19a, 18, 0)); }
duke@435 1283 void impdep2( int id1, int const19a ) { v9_only(); emit_long( op(arith_op) | fcn(id1) | op3(impdep2_op3) | u_field(const19a, 18, 0)); }
duke@435 1284
duke@435 1285 // pp 149 (v8)
duke@435 1286
duke@435 1287 void cpop1( int opc, int cr1, int cr2, int crd ) { v8_only(); emit_long( op(arith_op) | fcn(crd) | op3(impdep1_op3) | u_field(cr1, 18, 14) | opf(opc) | u_field(cr2, 4, 0)); }
duke@435 1288 void cpop2( int opc, int cr1, int cr2, int crd ) { v8_only(); emit_long( op(arith_op) | fcn(crd) | op3(impdep2_op3) | u_field(cr1, 18, 14) | opf(opc) | u_field(cr2, 4, 0)); }
duke@435 1289
duke@435 1290 // pp 170
duke@435 1291
duke@435 1292 void jmpl( Register s1, Register s2, Register d );
duke@435 1293 void jmpl( Register s1, int simm13a, Register d, RelocationHolder const& rspec = RelocationHolder() );
duke@435 1294
duke@435 1295 // 171
duke@435 1296
twisti@1441 1297 inline void ldf(FloatRegisterImpl::Width w, Register s1, RegisterOrConstant s2, FloatRegister d);
twisti@1162 1298 inline void ldf(FloatRegisterImpl::Width w, Register s1, Register s2, FloatRegister d);
twisti@1162 1299 inline void ldf(FloatRegisterImpl::Width w, Register s1, int simm13a, FloatRegister d, RelocationHolder const& rspec = RelocationHolder());
twisti@1162 1300
twisti@1162 1301 inline void ldf(FloatRegisterImpl::Width w, const Address& a, FloatRegister d, int offset = 0);
duke@435 1302
duke@435 1303
duke@435 1304 inline void ldfsr( Register s1, Register s2 );
duke@435 1305 inline void ldfsr( Register s1, int simm13a);
duke@435 1306 inline void ldxfsr( Register s1, Register s2 );
duke@435 1307 inline void ldxfsr( Register s1, int simm13a);
duke@435 1308
duke@435 1309 // pp 94 (v8)
duke@435 1310
duke@435 1311 inline void ldc( Register s1, Register s2, int crd );
duke@435 1312 inline void ldc( Register s1, int simm13a, int crd);
duke@435 1313 inline void lddc( Register s1, Register s2, int crd );
duke@435 1314 inline void lddc( Register s1, int simm13a, int crd);
duke@435 1315 inline void ldcsr( Register s1, Register s2, int crd );
duke@435 1316 inline void ldcsr( Register s1, int simm13a, int crd);
duke@435 1317
duke@435 1318
duke@435 1319 // 173
duke@435 1320
duke@435 1321 void ldfa( FloatRegisterImpl::Width w, Register s1, Register s2, int ia, FloatRegister d ) { v9_only(); emit_long( op(ldst_op) | fd(d, w) | alt_op3(ldf_op3 | alt_bit_op3, w) | rs1(s1) | imm_asi(ia) | rs2(s2) ); }
duke@435 1322 void ldfa( FloatRegisterImpl::Width w, Register s1, int simm13a, FloatRegister d ) { v9_only(); emit_long( op(ldst_op) | fd(d, w) | alt_op3(ldf_op3 | alt_bit_op3, w) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1323
duke@435 1324 // pp 175, lduw is ld on v8
duke@435 1325
duke@435 1326 inline void ldsb( Register s1, Register s2, Register d );
duke@435 1327 inline void ldsb( Register s1, int simm13a, Register d);
duke@435 1328 inline void ldsh( Register s1, Register s2, Register d );
duke@435 1329 inline void ldsh( Register s1, int simm13a, Register d);
duke@435 1330 inline void ldsw( Register s1, Register s2, Register d );
duke@435 1331 inline void ldsw( Register s1, int simm13a, Register d);
duke@435 1332 inline void ldub( Register s1, Register s2, Register d );
duke@435 1333 inline void ldub( Register s1, int simm13a, Register d);
duke@435 1334 inline void lduh( Register s1, Register s2, Register d );
duke@435 1335 inline void lduh( Register s1, int simm13a, Register d);
duke@435 1336 inline void lduw( Register s1, Register s2, Register d );
duke@435 1337 inline void lduw( Register s1, int simm13a, Register d);
duke@435 1338 inline void ldx( Register s1, Register s2, Register d );
duke@435 1339 inline void ldx( Register s1, int simm13a, Register d);
duke@435 1340 inline void ld( Register s1, Register s2, Register d );
duke@435 1341 inline void ld( Register s1, int simm13a, Register d);
duke@435 1342 inline void ldd( Register s1, Register s2, Register d );
duke@435 1343 inline void ldd( Register s1, int simm13a, Register d);
duke@435 1344
twisti@1162 1345 #ifdef ASSERT
twisti@1162 1346 // ByteSize is only a class when ASSERT is defined, otherwise it's an int.
twisti@1162 1347 inline void ld( Register s1, ByteSize simm13a, Register d);
twisti@1162 1348 #endif
twisti@1162 1349
twisti@1162 1350 inline void ldsb(const Address& a, Register d, int offset = 0);
twisti@1162 1351 inline void ldsh(const Address& a, Register d, int offset = 0);
twisti@1162 1352 inline void ldsw(const Address& a, Register d, int offset = 0);
twisti@1162 1353 inline void ldub(const Address& a, Register d, int offset = 0);
twisti@1162 1354 inline void lduh(const Address& a, Register d, int offset = 0);
twisti@1162 1355 inline void lduw(const Address& a, Register d, int offset = 0);
twisti@1162 1356 inline void ldx( const Address& a, Register d, int offset = 0);
twisti@1162 1357 inline void ld( const Address& a, Register d, int offset = 0);
twisti@1162 1358 inline void ldd( const Address& a, Register d, int offset = 0);
duke@435 1359
jrose@1100 1360 inline void ldub( Register s1, RegisterOrConstant s2, Register d );
jrose@1100 1361 inline void ldsb( Register s1, RegisterOrConstant s2, Register d );
jrose@1100 1362 inline void lduh( Register s1, RegisterOrConstant s2, Register d );
jrose@1100 1363 inline void ldsh( Register s1, RegisterOrConstant s2, Register d );
jrose@1100 1364 inline void lduw( Register s1, RegisterOrConstant s2, Register d );
jrose@1100 1365 inline void ldsw( Register s1, RegisterOrConstant s2, Register d );
jrose@1100 1366 inline void ldx( Register s1, RegisterOrConstant s2, Register d );
jrose@1100 1367 inline void ld( Register s1, RegisterOrConstant s2, Register d );
jrose@1100 1368 inline void ldd( Register s1, RegisterOrConstant s2, Register d );
jrose@1057 1369
duke@435 1370 // pp 177
duke@435 1371
duke@435 1372 void ldsba( Register s1, Register s2, int ia, Register d ) { emit_long( op(ldst_op) | rd(d) | op3(ldsb_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); }
duke@435 1373 void ldsba( Register s1, int simm13a, Register d ) { emit_long( op(ldst_op) | rd(d) | op3(ldsb_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1374 void ldsha( Register s1, Register s2, int ia, Register d ) { emit_long( op(ldst_op) | rd(d) | op3(ldsh_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); }
duke@435 1375 void ldsha( Register s1, int simm13a, Register d ) { emit_long( op(ldst_op) | rd(d) | op3(ldsh_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1376 void ldswa( Register s1, Register s2, int ia, Register d ) { v9_only(); emit_long( op(ldst_op) | rd(d) | op3(ldsw_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); }
duke@435 1377 void ldswa( Register s1, int simm13a, Register d ) { v9_only(); emit_long( op(ldst_op) | rd(d) | op3(ldsw_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1378 void lduba( Register s1, Register s2, int ia, Register d ) { emit_long( op(ldst_op) | rd(d) | op3(ldub_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); }
duke@435 1379 void lduba( Register s1, int simm13a, Register d ) { emit_long( op(ldst_op) | rd(d) | op3(ldub_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1380 void lduha( Register s1, Register s2, int ia, Register d ) { emit_long( op(ldst_op) | rd(d) | op3(lduh_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); }
duke@435 1381 void lduha( Register s1, int simm13a, Register d ) { emit_long( op(ldst_op) | rd(d) | op3(lduh_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1382 void lduwa( Register s1, Register s2, int ia, Register d ) { emit_long( op(ldst_op) | rd(d) | op3(lduw_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); }
duke@435 1383 void lduwa( Register s1, int simm13a, Register d ) { emit_long( op(ldst_op) | rd(d) | op3(lduw_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1384 void ldxa( Register s1, Register s2, int ia, Register d ) { v9_only(); emit_long( op(ldst_op) | rd(d) | op3(ldx_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); }
duke@435 1385 void ldxa( Register s1, int simm13a, Register d ) { v9_only(); emit_long( op(ldst_op) | rd(d) | op3(ldx_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1386 void ldda( Register s1, Register s2, int ia, Register d ) { v9_dep(); emit_long( op(ldst_op) | rd(d) | op3(ldd_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); }
duke@435 1387 void ldda( Register s1, int simm13a, Register d ) { v9_dep(); emit_long( op(ldst_op) | rd(d) | op3(ldd_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1388
duke@435 1389 // pp 179
duke@435 1390
duke@435 1391 inline void ldstub( Register s1, Register s2, Register d );
duke@435 1392 inline void ldstub( Register s1, int simm13a, Register d);
duke@435 1393
duke@435 1394 // pp 180
duke@435 1395
duke@435 1396 void ldstuba( Register s1, Register s2, int ia, Register d ) { emit_long( op(ldst_op) | rd(d) | op3(ldstub_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); }
duke@435 1397 void ldstuba( Register s1, int simm13a, Register d ) { emit_long( op(ldst_op) | rd(d) | op3(ldstub_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1398
duke@435 1399 // pp 181
duke@435 1400
twisti@1858 1401 void and3( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(and_op3 ) | rs1(s1) | rs2(s2) ); }
twisti@1858 1402 void and3( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(and_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1403 void andcc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(and_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); }
duke@435 1404 void andcc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(and_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1405 void andn( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(andn_op3 ) | rs1(s1) | rs2(s2) ); }
duke@435 1406 void andn( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(andn_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
twisti@1858 1407 void andn( Register s1, RegisterOrConstant s2, Register d);
duke@435 1408 void andncc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(andn_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); }
duke@435 1409 void andncc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(andn_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
twisti@1858 1410 void or3( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(or_op3 ) | rs1(s1) | rs2(s2) ); }
twisti@1858 1411 void or3( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(or_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1412 void orcc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(or_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); }
duke@435 1413 void orcc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(or_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1414 void orn( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(orn_op3) | rs1(s1) | rs2(s2) ); }
duke@435 1415 void orn( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(orn_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1416 void orncc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(orn_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); }
duke@435 1417 void orncc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(orn_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
twisti@1858 1418 void xor3( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(xor_op3 ) | rs1(s1) | rs2(s2) ); }
twisti@1858 1419 void xor3( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(xor_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1420 void xorcc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(xor_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); }
duke@435 1421 void xorcc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(xor_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1422 void xnor( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(xnor_op3 ) | rs1(s1) | rs2(s2) ); }
duke@435 1423 void xnor( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(xnor_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1424 void xnorcc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(xnor_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); }
duke@435 1425 void xnorcc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(xnor_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1426
duke@435 1427 // pp 183
duke@435 1428
duke@435 1429 void membar( Membar_mask_bits const7a ) { v9_only(); emit_long( op(arith_op) | op3(membar_op3) | rs1(O7) | immed(true) | u_field( int(const7a), 6, 0)); }
duke@435 1430
duke@435 1431 // pp 185
duke@435 1432
duke@435 1433 void fmov( FloatRegisterImpl::Width w, Condition c, bool floatCC, CC cca, FloatRegister s2, FloatRegister d ) { v9_only(); emit_long( op(arith_op) | fd(d, w) | op3(fpop2_op3) | cond_mov(c) | opf_cc(cca, floatCC) | opf_low6(w) | fs2(s2, w)); }
duke@435 1434
duke@435 1435 // pp 189
duke@435 1436
duke@435 1437 void fmov( FloatRegisterImpl::Width w, RCondition c, Register s1, FloatRegister s2, FloatRegister d ) { v9_only(); emit_long( op(arith_op) | fd(d, w) | op3(fpop2_op3) | rs1(s1) | rcond(c) | opf_low5(4 + w) | fs2(s2, w)); }
duke@435 1438
duke@435 1439 // pp 191
duke@435 1440
duke@435 1441 void movcc( Condition c, bool floatCC, CC cca, Register s2, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(movcc_op3) | mov_cc(cca, floatCC) | cond_mov(c) | rs2(s2) ); }
duke@435 1442 void movcc( Condition c, bool floatCC, CC cca, int simm11a, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(movcc_op3) | mov_cc(cca, floatCC) | cond_mov(c) | immed(true) | simm(simm11a, 11) ); }
duke@435 1443
duke@435 1444 // pp 195
duke@435 1445
duke@435 1446 void movr( RCondition c, Register s1, Register s2, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(movr_op3) | rs1(s1) | rcond(c) | rs2(s2) ); }
duke@435 1447 void movr( RCondition c, Register s1, int simm10a, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(movr_op3) | rs1(s1) | rcond(c) | immed(true) | simm(simm10a, 10) ); }
duke@435 1448
duke@435 1449 // pp 196
duke@435 1450
duke@435 1451 void mulx( Register s1, Register s2, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(mulx_op3 ) | rs1(s1) | rs2(s2) ); }
duke@435 1452 void mulx( Register s1, int simm13a, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(mulx_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1453 void sdivx( Register s1, Register s2, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(sdivx_op3) | rs1(s1) | rs2(s2) ); }
duke@435 1454 void sdivx( Register s1, int simm13a, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(sdivx_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1455 void udivx( Register s1, Register s2, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(udivx_op3) | rs1(s1) | rs2(s2) ); }
duke@435 1456 void udivx( Register s1, int simm13a, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(udivx_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1457
duke@435 1458 // pp 197
duke@435 1459
duke@435 1460 void umul( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(umul_op3 ) | rs1(s1) | rs2(s2) ); }
duke@435 1461 void umul( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(umul_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1462 void smul( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(smul_op3 ) | rs1(s1) | rs2(s2) ); }
duke@435 1463 void smul( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(smul_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1464 void umulcc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(umul_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); }
duke@435 1465 void umulcc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(umul_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1466 void smulcc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(smul_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); }
duke@435 1467 void smulcc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(smul_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1468
duke@435 1469 // pp 199
duke@435 1470
duke@435 1471 void mulscc( Register s1, Register s2, Register d ) { v9_dep(); emit_long( op(arith_op) | rd(d) | op3(mulscc_op3) | rs1(s1) | rs2(s2) ); }
duke@435 1472 void mulscc( Register s1, int simm13a, Register d ) { v9_dep(); emit_long( op(arith_op) | rd(d) | op3(mulscc_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1473
duke@435 1474 // pp 201
duke@435 1475
duke@435 1476 void nop() { emit_long( op(branch_op) | op2(sethi_op2) ); }
duke@435 1477
duke@435 1478
duke@435 1479 // pp 202
duke@435 1480
duke@435 1481 void popc( Register s, Register d) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(popc_op3) | rs2(s)); }
duke@435 1482 void popc( int simm13a, Register d) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(popc_op3) | immed(true) | simm(simm13a, 13)); }
duke@435 1483
duke@435 1484 // pp 203
duke@435 1485
duke@435 1486 void prefetch( Register s1, Register s2, PrefetchFcn f);
duke@435 1487 void prefetch( Register s1, int simm13a, PrefetchFcn f);
duke@435 1488 void prefetcha( Register s1, Register s2, int ia, PrefetchFcn f ) { v9_only(); emit_long( op(ldst_op) | fcn(f) | op3(prefetch_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); }
duke@435 1489 void prefetcha( Register s1, int simm13a, PrefetchFcn f ) { v9_only(); emit_long( op(ldst_op) | fcn(f) | op3(prefetch_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1490
duke@435 1491 inline void prefetch(const Address& a, PrefetchFcn F, int offset = 0);
duke@435 1492
duke@435 1493 // pp 208
duke@435 1494
duke@435 1495 // not implementing read privileged register
duke@435 1496
duke@435 1497 inline void rdy( Register d) { v9_dep(); emit_long( op(arith_op) | rd(d) | op3(rdreg_op3) | u_field(0, 18, 14)); }
duke@435 1498 inline void rdccr( Register d) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(rdreg_op3) | u_field(2, 18, 14)); }
duke@435 1499 inline void rdasi( Register d) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(rdreg_op3) | u_field(3, 18, 14)); }
duke@435 1500 inline void rdtick( Register d) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(rdreg_op3) | u_field(4, 18, 14)); } // Spoon!
duke@435 1501 inline void rdpc( Register d) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(rdreg_op3) | u_field(5, 18, 14)); }
duke@435 1502 inline void rdfprs( Register d) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(rdreg_op3) | u_field(6, 18, 14)); }
duke@435 1503
duke@435 1504 // pp 213
duke@435 1505
duke@435 1506 inline void rett( Register s1, Register s2);
duke@435 1507 inline void rett( Register s1, int simm13a, relocInfo::relocType rt = relocInfo::none);
duke@435 1508
duke@435 1509 // pp 214
duke@435 1510
duke@435 1511 void save( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(save_op3) | rs1(s1) | rs2(s2) ); }
ysr@777 1512 void save( Register s1, int simm13a, Register d ) {
ysr@777 1513 // make sure frame is at least large enough for the register save area
ysr@777 1514 assert(-simm13a >= 16 * wordSize, "frame too small");
ysr@777 1515 emit_long( op(arith_op) | rd(d) | op3(save_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) );
ysr@777 1516 }
duke@435 1517
duke@435 1518 void restore( Register s1 = G0, Register s2 = G0, Register d = G0 ) { emit_long( op(arith_op) | rd(d) | op3(restore_op3) | rs1(s1) | rs2(s2) ); }
duke@435 1519 void restore( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(restore_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1520
duke@435 1521 // pp 216
duke@435 1522
duke@435 1523 void saved() { v9_only(); emit_long( op(arith_op) | fcn(0) | op3(saved_op3)); }
duke@435 1524 void restored() { v9_only(); emit_long( op(arith_op) | fcn(1) | op3(saved_op3)); }
duke@435 1525
duke@435 1526 // pp 217
duke@435 1527
duke@435 1528 inline void sethi( int imm22a, Register d, RelocationHolder const& rspec = RelocationHolder() );
duke@435 1529 // pp 218
duke@435 1530
duke@435 1531 void sll( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(sll_op3) | rs1(s1) | sx(0) | rs2(s2) ); }
duke@435 1532 void sll( Register s1, int imm5a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(sll_op3) | rs1(s1) | sx(0) | immed(true) | u_field(imm5a, 4, 0) ); }
duke@435 1533 void srl( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(srl_op3) | rs1(s1) | sx(0) | rs2(s2) ); }
duke@435 1534 void srl( Register s1, int imm5a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(srl_op3) | rs1(s1) | sx(0) | immed(true) | u_field(imm5a, 4, 0) ); }
duke@435 1535 void sra( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(sra_op3) | rs1(s1) | sx(0) | rs2(s2) ); }
duke@435 1536 void sra( Register s1, int imm5a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(sra_op3) | rs1(s1) | sx(0) | immed(true) | u_field(imm5a, 4, 0) ); }
duke@435 1537
duke@435 1538 void sllx( Register s1, Register s2, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(sll_op3) | rs1(s1) | sx(1) | rs2(s2) ); }
duke@435 1539 void sllx( Register s1, int imm6a, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(sll_op3) | rs1(s1) | sx(1) | immed(true) | u_field(imm6a, 5, 0) ); }
duke@435 1540 void srlx( Register s1, Register s2, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(srl_op3) | rs1(s1) | sx(1) | rs2(s2) ); }
duke@435 1541 void srlx( Register s1, int imm6a, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(srl_op3) | rs1(s1) | sx(1) | immed(true) | u_field(imm6a, 5, 0) ); }
duke@435 1542 void srax( Register s1, Register s2, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(sra_op3) | rs1(s1) | sx(1) | rs2(s2) ); }
duke@435 1543 void srax( Register s1, int imm6a, Register d ) { v9_only(); emit_long( op(arith_op) | rd(d) | op3(sra_op3) | rs1(s1) | sx(1) | immed(true) | u_field(imm6a, 5, 0) ); }
duke@435 1544
duke@435 1545 // pp 220
duke@435 1546
duke@435 1547 void sir( int simm13a ) { emit_long( op(arith_op) | fcn(15) | op3(sir_op3) | immed(true) | simm(simm13a, 13)); }
duke@435 1548
duke@435 1549 // pp 221
duke@435 1550
duke@435 1551 void stbar() { emit_long( op(arith_op) | op3(membar_op3) | u_field(15, 18, 14)); }
duke@435 1552
duke@435 1553 // pp 222
duke@435 1554
twisti@1441 1555 inline void stf( FloatRegisterImpl::Width w, FloatRegister d, Register s1, RegisterOrConstant s2);
twisti@1441 1556 inline void stf( FloatRegisterImpl::Width w, FloatRegister d, Register s1, Register s2);
duke@435 1557 inline void stf( FloatRegisterImpl::Width w, FloatRegister d, Register s1, int simm13a);
duke@435 1558 inline void stf( FloatRegisterImpl::Width w, FloatRegister d, const Address& a, int offset = 0);
duke@435 1559
duke@435 1560 inline void stfsr( Register s1, Register s2 );
duke@435 1561 inline void stfsr( Register s1, int simm13a);
duke@435 1562 inline void stxfsr( Register s1, Register s2 );
duke@435 1563 inline void stxfsr( Register s1, int simm13a);
duke@435 1564
duke@435 1565 // pp 224
duke@435 1566
duke@435 1567 void stfa( FloatRegisterImpl::Width w, FloatRegister d, Register s1, Register s2, int ia ) { v9_only(); emit_long( op(ldst_op) | fd(d, w) | alt_op3(stf_op3 | alt_bit_op3, w) | rs1(s1) | imm_asi(ia) | rs2(s2) ); }
duke@435 1568 void stfa( FloatRegisterImpl::Width w, FloatRegister d, Register s1, int simm13a ) { v9_only(); emit_long( op(ldst_op) | fd(d, w) | alt_op3(stf_op3 | alt_bit_op3, w) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1569
duke@435 1570 // p 226
duke@435 1571
duke@435 1572 inline void stb( Register d, Register s1, Register s2 );
duke@435 1573 inline void stb( Register d, Register s1, int simm13a);
duke@435 1574 inline void sth( Register d, Register s1, Register s2 );
duke@435 1575 inline void sth( Register d, Register s1, int simm13a);
duke@435 1576 inline void stw( Register d, Register s1, Register s2 );
duke@435 1577 inline void stw( Register d, Register s1, int simm13a);
duke@435 1578 inline void st( Register d, Register s1, Register s2 );
duke@435 1579 inline void st( Register d, Register s1, int simm13a);
duke@435 1580 inline void stx( Register d, Register s1, Register s2 );
duke@435 1581 inline void stx( Register d, Register s1, int simm13a);
duke@435 1582 inline void std( Register d, Register s1, Register s2 );
duke@435 1583 inline void std( Register d, Register s1, int simm13a);
duke@435 1584
twisti@1162 1585 #ifdef ASSERT
twisti@1162 1586 // ByteSize is only a class when ASSERT is defined, otherwise it's an int.
twisti@1162 1587 inline void st( Register d, Register s1, ByteSize simm13a);
twisti@1162 1588 #endif
twisti@1162 1589
duke@435 1590 inline void stb( Register d, const Address& a, int offset = 0 );
duke@435 1591 inline void sth( Register d, const Address& a, int offset = 0 );
duke@435 1592 inline void stw( Register d, const Address& a, int offset = 0 );
duke@435 1593 inline void stx( Register d, const Address& a, int offset = 0 );
duke@435 1594 inline void st( Register d, const Address& a, int offset = 0 );
duke@435 1595 inline void std( Register d, const Address& a, int offset = 0 );
duke@435 1596
jrose@1100 1597 inline void stb( Register d, Register s1, RegisterOrConstant s2 );
jrose@1100 1598 inline void sth( Register d, Register s1, RegisterOrConstant s2 );
jrose@1100 1599 inline void stw( Register d, Register s1, RegisterOrConstant s2 );
jrose@1100 1600 inline void stx( Register d, Register s1, RegisterOrConstant s2 );
jrose@1100 1601 inline void std( Register d, Register s1, RegisterOrConstant s2 );
jrose@1100 1602 inline void st( Register d, Register s1, RegisterOrConstant s2 );
jrose@1057 1603
duke@435 1604 // pp 177
duke@435 1605
duke@435 1606 void stba( Register d, Register s1, Register s2, int ia ) { emit_long( op(ldst_op) | rd(d) | op3(stb_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); }
duke@435 1607 void stba( Register d, Register s1, int simm13a ) { emit_long( op(ldst_op) | rd(d) | op3(stb_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1608 void stha( Register d, Register s1, Register s2, int ia ) { emit_long( op(ldst_op) | rd(d) | op3(sth_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); }
duke@435 1609 void stha( Register d, Register s1, int simm13a ) { emit_long( op(ldst_op) | rd(d) | op3(sth_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1610 void stwa( Register d, Register s1, Register s2, int ia ) { emit_long( op(ldst_op) | rd(d) | op3(stw_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); }
duke@435 1611 void stwa( Register d, Register s1, int simm13a ) { emit_long( op(ldst_op) | rd(d) | op3(stw_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1612 void stxa( Register d, Register s1, Register s2, int ia ) { v9_only(); emit_long( op(ldst_op) | rd(d) | op3(stx_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); }
duke@435 1613 void stxa( Register d, Register s1, int simm13a ) { v9_only(); emit_long( op(ldst_op) | rd(d) | op3(stx_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1614 void stda( Register d, Register s1, Register s2, int ia ) { emit_long( op(ldst_op) | rd(d) | op3(std_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); }
duke@435 1615 void stda( Register d, Register s1, int simm13a ) { emit_long( op(ldst_op) | rd(d) | op3(std_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1616
duke@435 1617 // pp 97 (v8)
duke@435 1618
duke@435 1619 inline void stc( int crd, Register s1, Register s2 );
duke@435 1620 inline void stc( int crd, Register s1, int simm13a);
duke@435 1621 inline void stdc( int crd, Register s1, Register s2 );
duke@435 1622 inline void stdc( int crd, Register s1, int simm13a);
duke@435 1623 inline void stcsr( int crd, Register s1, Register s2 );
duke@435 1624 inline void stcsr( int crd, Register s1, int simm13a);
duke@435 1625 inline void stdcq( int crd, Register s1, Register s2 );
duke@435 1626 inline void stdcq( int crd, Register s1, int simm13a);
duke@435 1627
duke@435 1628 // pp 230
duke@435 1629
duke@435 1630 void sub( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(sub_op3 ) | rs1(s1) | rs2(s2) ); }
duke@435 1631 void sub( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(sub_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
twisti@2350 1632
twisti@2350 1633 // Note: offset is added to s2.
twisti@2350 1634 inline void sub(Register s1, RegisterOrConstant s2, Register d, int offset = 0);
twisti@2350 1635
duke@435 1636 void subcc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(sub_op3 | cc_bit_op3 ) | rs1(s1) | rs2(s2) ); }
duke@435 1637 void subcc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(sub_op3 | cc_bit_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1638 void subc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(subc_op3 ) | rs1(s1) | rs2(s2) ); }
duke@435 1639 void subc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(subc_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1640 void subccc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(subc_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); }
duke@435 1641 void subccc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(subc_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1642
duke@435 1643 // pp 231
duke@435 1644
duke@435 1645 inline void swap( Register s1, Register s2, Register d );
duke@435 1646 inline void swap( Register s1, int simm13a, Register d);
duke@435 1647 inline void swap( Address& a, Register d, int offset = 0 );
duke@435 1648
duke@435 1649 // pp 232
duke@435 1650
duke@435 1651 void swapa( Register s1, Register s2, int ia, Register d ) { v9_dep(); emit_long( op(ldst_op) | rd(d) | op3(swap_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); }
duke@435 1652 void swapa( Register s1, int simm13a, Register d ) { v9_dep(); emit_long( op(ldst_op) | rd(d) | op3(swap_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1653
duke@435 1654 // pp 234, note op in book is wrong, see pp 268
duke@435 1655
duke@435 1656 void taddcc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(taddcc_op3 ) | rs1(s1) | rs2(s2) ); }
duke@435 1657 void taddcc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(taddcc_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1658 void taddcctv( Register s1, Register s2, Register d ) { v9_dep(); emit_long( op(arith_op) | rd(d) | op3(taddcctv_op3) | rs1(s1) | rs2(s2) ); }
duke@435 1659 void taddcctv( Register s1, int simm13a, Register d ) { v9_dep(); emit_long( op(arith_op) | rd(d) | op3(taddcctv_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1660
duke@435 1661 // pp 235
duke@435 1662
duke@435 1663 void tsubcc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(tsubcc_op3 ) | rs1(s1) | rs2(s2) ); }
duke@435 1664 void tsubcc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(tsubcc_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1665 void tsubcctv( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(tsubcctv_op3) | rs1(s1) | rs2(s2) ); }
duke@435 1666 void tsubcctv( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(tsubcctv_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
duke@435 1667
duke@435 1668 // pp 237
duke@435 1669
duke@435 1670 void trap( Condition c, CC cc, Register s1, Register s2 ) { v8_no_cc(cc); emit_long( op(arith_op) | cond(c) | op3(trap_op3) | rs1(s1) | trapcc(cc) | rs2(s2)); }
duke@435 1671 void trap( Condition c, CC cc, Register s1, int trapa ) { v8_no_cc(cc); emit_long( op(arith_op) | cond(c) | op3(trap_op3) | rs1(s1) | trapcc(cc) | immed(true) | u_field(trapa, 6, 0)); }
duke@435 1672 // simple uncond. trap
duke@435 1673 void trap( int trapa ) { trap( always, icc, G0, trapa ); }
duke@435 1674
duke@435 1675 // pp 239 omit write priv register for now
duke@435 1676
duke@435 1677 inline void wry( Register d) { v9_dep(); emit_long( op(arith_op) | rs1(d) | op3(wrreg_op3) | u_field(0, 29, 25)); }
duke@435 1678 inline void wrccr(Register s) { v9_only(); emit_long( op(arith_op) | rs1(s) | op3(wrreg_op3) | u_field(2, 29, 25)); }
duke@435 1679 inline void wrccr(Register s, int simm13a) { v9_only(); emit_long( op(arith_op) |
duke@435 1680 rs1(s) |
duke@435 1681 op3(wrreg_op3) |
duke@435 1682 u_field(2, 29, 25) |
duke@435 1683 u_field(1, 13, 13) |
duke@435 1684 simm(simm13a, 13)); }
duke@435 1685 inline void wrasi( Register d) { v9_only(); emit_long( op(arith_op) | rs1(d) | op3(wrreg_op3) | u_field(3, 29, 25)); }
duke@435 1686 inline void wrfprs( Register d) { v9_only(); emit_long( op(arith_op) | rs1(d) | op3(wrreg_op3) | u_field(6, 29, 25)); }
duke@435 1687
ysr@777 1688 // For a given register condition, return the appropriate condition code
ysr@777 1689 // Condition (the one you would use to get the same effect after "tst" on
ysr@777 1690 // the target register.)
ysr@777 1691 Assembler::Condition reg_cond_to_cc_cond(RCondition in);
ysr@777 1692
duke@435 1693
duke@435 1694 // Creation
duke@435 1695 Assembler(CodeBuffer* code) : AbstractAssembler(code) {
duke@435 1696 #ifdef CHECK_DELAY
duke@435 1697 delay_state = no_delay;
duke@435 1698 #endif
duke@435 1699 }
duke@435 1700
duke@435 1701 // Testing
duke@435 1702 #ifndef PRODUCT
duke@435 1703 void test_v9();
duke@435 1704 void test_v8_onlys();
duke@435 1705 #endif
duke@435 1706 };
duke@435 1707
duke@435 1708
duke@435 1709 class RegistersForDebugging : public StackObj {
duke@435 1710 public:
duke@435 1711 intptr_t i[8], l[8], o[8], g[8];
duke@435 1712 float f[32];
duke@435 1713 double d[32];
duke@435 1714
duke@435 1715 void print(outputStream* s);
duke@435 1716
duke@435 1717 static int i_offset(int j) { return offset_of(RegistersForDebugging, i[j]); }
duke@435 1718 static int l_offset(int j) { return offset_of(RegistersForDebugging, l[j]); }
duke@435 1719 static int o_offset(int j) { return offset_of(RegistersForDebugging, o[j]); }
duke@435 1720 static int g_offset(int j) { return offset_of(RegistersForDebugging, g[j]); }
duke@435 1721 static int f_offset(int j) { return offset_of(RegistersForDebugging, f[j]); }
duke@435 1722 static int d_offset(int j) { return offset_of(RegistersForDebugging, d[j / 2]); }
duke@435 1723
duke@435 1724 // gen asm code to save regs
duke@435 1725 static void save_registers(MacroAssembler* a);
duke@435 1726
duke@435 1727 // restore global registers in case C code disturbed them
duke@435 1728 static void restore_registers(MacroAssembler* a, Register r);
ysr@777 1729
ysr@777 1730
duke@435 1731 };
duke@435 1732
duke@435 1733
duke@435 1734 // MacroAssembler extends Assembler by a few frequently used macros.
duke@435 1735 //
duke@435 1736 // Most of the standard SPARC synthetic ops are defined here.
duke@435 1737 // Instructions for which a 'better' code sequence exists depending
duke@435 1738 // on arguments should also go in here.
duke@435 1739
duke@435 1740 #define JMP2(r1, r2) jmp(r1, r2, __FILE__, __LINE__)
duke@435 1741 #define JMP(r1, off) jmp(r1, off, __FILE__, __LINE__)
twisti@1162 1742 #define JUMP(a, temp, off) jump(a, temp, off, __FILE__, __LINE__)
twisti@1162 1743 #define JUMPL(a, temp, d, off) jumpl(a, temp, d, off, __FILE__, __LINE__)
duke@435 1744
duke@435 1745
duke@435 1746 class MacroAssembler: public Assembler {
duke@435 1747 protected:
duke@435 1748 // Support for VM calls
duke@435 1749 // This is the base routine called by the different versions of call_VM_leaf. The interpreter
duke@435 1750 // may customize this version by overriding it for its purposes (e.g., to save/restore
duke@435 1751 // additional registers when doing a VM call).
duke@435 1752 #ifdef CC_INTERP
duke@435 1753 #define VIRTUAL
duke@435 1754 #else
duke@435 1755 #define VIRTUAL virtual
duke@435 1756 #endif
duke@435 1757
duke@435 1758 VIRTUAL void call_VM_leaf_base(Register thread_cache, address entry_point, int number_of_arguments);
duke@435 1759
duke@435 1760 //
duke@435 1761 // It is imperative that all calls into the VM are handled via the call_VM macros.
duke@435 1762 // They make sure that the stack linkage is setup correctly. call_VM's correspond
duke@435 1763 // to ENTRY/ENTRY_X entry points while call_VM_leaf's correspond to LEAF entry points.
duke@435 1764 //
duke@435 1765 // This is the base routine called by the different versions of call_VM. The interpreter
duke@435 1766 // may customize this version by overriding it for its purposes (e.g., to save/restore
duke@435 1767 // additional registers when doing a VM call).
duke@435 1768 //
duke@435 1769 // A non-volatile java_thread_cache register should be specified so
duke@435 1770 // that the G2_thread value can be preserved across the call.
duke@435 1771 // (If java_thread_cache is noreg, then a slow get_thread call
duke@435 1772 // will re-initialize the G2_thread.) call_VM_base returns the register that contains the
duke@435 1773 // thread.
duke@435 1774 //
duke@435 1775 // If no last_java_sp is specified (noreg) than SP will be used instead.
duke@435 1776
duke@435 1777 virtual void call_VM_base(
duke@435 1778 Register oop_result, // where an oop-result ends up if any; use noreg otherwise
duke@435 1779 Register java_thread_cache, // the thread if computed before ; use noreg otherwise
duke@435 1780 Register last_java_sp, // to set up last_Java_frame in stubs; use noreg otherwise
duke@435 1781 address entry_point, // the entry point
duke@435 1782 int number_of_arguments, // the number of arguments (w/o thread) to pop after call
duke@435 1783 bool check_exception=true // flag which indicates if exception should be checked
duke@435 1784 );
duke@435 1785
duke@435 1786 // This routine should emit JVMTI PopFrame and ForceEarlyReturn handling code.
duke@435 1787 // The implementation is only non-empty for the InterpreterMacroAssembler,
duke@435 1788 // as only the interpreter handles and ForceEarlyReturn PopFrame requests.
duke@435 1789 virtual void check_and_handle_popframe(Register scratch_reg);
duke@435 1790 virtual void check_and_handle_earlyret(Register scratch_reg);
duke@435 1791
duke@435 1792 public:
duke@435 1793 MacroAssembler(CodeBuffer* code) : Assembler(code) {}
duke@435 1794
duke@435 1795 // Support for NULL-checks
duke@435 1796 //
duke@435 1797 // Generates code that causes a NULL OS exception if the content of reg is NULL.
duke@435 1798 // If the accessed location is M[reg + offset] and the offset is known, provide the
duke@435 1799 // offset. No explicit code generation is needed if the offset is within a certain
duke@435 1800 // range (0 <= offset <= page_size).
duke@435 1801 //
duke@435 1802 // %%%%%% Currently not done for SPARC
duke@435 1803
duke@435 1804 void null_check(Register reg, int offset = -1);
duke@435 1805 static bool needs_explicit_null_check(intptr_t offset);
duke@435 1806
duke@435 1807 // support for delayed instructions
duke@435 1808 MacroAssembler* delayed() { Assembler::delayed(); return this; }
duke@435 1809
duke@435 1810 // branches that use right instruction for v8 vs. v9
duke@435 1811 inline void br( Condition c, bool a, Predict p, address d, relocInfo::relocType rt = relocInfo::none );
duke@435 1812 inline void br( Condition c, bool a, Predict p, Label& L );
iveresov@2344 1813
duke@435 1814 inline void fb( Condition c, bool a, Predict p, address d, relocInfo::relocType rt = relocInfo::none );
duke@435 1815 inline void fb( Condition c, bool a, Predict p, Label& L );
duke@435 1816
duke@435 1817 // compares register with zero and branches (V9 and V8 instructions)
duke@435 1818 void br_zero( Condition c, bool a, Predict p, Register s1, Label& L);
duke@435 1819 // Compares a pointer register with zero and branches on (not)null.
duke@435 1820 // Does a test & branch on 32-bit systems and a register-branch on 64-bit.
duke@435 1821 void br_null ( Register s1, bool a, Predict p, Label& L );
duke@435 1822 void br_notnull( Register s1, bool a, Predict p, Label& L );
duke@435 1823
ysr@777 1824 // These versions will do the most efficient thing on v8 and v9. Perhaps
ysr@777 1825 // this is what the routine above was meant to do, but it didn't (and
ysr@777 1826 // didn't cover both target address kinds.)
ysr@777 1827 void br_on_reg_cond( RCondition c, bool a, Predict p, Register s1, address d, relocInfo::relocType rt = relocInfo::none );
ysr@777 1828 void br_on_reg_cond( RCondition c, bool a, Predict p, Register s1, Label& L);
ysr@777 1829
duke@435 1830 inline void bp( Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt = relocInfo::none );
duke@435 1831 inline void bp( Condition c, bool a, CC cc, Predict p, Label& L );
duke@435 1832
duke@435 1833 // Branch that tests xcc in LP64 and icc in !LP64
duke@435 1834 inline void brx( Condition c, bool a, Predict p, address d, relocInfo::relocType rt = relocInfo::none );
duke@435 1835 inline void brx( Condition c, bool a, Predict p, Label& L );
duke@435 1836
duke@435 1837 // unconditional short branch
duke@435 1838 inline void ba( bool a, Label& L );
duke@435 1839
duke@435 1840 // Branch that tests fp condition codes
duke@435 1841 inline void fbp( Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt = relocInfo::none );
duke@435 1842 inline void fbp( Condition c, bool a, CC cc, Predict p, Label& L );
duke@435 1843
duke@435 1844 // get PC the best way
duke@435 1845 inline int get_pc( Register d );
duke@435 1846
duke@435 1847 // Sparc shorthands(pp 85, V8 manual, pp 289 V9 manual)
duke@435 1848 inline void cmp( Register s1, Register s2 ) { subcc( s1, s2, G0 ); }
duke@435 1849 inline void cmp( Register s1, int simm13a ) { subcc( s1, simm13a, G0 ); }
duke@435 1850
duke@435 1851 inline void jmp( Register s1, Register s2 );
duke@435 1852 inline void jmp( Register s1, int simm13a, RelocationHolder const& rspec = RelocationHolder() );
duke@435 1853
iveresov@2441 1854 // Check if the call target is out of wdisp30 range (relative to the code cache)
iveresov@2441 1855 static inline bool is_far_target(address d);
duke@435 1856 inline void call( address d, relocInfo::relocType rt = relocInfo::runtime_call_type );
duke@435 1857 inline void call( Label& L, relocInfo::relocType rt = relocInfo::runtime_call_type );
duke@435 1858 inline void callr( Register s1, Register s2 );
duke@435 1859 inline void callr( Register s1, int simm13a, RelocationHolder const& rspec = RelocationHolder() );
duke@435 1860
duke@435 1861 // Emits nothing on V8
duke@435 1862 inline void iprefetch( address d, relocInfo::relocType rt = relocInfo::none );
duke@435 1863 inline void iprefetch( Label& L);
duke@435 1864
duke@435 1865 inline void tst( Register s ) { orcc( G0, s, G0 ); }
duke@435 1866
duke@435 1867 #ifdef PRODUCT
duke@435 1868 inline void ret( bool trace = TraceJumps ) { if (trace) {
duke@435 1869 mov(I7, O7); // traceable register
duke@435 1870 JMP(O7, 2 * BytesPerInstWord);
duke@435 1871 } else {
duke@435 1872 jmpl( I7, 2 * BytesPerInstWord, G0 );
duke@435 1873 }
duke@435 1874 }
duke@435 1875
duke@435 1876 inline void retl( bool trace = TraceJumps ) { if (trace) JMP(O7, 2 * BytesPerInstWord);
duke@435 1877 else jmpl( O7, 2 * BytesPerInstWord, G0 ); }
duke@435 1878 #else
duke@435 1879 void ret( bool trace = TraceJumps );
duke@435 1880 void retl( bool trace = TraceJumps );
duke@435 1881 #endif /* PRODUCT */
duke@435 1882
duke@435 1883 // Required platform-specific helpers for Label::patch_instructions.
duke@435 1884 // They _shadow_ the declarations in AbstractAssembler, which are undefined.
duke@435 1885 void pd_patch_instruction(address branch, address target);
duke@435 1886 #ifndef PRODUCT
duke@435 1887 static void pd_print_patched_instruction(address branch);
duke@435 1888 #endif
duke@435 1889
duke@435 1890 // sethi Macro handles optimizations and relocations
twisti@1162 1891 private:
twisti@1162 1892 void internal_sethi(const AddressLiteral& addrlit, Register d, bool ForceRelocatable);
twisti@1162 1893 public:
twisti@1162 1894 void sethi(const AddressLiteral& addrlit, Register d);
twisti@1162 1895 void patchable_sethi(const AddressLiteral& addrlit, Register d);
duke@435 1896
twisti@2399 1897 // compute the number of instructions for a sethi/set
twisti@2399 1898 static int insts_for_sethi( address a, bool worst_case = false );
twisti@2399 1899 static int worst_case_insts_for_set();
duke@435 1900
duke@435 1901 // set may be either setsw or setuw (high 32 bits may be zero or sign)
twisti@1162 1902 private:
twisti@1162 1903 void internal_set(const AddressLiteral& al, Register d, bool ForceRelocatable);
twisti@2399 1904 static int insts_for_internal_set(intptr_t value);
twisti@1162 1905 public:
twisti@1162 1906 void set(const AddressLiteral& addrlit, Register d);
twisti@1162 1907 void set(intptr_t value, Register d);
twisti@1162 1908 void set(address addr, Register d, RelocationHolder const& rspec);
twisti@2399 1909 static int insts_for_set(intptr_t value) { return insts_for_internal_set(value); }
twisti@2399 1910
twisti@1162 1911 void patchable_set(const AddressLiteral& addrlit, Register d);
twisti@1162 1912 void patchable_set(intptr_t value, Register d);
twisti@1162 1913 void set64(jlong value, Register d, Register tmp);
twisti@2399 1914 static int insts_for_set64(jlong value);
twisti@2350 1915
duke@435 1916 // sign-extend 32 to 64
duke@435 1917 inline void signx( Register s, Register d ) { sra( s, G0, d); }
duke@435 1918 inline void signx( Register d ) { sra( d, G0, d); }
duke@435 1919
duke@435 1920 inline void not1( Register s, Register d ) { xnor( s, G0, d ); }
duke@435 1921 inline void not1( Register d ) { xnor( d, G0, d ); }
duke@435 1922
duke@435 1923 inline void neg( Register s, Register d ) { sub( G0, s, d ); }
duke@435 1924 inline void neg( Register d ) { sub( G0, d, d ); }
duke@435 1925
duke@435 1926 inline void cas( Register s1, Register s2, Register d) { casa( s1, s2, d, ASI_PRIMARY); }
duke@435 1927 inline void casx( Register s1, Register s2, Register d) { casxa(s1, s2, d, ASI_PRIMARY); }
duke@435 1928 // Functions for isolating 64 bit atomic swaps for LP64
duke@435 1929 // cas_ptr will perform cas for 32 bit VM's and casx for 64 bit VM's
duke@435 1930 inline void cas_ptr( Register s1, Register s2, Register d) {
duke@435 1931 #ifdef _LP64
duke@435 1932 casx( s1, s2, d );
duke@435 1933 #else
duke@435 1934 cas( s1, s2, d );
duke@435 1935 #endif
duke@435 1936 }
duke@435 1937
duke@435 1938 // Functions for isolating 64 bit shifts for LP64
duke@435 1939 inline void sll_ptr( Register s1, Register s2, Register d );
duke@435 1940 inline void sll_ptr( Register s1, int imm6a, Register d );
jrose@1100 1941 inline void sll_ptr( Register s1, RegisterOrConstant s2, Register d );
duke@435 1942 inline void srl_ptr( Register s1, Register s2, Register d );
duke@435 1943 inline void srl_ptr( Register s1, int imm6a, Register d );
duke@435 1944
duke@435 1945 // little-endian
duke@435 1946 inline void casl( Register s1, Register s2, Register d) { casa( s1, s2, d, ASI_PRIMARY_LITTLE); }
duke@435 1947 inline void casxl( Register s1, Register s2, Register d) { casxa(s1, s2, d, ASI_PRIMARY_LITTLE); }
duke@435 1948
duke@435 1949 inline void inc( Register d, int const13 = 1 ) { add( d, const13, d); }
duke@435 1950 inline void inccc( Register d, int const13 = 1 ) { addcc( d, const13, d); }
duke@435 1951
duke@435 1952 inline void dec( Register d, int const13 = 1 ) { sub( d, const13, d); }
duke@435 1953 inline void deccc( Register d, int const13 = 1 ) { subcc( d, const13, d); }
duke@435 1954
duke@435 1955 inline void btst( Register s1, Register s2 ) { andcc( s1, s2, G0 ); }
duke@435 1956 inline void btst( int simm13a, Register s ) { andcc( s, simm13a, G0 ); }
duke@435 1957
duke@435 1958 inline void bset( Register s1, Register s2 ) { or3( s1, s2, s2 ); }
duke@435 1959 inline void bset( int simm13a, Register s ) { or3( s, simm13a, s ); }
duke@435 1960
duke@435 1961 inline void bclr( Register s1, Register s2 ) { andn( s1, s2, s2 ); }
duke@435 1962 inline void bclr( int simm13a, Register s ) { andn( s, simm13a, s ); }
duke@435 1963
duke@435 1964 inline void btog( Register s1, Register s2 ) { xor3( s1, s2, s2 ); }
duke@435 1965 inline void btog( int simm13a, Register s ) { xor3( s, simm13a, s ); }
duke@435 1966
duke@435 1967 inline void clr( Register d ) { or3( G0, G0, d ); }
duke@435 1968
duke@435 1969 inline void clrb( Register s1, Register s2);
duke@435 1970 inline void clrh( Register s1, Register s2);
duke@435 1971 inline void clr( Register s1, Register s2);
duke@435 1972 inline void clrx( Register s1, Register s2);
duke@435 1973
duke@435 1974 inline void clrb( Register s1, int simm13a);
duke@435 1975 inline void clrh( Register s1, int simm13a);
duke@435 1976 inline void clr( Register s1, int simm13a);
duke@435 1977 inline void clrx( Register s1, int simm13a);
duke@435 1978
duke@435 1979 // copy & clear upper word
duke@435 1980 inline void clruw( Register s, Register d ) { srl( s, G0, d); }
duke@435 1981 // clear upper word
duke@435 1982 inline void clruwu( Register d ) { srl( d, G0, d); }
duke@435 1983
duke@435 1984 // membar psuedo instruction. takes into account target memory model.
duke@435 1985 inline void membar( Assembler::Membar_mask_bits const7a );
duke@435 1986
duke@435 1987 // returns if membar generates anything.
duke@435 1988 inline bool membar_has_effect( Assembler::Membar_mask_bits const7a );
duke@435 1989
duke@435 1990 // mov pseudo instructions
duke@435 1991 inline void mov( Register s, Register d) {
duke@435 1992 if ( s != d ) or3( G0, s, d);
duke@435 1993 else assert_not_delayed(); // Put something useful in the delay slot!
duke@435 1994 }
duke@435 1995
duke@435 1996 inline void mov_or_nop( Register s, Register d) {
duke@435 1997 if ( s != d ) or3( G0, s, d);
duke@435 1998 else nop();
duke@435 1999 }
duke@435 2000
duke@435 2001 inline void mov( int simm13a, Register d) { or3( G0, simm13a, d); }
duke@435 2002
duke@435 2003 // address pseudos: make these names unlike instruction names to avoid confusion
duke@435 2004 inline intptr_t load_pc_address( Register reg, int bytes_to_skip );
coleenp@2035 2005 inline void load_contents(const AddressLiteral& addrlit, Register d, int offset = 0);
coleenp@2035 2006 inline void load_ptr_contents(const AddressLiteral& addrlit, Register d, int offset = 0);
coleenp@2035 2007 inline void store_contents(Register s, const AddressLiteral& addrlit, Register temp, int offset = 0);
coleenp@2035 2008 inline void store_ptr_contents(Register s, const AddressLiteral& addrlit, Register temp, int offset = 0);
coleenp@2035 2009 inline void jumpl_to(const AddressLiteral& addrlit, Register temp, Register d, int offset = 0);
coleenp@2035 2010 inline void jump_to(const AddressLiteral& addrlit, Register temp, int offset = 0);
twisti@1162 2011 inline void jump_indirect_to(Address& a, Register temp, int ld_offset = 0, int jmp_offset = 0);
duke@435 2012
duke@435 2013 // ring buffer traceable jumps
duke@435 2014
duke@435 2015 void jmp2( Register r1, Register r2, const char* file, int line );
duke@435 2016 void jmp ( Register r1, int offset, const char* file, int line );
duke@435 2017
coleenp@2035 2018 void jumpl(const AddressLiteral& addrlit, Register temp, Register d, int offset, const char* file, int line);
coleenp@2035 2019 void jump (const AddressLiteral& addrlit, Register temp, int offset, const char* file, int line);
duke@435 2020
duke@435 2021
duke@435 2022 // argument pseudos:
duke@435 2023
duke@435 2024 inline void load_argument( Argument& a, Register d );
duke@435 2025 inline void store_argument( Register s, Argument& a );
duke@435 2026 inline void store_ptr_argument( Register s, Argument& a );
duke@435 2027 inline void store_float_argument( FloatRegister s, Argument& a );
duke@435 2028 inline void store_double_argument( FloatRegister s, Argument& a );
duke@435 2029 inline void store_long_argument( Register s, Argument& a );
duke@435 2030
duke@435 2031 // handy macros:
duke@435 2032
duke@435 2033 inline void round_to( Register r, int modulus ) {
duke@435 2034 assert_not_delayed();
duke@435 2035 inc( r, modulus - 1 );
duke@435 2036 and3( r, -modulus, r );
duke@435 2037 }
duke@435 2038
duke@435 2039 // --------------------------------------------------
duke@435 2040
duke@435 2041 // Functions for isolating 64 bit loads for LP64
duke@435 2042 // ld_ptr will perform ld for 32 bit VM's and ldx for 64 bit VM's
duke@435 2043 // st_ptr will perform st for 32 bit VM's and stx for 64 bit VM's
twisti@1162 2044 inline void ld_ptr(Register s1, Register s2, Register d);
twisti@1162 2045 inline void ld_ptr(Register s1, int simm13a, Register d);
twisti@1162 2046 inline void ld_ptr(Register s1, RegisterOrConstant s2, Register d);
twisti@1162 2047 inline void ld_ptr(const Address& a, Register d, int offset = 0);
twisti@1162 2048 inline void st_ptr(Register d, Register s1, Register s2);
twisti@1162 2049 inline void st_ptr(Register d, Register s1, int simm13a);
twisti@1162 2050 inline void st_ptr(Register d, Register s1, RegisterOrConstant s2);
twisti@1162 2051 inline void st_ptr(Register d, const Address& a, int offset = 0);
twisti@1162 2052
twisti@1162 2053 #ifdef ASSERT
twisti@1162 2054 // ByteSize is only a class when ASSERT is defined, otherwise it's an int.
twisti@1162 2055 inline void ld_ptr(Register s1, ByteSize simm13a, Register d);
twisti@1162 2056 inline void st_ptr(Register d, Register s1, ByteSize simm13a);
twisti@1162 2057 #endif
duke@435 2058
twisti@1858 2059 // ld_long will perform ldd for 32 bit VM's and ldx for 64 bit VM's
twisti@1858 2060 // st_long will perform std for 32 bit VM's and stx for 64 bit VM's
twisti@1162 2061 inline void ld_long(Register s1, Register s2, Register d);
twisti@1162 2062 inline void ld_long(Register s1, int simm13a, Register d);
twisti@1162 2063 inline void ld_long(Register s1, RegisterOrConstant s2, Register d);
twisti@1162 2064 inline void ld_long(const Address& a, Register d, int offset = 0);
twisti@1162 2065 inline void st_long(Register d, Register s1, Register s2);
twisti@1162 2066 inline void st_long(Register d, Register s1, int simm13a);
twisti@1162 2067 inline void st_long(Register d, Register s1, RegisterOrConstant s2);
twisti@1162 2068 inline void st_long(Register d, const Address& a, int offset = 0);
jrose@1057 2069
jrose@1058 2070 // Helpers for address formation.
twisti@1858 2071 // - They emit only a move if s2 is a constant zero.
twisti@1858 2072 // - If dest is a constant and either s1 or s2 is a register, the temp argument is required and becomes the result.
twisti@1858 2073 // - If dest is a register and either s1 or s2 is a non-simm13 constant, the temp argument is required and used to materialize the constant.
twisti@1858 2074 RegisterOrConstant regcon_andn_ptr(RegisterOrConstant s1, RegisterOrConstant s2, RegisterOrConstant d, Register temp = noreg);
twisti@1858 2075 RegisterOrConstant regcon_inc_ptr( RegisterOrConstant s1, RegisterOrConstant s2, RegisterOrConstant d, Register temp = noreg);
twisti@1858 2076 RegisterOrConstant regcon_sll_ptr( RegisterOrConstant s1, RegisterOrConstant s2, RegisterOrConstant d, Register temp = noreg);
twisti@1858 2077
twisti@1858 2078 RegisterOrConstant ensure_simm13_or_reg(RegisterOrConstant src, Register temp) {
twisti@1858 2079 if (is_simm13(src.constant_or_zero()))
twisti@1858 2080 return src; // register or short constant
twisti@1858 2081 guarantee(temp != noreg, "constant offset overflow");
twisti@1858 2082 set(src.as_constant(), temp);
twisti@1858 2083 return temp;
jrose@1058 2084 }
jrose@1058 2085
duke@435 2086 // --------------------------------------------------
duke@435 2087
duke@435 2088 public:
duke@435 2089 // traps as per trap.h (SPARC ABI?)
duke@435 2090
duke@435 2091 void breakpoint_trap();
duke@435 2092 void breakpoint_trap(Condition c, CC cc = icc);
duke@435 2093 void flush_windows_trap();
duke@435 2094 void clean_windows_trap();
duke@435 2095 void get_psr_trap();
duke@435 2096 void set_psr_trap();
duke@435 2097
duke@435 2098 // V8/V9 flush_windows
duke@435 2099 void flush_windows();
duke@435 2100
duke@435 2101 // Support for serializing memory accesses between threads
duke@435 2102 void serialize_memory(Register thread, Register tmp1, Register tmp2);
duke@435 2103
duke@435 2104 // Stack frame creation/removal
duke@435 2105 void enter();
duke@435 2106 void leave();
duke@435 2107
duke@435 2108 // V8/V9 integer multiply
duke@435 2109 void mult(Register s1, Register s2, Register d);
duke@435 2110 void mult(Register s1, int simm13a, Register d);
duke@435 2111
duke@435 2112 // V8/V9 read and write of condition codes.
duke@435 2113 void read_ccr(Register d);
duke@435 2114 void write_ccr(Register s);
duke@435 2115
duke@435 2116 // Manipulation of C++ bools
duke@435 2117 // These are idioms to flag the need for care with accessing bools but on
duke@435 2118 // this platform we assume byte size
duke@435 2119
twisti@1162 2120 inline void stbool(Register d, const Address& a) { stb(d, a); }
twisti@1162 2121 inline void ldbool(const Address& a, Register d) { ldsb(a, d); }
duke@435 2122 inline void tstbool( Register s ) { tst(s); }
duke@435 2123 inline void movbool( bool boolconst, Register d) { mov( (int) boolconst, d); }
duke@435 2124
coleenp@548 2125 // klass oop manipulations if compressed
kvn@599 2126 void load_klass(Register src_oop, Register klass);
kvn@599 2127 void store_klass(Register klass, Register dst_oop);
coleenp@602 2128 void store_klass_gap(Register s, Register dst_oop);
coleenp@548 2129
coleenp@548 2130 // oop manipulations
twisti@1162 2131 void load_heap_oop(const Address& s, Register d);
coleenp@548 2132 void load_heap_oop(Register s1, Register s2, Register d);
coleenp@548 2133 void load_heap_oop(Register s1, int simm13a, Register d);
twisti@2201 2134 void load_heap_oop(Register s1, RegisterOrConstant s2, Register d);
coleenp@548 2135 void store_heap_oop(Register d, Register s1, Register s2);
coleenp@548 2136 void store_heap_oop(Register d, Register s1, int simm13a);
coleenp@548 2137 void store_heap_oop(Register d, const Address& a, int offset = 0);
coleenp@548 2138
coleenp@548 2139 void encode_heap_oop(Register src, Register dst);
coleenp@548 2140 void encode_heap_oop(Register r) {
coleenp@548 2141 encode_heap_oop(r, r);
coleenp@548 2142 }
coleenp@548 2143 void decode_heap_oop(Register src, Register dst);
coleenp@548 2144 void decode_heap_oop(Register r) {
coleenp@548 2145 decode_heap_oop(r, r);
coleenp@548 2146 }
coleenp@548 2147 void encode_heap_oop_not_null(Register r);
coleenp@548 2148 void decode_heap_oop_not_null(Register r);
kvn@559 2149 void encode_heap_oop_not_null(Register src, Register dst);
kvn@559 2150 void decode_heap_oop_not_null(Register src, Register dst);
coleenp@548 2151
duke@435 2152 // Support for managing the JavaThread pointer (i.e.; the reference to
duke@435 2153 // thread-local information).
duke@435 2154 void get_thread(); // load G2_thread
duke@435 2155 void verify_thread(); // verify G2_thread contents
duke@435 2156 void save_thread (const Register threache); // save to cache
duke@435 2157 void restore_thread(const Register thread_cache); // restore from cache
duke@435 2158
duke@435 2159 // Support for last Java frame (but use call_VM instead where possible)
duke@435 2160 void set_last_Java_frame(Register last_java_sp, Register last_Java_pc);
duke@435 2161 void reset_last_Java_frame(void);
duke@435 2162
duke@435 2163 // Call into the VM.
duke@435 2164 // Passes the thread pointer (in O0) as a prepended argument.
duke@435 2165 // Makes sure oop return values are visible to the GC.
duke@435 2166 void call_VM(Register oop_result, address entry_point, int number_of_arguments = 0, bool check_exceptions = true);
duke@435 2167 void call_VM(Register oop_result, address entry_point, Register arg_1, bool check_exceptions = true);
duke@435 2168 void call_VM(Register oop_result, address entry_point, Register arg_1, Register arg_2, bool check_exceptions = true);
duke@435 2169 void call_VM(Register oop_result, address entry_point, Register arg_1, Register arg_2, Register arg_3, bool check_exceptions = true);
duke@435 2170
duke@435 2171 // these overloadings are not presently used on SPARC:
duke@435 2172 void call_VM(Register oop_result, Register last_java_sp, address entry_point, int number_of_arguments = 0, bool check_exceptions = true);
duke@435 2173 void call_VM(Register oop_result, Register last_java_sp, address entry_point, Register arg_1, bool check_exceptions = true);
duke@435 2174 void call_VM(Register oop_result, Register last_java_sp, address entry_point, Register arg_1, Register arg_2, bool check_exceptions = true);
duke@435 2175 void call_VM(Register oop_result, Register last_java_sp, address entry_point, Register arg_1, Register arg_2, Register arg_3, bool check_exceptions = true);
duke@435 2176
duke@435 2177 void call_VM_leaf(Register thread_cache, address entry_point, int number_of_arguments = 0);
duke@435 2178 void call_VM_leaf(Register thread_cache, address entry_point, Register arg_1);
duke@435 2179 void call_VM_leaf(Register thread_cache, address entry_point, Register arg_1, Register arg_2);
duke@435 2180 void call_VM_leaf(Register thread_cache, address entry_point, Register arg_1, Register arg_2, Register arg_3);
duke@435 2181
duke@435 2182 void get_vm_result (Register oop_result);
duke@435 2183 void get_vm_result_2(Register oop_result);
duke@435 2184
duke@435 2185 // vm result is currently getting hijacked to for oop preservation
duke@435 2186 void set_vm_result(Register oop_result);
duke@435 2187
duke@435 2188 // if call_VM_base was called with check_exceptions=false, then call
duke@435 2189 // check_and_forward_exception to handle exceptions when it is safe
duke@435 2190 void check_and_forward_exception(Register scratch_reg);
duke@435 2191
duke@435 2192 private:
duke@435 2193 // For V8
duke@435 2194 void read_ccr_trap(Register ccr_save);
duke@435 2195 void write_ccr_trap(Register ccr_save1, Register scratch1, Register scratch2);
duke@435 2196
duke@435 2197 #ifdef ASSERT
duke@435 2198 // For V8 debugging. Uses V8 instruction sequence and checks
duke@435 2199 // result with V9 insturctions rdccr and wrccr.
duke@435 2200 // Uses Gscatch and Gscatch2
duke@435 2201 void read_ccr_v8_assert(Register ccr_save);
duke@435 2202 void write_ccr_v8_assert(Register ccr_save);
duke@435 2203 #endif // ASSERT
duke@435 2204
duke@435 2205 public:
ysr@777 2206
ysr@777 2207 // Write to card table for - register is destroyed afterwards.
ysr@777 2208 void card_table_write(jbyte* byte_map_base, Register tmp, Register obj);
ysr@777 2209
ysr@777 2210 void card_write_barrier_post(Register store_addr, Register new_val, Register tmp);
ysr@777 2211
ysr@777 2212 #ifndef SERIALGC
johnc@2781 2213 // General G1 pre-barrier generator.
johnc@2781 2214 void g1_write_barrier_pre(Register obj, Register index, int offset, Register pre_val, Register tmp, bool preserve_o_regs);
johnc@2781 2215
johnc@2781 2216 // General G1 post-barrier generator
ysr@777 2217 void g1_write_barrier_post(Register store_addr, Register new_val, Register tmp);
ysr@777 2218 #endif // SERIALGC
duke@435 2219
duke@435 2220 // pushes double TOS element of FPU stack on CPU stack; pops from FPU stack
duke@435 2221 void push_fTOS();
duke@435 2222
duke@435 2223 // pops double TOS element from CPU stack and pushes on FPU stack
duke@435 2224 void pop_fTOS();
duke@435 2225
duke@435 2226 void empty_FPU_stack();
duke@435 2227
duke@435 2228 void push_IU_state();
duke@435 2229 void pop_IU_state();
duke@435 2230
duke@435 2231 void push_FPU_state();
duke@435 2232 void pop_FPU_state();
duke@435 2233
duke@435 2234 void push_CPU_state();
duke@435 2235 void pop_CPU_state();
duke@435 2236
coleenp@548 2237 // if heap base register is used - reinit it with the correct value
coleenp@548 2238 void reinit_heapbase();
coleenp@548 2239
duke@435 2240 // Debugging
duke@435 2241 void _verify_oop(Register reg, const char * msg, const char * file, int line);
duke@435 2242 void _verify_oop_addr(Address addr, const char * msg, const char * file, int line);
duke@435 2243
duke@435 2244 #define verify_oop(reg) _verify_oop(reg, "broken oop " #reg, __FILE__, __LINE__)
duke@435 2245 #define verify_oop_addr(addr) _verify_oop_addr(addr, "broken oop addr ", __FILE__, __LINE__)
duke@435 2246
duke@435 2247 // only if +VerifyOops
duke@435 2248 void verify_FPU(int stack_depth, const char* s = "illegal FPU state");
duke@435 2249 // only if +VerifyFPU
duke@435 2250 void stop(const char* msg); // prints msg, dumps registers and stops execution
duke@435 2251 void warn(const char* msg); // prints msg, but don't stop
duke@435 2252 void untested(const char* what = "");
twisti@2201 2253 void unimplemented(const char* what = "") { char* b = new char[1024]; jio_snprintf(b, 1024, "unimplemented: %s", what); stop(b); }
duke@435 2254 void should_not_reach_here() { stop("should not reach here"); }
duke@435 2255 void print_CPU_state();
duke@435 2256
duke@435 2257 // oops in code
twisti@1162 2258 AddressLiteral allocate_oop_address(jobject obj); // allocate_index
twisti@1162 2259 AddressLiteral constant_oop_address(jobject obj); // find_index
twisti@1162 2260 inline void set_oop (jobject obj, Register d); // uses allocate_oop_address
twisti@1162 2261 inline void set_oop_constant (jobject obj, Register d); // uses constant_oop_address
jcoomes@1902 2262 inline void set_oop (const AddressLiteral& obj_addr, Register d); // same as load_address
duke@435 2263
kvn@599 2264 void set_narrow_oop( jobject obj, Register d );
kvn@599 2265
duke@435 2266 // nop padding
duke@435 2267 void align(int modulus);
duke@435 2268
duke@435 2269 // declare a safepoint
duke@435 2270 void safepoint();
duke@435 2271
duke@435 2272 // factor out part of stop into subroutine to save space
duke@435 2273 void stop_subroutine();
duke@435 2274 // factor out part of verify_oop into subroutine to save space
duke@435 2275 void verify_oop_subroutine();
duke@435 2276
duke@435 2277 // side-door communication with signalHandler in os_solaris.cpp
duke@435 2278 static address _verify_oop_implicit_branch[3];
duke@435 2279
duke@435 2280 #ifndef PRODUCT
duke@435 2281 static void test();
duke@435 2282 #endif
duke@435 2283
duke@435 2284 // convert an incoming arglist to varargs format; put the pointer in d
duke@435 2285 void set_varargs( Argument a, Register d );
duke@435 2286
duke@435 2287 int total_frame_size_in_bytes(int extraWords);
duke@435 2288
duke@435 2289 // used when extraWords known statically
duke@435 2290 void save_frame(int extraWords);
duke@435 2291 void save_frame_c1(int size_in_bytes);
duke@435 2292 // make a frame, and simultaneously pass up one or two register value
duke@435 2293 // into the new register window
duke@435 2294 void save_frame_and_mov(int extraWords, Register s1, Register d1, Register s2 = Register(), Register d2 = Register());
duke@435 2295
duke@435 2296 // give no. (outgoing) params, calc # of words will need on frame
duke@435 2297 void calc_mem_param_words(Register Rparam_words, Register Rresult);
duke@435 2298
duke@435 2299 // used to calculate frame size dynamically
duke@435 2300 // result is in bytes and must be negated for save inst
duke@435 2301 void calc_frame_size(Register extraWords, Register resultReg);
duke@435 2302
duke@435 2303 // calc and also save
duke@435 2304 void calc_frame_size_and_save(Register extraWords, Register resultReg);
duke@435 2305
duke@435 2306 static void debug(char* msg, RegistersForDebugging* outWindow);
duke@435 2307
duke@435 2308 // implementations of bytecodes used by both interpreter and compiler
duke@435 2309
duke@435 2310 void lcmp( Register Ra_hi, Register Ra_low,
duke@435 2311 Register Rb_hi, Register Rb_low,
duke@435 2312 Register Rresult);
duke@435 2313
duke@435 2314 void lneg( Register Rhi, Register Rlow );
duke@435 2315
duke@435 2316 void lshl( Register Rin_high, Register Rin_low, Register Rcount,
duke@435 2317 Register Rout_high, Register Rout_low, Register Rtemp );
duke@435 2318
duke@435 2319 void lshr( Register Rin_high, Register Rin_low, Register Rcount,
duke@435 2320 Register Rout_high, Register Rout_low, Register Rtemp );
duke@435 2321
duke@435 2322 void lushr( Register Rin_high, Register Rin_low, Register Rcount,
duke@435 2323 Register Rout_high, Register Rout_low, Register Rtemp );
duke@435 2324
duke@435 2325 #ifdef _LP64
duke@435 2326 void lcmp( Register Ra, Register Rb, Register Rresult);
duke@435 2327 #endif
duke@435 2328
twisti@2565 2329 // Load and store values by size and signed-ness
twisti@2565 2330 void load_sized_value( Address src, Register dst, size_t size_in_bytes, bool is_signed);
twisti@2565 2331 void store_sized_value(Register src, Address dst, size_t size_in_bytes);
twisti@1858 2332
duke@435 2333 void float_cmp( bool is_float, int unordered_result,
duke@435 2334 FloatRegister Fa, FloatRegister Fb,
duke@435 2335 Register Rresult);
duke@435 2336
duke@435 2337 void fneg( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d);
duke@435 2338 void fneg( FloatRegisterImpl::Width w, FloatRegister sd ) { Assembler::fneg(w, sd); }
duke@435 2339 void fmov( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d);
duke@435 2340 void fabs( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d);
duke@435 2341
duke@435 2342 void save_all_globals_into_locals();
duke@435 2343 void restore_globals_from_locals();
duke@435 2344
duke@435 2345 void casx_under_lock(Register top_ptr_reg, Register top_reg, Register ptr_reg,
duke@435 2346 address lock_addr=0, bool use_call_vm=false);
duke@435 2347 void cas_under_lock(Register top_ptr_reg, Register top_reg, Register ptr_reg,
duke@435 2348 address lock_addr=0, bool use_call_vm=false);
duke@435 2349 void casn (Register addr_reg, Register cmp_reg, Register set_reg) ;
duke@435 2350
duke@435 2351 // These set the icc condition code to equal if the lock succeeded
duke@435 2352 // and notEqual if it failed and requires a slow case
kvn@855 2353 void compiler_lock_object(Register Roop, Register Rmark, Register Rbox,
kvn@855 2354 Register Rscratch,
kvn@855 2355 BiasedLockingCounters* counters = NULL,
kvn@855 2356 bool try_bias = UseBiasedLocking);
kvn@855 2357 void compiler_unlock_object(Register Roop, Register Rmark, Register Rbox,
kvn@855 2358 Register Rscratch,
kvn@855 2359 bool try_bias = UseBiasedLocking);
duke@435 2360
duke@435 2361 // Biased locking support
duke@435 2362 // Upon entry, lock_reg must point to the lock record on the stack,
duke@435 2363 // obj_reg must contain the target object, and mark_reg must contain
duke@435 2364 // the target object's header.
duke@435 2365 // Destroys mark_reg if an attempt is made to bias an anonymously
duke@435 2366 // biased lock. In this case a failure will go either to the slow
duke@435 2367 // case or fall through with the notEqual condition code set with
duke@435 2368 // the expectation that the slow case in the runtime will be called.
duke@435 2369 // In the fall-through case where the CAS-based lock is done,
duke@435 2370 // mark_reg is not destroyed.
duke@435 2371 void biased_locking_enter(Register obj_reg, Register mark_reg, Register temp_reg,
duke@435 2372 Label& done, Label* slow_case = NULL,
duke@435 2373 BiasedLockingCounters* counters = NULL);
duke@435 2374 // Upon entry, the base register of mark_addr must contain the oop.
duke@435 2375 // Destroys temp_reg.
duke@435 2376
duke@435 2377 // If allow_delay_slot_filling is set to true, the next instruction
duke@435 2378 // emitted after this one will go in an annulled delay slot if the
duke@435 2379 // biased locking exit case failed.
duke@435 2380 void biased_locking_exit(Address mark_addr, Register temp_reg, Label& done, bool allow_delay_slot_filling = false);
duke@435 2381
duke@435 2382 // allocation
duke@435 2383 void eden_allocate(
duke@435 2384 Register obj, // result: pointer to object after successful allocation
duke@435 2385 Register var_size_in_bytes, // object size in bytes if unknown at compile time; invalid otherwise
duke@435 2386 int con_size_in_bytes, // object size in bytes if known at compile time
duke@435 2387 Register t1, // temp register
duke@435 2388 Register t2, // temp register
duke@435 2389 Label& slow_case // continuation point if fast allocation fails
duke@435 2390 );
duke@435 2391 void tlab_allocate(
duke@435 2392 Register obj, // result: pointer to object after successful allocation
duke@435 2393 Register var_size_in_bytes, // object size in bytes if unknown at compile time; invalid otherwise
duke@435 2394 int con_size_in_bytes, // object size in bytes if known at compile time
duke@435 2395 Register t1, // temp register
duke@435 2396 Label& slow_case // continuation point if fast allocation fails
duke@435 2397 );
duke@435 2398 void tlab_refill(Label& retry_tlab, Label& try_eden, Label& slow_case);
phh@2447 2399 void incr_allocated_bytes(RegisterOrConstant size_in_bytes,
phh@2447 2400 Register t1, Register t2);
duke@435 2401
jrose@1058 2402 // interface method calling
jrose@1058 2403 void lookup_interface_method(Register recv_klass,
jrose@1058 2404 Register intf_klass,
jrose@1100 2405 RegisterOrConstant itable_index,
jrose@1058 2406 Register method_result,
jrose@1058 2407 Register temp_reg, Register temp2_reg,
jrose@1058 2408 Label& no_such_interface);
jrose@1058 2409
jrose@1079 2410 // Test sub_klass against super_klass, with fast and slow paths.
jrose@1079 2411
jrose@1079 2412 // The fast path produces a tri-state answer: yes / no / maybe-slow.
jrose@1079 2413 // One of the three labels can be NULL, meaning take the fall-through.
jrose@1079 2414 // If super_check_offset is -1, the value is loaded up from super_klass.
jrose@1079 2415 // No registers are killed, except temp_reg and temp2_reg.
jrose@1079 2416 // If super_check_offset is not -1, temp2_reg is not used and can be noreg.
jrose@1079 2417 void check_klass_subtype_fast_path(Register sub_klass,
jrose@1079 2418 Register super_klass,
jrose@1079 2419 Register temp_reg,
jrose@1079 2420 Register temp2_reg,
jrose@1079 2421 Label* L_success,
jrose@1079 2422 Label* L_failure,
jrose@1079 2423 Label* L_slow_path,
jrose@1100 2424 RegisterOrConstant super_check_offset = RegisterOrConstant(-1),
jrose@1079 2425 Register instanceof_hack = noreg);
jrose@1079 2426
jrose@1079 2427 // The rest of the type check; must be wired to a corresponding fast path.
jrose@1079 2428 // It does not repeat the fast path logic, so don't use it standalone.
jrose@1079 2429 // The temp_reg can be noreg, if no temps are available.
jrose@1079 2430 // It can also be sub_klass or super_klass, meaning it's OK to kill that one.
jrose@1079 2431 // Updates the sub's secondary super cache as necessary.
jrose@1079 2432 void check_klass_subtype_slow_path(Register sub_klass,
jrose@1079 2433 Register super_klass,
jrose@1079 2434 Register temp_reg,
jrose@1079 2435 Register temp2_reg,
jrose@1079 2436 Register temp3_reg,
jrose@1079 2437 Register temp4_reg,
jrose@1079 2438 Label* L_success,
jrose@1079 2439 Label* L_failure);
jrose@1079 2440
jrose@1079 2441 // Simplified, combined version, good for typical uses.
jrose@1079 2442 // Falls through on failure.
jrose@1079 2443 void check_klass_subtype(Register sub_klass,
jrose@1079 2444 Register super_klass,
jrose@1079 2445 Register temp_reg,
jrose@1079 2446 Register temp2_reg,
jrose@1079 2447 Label& L_success);
jrose@1079 2448
jrose@1145 2449 // method handles (JSR 292)
jrose@1145 2450 void check_method_handle_type(Register mtype_reg, Register mh_reg,
jrose@1145 2451 Register temp_reg,
jrose@1145 2452 Label& wrong_method_type);
twisti@1858 2453 void load_method_handle_vmslots(Register vmslots_reg, Register mh_reg,
twisti@1858 2454 Register temp_reg);
twisti@1858 2455 void jump_to_method_handle_entry(Register mh_reg, Register temp_reg, bool emit_delayed_nop = true);
jrose@1145 2456 // offset relative to Gargs of argument at tos[arg_slot].
jrose@1145 2457 // (arg_slot == 0 means the last argument, not the first).
jrose@1145 2458 RegisterOrConstant argument_offset(RegisterOrConstant arg_slot,
jrose@1145 2459 int extra_slot_offset = 0);
twisti@1858 2460 // Address of Gargs and argument_offset.
twisti@1858 2461 Address argument_address(RegisterOrConstant arg_slot,
twisti@1858 2462 int extra_slot_offset = 0);
jrose@1079 2463
duke@435 2464 // Stack overflow checking
duke@435 2465
duke@435 2466 // Note: this clobbers G3_scratch
duke@435 2467 void bang_stack_with_offset(int offset) {
duke@435 2468 // stack grows down, caller passes positive offset
duke@435 2469 assert(offset > 0, "must bang with negative offset");
duke@435 2470 set((-offset)+STACK_BIAS, G3_scratch);
duke@435 2471 st(G0, SP, G3_scratch);
duke@435 2472 }
duke@435 2473
duke@435 2474 // Writes to stack successive pages until offset reached to check for
duke@435 2475 // stack overflow + shadow pages. Clobbers tsp and scratch registers.
duke@435 2476 void bang_stack_size(Register Rsize, Register Rtsp, Register Rscratch);
duke@435 2477
jrose@1100 2478 virtual RegisterOrConstant delayed_value_impl(intptr_t* delayed_value_addr, Register tmp, int offset);
jrose@1057 2479
duke@435 2480 void verify_tlab();
duke@435 2481
duke@435 2482 Condition negate_condition(Condition cond);
duke@435 2483
duke@435 2484 // Helper functions for statistics gathering.
duke@435 2485 // Conditionally (non-atomically) increments passed counter address, preserving condition codes.
duke@435 2486 void cond_inc(Condition cond, address counter_addr, Register Rtemp1, Register Rtemp2);
duke@435 2487 // Unconditional increment.
twisti@1162 2488 void inc_counter(address counter_addr, Register Rtmp1, Register Rtmp2);
twisti@1162 2489 void inc_counter(int* counter_addr, Register Rtmp1, Register Rtmp2);
duke@435 2490
kvn@1421 2491 // Compare char[] arrays aligned to 4 bytes.
kvn@1421 2492 void char_arrays_equals(Register ary1, Register ary2,
kvn@1421 2493 Register limit, Register result,
kvn@1421 2494 Register chr1, Register chr2, Label& Ldone);
kvn@1421 2495
duke@435 2496 #undef VIRTUAL
duke@435 2497
duke@435 2498 };
duke@435 2499
duke@435 2500 /**
duke@435 2501 * class SkipIfEqual:
duke@435 2502 *
duke@435 2503 * Instantiating this class will result in assembly code being output that will
duke@435 2504 * jump around any code emitted between the creation of the instance and it's
duke@435 2505 * automatic destruction at the end of a scope block, depending on the value of
duke@435 2506 * the flag passed to the constructor, which will be checked at run-time.
duke@435 2507 */
duke@435 2508 class SkipIfEqual : public StackObj {
duke@435 2509 private:
duke@435 2510 MacroAssembler* _masm;
duke@435 2511 Label _label;
duke@435 2512
duke@435 2513 public:
duke@435 2514 // 'temp' is a temp register that this object can use (and trash)
duke@435 2515 SkipIfEqual(MacroAssembler*, Register temp,
duke@435 2516 const bool* flag_addr, Assembler::Condition condition);
duke@435 2517 ~SkipIfEqual();
duke@435 2518 };
duke@435 2519
duke@435 2520 #ifdef ASSERT
duke@435 2521 // On RISC, there's no benefit to verifying instruction boundaries.
duke@435 2522 inline bool AbstractAssembler::pd_check_instruction_mark() { return false; }
duke@435 2523 #endif
stefank@2314 2524
stefank@2314 2525 #endif // CPU_SPARC_VM_ASSEMBLER_SPARC_HPP

mercurial