src/cpu/x86/vm/assembler_x86.hpp

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

author
johnc
date
Thu, 07 Apr 2011 09:53:20 -0700
changeset 2781
e1162778c1c8
parent 2602
41d4973cf100
child 2784
92add02409c9
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_X86_VM_ASSEMBLER_X86_HPP
stefank@2314 26 #define CPU_X86_VM_ASSEMBLER_X86_HPP
stefank@2314 27
duke@435 28 class BiasedLockingCounters;
duke@435 29
duke@435 30 // Contains all the definitions needed for x86 assembly code generation.
duke@435 31
duke@435 32 // Calling convention
duke@435 33 class Argument VALUE_OBJ_CLASS_SPEC {
duke@435 34 public:
duke@435 35 enum {
duke@435 36 #ifdef _LP64
duke@435 37 #ifdef _WIN64
duke@435 38 n_int_register_parameters_c = 4, // rcx, rdx, r8, r9 (c_rarg0, c_rarg1, ...)
duke@435 39 n_float_register_parameters_c = 4, // xmm0 - xmm3 (c_farg0, c_farg1, ... )
duke@435 40 #else
duke@435 41 n_int_register_parameters_c = 6, // rdi, rsi, rdx, rcx, r8, r9 (c_rarg0, c_rarg1, ...)
duke@435 42 n_float_register_parameters_c = 8, // xmm0 - xmm7 (c_farg0, c_farg1, ... )
duke@435 43 #endif // _WIN64
duke@435 44 n_int_register_parameters_j = 6, // j_rarg0, j_rarg1, ...
duke@435 45 n_float_register_parameters_j = 8 // j_farg0, j_farg1, ...
duke@435 46 #else
duke@435 47 n_register_parameters = 0 // 0 registers used to pass arguments
duke@435 48 #endif // _LP64
duke@435 49 };
duke@435 50 };
duke@435 51
duke@435 52
duke@435 53 #ifdef _LP64
duke@435 54 // Symbolically name the register arguments used by the c calling convention.
duke@435 55 // Windows is different from linux/solaris. So much for standards...
duke@435 56
duke@435 57 #ifdef _WIN64
duke@435 58
duke@435 59 REGISTER_DECLARATION(Register, c_rarg0, rcx);
duke@435 60 REGISTER_DECLARATION(Register, c_rarg1, rdx);
duke@435 61 REGISTER_DECLARATION(Register, c_rarg2, r8);
duke@435 62 REGISTER_DECLARATION(Register, c_rarg3, r9);
duke@435 63
never@739 64 REGISTER_DECLARATION(XMMRegister, c_farg0, xmm0);
never@739 65 REGISTER_DECLARATION(XMMRegister, c_farg1, xmm1);
never@739 66 REGISTER_DECLARATION(XMMRegister, c_farg2, xmm2);
never@739 67 REGISTER_DECLARATION(XMMRegister, c_farg3, xmm3);
duke@435 68
duke@435 69 #else
duke@435 70
duke@435 71 REGISTER_DECLARATION(Register, c_rarg0, rdi);
duke@435 72 REGISTER_DECLARATION(Register, c_rarg1, rsi);
duke@435 73 REGISTER_DECLARATION(Register, c_rarg2, rdx);
duke@435 74 REGISTER_DECLARATION(Register, c_rarg3, rcx);
duke@435 75 REGISTER_DECLARATION(Register, c_rarg4, r8);
duke@435 76 REGISTER_DECLARATION(Register, c_rarg5, r9);
duke@435 77
never@739 78 REGISTER_DECLARATION(XMMRegister, c_farg0, xmm0);
never@739 79 REGISTER_DECLARATION(XMMRegister, c_farg1, xmm1);
never@739 80 REGISTER_DECLARATION(XMMRegister, c_farg2, xmm2);
never@739 81 REGISTER_DECLARATION(XMMRegister, c_farg3, xmm3);
never@739 82 REGISTER_DECLARATION(XMMRegister, c_farg4, xmm4);
never@739 83 REGISTER_DECLARATION(XMMRegister, c_farg5, xmm5);
never@739 84 REGISTER_DECLARATION(XMMRegister, c_farg6, xmm6);
never@739 85 REGISTER_DECLARATION(XMMRegister, c_farg7, xmm7);
duke@435 86
duke@435 87 #endif // _WIN64
duke@435 88
duke@435 89 // Symbolically name the register arguments used by the Java calling convention.
duke@435 90 // We have control over the convention for java so we can do what we please.
duke@435 91 // What pleases us is to offset the java calling convention so that when
duke@435 92 // we call a suitable jni method the arguments are lined up and we don't
duke@435 93 // have to do little shuffling. A suitable jni method is non-static and a
duke@435 94 // small number of arguments (two fewer args on windows)
duke@435 95 //
duke@435 96 // |-------------------------------------------------------|
duke@435 97 // | c_rarg0 c_rarg1 c_rarg2 c_rarg3 c_rarg4 c_rarg5 |
duke@435 98 // |-------------------------------------------------------|
duke@435 99 // | rcx rdx r8 r9 rdi* rsi* | windows (* not a c_rarg)
duke@435 100 // | rdi rsi rdx rcx r8 r9 | solaris/linux
duke@435 101 // |-------------------------------------------------------|
duke@435 102 // | j_rarg5 j_rarg0 j_rarg1 j_rarg2 j_rarg3 j_rarg4 |
duke@435 103 // |-------------------------------------------------------|
duke@435 104
duke@435 105 REGISTER_DECLARATION(Register, j_rarg0, c_rarg1);
duke@435 106 REGISTER_DECLARATION(Register, j_rarg1, c_rarg2);
duke@435 107 REGISTER_DECLARATION(Register, j_rarg2, c_rarg3);
duke@435 108 // Windows runs out of register args here
duke@435 109 #ifdef _WIN64
duke@435 110 REGISTER_DECLARATION(Register, j_rarg3, rdi);
duke@435 111 REGISTER_DECLARATION(Register, j_rarg4, rsi);
duke@435 112 #else
duke@435 113 REGISTER_DECLARATION(Register, j_rarg3, c_rarg4);
duke@435 114 REGISTER_DECLARATION(Register, j_rarg4, c_rarg5);
duke@435 115 #endif /* _WIN64 */
duke@435 116 REGISTER_DECLARATION(Register, j_rarg5, c_rarg0);
duke@435 117
never@739 118 REGISTER_DECLARATION(XMMRegister, j_farg0, xmm0);
never@739 119 REGISTER_DECLARATION(XMMRegister, j_farg1, xmm1);
never@739 120 REGISTER_DECLARATION(XMMRegister, j_farg2, xmm2);
never@739 121 REGISTER_DECLARATION(XMMRegister, j_farg3, xmm3);
never@739 122 REGISTER_DECLARATION(XMMRegister, j_farg4, xmm4);
never@739 123 REGISTER_DECLARATION(XMMRegister, j_farg5, xmm5);
never@739 124 REGISTER_DECLARATION(XMMRegister, j_farg6, xmm6);
never@739 125 REGISTER_DECLARATION(XMMRegister, j_farg7, xmm7);
duke@435 126
duke@435 127 REGISTER_DECLARATION(Register, rscratch1, r10); // volatile
duke@435 128 REGISTER_DECLARATION(Register, rscratch2, r11); // volatile
duke@435 129
never@739 130 REGISTER_DECLARATION(Register, r12_heapbase, r12); // callee-saved
duke@435 131 REGISTER_DECLARATION(Register, r15_thread, r15); // callee-saved
duke@435 132
never@739 133 #else
never@739 134 // rscratch1 will apear in 32bit code that is dead but of course must compile
never@739 135 // Using noreg ensures if the dead code is incorrectly live and executed it
never@739 136 // will cause an assertion failure
never@739 137 #define rscratch1 noreg
iveresov@2344 138 #define rscratch2 noreg
never@739 139
duke@435 140 #endif // _LP64
duke@435 141
twisti@1919 142 // JSR 292 fixed register usages:
twisti@1919 143 REGISTER_DECLARATION(Register, rbp_mh_SP_save, rbp);
twisti@1919 144
duke@435 145 // Address is an abstraction used to represent a memory location
duke@435 146 // using any of the amd64 addressing modes with one object.
duke@435 147 //
duke@435 148 // Note: A register location is represented via a Register, not
duke@435 149 // via an address for efficiency & simplicity reasons.
duke@435 150
duke@435 151 class ArrayAddress;
duke@435 152
duke@435 153 class Address VALUE_OBJ_CLASS_SPEC {
duke@435 154 public:
duke@435 155 enum ScaleFactor {
duke@435 156 no_scale = -1,
duke@435 157 times_1 = 0,
duke@435 158 times_2 = 1,
duke@435 159 times_4 = 2,
never@739 160 times_8 = 3,
never@739 161 times_ptr = LP64_ONLY(times_8) NOT_LP64(times_4)
duke@435 162 };
jrose@1057 163 static ScaleFactor times(int size) {
jrose@1057 164 assert(size >= 1 && size <= 8 && is_power_of_2(size), "bad scale size");
jrose@1057 165 if (size == 8) return times_8;
jrose@1057 166 if (size == 4) return times_4;
jrose@1057 167 if (size == 2) return times_2;
jrose@1057 168 return times_1;
jrose@1057 169 }
jrose@1057 170 static int scale_size(ScaleFactor scale) {
jrose@1057 171 assert(scale != no_scale, "");
jrose@1057 172 assert(((1 << (int)times_1) == 1 &&
jrose@1057 173 (1 << (int)times_2) == 2 &&
jrose@1057 174 (1 << (int)times_4) == 4 &&
jrose@1057 175 (1 << (int)times_8) == 8), "");
jrose@1057 176 return (1 << (int)scale);
jrose@1057 177 }
duke@435 178
duke@435 179 private:
duke@435 180 Register _base;
duke@435 181 Register _index;
duke@435 182 ScaleFactor _scale;
duke@435 183 int _disp;
duke@435 184 RelocationHolder _rspec;
duke@435 185
never@739 186 // Easily misused constructors make them private
never@739 187 // %%% can we make these go away?
never@739 188 NOT_LP64(Address(address loc, RelocationHolder spec);)
never@739 189 Address(int disp, address loc, relocInfo::relocType rtype);
never@739 190 Address(int disp, address loc, RelocationHolder spec);
duke@435 191
duke@435 192 public:
never@739 193
never@739 194 int disp() { return _disp; }
duke@435 195 // creation
duke@435 196 Address()
duke@435 197 : _base(noreg),
duke@435 198 _index(noreg),
duke@435 199 _scale(no_scale),
duke@435 200 _disp(0) {
duke@435 201 }
duke@435 202
duke@435 203 // No default displacement otherwise Register can be implicitly
duke@435 204 // converted to 0(Register) which is quite a different animal.
duke@435 205
duke@435 206 Address(Register base, int disp)
duke@435 207 : _base(base),
duke@435 208 _index(noreg),
duke@435 209 _scale(no_scale),
duke@435 210 _disp(disp) {
duke@435 211 }
duke@435 212
duke@435 213 Address(Register base, Register index, ScaleFactor scale, int disp = 0)
duke@435 214 : _base (base),
duke@435 215 _index(index),
duke@435 216 _scale(scale),
duke@435 217 _disp (disp) {
duke@435 218 assert(!index->is_valid() == (scale == Address::no_scale),
duke@435 219 "inconsistent address");
duke@435 220 }
duke@435 221
jrose@1100 222 Address(Register base, RegisterOrConstant index, ScaleFactor scale = times_1, int disp = 0)
jrose@1057 223 : _base (base),
jrose@1057 224 _index(index.register_or_noreg()),
jrose@1057 225 _scale(scale),
jrose@1057 226 _disp (disp + (index.constant_or_zero() * scale_size(scale))) {
jrose@1057 227 if (!index.is_register()) scale = Address::no_scale;
jrose@1057 228 assert(!_index->is_valid() == (scale == Address::no_scale),
jrose@1057 229 "inconsistent address");
jrose@1057 230 }
jrose@1057 231
jrose@1057 232 Address plus_disp(int disp) const {
jrose@1057 233 Address a = (*this);
jrose@1057 234 a._disp += disp;
jrose@1057 235 return a;
jrose@1057 236 }
jrose@1057 237
duke@435 238 // The following two overloads are used in connection with the
duke@435 239 // ByteSize type (see sizes.hpp). They simplify the use of
duke@435 240 // ByteSize'd arguments in assembly code. Note that their equivalent
duke@435 241 // for the optimized build are the member functions with int disp
duke@435 242 // argument since ByteSize is mapped to an int type in that case.
duke@435 243 //
duke@435 244 // Note: DO NOT introduce similar overloaded functions for WordSize
duke@435 245 // arguments as in the optimized mode, both ByteSize and WordSize
duke@435 246 // are mapped to the same type and thus the compiler cannot make a
duke@435 247 // distinction anymore (=> compiler errors).
duke@435 248
duke@435 249 #ifdef ASSERT
duke@435 250 Address(Register base, ByteSize disp)
duke@435 251 : _base(base),
duke@435 252 _index(noreg),
duke@435 253 _scale(no_scale),
duke@435 254 _disp(in_bytes(disp)) {
duke@435 255 }
duke@435 256
duke@435 257 Address(Register base, Register index, ScaleFactor scale, ByteSize disp)
duke@435 258 : _base(base),
duke@435 259 _index(index),
duke@435 260 _scale(scale),
duke@435 261 _disp(in_bytes(disp)) {
duke@435 262 assert(!index->is_valid() == (scale == Address::no_scale),
duke@435 263 "inconsistent address");
duke@435 264 }
jrose@1057 265
jrose@1100 266 Address(Register base, RegisterOrConstant index, ScaleFactor scale, ByteSize disp)
jrose@1057 267 : _base (base),
jrose@1057 268 _index(index.register_or_noreg()),
jrose@1057 269 _scale(scale),
jrose@1057 270 _disp (in_bytes(disp) + (index.constant_or_zero() * scale_size(scale))) {
jrose@1057 271 if (!index.is_register()) scale = Address::no_scale;
jrose@1057 272 assert(!_index->is_valid() == (scale == Address::no_scale),
jrose@1057 273 "inconsistent address");
jrose@1057 274 }
jrose@1057 275
duke@435 276 #endif // ASSERT
duke@435 277
duke@435 278 // accessors
ysr@777 279 bool uses(Register reg) const { return _base == reg || _index == reg; }
ysr@777 280 Register base() const { return _base; }
ysr@777 281 Register index() const { return _index; }
ysr@777 282 ScaleFactor scale() const { return _scale; }
ysr@777 283 int disp() const { return _disp; }
duke@435 284
duke@435 285 // Convert the raw encoding form into the form expected by the constructor for
duke@435 286 // Address. An index of 4 (rsp) corresponds to having no index, so convert
duke@435 287 // that to noreg for the Address constructor.
twisti@1059 288 static Address make_raw(int base, int index, int scale, int disp, bool disp_is_oop);
duke@435 289
duke@435 290 static Address make_array(ArrayAddress);
duke@435 291
duke@435 292 private:
duke@435 293 bool base_needs_rex() const {
duke@435 294 return _base != noreg && _base->encoding() >= 8;
duke@435 295 }
duke@435 296
duke@435 297 bool index_needs_rex() const {
duke@435 298 return _index != noreg &&_index->encoding() >= 8;
duke@435 299 }
duke@435 300
duke@435 301 relocInfo::relocType reloc() const { return _rspec.type(); }
duke@435 302
duke@435 303 friend class Assembler;
duke@435 304 friend class MacroAssembler;
duke@435 305 friend class LIR_Assembler; // base/index/scale/disp
duke@435 306 };
duke@435 307
duke@435 308 //
duke@435 309 // AddressLiteral has been split out from Address because operands of this type
duke@435 310 // need to be treated specially on 32bit vs. 64bit platforms. By splitting it out
duke@435 311 // the few instructions that need to deal with address literals are unique and the
duke@435 312 // MacroAssembler does not have to implement every instruction in the Assembler
duke@435 313 // in order to search for address literals that may need special handling depending
duke@435 314 // on the instruction and the platform. As small step on the way to merging i486/amd64
duke@435 315 // directories.
duke@435 316 //
duke@435 317 class AddressLiteral VALUE_OBJ_CLASS_SPEC {
duke@435 318 friend class ArrayAddress;
duke@435 319 RelocationHolder _rspec;
duke@435 320 // Typically we use AddressLiterals we want to use their rval
duke@435 321 // However in some situations we want the lval (effect address) of the item.
duke@435 322 // We provide a special factory for making those lvals.
duke@435 323 bool _is_lval;
duke@435 324
duke@435 325 // If the target is far we'll need to load the ea of this to
duke@435 326 // a register to reach it. Otherwise if near we can do rip
duke@435 327 // relative addressing.
duke@435 328
duke@435 329 address _target;
duke@435 330
duke@435 331 protected:
duke@435 332 // creation
duke@435 333 AddressLiteral()
duke@435 334 : _is_lval(false),
duke@435 335 _target(NULL)
duke@435 336 {}
duke@435 337
duke@435 338 public:
duke@435 339
duke@435 340
duke@435 341 AddressLiteral(address target, relocInfo::relocType rtype);
duke@435 342
duke@435 343 AddressLiteral(address target, RelocationHolder const& rspec)
duke@435 344 : _rspec(rspec),
duke@435 345 _is_lval(false),
duke@435 346 _target(target)
duke@435 347 {}
duke@435 348
duke@435 349 AddressLiteral addr() {
duke@435 350 AddressLiteral ret = *this;
duke@435 351 ret._is_lval = true;
duke@435 352 return ret;
duke@435 353 }
duke@435 354
duke@435 355
duke@435 356 private:
duke@435 357
duke@435 358 address target() { return _target; }
duke@435 359 bool is_lval() { return _is_lval; }
duke@435 360
duke@435 361 relocInfo::relocType reloc() const { return _rspec.type(); }
duke@435 362 const RelocationHolder& rspec() const { return _rspec; }
duke@435 363
duke@435 364 friend class Assembler;
duke@435 365 friend class MacroAssembler;
duke@435 366 friend class Address;
duke@435 367 friend class LIR_Assembler;
duke@435 368 };
duke@435 369
duke@435 370 // Convience classes
duke@435 371 class RuntimeAddress: public AddressLiteral {
duke@435 372
duke@435 373 public:
duke@435 374
duke@435 375 RuntimeAddress(address target) : AddressLiteral(target, relocInfo::runtime_call_type) {}
duke@435 376
duke@435 377 };
duke@435 378
duke@435 379 class OopAddress: public AddressLiteral {
duke@435 380
duke@435 381 public:
duke@435 382
duke@435 383 OopAddress(address target) : AddressLiteral(target, relocInfo::oop_type){}
duke@435 384
duke@435 385 };
duke@435 386
duke@435 387 class ExternalAddress: public AddressLiteral {
duke@435 388
duke@435 389 public:
duke@435 390
duke@435 391 ExternalAddress(address target) : AddressLiteral(target, relocInfo::external_word_type){}
duke@435 392
duke@435 393 };
duke@435 394
duke@435 395 class InternalAddress: public AddressLiteral {
duke@435 396
duke@435 397 public:
duke@435 398
duke@435 399 InternalAddress(address target) : AddressLiteral(target, relocInfo::internal_word_type) {}
duke@435 400
duke@435 401 };
duke@435 402
duke@435 403 // x86 can do array addressing as a single operation since disp can be an absolute
duke@435 404 // address amd64 can't. We create a class that expresses the concept but does extra
duke@435 405 // magic on amd64 to get the final result
duke@435 406
duke@435 407 class ArrayAddress VALUE_OBJ_CLASS_SPEC {
duke@435 408 private:
duke@435 409
duke@435 410 AddressLiteral _base;
duke@435 411 Address _index;
duke@435 412
duke@435 413 public:
duke@435 414
duke@435 415 ArrayAddress() {};
duke@435 416 ArrayAddress(AddressLiteral base, Address index): _base(base), _index(index) {};
duke@435 417 AddressLiteral base() { return _base; }
duke@435 418 Address index() { return _index; }
duke@435 419
duke@435 420 };
duke@435 421
never@739 422 const int FPUStateSizeInWords = NOT_LP64(27) LP64_ONLY( 512 / wordSize);
duke@435 423
duke@435 424 // The Intel x86/Amd64 Assembler: Pure assembler doing NO optimizations on the instruction
duke@435 425 // level (e.g. mov rax, 0 is not translated into xor rax, rax!); i.e., what you write
duke@435 426 // is what you get. The Assembler is generating code into a CodeBuffer.
duke@435 427
duke@435 428 class Assembler : public AbstractAssembler {
duke@435 429 friend class AbstractAssembler; // for the non-virtual hack
duke@435 430 friend class LIR_Assembler; // as_Address()
never@739 431 friend class StubGenerator;
duke@435 432
duke@435 433 public:
duke@435 434 enum Condition { // The x86 condition codes used for conditional jumps/moves.
duke@435 435 zero = 0x4,
duke@435 436 notZero = 0x5,
duke@435 437 equal = 0x4,
duke@435 438 notEqual = 0x5,
duke@435 439 less = 0xc,
duke@435 440 lessEqual = 0xe,
duke@435 441 greater = 0xf,
duke@435 442 greaterEqual = 0xd,
duke@435 443 below = 0x2,
duke@435 444 belowEqual = 0x6,
duke@435 445 above = 0x7,
duke@435 446 aboveEqual = 0x3,
duke@435 447 overflow = 0x0,
duke@435 448 noOverflow = 0x1,
duke@435 449 carrySet = 0x2,
duke@435 450 carryClear = 0x3,
duke@435 451 negative = 0x8,
duke@435 452 positive = 0x9,
duke@435 453 parity = 0xa,
duke@435 454 noParity = 0xb
duke@435 455 };
duke@435 456
duke@435 457 enum Prefix {
duke@435 458 // segment overrides
duke@435 459 CS_segment = 0x2e,
duke@435 460 SS_segment = 0x36,
duke@435 461 DS_segment = 0x3e,
duke@435 462 ES_segment = 0x26,
duke@435 463 FS_segment = 0x64,
duke@435 464 GS_segment = 0x65,
duke@435 465
duke@435 466 REX = 0x40,
duke@435 467
duke@435 468 REX_B = 0x41,
duke@435 469 REX_X = 0x42,
duke@435 470 REX_XB = 0x43,
duke@435 471 REX_R = 0x44,
duke@435 472 REX_RB = 0x45,
duke@435 473 REX_RX = 0x46,
duke@435 474 REX_RXB = 0x47,
duke@435 475
duke@435 476 REX_W = 0x48,
duke@435 477
duke@435 478 REX_WB = 0x49,
duke@435 479 REX_WX = 0x4A,
duke@435 480 REX_WXB = 0x4B,
duke@435 481 REX_WR = 0x4C,
duke@435 482 REX_WRB = 0x4D,
duke@435 483 REX_WRX = 0x4E,
duke@435 484 REX_WRXB = 0x4F
duke@435 485 };
duke@435 486
duke@435 487 enum WhichOperand {
duke@435 488 // input to locate_operand, and format code for relocations
never@739 489 imm_operand = 0, // embedded 32-bit|64-bit immediate operand
duke@435 490 disp32_operand = 1, // embedded 32-bit displacement or address
duke@435 491 call32_operand = 2, // embedded 32-bit self-relative displacement
never@739 492 #ifndef _LP64
duke@435 493 _WhichOperand_limit = 3
never@739 494 #else
never@739 495 narrow_oop_operand = 3, // embedded 32-bit immediate narrow oop
never@739 496 _WhichOperand_limit = 4
never@739 497 #endif
duke@435 498 };
duke@435 499
never@739 500
never@739 501
never@739 502 // NOTE: The general philopsophy of the declarations here is that 64bit versions
never@739 503 // of instructions are freely declared without the need for wrapping them an ifdef.
never@739 504 // (Some dangerous instructions are ifdef's out of inappropriate jvm's.)
never@739 505 // In the .cpp file the implementations are wrapped so that they are dropped out
never@739 506 // of the resulting jvm. This is done mostly to keep the footprint of KERNEL
never@739 507 // to the size it was prior to merging up the 32bit and 64bit assemblers.
never@739 508 //
never@739 509 // This does mean you'll get a linker/runtime error if you use a 64bit only instruction
never@739 510 // in a 32bit vm. This is somewhat unfortunate but keeps the ifdef noise down.
never@739 511
never@739 512 private:
never@739 513
never@739 514
never@739 515 // 64bit prefixes
never@739 516 int prefix_and_encode(int reg_enc, bool byteinst = false);
never@739 517 int prefixq_and_encode(int reg_enc);
never@739 518
never@739 519 int prefix_and_encode(int dst_enc, int src_enc, bool byteinst = false);
never@739 520 int prefixq_and_encode(int dst_enc, int src_enc);
never@739 521
never@739 522 void prefix(Register reg);
never@739 523 void prefix(Address adr);
never@739 524 void prefixq(Address adr);
never@739 525
never@739 526 void prefix(Address adr, Register reg, bool byteinst = false);
never@739 527 void prefixq(Address adr, Register reg);
never@739 528
never@739 529 void prefix(Address adr, XMMRegister reg);
never@739 530
never@739 531 void prefetch_prefix(Address src);
never@739 532
never@739 533 // Helper functions for groups of instructions
never@739 534 void emit_arith_b(int op1, int op2, Register dst, int imm8);
never@739 535
never@739 536 void emit_arith(int op1, int op2, Register dst, int32_t imm32);
never@739 537 // only 32bit??
never@739 538 void emit_arith(int op1, int op2, Register dst, jobject obj);
never@739 539 void emit_arith(int op1, int op2, Register dst, Register src);
never@739 540
never@739 541 void emit_operand(Register reg,
never@739 542 Register base, Register index, Address::ScaleFactor scale,
never@739 543 int disp,
never@739 544 RelocationHolder const& rspec,
never@739 545 int rip_relative_correction = 0);
never@739 546
never@739 547 void emit_operand(Register reg, Address adr, int rip_relative_correction = 0);
never@739 548
never@739 549 // operands that only take the original 32bit registers
never@739 550 void emit_operand32(Register reg, Address adr);
never@739 551
never@739 552 void emit_operand(XMMRegister reg,
never@739 553 Register base, Register index, Address::ScaleFactor scale,
never@739 554 int disp,
never@739 555 RelocationHolder const& rspec);
never@739 556
never@739 557 void emit_operand(XMMRegister reg, Address adr);
never@739 558
never@739 559 void emit_operand(MMXRegister reg, Address adr);
never@739 560
never@739 561 // workaround gcc (3.2.1-7) bug
never@739 562 void emit_operand(Address adr, MMXRegister reg);
never@739 563
never@739 564
never@739 565 // Immediate-to-memory forms
never@739 566 void emit_arith_operand(int op1, Register rm, Address adr, int32_t imm32);
never@739 567
never@739 568 void emit_farith(int b1, int b2, int i);
never@739 569
duke@435 570
duke@435 571 protected:
never@739 572 #ifdef ASSERT
never@739 573 void check_relocation(RelocationHolder const& rspec, int format);
never@739 574 #endif
never@739 575
never@739 576 inline void emit_long64(jlong x);
never@739 577
never@739 578 void emit_data(jint data, relocInfo::relocType rtype, int format);
never@739 579 void emit_data(jint data, RelocationHolder const& rspec, int format);
never@739 580 void emit_data64(jlong data, relocInfo::relocType rtype, int format = 0);
never@739 581 void emit_data64(jlong data, RelocationHolder const& rspec, int format = 0);
never@739 582
never@739 583
never@739 584 bool reachable(AddressLiteral adr) NOT_LP64({ return true;});
never@739 585
never@739 586 // These are all easily abused and hence protected
never@739 587
never@739 588 // 32BIT ONLY SECTION
never@739 589 #ifndef _LP64
never@739 590 // Make these disappear in 64bit mode since they would never be correct
never@739 591 void cmp_literal32(Register src1, int32_t imm32, RelocationHolder const& rspec); // 32BIT ONLY
never@739 592 void cmp_literal32(Address src1, int32_t imm32, RelocationHolder const& rspec); // 32BIT ONLY
never@739 593
kvn@1077 594 void mov_literal32(Register dst, int32_t imm32, RelocationHolder const& rspec); // 32BIT ONLY
never@739 595 void mov_literal32(Address dst, int32_t imm32, RelocationHolder const& rspec); // 32BIT ONLY
never@739 596
never@739 597 void push_literal32(int32_t imm32, RelocationHolder const& rspec); // 32BIT ONLY
never@739 598 #else
never@739 599 // 64BIT ONLY SECTION
never@739 600 void mov_literal64(Register dst, intptr_t imm64, RelocationHolder const& rspec); // 64BIT ONLY
kvn@1077 601
kvn@1077 602 void cmp_narrow_oop(Register src1, int32_t imm32, RelocationHolder const& rspec);
kvn@1077 603 void cmp_narrow_oop(Address src1, int32_t imm32, RelocationHolder const& rspec);
kvn@1077 604
kvn@1077 605 void mov_narrow_oop(Register dst, int32_t imm32, RelocationHolder const& rspec);
kvn@1077 606 void mov_narrow_oop(Address dst, int32_t imm32, RelocationHolder const& rspec);
never@739 607 #endif // _LP64
never@739 608
never@739 609 // These are unique in that we are ensured by the caller that the 32bit
never@739 610 // relative in these instructions will always be able to reach the potentially
never@739 611 // 64bit address described by entry. Since they can take a 64bit address they
never@739 612 // don't have the 32 suffix like the other instructions in this class.
never@739 613
never@739 614 void call_literal(address entry, RelocationHolder const& rspec);
never@739 615 void jmp_literal(address entry, RelocationHolder const& rspec);
never@739 616
never@739 617 // Avoid using directly section
never@739 618 // Instructions in this section are actually usable by anyone without danger
never@739 619 // of failure but have performance issues that are addressed my enhanced
never@739 620 // instructions which will do the proper thing base on the particular cpu.
never@739 621 // We protect them because we don't trust you...
never@739 622
duke@435 623 // Don't use next inc() and dec() methods directly. INC & DEC instructions
duke@435 624 // could cause a partial flag stall since they don't set CF flag.
duke@435 625 // Use MacroAssembler::decrement() & MacroAssembler::increment() methods
duke@435 626 // which call inc() & dec() or add() & sub() in accordance with
duke@435 627 // the product flag UseIncDec value.
duke@435 628
duke@435 629 void decl(Register dst);
duke@435 630 void decl(Address dst);
never@739 631 void decq(Register dst);
never@739 632 void decq(Address dst);
duke@435 633
duke@435 634 void incl(Register dst);
duke@435 635 void incl(Address dst);
never@739 636 void incq(Register dst);
never@739 637 void incq(Address dst);
never@739 638
never@739 639 // New cpus require use of movsd and movss to avoid partial register stall
never@739 640 // when loading from memory. But for old Opteron use movlpd instead of movsd.
never@739 641 // The selection is done in MacroAssembler::movdbl() and movflt().
never@739 642
never@739 643 // Move Scalar Single-Precision Floating-Point Values
never@739 644 void movss(XMMRegister dst, Address src);
never@739 645 void movss(XMMRegister dst, XMMRegister src);
never@739 646 void movss(Address dst, XMMRegister src);
never@739 647
never@739 648 // Move Scalar Double-Precision Floating-Point Values
never@739 649 void movsd(XMMRegister dst, Address src);
never@739 650 void movsd(XMMRegister dst, XMMRegister src);
never@739 651 void movsd(Address dst, XMMRegister src);
never@739 652 void movlpd(XMMRegister dst, Address src);
never@739 653
never@739 654 // New cpus require use of movaps and movapd to avoid partial register stall
never@739 655 // when moving between registers.
never@739 656 void movaps(XMMRegister dst, XMMRegister src);
never@739 657 void movapd(XMMRegister dst, XMMRegister src);
never@739 658
never@739 659 // End avoid using directly
never@739 660
never@739 661
never@739 662 // Instruction prefixes
never@739 663 void prefix(Prefix p);
never@739 664
never@739 665 public:
never@739 666
never@739 667 // Creation
never@739 668 Assembler(CodeBuffer* code) : AbstractAssembler(code) {}
never@739 669
never@739 670 // Decoding
never@739 671 static address locate_operand(address inst, WhichOperand which);
never@739 672 static address locate_next_instruction(address inst);
never@739 673
never@739 674 // Utilities
never@739 675
never@739 676 #ifdef _LP64
phh@2423 677 static bool is_simm(int64_t x, int nbits) { return -(CONST64(1) << (nbits-1)) <= x &&
phh@2423 678 x < (CONST64(1) << (nbits-1)); }
never@739 679 static bool is_simm32(int64_t x) { return x == (int64_t)(int32_t)x; }
never@739 680 #else
phh@2423 681 static bool is_simm(int32_t x, int nbits) { return -(1 << (nbits-1)) <= x &&
phh@2423 682 x < (1 << (nbits-1)); }
never@739 683 static bool is_simm32(int32_t x) { return true; }
phh@2423 684 #endif // _LP64
never@739 685
never@739 686 // Generic instructions
never@739 687 // Does 32bit or 64bit as needed for the platform. In some sense these
never@739 688 // belong in macro assembler but there is no need for both varieties to exist
never@739 689
never@739 690 void lea(Register dst, Address src);
never@739 691
never@739 692 void mov(Register dst, Register src);
never@739 693
never@739 694 void pusha();
never@739 695 void popa();
never@739 696
never@739 697 void pushf();
never@739 698 void popf();
never@739 699
never@739 700 void push(int32_t imm32);
never@739 701
never@739 702 void push(Register src);
never@739 703
never@739 704 void pop(Register dst);
never@739 705
never@739 706 // These are dummies to prevent surprise implicit conversions to Register
never@739 707 void push(void* v);
never@739 708 void pop(void* v);
never@739 709
never@739 710 // These do register sized moves/scans
never@739 711 void rep_mov();
never@739 712 void rep_set();
never@739 713 void repne_scan();
never@739 714 #ifdef _LP64
never@739 715 void repne_scanl();
never@739 716 #endif
never@739 717
never@739 718 // Vanilla instructions in lexical order
never@739 719
phh@2423 720 void adcl(Address dst, int32_t imm32);
phh@2423 721 void adcl(Address dst, Register src);
never@739 722 void adcl(Register dst, int32_t imm32);
never@739 723 void adcl(Register dst, Address src);
never@739 724 void adcl(Register dst, Register src);
never@739 725
never@739 726 void adcq(Register dst, int32_t imm32);
never@739 727 void adcq(Register dst, Address src);
never@739 728 void adcq(Register dst, Register src);
never@739 729
never@739 730 void addl(Address dst, int32_t imm32);
never@739 731 void addl(Address dst, Register src);
never@739 732 void addl(Register dst, int32_t imm32);
never@739 733 void addl(Register dst, Address src);
never@739 734 void addl(Register dst, Register src);
never@739 735
never@739 736 void addq(Address dst, int32_t imm32);
never@739 737 void addq(Address dst, Register src);
never@739 738 void addq(Register dst, int32_t imm32);
never@739 739 void addq(Register dst, Address src);
never@739 740 void addq(Register dst, Register src);
never@739 741
duke@435 742 void addr_nop_4();
duke@435 743 void addr_nop_5();
duke@435 744 void addr_nop_7();
duke@435 745 void addr_nop_8();
duke@435 746
never@739 747 // Add Scalar Double-Precision Floating-Point Values
never@739 748 void addsd(XMMRegister dst, Address src);
never@739 749 void addsd(XMMRegister dst, XMMRegister src);
never@739 750
never@739 751 // Add Scalar Single-Precision Floating-Point Values
never@739 752 void addss(XMMRegister dst, Address src);
never@739 753 void addss(XMMRegister dst, XMMRegister src);
never@739 754
never@739 755 void andl(Register dst, int32_t imm32);
never@739 756 void andl(Register dst, Address src);
never@739 757 void andl(Register dst, Register src);
never@739 758
never@739 759 void andq(Register dst, int32_t imm32);
never@739 760 void andq(Register dst, Address src);
never@739 761 void andq(Register dst, Register src);
never@739 762
never@739 763 // Bitwise Logical AND of Packed Double-Precision Floating-Point Values
never@739 764 void andpd(XMMRegister dst, Address src);
never@739 765 void andpd(XMMRegister dst, XMMRegister src);
never@739 766
twisti@1210 767 void bsfl(Register dst, Register src);
twisti@1210 768 void bsrl(Register dst, Register src);
twisti@1210 769
twisti@1210 770 #ifdef _LP64
twisti@1210 771 void bsfq(Register dst, Register src);
twisti@1210 772 void bsrq(Register dst, Register src);
twisti@1210 773 #endif
twisti@1210 774
never@739 775 void bswapl(Register reg);
never@739 776
never@739 777 void bswapq(Register reg);
never@739 778
duke@435 779 void call(Label& L, relocInfo::relocType rtype);
duke@435 780 void call(Register reg); // push pc; pc <- reg
duke@435 781 void call(Address adr); // push pc; pc <- adr
duke@435 782
never@739 783 void cdql();
never@739 784
never@739 785 void cdqq();
never@739 786
never@739 787 void cld() { emit_byte(0xfc); }
never@739 788
never@739 789 void clflush(Address adr);
never@739 790
never@739 791 void cmovl(Condition cc, Register dst, Register src);
never@739 792 void cmovl(Condition cc, Register dst, Address src);
never@739 793
never@739 794 void cmovq(Condition cc, Register dst, Register src);
never@739 795 void cmovq(Condition cc, Register dst, Address src);
never@739 796
never@739 797
never@739 798 void cmpb(Address dst, int imm8);
never@739 799
never@739 800 void cmpl(Address dst, int32_t imm32);
never@739 801
never@739 802 void cmpl(Register dst, int32_t imm32);
never@739 803 void cmpl(Register dst, Register src);
never@739 804 void cmpl(Register dst, Address src);
never@739 805
never@739 806 void cmpq(Address dst, int32_t imm32);
never@739 807 void cmpq(Address dst, Register src);
never@739 808
never@739 809 void cmpq(Register dst, int32_t imm32);
never@739 810 void cmpq(Register dst, Register src);
never@739 811 void cmpq(Register dst, Address src);
never@739 812
never@739 813 // these are dummies used to catch attempting to convert NULL to Register
never@739 814 void cmpl(Register dst, void* junk); // dummy
never@739 815 void cmpq(Register dst, void* junk); // dummy
never@739 816
never@739 817 void cmpw(Address dst, int imm16);
never@739 818
never@739 819 void cmpxchg8 (Address adr);
never@739 820
never@739 821 void cmpxchgl(Register reg, Address adr);
never@739 822
never@739 823 void cmpxchgq(Register reg, Address adr);
never@739 824
never@739 825 // Ordered Compare Scalar Double-Precision Floating-Point Values and set EFLAGS
never@739 826 void comisd(XMMRegister dst, Address src);
never@739 827
never@739 828 // Ordered Compare Scalar Single-Precision Floating-Point Values and set EFLAGS
never@739 829 void comiss(XMMRegister dst, Address src);
never@739 830
never@739 831 // Identify processor type and features
never@739 832 void cpuid() {
never@739 833 emit_byte(0x0F);
never@739 834 emit_byte(0xA2);
never@739 835 }
never@739 836
never@739 837 // Convert Scalar Double-Precision Floating-Point Value to Scalar Single-Precision Floating-Point Value
never@739 838 void cvtsd2ss(XMMRegister dst, XMMRegister src);
never@739 839
never@739 840 // Convert Doubleword Integer to Scalar Double-Precision Floating-Point Value
never@739 841 void cvtsi2sdl(XMMRegister dst, Register src);
never@739 842 void cvtsi2sdq(XMMRegister dst, Register src);
never@739 843
never@739 844 // Convert Doubleword Integer to Scalar Single-Precision Floating-Point Value
never@739 845 void cvtsi2ssl(XMMRegister dst, Register src);
never@739 846 void cvtsi2ssq(XMMRegister dst, Register src);
never@739 847
never@739 848 // Convert Packed Signed Doubleword Integers to Packed Double-Precision Floating-Point Value
never@739 849 void cvtdq2pd(XMMRegister dst, XMMRegister src);
never@739 850
never@739 851 // Convert Packed Signed Doubleword Integers to Packed Single-Precision Floating-Point Value
never@739 852 void cvtdq2ps(XMMRegister dst, XMMRegister src);
never@739 853
never@739 854 // Convert Scalar Single-Precision Floating-Point Value to Scalar Double-Precision Floating-Point Value
never@739 855 void cvtss2sd(XMMRegister dst, XMMRegister src);
never@739 856
never@739 857 // Convert with Truncation Scalar Double-Precision Floating-Point Value to Doubleword Integer
never@739 858 void cvttsd2sil(Register dst, Address src);
never@739 859 void cvttsd2sil(Register dst, XMMRegister src);
never@739 860 void cvttsd2siq(Register dst, XMMRegister src);
never@739 861
never@739 862 // Convert with Truncation Scalar Single-Precision Floating-Point Value to Doubleword Integer
never@739 863 void cvttss2sil(Register dst, XMMRegister src);
never@739 864 void cvttss2siq(Register dst, XMMRegister src);
never@739 865
never@739 866 // Divide Scalar Double-Precision Floating-Point Values
never@739 867 void divsd(XMMRegister dst, Address src);
never@739 868 void divsd(XMMRegister dst, XMMRegister src);
never@739 869
never@739 870 // Divide Scalar Single-Precision Floating-Point Values
never@739 871 void divss(XMMRegister dst, Address src);
never@739 872 void divss(XMMRegister dst, XMMRegister src);
never@739 873
never@739 874 void emms();
never@739 875
never@739 876 void fabs();
never@739 877
never@739 878 void fadd(int i);
never@739 879
never@739 880 void fadd_d(Address src);
never@739 881 void fadd_s(Address src);
never@739 882
never@739 883 // "Alternate" versions of x87 instructions place result down in FPU
never@739 884 // stack instead of on TOS
never@739 885
never@739 886 void fadda(int i); // "alternate" fadd
never@739 887 void faddp(int i = 1);
never@739 888
never@739 889 void fchs();
never@739 890
never@739 891 void fcom(int i);
never@739 892
never@739 893 void fcomp(int i = 1);
never@739 894 void fcomp_d(Address src);
never@739 895 void fcomp_s(Address src);
never@739 896
never@739 897 void fcompp();
never@739 898
never@739 899 void fcos();
never@739 900
never@739 901 void fdecstp();
never@739 902
never@739 903 void fdiv(int i);
never@739 904 void fdiv_d(Address src);
never@739 905 void fdivr_s(Address src);
never@739 906 void fdiva(int i); // "alternate" fdiv
never@739 907 void fdivp(int i = 1);
never@739 908
never@739 909 void fdivr(int i);
never@739 910 void fdivr_d(Address src);
never@739 911 void fdiv_s(Address src);
never@739 912
never@739 913 void fdivra(int i); // "alternate" reversed fdiv
never@739 914
never@739 915 void fdivrp(int i = 1);
never@739 916
never@739 917 void ffree(int i = 0);
never@739 918
never@739 919 void fild_d(Address adr);
never@739 920 void fild_s(Address adr);
never@739 921
never@739 922 void fincstp();
never@739 923
never@739 924 void finit();
never@739 925
never@739 926 void fist_s (Address adr);
never@739 927 void fistp_d(Address adr);
never@739 928 void fistp_s(Address adr);
never@739 929
never@739 930 void fld1();
never@739 931
never@739 932 void fld_d(Address adr);
never@739 933 void fld_s(Address adr);
never@739 934 void fld_s(int index);
never@739 935 void fld_x(Address adr); // extended-precision (80-bit) format
never@739 936
never@739 937 void fldcw(Address src);
never@739 938
never@739 939 void fldenv(Address src);
never@739 940
never@739 941 void fldlg2();
never@739 942
never@739 943 void fldln2();
never@739 944
never@739 945 void fldz();
never@739 946
never@739 947 void flog();
never@739 948 void flog10();
never@739 949
never@739 950 void fmul(int i);
never@739 951
never@739 952 void fmul_d(Address src);
never@739 953 void fmul_s(Address src);
never@739 954
never@739 955 void fmula(int i); // "alternate" fmul
never@739 956
never@739 957 void fmulp(int i = 1);
never@739 958
never@739 959 void fnsave(Address dst);
never@739 960
never@739 961 void fnstcw(Address src);
never@739 962
never@739 963 void fnstsw_ax();
never@739 964
never@739 965 void fprem();
never@739 966 void fprem1();
never@739 967
never@739 968 void frstor(Address src);
never@739 969
never@739 970 void fsin();
never@739 971
never@739 972 void fsqrt();
never@739 973
never@739 974 void fst_d(Address adr);
never@739 975 void fst_s(Address adr);
never@739 976
never@739 977 void fstp_d(Address adr);
never@739 978 void fstp_d(int index);
never@739 979 void fstp_s(Address adr);
never@739 980 void fstp_x(Address adr); // extended-precision (80-bit) format
never@739 981
never@739 982 void fsub(int i);
never@739 983 void fsub_d(Address src);
never@739 984 void fsub_s(Address src);
never@739 985
never@739 986 void fsuba(int i); // "alternate" fsub
never@739 987
never@739 988 void fsubp(int i = 1);
never@739 989
never@739 990 void fsubr(int i);
never@739 991 void fsubr_d(Address src);
never@739 992 void fsubr_s(Address src);
never@739 993
never@739 994 void fsubra(int i); // "alternate" reversed fsub
never@739 995
never@739 996 void fsubrp(int i = 1);
never@739 997
never@739 998 void ftan();
never@739 999
never@739 1000 void ftst();
never@739 1001
never@739 1002 void fucomi(int i = 1);
never@739 1003 void fucomip(int i = 1);
never@739 1004
never@739 1005 void fwait();
never@739 1006
never@739 1007 void fxch(int i = 1);
never@739 1008
never@739 1009 void fxrstor(Address src);
never@739 1010
never@739 1011 void fxsave(Address dst);
never@739 1012
never@739 1013 void fyl2x();
never@739 1014
never@739 1015 void hlt();
never@739 1016
never@739 1017 void idivl(Register src);
kvn@2275 1018 void divl(Register src); // Unsigned division
never@739 1019
never@739 1020 void idivq(Register src);
never@739 1021
never@739 1022 void imull(Register dst, Register src);
never@739 1023 void imull(Register dst, Register src, int value);
never@739 1024
never@739 1025 void imulq(Register dst, Register src);
never@739 1026 void imulq(Register dst, Register src, int value);
never@739 1027
duke@435 1028
duke@435 1029 // jcc is the generic conditional branch generator to run-
duke@435 1030 // time routines, jcc is used for branches to labels. jcc
duke@435 1031 // takes a branch opcode (cc) and a label (L) and generates
duke@435 1032 // either a backward branch or a forward branch and links it
duke@435 1033 // to the label fixup chain. Usage:
duke@435 1034 //
duke@435 1035 // Label L; // unbound label
duke@435 1036 // jcc(cc, L); // forward branch to unbound label
duke@435 1037 // bind(L); // bind label to the current pc
duke@435 1038 // jcc(cc, L); // backward branch to bound label
duke@435 1039 // bind(L); // illegal: a label may be bound only once
duke@435 1040 //
duke@435 1041 // Note: The same Label can be used for forward and backward branches
duke@435 1042 // but it may be bound only once.
duke@435 1043
duke@435 1044 void jcc(Condition cc, Label& L,
duke@435 1045 relocInfo::relocType rtype = relocInfo::none);
duke@435 1046
duke@435 1047 // Conditional jump to a 8-bit offset to L.
duke@435 1048 // WARNING: be very careful using this for forward jumps. If the label is
duke@435 1049 // not bound within an 8-bit offset of this instruction, a run-time error
duke@435 1050 // will occur.
duke@435 1051 void jccb(Condition cc, Label& L);
duke@435 1052
never@739 1053 void jmp(Address entry); // pc <- entry
never@739 1054
never@739 1055 // Label operations & relative jumps (PPUM Appendix D)
never@739 1056 void jmp(Label& L, relocInfo::relocType rtype = relocInfo::none); // unconditional jump to L
never@739 1057
never@739 1058 void jmp(Register entry); // pc <- entry
never@739 1059
never@739 1060 // Unconditional 8-bit offset jump to L.
never@739 1061 // WARNING: be very careful using this for forward jumps. If the label is
never@739 1062 // not bound within an 8-bit offset of this instruction, a run-time error
never@739 1063 // will occur.
never@739 1064 void jmpb(Label& L);
never@739 1065
never@739 1066 void ldmxcsr( Address src );
never@739 1067
never@739 1068 void leal(Register dst, Address src);
never@739 1069
never@739 1070 void leaq(Register dst, Address src);
never@739 1071
never@739 1072 void lfence() {
never@739 1073 emit_byte(0x0F);
never@739 1074 emit_byte(0xAE);
never@739 1075 emit_byte(0xE8);
never@739 1076 }
never@739 1077
never@739 1078 void lock();
never@739 1079
twisti@1210 1080 void lzcntl(Register dst, Register src);
twisti@1210 1081
twisti@1210 1082 #ifdef _LP64
twisti@1210 1083 void lzcntq(Register dst, Register src);
twisti@1210 1084 #endif
twisti@1210 1085
never@739 1086 enum Membar_mask_bits {
never@739 1087 StoreStore = 1 << 3,
never@739 1088 LoadStore = 1 << 2,
never@739 1089 StoreLoad = 1 << 1,
never@739 1090 LoadLoad = 1 << 0
never@739 1091 };
never@739 1092
never@1106 1093 // Serializes memory and blows flags
never@739 1094 void membar(Membar_mask_bits order_constraint) {
never@1106 1095 if (os::is_MP()) {
never@1106 1096 // We only have to handle StoreLoad
never@1106 1097 if (order_constraint & StoreLoad) {
never@1106 1098 // All usable chips support "locked" instructions which suffice
never@1106 1099 // as barriers, and are much faster than the alternative of
never@1106 1100 // using cpuid instruction. We use here a locked add [esp],0.
never@1106 1101 // This is conveniently otherwise a no-op except for blowing
never@1106 1102 // flags.
never@1106 1103 // Any change to this code may need to revisit other places in
never@1106 1104 // the code where this idiom is used, in particular the
never@1106 1105 // orderAccess code.
never@1106 1106 lock();
never@1106 1107 addl(Address(rsp, 0), 0);// Assert the lock# signal here
never@1106 1108 }
never@1106 1109 }
never@739 1110 }
never@739 1111
never@739 1112 void mfence();
never@739 1113
never@739 1114 // Moves
never@739 1115
never@739 1116 void mov64(Register dst, int64_t imm64);
never@739 1117
never@739 1118 void movb(Address dst, Register src);
never@739 1119 void movb(Address dst, int imm8);
never@739 1120 void movb(Register dst, Address src);
never@739 1121
never@739 1122 void movdl(XMMRegister dst, Register src);
never@739 1123 void movdl(Register dst, XMMRegister src);
kvn@2602 1124 void movdl(XMMRegister dst, Address src);
never@739 1125
never@739 1126 // Move Double Quadword
never@739 1127 void movdq(XMMRegister dst, Register src);
never@739 1128 void movdq(Register dst, XMMRegister src);
never@739 1129
never@739 1130 // Move Aligned Double Quadword
never@739 1131 void movdqa(Address dst, XMMRegister src);
never@739 1132 void movdqa(XMMRegister dst, Address src);
never@739 1133 void movdqa(XMMRegister dst, XMMRegister src);
never@739 1134
kvn@840 1135 // Move Unaligned Double Quadword
kvn@840 1136 void movdqu(Address dst, XMMRegister src);
kvn@840 1137 void movdqu(XMMRegister dst, Address src);
kvn@840 1138 void movdqu(XMMRegister dst, XMMRegister src);
kvn@840 1139
never@739 1140 void movl(Register dst, int32_t imm32);
never@739 1141 void movl(Address dst, int32_t imm32);
never@739 1142 void movl(Register dst, Register src);
never@739 1143 void movl(Register dst, Address src);
never@739 1144 void movl(Address dst, Register src);
never@739 1145
never@739 1146 // These dummies prevent using movl from converting a zero (like NULL) into Register
never@739 1147 // by giving the compiler two choices it can't resolve
never@739 1148
never@739 1149 void movl(Address dst, void* junk);
never@739 1150 void movl(Register dst, void* junk);
never@739 1151
never@739 1152 #ifdef _LP64
never@739 1153 void movq(Register dst, Register src);
never@739 1154 void movq(Register dst, Address src);
phh@2423 1155 void movq(Address dst, Register src);
never@739 1156 #endif
never@739 1157
never@739 1158 void movq(Address dst, MMXRegister src );
never@739 1159 void movq(MMXRegister dst, Address src );
never@739 1160
never@739 1161 #ifdef _LP64
never@739 1162 // These dummies prevent using movq from converting a zero (like NULL) into Register
never@739 1163 // by giving the compiler two choices it can't resolve
never@739 1164
never@739 1165 void movq(Address dst, void* dummy);
never@739 1166 void movq(Register dst, void* dummy);
never@739 1167 #endif
never@739 1168
never@739 1169 // Move Quadword
never@739 1170 void movq(Address dst, XMMRegister src);
never@739 1171 void movq(XMMRegister dst, Address src);
never@739 1172
never@739 1173 void movsbl(Register dst, Address src);
never@739 1174 void movsbl(Register dst, Register src);
never@739 1175
never@739 1176 #ifdef _LP64
twisti@1059 1177 void movsbq(Register dst, Address src);
twisti@1059 1178 void movsbq(Register dst, Register src);
twisti@1059 1179
never@739 1180 // Move signed 32bit immediate to 64bit extending sign
phh@2423 1181 void movslq(Address dst, int32_t imm64);
never@739 1182 void movslq(Register dst, int32_t imm64);
never@739 1183
never@739 1184 void movslq(Register dst, Address src);
never@739 1185 void movslq(Register dst, Register src);
never@739 1186 void movslq(Register dst, void* src); // Dummy declaration to cause NULL to be ambiguous
never@739 1187 #endif
never@739 1188
never@739 1189 void movswl(Register dst, Address src);
never@739 1190 void movswl(Register dst, Register src);
never@739 1191
twisti@1059 1192 #ifdef _LP64
twisti@1059 1193 void movswq(Register dst, Address src);
twisti@1059 1194 void movswq(Register dst, Register src);
twisti@1059 1195 #endif
twisti@1059 1196
never@739 1197 void movw(Address dst, int imm16);
never@739 1198 void movw(Register dst, Address src);
never@739 1199 void movw(Address dst, Register src);
never@739 1200
never@739 1201 void movzbl(Register dst, Address src);
never@739 1202 void movzbl(Register dst, Register src);
never@739 1203
twisti@1059 1204 #ifdef _LP64
twisti@1059 1205 void movzbq(Register dst, Address src);
twisti@1059 1206 void movzbq(Register dst, Register src);
twisti@1059 1207 #endif
twisti@1059 1208
never@739 1209 void movzwl(Register dst, Address src);
never@739 1210 void movzwl(Register dst, Register src);
never@739 1211
twisti@1059 1212 #ifdef _LP64
twisti@1059 1213 void movzwq(Register dst, Address src);
twisti@1059 1214 void movzwq(Register dst, Register src);
twisti@1059 1215 #endif
twisti@1059 1216
never@739 1217 void mull(Address src);
never@739 1218 void mull(Register src);
never@739 1219
never@739 1220 // Multiply Scalar Double-Precision Floating-Point Values
never@739 1221 void mulsd(XMMRegister dst, Address src);
never@739 1222 void mulsd(XMMRegister dst, XMMRegister src);
never@739 1223
never@739 1224 // Multiply Scalar Single-Precision Floating-Point Values
never@739 1225 void mulss(XMMRegister dst, Address src);
never@739 1226 void mulss(XMMRegister dst, XMMRegister src);
never@739 1227
never@739 1228 void negl(Register dst);
never@739 1229
never@739 1230 #ifdef _LP64
never@739 1231 void negq(Register dst);
never@739 1232 #endif
never@739 1233
never@739 1234 void nop(int i = 1);
never@739 1235
never@739 1236 void notl(Register dst);
never@739 1237
never@739 1238 #ifdef _LP64
never@739 1239 void notq(Register dst);
never@739 1240 #endif
never@739 1241
never@739 1242 void orl(Address dst, int32_t imm32);
never@739 1243 void orl(Register dst, int32_t imm32);
never@739 1244 void orl(Register dst, Address src);
never@739 1245 void orl(Register dst, Register src);
never@739 1246
never@739 1247 void orq(Address dst, int32_t imm32);
never@739 1248 void orq(Register dst, int32_t imm32);
never@739 1249 void orq(Register dst, Address src);
never@739 1250 void orq(Register dst, Register src);
never@739 1251
cfang@1116 1252 // SSE4.2 string instructions
cfang@1116 1253 void pcmpestri(XMMRegister xmm1, XMMRegister xmm2, int imm8);
cfang@1116 1254 void pcmpestri(XMMRegister xmm1, Address src, int imm8);
cfang@1116 1255
roland@1495 1256 #ifndef _LP64 // no 32bit push/pop on amd64
never@739 1257 void popl(Address dst);
roland@1495 1258 #endif
never@739 1259
never@739 1260 #ifdef _LP64
never@739 1261 void popq(Address dst);
never@739 1262 #endif
never@739 1263
twisti@1078 1264 void popcntl(Register dst, Address src);
twisti@1078 1265 void popcntl(Register dst, Register src);
twisti@1078 1266
twisti@1078 1267 #ifdef _LP64
twisti@1078 1268 void popcntq(Register dst, Address src);
twisti@1078 1269 void popcntq(Register dst, Register src);
twisti@1078 1270 #endif
twisti@1078 1271
never@739 1272 // Prefetches (SSE, SSE2, 3DNOW only)
never@739 1273
never@739 1274 void prefetchnta(Address src);
never@739 1275 void prefetchr(Address src);
never@739 1276 void prefetcht0(Address src);
never@739 1277 void prefetcht1(Address src);
never@739 1278 void prefetcht2(Address src);
never@739 1279 void prefetchw(Address src);
never@739 1280
never@2569 1281 // POR - Bitwise logical OR
never@2569 1282 void por(XMMRegister dst, XMMRegister src);
never@2569 1283
never@739 1284 // Shuffle Packed Doublewords
never@739 1285 void pshufd(XMMRegister dst, XMMRegister src, int mode);
never@739 1286 void pshufd(XMMRegister dst, Address src, int mode);
never@739 1287
never@739 1288 // Shuffle Packed Low Words
never@739 1289 void pshuflw(XMMRegister dst, XMMRegister src, int mode);
never@739 1290 void pshuflw(XMMRegister dst, Address src, int mode);
never@739 1291
kvn@2602 1292 // Shift Right by bits Logical Quadword Immediate
never@739 1293 void psrlq(XMMRegister dst, int shift);
never@739 1294
kvn@2602 1295 // Shift Right by bytes Logical DoubleQuadword Immediate
kvn@2602 1296 void psrldq(XMMRegister dst, int shift);
kvn@2602 1297
cfang@1116 1298 // Logical Compare Double Quadword
cfang@1116 1299 void ptest(XMMRegister dst, XMMRegister src);
cfang@1116 1300 void ptest(XMMRegister dst, Address src);
cfang@1116 1301
never@739 1302 // Interleave Low Bytes
never@739 1303 void punpcklbw(XMMRegister dst, XMMRegister src);
never@739 1304
roland@1495 1305 #ifndef _LP64 // no 32bit push/pop on amd64
never@739 1306 void pushl(Address src);
roland@1495 1307 #endif
never@739 1308
never@739 1309 void pushq(Address src);
never@739 1310
never@739 1311 // Xor Packed Byte Integer Values
never@739 1312 void pxor(XMMRegister dst, Address src);
never@739 1313 void pxor(XMMRegister dst, XMMRegister src);
never@739 1314
never@739 1315 void rcll(Register dst, int imm8);
never@739 1316
never@739 1317 void rclq(Register dst, int imm8);
never@739 1318
never@739 1319 void ret(int imm16);
duke@435 1320
duke@435 1321 void sahf();
duke@435 1322
never@739 1323 void sarl(Register dst, int imm8);
never@739 1324 void sarl(Register dst);
never@739 1325
never@739 1326 void sarq(Register dst, int imm8);
never@739 1327 void sarq(Register dst);
never@739 1328
never@739 1329 void sbbl(Address dst, int32_t imm32);
never@739 1330 void sbbl(Register dst, int32_t imm32);
never@739 1331 void sbbl(Register dst, Address src);
never@739 1332 void sbbl(Register dst, Register src);
never@739 1333
never@739 1334 void sbbq(Address dst, int32_t imm32);
never@739 1335 void sbbq(Register dst, int32_t imm32);
never@739 1336 void sbbq(Register dst, Address src);
never@739 1337 void sbbq(Register dst, Register src);
never@739 1338
never@739 1339 void setb(Condition cc, Register dst);
never@739 1340
never@739 1341 void shldl(Register dst, Register src);
never@739 1342
never@739 1343 void shll(Register dst, int imm8);
never@739 1344 void shll(Register dst);
never@739 1345
never@739 1346 void shlq(Register dst, int imm8);
never@739 1347 void shlq(Register dst);
never@739 1348
never@739 1349 void shrdl(Register dst, Register src);
never@739 1350
never@739 1351 void shrl(Register dst, int imm8);
never@739 1352 void shrl(Register dst);
never@739 1353
never@739 1354 void shrq(Register dst, int imm8);
never@739 1355 void shrq(Register dst);
never@739 1356
never@739 1357 void smovl(); // QQQ generic?
never@739 1358
never@739 1359 // Compute Square Root of Scalar Double-Precision Floating-Point Value
never@739 1360 void sqrtsd(XMMRegister dst, Address src);
never@739 1361 void sqrtsd(XMMRegister dst, XMMRegister src);
never@739 1362
twisti@2350 1363 // Compute Square Root of Scalar Single-Precision Floating-Point Value
twisti@2350 1364 void sqrtss(XMMRegister dst, Address src);
twisti@2350 1365 void sqrtss(XMMRegister dst, XMMRegister src);
twisti@2350 1366
never@739 1367 void std() { emit_byte(0xfd); }
never@739 1368
never@739 1369 void stmxcsr( Address dst );
never@739 1370
never@739 1371 void subl(Address dst, int32_t imm32);
never@739 1372 void subl(Address dst, Register src);
never@739 1373 void subl(Register dst, int32_t imm32);
never@739 1374 void subl(Register dst, Address src);
never@739 1375 void subl(Register dst, Register src);
never@739 1376
never@739 1377 void subq(Address dst, int32_t imm32);
never@739 1378 void subq(Address dst, Register src);
never@739 1379 void subq(Register dst, int32_t imm32);
never@739 1380 void subq(Register dst, Address src);
never@739 1381 void subq(Register dst, Register src);
never@739 1382
never@739 1383
never@739 1384 // Subtract Scalar Double-Precision Floating-Point Values
never@739 1385 void subsd(XMMRegister dst, Address src);
never@739 1386 void subsd(XMMRegister dst, XMMRegister src);
never@739 1387
never@739 1388 // Subtract Scalar Single-Precision Floating-Point Values
never@739 1389 void subss(XMMRegister dst, Address src);
duke@435 1390 void subss(XMMRegister dst, XMMRegister src);
never@739 1391
never@739 1392 void testb(Register dst, int imm8);
never@739 1393
never@739 1394 void testl(Register dst, int32_t imm32);
never@739 1395 void testl(Register dst, Register src);
never@739 1396 void testl(Register dst, Address src);
never@739 1397
never@739 1398 void testq(Register dst, int32_t imm32);
never@739 1399 void testq(Register dst, Register src);
never@739 1400
never@739 1401
never@739 1402 // Unordered Compare Scalar Double-Precision Floating-Point Values and set EFLAGS
never@739 1403 void ucomisd(XMMRegister dst, Address src);
never@739 1404 void ucomisd(XMMRegister dst, XMMRegister src);
never@739 1405
never@739 1406 // Unordered Compare Scalar Single-Precision Floating-Point Values and set EFLAGS
never@739 1407 void ucomiss(XMMRegister dst, Address src);
duke@435 1408 void ucomiss(XMMRegister dst, XMMRegister src);
never@739 1409
never@739 1410 void xaddl(Address dst, Register src);
never@739 1411
never@739 1412 void xaddq(Address dst, Register src);
never@739 1413
never@739 1414 void xchgl(Register reg, Address adr);
never@739 1415 void xchgl(Register dst, Register src);
never@739 1416
never@739 1417 void xchgq(Register reg, Address adr);
never@739 1418 void xchgq(Register dst, Register src);
never@739 1419
never@739 1420 void xorl(Register dst, int32_t imm32);
never@739 1421 void xorl(Register dst, Address src);
never@739 1422 void xorl(Register dst, Register src);
never@739 1423
never@739 1424 void xorq(Register dst, Address src);
never@739 1425 void xorq(Register dst, Register src);
never@739 1426
never@739 1427 // Bitwise Logical XOR of Packed Double-Precision Floating-Point Values
never@739 1428 void xorpd(XMMRegister dst, Address src);
never@739 1429 void xorpd(XMMRegister dst, XMMRegister src);
never@739 1430
never@739 1431 // Bitwise Logical XOR of Packed Single-Precision Floating-Point Values
never@739 1432 void xorps(XMMRegister dst, Address src);
duke@435 1433 void xorps(XMMRegister dst, XMMRegister src);
never@739 1434
never@739 1435 void set_byte_if_not_zero(Register dst); // sets reg to 1 if not zero, otherwise 0
duke@435 1436 };
duke@435 1437
duke@435 1438
duke@435 1439 // MacroAssembler extends Assembler by frequently used macros.
duke@435 1440 //
duke@435 1441 // Instructions for which a 'better' code sequence exists depending
duke@435 1442 // on arguments should also go in here.
duke@435 1443
duke@435 1444 class MacroAssembler: public Assembler {
ysr@777 1445 friend class LIR_Assembler;
ysr@777 1446 friend class Runtime1; // as_Address()
johnc@2781 1447
duke@435 1448 protected:
duke@435 1449
duke@435 1450 Address as_Address(AddressLiteral adr);
duke@435 1451 Address as_Address(ArrayAddress adr);
duke@435 1452
duke@435 1453 // Support for VM calls
duke@435 1454 //
duke@435 1455 // This is the base routine called by the different versions of call_VM_leaf. The interpreter
duke@435 1456 // may customize this version by overriding it for its purposes (e.g., to save/restore
duke@435 1457 // additional registers when doing a VM call).
duke@435 1458 #ifdef CC_INTERP
duke@435 1459 // c++ interpreter never wants to use interp_masm version of call_VM
duke@435 1460 #define VIRTUAL
duke@435 1461 #else
duke@435 1462 #define VIRTUAL virtual
duke@435 1463 #endif
duke@435 1464
duke@435 1465 VIRTUAL void call_VM_leaf_base(
duke@435 1466 address entry_point, // the entry point
duke@435 1467 int number_of_arguments // the number of arguments to pop after the call
duke@435 1468 );
duke@435 1469
duke@435 1470 // This is the base routine called by the different versions of call_VM. The interpreter
duke@435 1471 // may customize this version by overriding it for its purposes (e.g., to save/restore
duke@435 1472 // additional registers when doing a VM call).
duke@435 1473 //
duke@435 1474 // If no java_thread register is specified (noreg) than rdi will be used instead. call_VM_base
duke@435 1475 // returns the register which contains the thread upon return. If a thread register has been
duke@435 1476 // specified, the return value will correspond to that register. If no last_java_sp is specified
duke@435 1477 // (noreg) than rsp will be used instead.
duke@435 1478 VIRTUAL void call_VM_base( // returns the register containing the thread upon return
duke@435 1479 Register oop_result, // where an oop-result ends up if any; use noreg otherwise
duke@435 1480 Register java_thread, // the thread if computed before ; use noreg otherwise
duke@435 1481 Register last_java_sp, // to set up last_Java_frame in stubs; use noreg otherwise
duke@435 1482 address entry_point, // the entry point
duke@435 1483 int number_of_arguments, // the number of arguments (w/o thread) to pop after the call
duke@435 1484 bool check_exceptions // whether to check for pending exceptions after return
duke@435 1485 );
duke@435 1486
duke@435 1487 // These routines should emit JVMTI PopFrame and ForceEarlyReturn handling code.
duke@435 1488 // The implementation is only non-empty for the InterpreterMacroAssembler,
duke@435 1489 // as only the interpreter handles PopFrame and ForceEarlyReturn requests.
duke@435 1490 virtual void check_and_handle_popframe(Register java_thread);
duke@435 1491 virtual void check_and_handle_earlyret(Register java_thread);
duke@435 1492
duke@435 1493 void call_VM_helper(Register oop_result, address entry_point, int number_of_arguments, bool check_exceptions = true);
duke@435 1494
duke@435 1495 // helpers for FPU flag access
duke@435 1496 // tmp is a temporary register, if none is available use noreg
duke@435 1497 void save_rax (Register tmp);
duke@435 1498 void restore_rax(Register tmp);
duke@435 1499
duke@435 1500 public:
duke@435 1501 MacroAssembler(CodeBuffer* code) : Assembler(code) {}
duke@435 1502
duke@435 1503 // Support for NULL-checks
duke@435 1504 //
duke@435 1505 // Generates code that causes a NULL OS exception if the content of reg is NULL.
duke@435 1506 // If the accessed location is M[reg + offset] and the offset is known, provide the
duke@435 1507 // offset. No explicit code generation is needed if the offset is within a certain
duke@435 1508 // range (0 <= offset <= page_size).
duke@435 1509
duke@435 1510 void null_check(Register reg, int offset = -1);
kvn@603 1511 static bool needs_explicit_null_check(intptr_t offset);
duke@435 1512
duke@435 1513 // Required platform-specific helpers for Label::patch_instructions.
duke@435 1514 // They _shadow_ the declarations in AbstractAssembler, which are undefined.
duke@435 1515 void pd_patch_instruction(address branch, address target);
duke@435 1516 #ifndef PRODUCT
duke@435 1517 static void pd_print_patched_instruction(address branch);
duke@435 1518 #endif
duke@435 1519
duke@435 1520 // The following 4 methods return the offset of the appropriate move instruction
duke@435 1521
jrose@1057 1522 // Support for fast byte/short loading with zero extension (depending on particular CPU)
duke@435 1523 int load_unsigned_byte(Register dst, Address src);
jrose@1057 1524 int load_unsigned_short(Register dst, Address src);
jrose@1057 1525
jrose@1057 1526 // Support for fast byte/short loading with sign extension (depending on particular CPU)
duke@435 1527 int load_signed_byte(Register dst, Address src);
jrose@1057 1528 int load_signed_short(Register dst, Address src);
duke@435 1529
duke@435 1530 // Support for sign-extension (hi:lo = extend_sign(lo))
duke@435 1531 void extend_sign(Register hi, Register lo);
duke@435 1532
twisti@2565 1533 // Load and store values by size and signed-ness
twisti@2565 1534 void load_sized_value(Register dst, Address src, size_t size_in_bytes, bool is_signed, Register dst2 = noreg);
twisti@2565 1535 void store_sized_value(Address dst, Register src, size_t size_in_bytes, Register src2 = noreg);
jrose@1057 1536
duke@435 1537 // Support for inc/dec with optimal instruction selection depending on value
never@739 1538
never@739 1539 void increment(Register reg, int value = 1) { LP64_ONLY(incrementq(reg, value)) NOT_LP64(incrementl(reg, value)) ; }
never@739 1540 void decrement(Register reg, int value = 1) { LP64_ONLY(decrementq(reg, value)) NOT_LP64(decrementl(reg, value)) ; }
never@739 1541
never@739 1542 void decrementl(Address dst, int value = 1);
never@739 1543 void decrementl(Register reg, int value = 1);
never@739 1544
never@739 1545 void decrementq(Register reg, int value = 1);
never@739 1546 void decrementq(Address dst, int value = 1);
never@739 1547
never@739 1548 void incrementl(Address dst, int value = 1);
never@739 1549 void incrementl(Register reg, int value = 1);
never@739 1550
never@739 1551 void incrementq(Register reg, int value = 1);
never@739 1552 void incrementq(Address dst, int value = 1);
never@739 1553
duke@435 1554
duke@435 1555 // Support optimal SSE move instructions.
duke@435 1556 void movflt(XMMRegister dst, XMMRegister src) {
duke@435 1557 if (UseXmmRegToRegMoveAll) { movaps(dst, src); return; }
duke@435 1558 else { movss (dst, src); return; }
duke@435 1559 }
duke@435 1560 void movflt(XMMRegister dst, Address src) { movss(dst, src); }
duke@435 1561 void movflt(XMMRegister dst, AddressLiteral src);
duke@435 1562 void movflt(Address dst, XMMRegister src) { movss(dst, src); }
duke@435 1563
duke@435 1564 void movdbl(XMMRegister dst, XMMRegister src) {
duke@435 1565 if (UseXmmRegToRegMoveAll) { movapd(dst, src); return; }
duke@435 1566 else { movsd (dst, src); return; }
duke@435 1567 }
duke@435 1568
duke@435 1569 void movdbl(XMMRegister dst, AddressLiteral src);
duke@435 1570
duke@435 1571 void movdbl(XMMRegister dst, Address src) {
duke@435 1572 if (UseXmmLoadAndClearUpper) { movsd (dst, src); return; }
duke@435 1573 else { movlpd(dst, src); return; }
duke@435 1574 }
duke@435 1575 void movdbl(Address dst, XMMRegister src) { movsd(dst, src); }
duke@435 1576
never@739 1577 void incrementl(AddressLiteral dst);
never@739 1578 void incrementl(ArrayAddress dst);
duke@435 1579
duke@435 1580 // Alignment
duke@435 1581 void align(int modulus);
duke@435 1582
duke@435 1583 // Misc
duke@435 1584 void fat_nop(); // 5 byte nop
duke@435 1585
duke@435 1586 // Stack frame creation/removal
duke@435 1587 void enter();
duke@435 1588 void leave();
duke@435 1589
duke@435 1590 // Support for getting the JavaThread pointer (i.e.; a reference to thread-local information)
duke@435 1591 // The pointer will be loaded into the thread register.
duke@435 1592 void get_thread(Register thread);
duke@435 1593
apetrusenko@797 1594
duke@435 1595 // Support for VM calls
duke@435 1596 //
duke@435 1597 // It is imperative that all calls into the VM are handled via the call_VM macros.
duke@435 1598 // They make sure that the stack linkage is setup correctly. call_VM's correspond
duke@435 1599 // to ENTRY/ENTRY_X entry points while call_VM_leaf's correspond to LEAF entry points.
duke@435 1600
never@739 1601
never@739 1602 void call_VM(Register oop_result,
never@739 1603 address entry_point,
never@739 1604 bool check_exceptions = true);
never@739 1605 void call_VM(Register oop_result,
never@739 1606 address entry_point,
never@739 1607 Register arg_1,
never@739 1608 bool check_exceptions = true);
never@739 1609 void call_VM(Register oop_result,
never@739 1610 address entry_point,
never@739 1611 Register arg_1, Register arg_2,
never@739 1612 bool check_exceptions = true);
never@739 1613 void call_VM(Register oop_result,
never@739 1614 address entry_point,
never@739 1615 Register arg_1, Register arg_2, Register arg_3,
never@739 1616 bool check_exceptions = true);
never@739 1617
never@739 1618 // Overloadings with last_Java_sp
never@739 1619 void call_VM(Register oop_result,
never@739 1620 Register last_java_sp,
never@739 1621 address entry_point,
never@739 1622 int number_of_arguments = 0,
never@739 1623 bool check_exceptions = true);
never@739 1624 void call_VM(Register oop_result,
never@739 1625 Register last_java_sp,
never@739 1626 address entry_point,
never@739 1627 Register arg_1, bool
never@739 1628 check_exceptions = true);
never@739 1629 void call_VM(Register oop_result,
never@739 1630 Register last_java_sp,
never@739 1631 address entry_point,
never@739 1632 Register arg_1, Register arg_2,
never@739 1633 bool check_exceptions = true);
never@739 1634 void call_VM(Register oop_result,
never@739 1635 Register last_java_sp,
never@739 1636 address entry_point,
never@739 1637 Register arg_1, Register arg_2, Register arg_3,
never@739 1638 bool check_exceptions = true);
never@739 1639
never@739 1640 void call_VM_leaf(address entry_point,
never@739 1641 int number_of_arguments = 0);
never@739 1642 void call_VM_leaf(address entry_point,
never@739 1643 Register arg_1);
never@739 1644 void call_VM_leaf(address entry_point,
never@739 1645 Register arg_1, Register arg_2);
never@739 1646 void call_VM_leaf(address entry_point,
never@739 1647 Register arg_1, Register arg_2, Register arg_3);
duke@435 1648
duke@435 1649 // last Java Frame (fills frame anchor)
never@739 1650 void set_last_Java_frame(Register thread,
never@739 1651 Register last_java_sp,
never@739 1652 Register last_java_fp,
never@739 1653 address last_java_pc);
never@739 1654
never@739 1655 // thread in the default location (r15_thread on 64bit)
never@739 1656 void set_last_Java_frame(Register last_java_sp,
never@739 1657 Register last_java_fp,
never@739 1658 address last_java_pc);
never@739 1659
duke@435 1660 void reset_last_Java_frame(Register thread, bool clear_fp, bool clear_pc);
duke@435 1661
never@739 1662 // thread in the default location (r15_thread on 64bit)
never@739 1663 void reset_last_Java_frame(bool clear_fp, bool clear_pc);
never@739 1664
duke@435 1665 // Stores
duke@435 1666 void store_check(Register obj); // store check for obj - register is destroyed afterwards
duke@435 1667 void store_check(Register obj, Address dst); // same as above, dst is exact store location (reg. is destroyed)
duke@435 1668
johnc@2781 1669 #ifndef SERIALGC
johnc@2781 1670
apetrusenko@797 1671 void g1_write_barrier_pre(Register obj,
johnc@2781 1672 Register pre_val,
apetrusenko@797 1673 Register thread,
apetrusenko@797 1674 Register tmp,
johnc@2781 1675 bool tosca_live,
johnc@2781 1676 bool expand_call);
johnc@2781 1677
apetrusenko@797 1678 void g1_write_barrier_post(Register store_addr,
apetrusenko@797 1679 Register new_val,
apetrusenko@797 1680 Register thread,
apetrusenko@797 1681 Register tmp,
apetrusenko@797 1682 Register tmp2);
ysr@777 1683
johnc@2781 1684 #endif // SERIALGC
ysr@777 1685
duke@435 1686 // split store_check(Register obj) to enhance instruction interleaving
duke@435 1687 void store_check_part_1(Register obj);
duke@435 1688 void store_check_part_2(Register obj);
duke@435 1689
duke@435 1690 // C 'boolean' to Java boolean: x == 0 ? 0 : 1
duke@435 1691 void c2bool(Register x);
duke@435 1692
duke@435 1693 // C++ bool manipulation
duke@435 1694
duke@435 1695 void movbool(Register dst, Address src);
duke@435 1696 void movbool(Address dst, bool boolconst);
duke@435 1697 void movbool(Address dst, Register src);
duke@435 1698 void testbool(Register dst);
duke@435 1699
never@739 1700 // oop manipulations
never@739 1701 void load_klass(Register dst, Register src);
never@739 1702 void store_klass(Register dst, Register src);
never@739 1703
twisti@2201 1704 void load_heap_oop(Register dst, Address src);
twisti@2201 1705 void store_heap_oop(Address dst, Register src);
twisti@2201 1706
twisti@2201 1707 // Used for storing NULL. All other oop constants should be
twisti@2201 1708 // stored using routines that take a jobject.
twisti@2201 1709 void store_heap_oop_null(Address dst);
twisti@2201 1710
never@739 1711 void load_prototype_header(Register dst, Register src);
never@739 1712
never@739 1713 #ifdef _LP64
never@739 1714 void store_klass_gap(Register dst, Register src);
never@739 1715
johnc@1482 1716 // This dummy is to prevent a call to store_heap_oop from
johnc@1482 1717 // converting a zero (like NULL) into a Register by giving
johnc@1482 1718 // the compiler two choices it can't resolve
johnc@1482 1719
johnc@1482 1720 void store_heap_oop(Address dst, void* dummy);
johnc@1482 1721
never@739 1722 void encode_heap_oop(Register r);
never@739 1723 void decode_heap_oop(Register r);
never@739 1724 void encode_heap_oop_not_null(Register r);
never@739 1725 void decode_heap_oop_not_null(Register r);
never@739 1726 void encode_heap_oop_not_null(Register dst, Register src);
never@739 1727 void decode_heap_oop_not_null(Register dst, Register src);
never@739 1728
never@739 1729 void set_narrow_oop(Register dst, jobject obj);
kvn@1077 1730 void set_narrow_oop(Address dst, jobject obj);
kvn@1077 1731 void cmp_narrow_oop(Register dst, jobject obj);
kvn@1077 1732 void cmp_narrow_oop(Address dst, jobject obj);
never@739 1733
never@739 1734 // if heap base register is used - reinit it with the correct value
never@739 1735 void reinit_heapbase();
kvn@2039 1736
kvn@2039 1737 DEBUG_ONLY(void verify_heapbase(const char* msg);)
kvn@2039 1738
never@739 1739 #endif // _LP64
never@739 1740
never@739 1741 // Int division/remainder for Java
duke@435 1742 // (as idivl, but checks for special case as described in JVM spec.)
duke@435 1743 // returns idivl instruction offset for implicit exception handling
duke@435 1744 int corrected_idivl(Register reg);
duke@435 1745
never@739 1746 // Long division/remainder for Java
never@739 1747 // (as idivq, but checks for special case as described in JVM spec.)
never@739 1748 // returns idivq instruction offset for implicit exception handling
never@739 1749 int corrected_idivq(Register reg);
never@739 1750
duke@435 1751 void int3();
duke@435 1752
never@739 1753 // Long operation macros for a 32bit cpu
duke@435 1754 // Long negation for Java
duke@435 1755 void lneg(Register hi, Register lo);
duke@435 1756
duke@435 1757 // Long multiplication for Java
never@739 1758 // (destroys contents of eax, ebx, ecx and edx)
duke@435 1759 void lmul(int x_rsp_offset, int y_rsp_offset); // rdx:rax = x * y
duke@435 1760
duke@435 1761 // Long shifts for Java
duke@435 1762 // (semantics as described in JVM spec.)
duke@435 1763 void lshl(Register hi, Register lo); // hi:lo << (rcx & 0x3f)
duke@435 1764 void lshr(Register hi, Register lo, bool sign_extension = false); // hi:lo >> (rcx & 0x3f)
duke@435 1765
duke@435 1766 // Long compare for Java
duke@435 1767 // (semantics as described in JVM spec.)
duke@435 1768 void lcmp2int(Register x_hi, Register x_lo, Register y_hi, Register y_lo); // x_hi = lcmp(x, y)
duke@435 1769
never@739 1770
never@739 1771 // misc
never@739 1772
never@739 1773 // Sign extension
never@739 1774 void sign_extend_short(Register reg);
never@739 1775 void sign_extend_byte(Register reg);
never@739 1776
never@739 1777 // Division by power of 2, rounding towards 0
never@739 1778 void division_with_shift(Register reg, int shift_value);
never@739 1779
duke@435 1780 // Compares the top-most stack entries on the FPU stack and sets the eflags as follows:
duke@435 1781 //
duke@435 1782 // CF (corresponds to C0) if x < y
duke@435 1783 // PF (corresponds to C2) if unordered
duke@435 1784 // ZF (corresponds to C3) if x = y
duke@435 1785 //
duke@435 1786 // The arguments are in reversed order on the stack (i.e., top of stack is first argument).
duke@435 1787 // tmp is a temporary register, if none is available use noreg (only matters for non-P6 code)
duke@435 1788 void fcmp(Register tmp);
duke@435 1789 // Variant of the above which allows y to be further down the stack
duke@435 1790 // and which only pops x and y if specified. If pop_right is
duke@435 1791 // specified then pop_left must also be specified.
duke@435 1792 void fcmp(Register tmp, int index, bool pop_left, bool pop_right);
duke@435 1793
duke@435 1794 // Floating-point comparison for Java
duke@435 1795 // Compares the top-most stack entries on the FPU stack and stores the result in dst.
duke@435 1796 // The arguments are in reversed order on the stack (i.e., top of stack is first argument).
duke@435 1797 // (semantics as described in JVM spec.)
duke@435 1798 void fcmp2int(Register dst, bool unordered_is_less);
duke@435 1799 // Variant of the above which allows y to be further down the stack
duke@435 1800 // and which only pops x and y if specified. If pop_right is
duke@435 1801 // specified then pop_left must also be specified.
duke@435 1802 void fcmp2int(Register dst, bool unordered_is_less, int index, bool pop_left, bool pop_right);
duke@435 1803
duke@435 1804 // Floating-point remainder for Java (ST0 = ST0 fremr ST1, ST1 is empty afterwards)
duke@435 1805 // tmp is a temporary register, if none is available use noreg
duke@435 1806 void fremr(Register tmp);
duke@435 1807
duke@435 1808
duke@435 1809 // same as fcmp2int, but using SSE2
duke@435 1810 void cmpss2int(XMMRegister opr1, XMMRegister opr2, Register dst, bool unordered_is_less);
duke@435 1811 void cmpsd2int(XMMRegister opr1, XMMRegister opr2, Register dst, bool unordered_is_less);
duke@435 1812
duke@435 1813 // Inlined sin/cos generator for Java; must not use CPU instruction
duke@435 1814 // directly on Intel as it does not have high enough precision
duke@435 1815 // outside of the range [-pi/4, pi/4]. Extra argument indicate the
duke@435 1816 // number of FPU stack slots in use; all but the topmost will
duke@435 1817 // require saving if a slow case is necessary. Assumes argument is
duke@435 1818 // on FP TOS; result is on FP TOS. No cpu registers are changed by
duke@435 1819 // this code.
duke@435 1820 void trigfunc(char trig, int num_fpu_regs_in_use = 1);
duke@435 1821
duke@435 1822 // branch to L if FPU flag C2 is set/not set
duke@435 1823 // tmp is a temporary register, if none is available use noreg
duke@435 1824 void jC2 (Register tmp, Label& L);
duke@435 1825 void jnC2(Register tmp, Label& L);
duke@435 1826
duke@435 1827 // Pop ST (ffree & fincstp combined)
duke@435 1828 void fpop();
duke@435 1829
duke@435 1830 // pushes double TOS element of FPU stack on CPU stack; pops from FPU stack
duke@435 1831 void push_fTOS();
duke@435 1832
duke@435 1833 // pops double TOS element from CPU stack and pushes on FPU stack
duke@435 1834 void pop_fTOS();
duke@435 1835
duke@435 1836 void empty_FPU_stack();
duke@435 1837
duke@435 1838 void push_IU_state();
duke@435 1839 void pop_IU_state();
duke@435 1840
duke@435 1841 void push_FPU_state();
duke@435 1842 void pop_FPU_state();
duke@435 1843
duke@435 1844 void push_CPU_state();
duke@435 1845 void pop_CPU_state();
duke@435 1846
duke@435 1847 // Round up to a power of two
duke@435 1848 void round_to(Register reg, int modulus);
duke@435 1849
duke@435 1850 // Callee saved registers handling
duke@435 1851 void push_callee_saved_registers();
duke@435 1852 void pop_callee_saved_registers();
duke@435 1853
duke@435 1854 // allocation
duke@435 1855 void eden_allocate(
duke@435 1856 Register obj, // result: pointer to object after successful allocation
duke@435 1857 Register var_size_in_bytes, // object size in bytes if unknown at compile time; invalid otherwise
duke@435 1858 int con_size_in_bytes, // object size in bytes if known at compile time
duke@435 1859 Register t1, // temp register
duke@435 1860 Label& slow_case // continuation point if fast allocation fails
duke@435 1861 );
duke@435 1862 void tlab_allocate(
duke@435 1863 Register obj, // result: pointer to object after successful allocation
duke@435 1864 Register var_size_in_bytes, // object size in bytes if unknown at compile time; invalid otherwise
duke@435 1865 int con_size_in_bytes, // object size in bytes if known at compile time
duke@435 1866 Register t1, // temp register
duke@435 1867 Register t2, // temp register
duke@435 1868 Label& slow_case // continuation point if fast allocation fails
duke@435 1869 );
phh@2423 1870 Register tlab_refill(Label& retry_tlab, Label& try_eden, Label& slow_case); // returns TLS address
phh@2423 1871 void incr_allocated_bytes(Register thread,
phh@2423 1872 Register var_size_in_bytes, int con_size_in_bytes,
phh@2423 1873 Register t1 = noreg);
duke@435 1874
jrose@1058 1875 // interface method calling
jrose@1058 1876 void lookup_interface_method(Register recv_klass,
jrose@1058 1877 Register intf_klass,
jrose@1100 1878 RegisterOrConstant itable_index,
jrose@1058 1879 Register method_result,
jrose@1058 1880 Register scan_temp,
jrose@1058 1881 Label& no_such_interface);
jrose@1058 1882
jrose@1079 1883 // Test sub_klass against super_klass, with fast and slow paths.
jrose@1079 1884
jrose@1079 1885 // The fast path produces a tri-state answer: yes / no / maybe-slow.
jrose@1079 1886 // One of the three labels can be NULL, meaning take the fall-through.
jrose@1079 1887 // If super_check_offset is -1, the value is loaded up from super_klass.
jrose@1079 1888 // No registers are killed, except temp_reg.
jrose@1079 1889 void check_klass_subtype_fast_path(Register sub_klass,
jrose@1079 1890 Register super_klass,
jrose@1079 1891 Register temp_reg,
jrose@1079 1892 Label* L_success,
jrose@1079 1893 Label* L_failure,
jrose@1079 1894 Label* L_slow_path,
jrose@1100 1895 RegisterOrConstant super_check_offset = RegisterOrConstant(-1));
jrose@1079 1896
jrose@1079 1897 // The rest of the type check; must be wired to a corresponding fast path.
jrose@1079 1898 // It does not repeat the fast path logic, so don't use it standalone.
jrose@1079 1899 // The temp_reg and temp2_reg can be noreg, if no temps are available.
jrose@1079 1900 // Updates the sub's secondary super cache as necessary.
jrose@1079 1901 // If set_cond_codes, condition codes will be Z on success, NZ on failure.
jrose@1079 1902 void check_klass_subtype_slow_path(Register sub_klass,
jrose@1079 1903 Register super_klass,
jrose@1079 1904 Register temp_reg,
jrose@1079 1905 Register temp2_reg,
jrose@1079 1906 Label* L_success,
jrose@1079 1907 Label* L_failure,
jrose@1079 1908 bool set_cond_codes = false);
jrose@1079 1909
jrose@1079 1910 // Simplified, combined version, good for typical uses.
jrose@1079 1911 // Falls through on failure.
jrose@1079 1912 void check_klass_subtype(Register sub_klass,
jrose@1079 1913 Register super_klass,
jrose@1079 1914 Register temp_reg,
jrose@1079 1915 Label& L_success);
jrose@1079 1916
jrose@1145 1917 // method handles (JSR 292)
jrose@1145 1918 void check_method_handle_type(Register mtype_reg, Register mh_reg,
jrose@1145 1919 Register temp_reg,
jrose@1145 1920 Label& wrong_method_type);
jrose@1145 1921 void load_method_handle_vmslots(Register vmslots_reg, Register mh_reg,
jrose@1145 1922 Register temp_reg);
jrose@1145 1923 void jump_to_method_handle_entry(Register mh_reg, Register temp_reg);
jrose@1145 1924 Address argument_address(RegisterOrConstant arg_slot, int extra_slot_offset = 0);
jrose@1145 1925
jrose@1145 1926
duke@435 1927 //----
duke@435 1928 void set_word_if_not_zero(Register reg); // sets reg to 1 if not zero, otherwise 0
duke@435 1929
duke@435 1930 // Debugging
never@739 1931
never@739 1932 // only if +VerifyOops
never@739 1933 void verify_oop(Register reg, const char* s = "broken oop");
duke@435 1934 void verify_oop_addr(Address addr, const char * s = "broken oop addr");
duke@435 1935
never@739 1936 // only if +VerifyFPU
never@739 1937 void verify_FPU(int stack_depth, const char* s = "illegal FPU state");
never@739 1938
never@739 1939 // prints msg, dumps registers and stops execution
never@739 1940 void stop(const char* msg);
never@739 1941
never@739 1942 // prints msg and continues
never@739 1943 void warn(const char* msg);
never@739 1944
never@739 1945 static void debug32(int rdi, int rsi, int rbp, int rsp, int rbx, int rdx, int rcx, int rax, int eip, char* msg);
never@739 1946 static void debug64(char* msg, int64_t pc, int64_t regs[]);
never@739 1947
duke@435 1948 void os_breakpoint();
never@739 1949
duke@435 1950 void untested() { stop("untested"); }
never@739 1951
twisti@2201 1952 void unimplemented(const char* what = "") { char* b = new char[1024]; jio_snprintf(b, 1024, "unimplemented: %s", what); stop(b); }
never@739 1953
duke@435 1954 void should_not_reach_here() { stop("should not reach here"); }
never@739 1955
duke@435 1956 void print_CPU_state();
duke@435 1957
duke@435 1958 // Stack overflow checking
duke@435 1959 void bang_stack_with_offset(int offset) {
duke@435 1960 // stack grows down, caller passes positive offset
duke@435 1961 assert(offset > 0, "must bang with negative offset");
duke@435 1962 movl(Address(rsp, (-offset)), rax);
duke@435 1963 }
duke@435 1964
duke@435 1965 // Writes to stack successive pages until offset reached to check for
duke@435 1966 // stack overflow + shadow pages. Also, clobbers tmp
duke@435 1967 void bang_stack_size(Register size, Register tmp);
duke@435 1968
jrose@1100 1969 virtual RegisterOrConstant delayed_value_impl(intptr_t* delayed_value_addr,
jrose@1100 1970 Register tmp,
jrose@1100 1971 int offset);
jrose@1057 1972
duke@435 1973 // Support for serializing memory accesses between threads
duke@435 1974 void serialize_memory(Register thread, Register tmp);
duke@435 1975
duke@435 1976 void verify_tlab();
duke@435 1977
duke@435 1978 // Biased locking support
duke@435 1979 // lock_reg and obj_reg must be loaded up with the appropriate values.
duke@435 1980 // swap_reg must be rax, and is killed.
duke@435 1981 // tmp_reg is optional. If it is supplied (i.e., != noreg) it will
duke@435 1982 // be killed; if not supplied, push/pop will be used internally to
duke@435 1983 // allocate a temporary (inefficient, avoid if possible).
duke@435 1984 // Optional slow case is for implementations (interpreter and C1) which branch to
duke@435 1985 // slow case directly. Leaves condition codes set for C2's Fast_Lock node.
duke@435 1986 // Returns offset of first potentially-faulting instruction for null
duke@435 1987 // check info (currently consumed only by C1). If
duke@435 1988 // swap_reg_contains_mark is true then returns -1 as it is assumed
duke@435 1989 // the calling code has already passed any potential faults.
kvn@855 1990 int biased_locking_enter(Register lock_reg, Register obj_reg,
kvn@855 1991 Register swap_reg, Register tmp_reg,
duke@435 1992 bool swap_reg_contains_mark,
duke@435 1993 Label& done, Label* slow_case = NULL,
duke@435 1994 BiasedLockingCounters* counters = NULL);
duke@435 1995 void biased_locking_exit (Register obj_reg, Register temp_reg, Label& done);
duke@435 1996
duke@435 1997
duke@435 1998 Condition negate_condition(Condition cond);
duke@435 1999
duke@435 2000 // Instructions that use AddressLiteral operands. These instruction can handle 32bit/64bit
duke@435 2001 // operands. In general the names are modified to avoid hiding the instruction in Assembler
duke@435 2002 // so that we don't need to implement all the varieties in the Assembler with trivial wrappers
duke@435 2003 // here in MacroAssembler. The major exception to this rule is call
duke@435 2004
duke@435 2005 // Arithmetics
duke@435 2006
never@739 2007
never@739 2008 void addptr(Address dst, int32_t src) { LP64_ONLY(addq(dst, src)) NOT_LP64(addl(dst, src)) ; }
never@739 2009 void addptr(Address dst, Register src);
never@739 2010
never@739 2011 void addptr(Register dst, Address src) { LP64_ONLY(addq(dst, src)) NOT_LP64(addl(dst, src)); }
never@739 2012 void addptr(Register dst, int32_t src);
never@739 2013 void addptr(Register dst, Register src);
never@739 2014
never@739 2015 void andptr(Register dst, int32_t src);
never@739 2016 void andptr(Register src1, Register src2) { LP64_ONLY(andq(src1, src2)) NOT_LP64(andl(src1, src2)) ; }
never@739 2017
never@739 2018 void cmp8(AddressLiteral src1, int imm);
never@739 2019
never@739 2020 // renamed to drag out the casting of address to int32_t/intptr_t
duke@435 2021 void cmp32(Register src1, int32_t imm);
duke@435 2022
duke@435 2023 void cmp32(AddressLiteral src1, int32_t imm);
duke@435 2024 // compare reg - mem, or reg - &mem
duke@435 2025 void cmp32(Register src1, AddressLiteral src2);
duke@435 2026
duke@435 2027 void cmp32(Register src1, Address src2);
duke@435 2028
never@739 2029 #ifndef _LP64
never@739 2030 void cmpoop(Address dst, jobject obj);
never@739 2031 void cmpoop(Register dst, jobject obj);
never@739 2032 #endif // _LP64
never@739 2033
duke@435 2034 // NOTE src2 must be the lval. This is NOT an mem-mem compare
duke@435 2035 void cmpptr(Address src1, AddressLiteral src2);
duke@435 2036
duke@435 2037 void cmpptr(Register src1, AddressLiteral src2);
duke@435 2038
never@739 2039 void cmpptr(Register src1, Register src2) { LP64_ONLY(cmpq(src1, src2)) NOT_LP64(cmpl(src1, src2)) ; }
never@739 2040 void cmpptr(Register src1, Address src2) { LP64_ONLY(cmpq(src1, src2)) NOT_LP64(cmpl(src1, src2)) ; }
never@739 2041 // void cmpptr(Address src1, Register src2) { LP64_ONLY(cmpq(src1, src2)) NOT_LP64(cmpl(src1, src2)) ; }
never@739 2042
never@739 2043 void cmpptr(Register src1, int32_t src2) { LP64_ONLY(cmpq(src1, src2)) NOT_LP64(cmpl(src1, src2)) ; }
never@739 2044 void cmpptr(Address src1, int32_t src2) { LP64_ONLY(cmpq(src1, src2)) NOT_LP64(cmpl(src1, src2)) ; }
never@739 2045
never@739 2046 // cmp64 to avoild hiding cmpq
never@739 2047 void cmp64(Register src1, AddressLiteral src);
never@739 2048
never@739 2049 void cmpxchgptr(Register reg, Address adr);
never@739 2050
never@739 2051 void locked_cmpxchgptr(Register reg, AddressLiteral adr);
never@739 2052
never@739 2053
never@739 2054 void imulptr(Register dst, Register src) { LP64_ONLY(imulq(dst, src)) NOT_LP64(imull(dst, src)); }
never@739 2055
never@739 2056
never@739 2057 void negptr(Register dst) { LP64_ONLY(negq(dst)) NOT_LP64(negl(dst)); }
never@739 2058
never@739 2059 void notptr(Register dst) { LP64_ONLY(notq(dst)) NOT_LP64(notl(dst)); }
never@739 2060
never@739 2061 void shlptr(Register dst, int32_t shift);
never@739 2062 void shlptr(Register dst) { LP64_ONLY(shlq(dst)) NOT_LP64(shll(dst)); }
never@739 2063
never@739 2064 void shrptr(Register dst, int32_t shift);
never@739 2065 void shrptr(Register dst) { LP64_ONLY(shrq(dst)) NOT_LP64(shrl(dst)); }
never@739 2066
never@739 2067 void sarptr(Register dst) { LP64_ONLY(sarq(dst)) NOT_LP64(sarl(dst)); }
never@739 2068 void sarptr(Register dst, int32_t src) { LP64_ONLY(sarq(dst, src)) NOT_LP64(sarl(dst, src)); }
never@739 2069
never@739 2070 void subptr(Address dst, int32_t src) { LP64_ONLY(subq(dst, src)) NOT_LP64(subl(dst, src)); }
never@739 2071
never@739 2072 void subptr(Register dst, Address src) { LP64_ONLY(subq(dst, src)) NOT_LP64(subl(dst, src)); }
never@739 2073 void subptr(Register dst, int32_t src);
never@739 2074 void subptr(Register dst, Register src);
never@739 2075
never@739 2076
never@739 2077 void sbbptr(Address dst, int32_t src) { LP64_ONLY(sbbq(dst, src)) NOT_LP64(sbbl(dst, src)); }
never@739 2078 void sbbptr(Register dst, int32_t src) { LP64_ONLY(sbbq(dst, src)) NOT_LP64(sbbl(dst, src)); }
never@739 2079
never@739 2080 void xchgptr(Register src1, Register src2) { LP64_ONLY(xchgq(src1, src2)) NOT_LP64(xchgl(src1, src2)) ; }
never@739 2081 void xchgptr(Register src1, Address src2) { LP64_ONLY(xchgq(src1, src2)) NOT_LP64(xchgl(src1, src2)) ; }
never@739 2082
never@739 2083 void xaddptr(Address src1, Register src2) { LP64_ONLY(xaddq(src1, src2)) NOT_LP64(xaddl(src1, src2)) ; }
never@739 2084
never@739 2085
duke@435 2086
duke@435 2087 // Helper functions for statistics gathering.
duke@435 2088 // Conditionally (atomically, on MPs) increments passed counter address, preserving condition codes.
duke@435 2089 void cond_inc32(Condition cond, AddressLiteral counter_addr);
duke@435 2090 // Unconditional atomic increment.
duke@435 2091 void atomic_incl(AddressLiteral counter_addr);
duke@435 2092
duke@435 2093 void lea(Register dst, AddressLiteral adr);
duke@435 2094 void lea(Address dst, AddressLiteral adr);
never@739 2095 void lea(Register dst, Address adr) { Assembler::lea(dst, adr); }
never@739 2096
never@739 2097 void leal32(Register dst, Address src) { leal(dst, src); }
never@739 2098
never@739 2099 void test32(Register src1, AddressLiteral src2);
never@739 2100
never@739 2101 void orptr(Register dst, Address src) { LP64_ONLY(orq(dst, src)) NOT_LP64(orl(dst, src)); }
never@739 2102 void orptr(Register dst, Register src) { LP64_ONLY(orq(dst, src)) NOT_LP64(orl(dst, src)); }
never@739 2103 void orptr(Register dst, int32_t src) { LP64_ONLY(orq(dst, src)) NOT_LP64(orl(dst, src)); }
never@739 2104
never@739 2105 void testptr(Register src, int32_t imm32) { LP64_ONLY(testq(src, imm32)) NOT_LP64(testl(src, imm32)); }
never@739 2106 void testptr(Register src1, Register src2);
never@739 2107
never@739 2108 void xorptr(Register dst, Register src) { LP64_ONLY(xorq(dst, src)) NOT_LP64(xorl(dst, src)); }
never@739 2109 void xorptr(Register dst, Address src) { LP64_ONLY(xorq(dst, src)) NOT_LP64(xorl(dst, src)); }
duke@435 2110
duke@435 2111 // Calls
duke@435 2112
duke@435 2113 void call(Label& L, relocInfo::relocType rtype);
duke@435 2114 void call(Register entry);
duke@435 2115
duke@435 2116 // NOTE: this call tranfers to the effective address of entry NOT
duke@435 2117 // the address contained by entry. This is because this is more natural
duke@435 2118 // for jumps/calls.
duke@435 2119 void call(AddressLiteral entry);
duke@435 2120
duke@435 2121 // Jumps
duke@435 2122
duke@435 2123 // NOTE: these jumps tranfer to the effective address of dst NOT
duke@435 2124 // the address contained by dst. This is because this is more natural
duke@435 2125 // for jumps/calls.
duke@435 2126 void jump(AddressLiteral dst);
duke@435 2127 void jump_cc(Condition cc, AddressLiteral dst);
duke@435 2128
duke@435 2129 // 32bit can do a case table jump in one instruction but we no longer allow the base
duke@435 2130 // to be installed in the Address class. This jump will tranfers to the address
duke@435 2131 // contained in the location described by entry (not the address of entry)
duke@435 2132 void jump(ArrayAddress entry);
duke@435 2133
duke@435 2134 // Floating
duke@435 2135
duke@435 2136 void andpd(XMMRegister dst, Address src) { Assembler::andpd(dst, src); }
duke@435 2137 void andpd(XMMRegister dst, AddressLiteral src);
duke@435 2138
duke@435 2139 void comiss(XMMRegister dst, Address src) { Assembler::comiss(dst, src); }
duke@435 2140 void comiss(XMMRegister dst, AddressLiteral src);
duke@435 2141
duke@435 2142 void comisd(XMMRegister dst, Address src) { Assembler::comisd(dst, src); }
duke@435 2143 void comisd(XMMRegister dst, AddressLiteral src);
duke@435 2144
twisti@2350 2145 void fadd_s(Address src) { Assembler::fadd_s(src); }
twisti@2350 2146 void fadd_s(AddressLiteral src) { Assembler::fadd_s(as_Address(src)); }
twisti@2350 2147
duke@435 2148 void fldcw(Address src) { Assembler::fldcw(src); }
duke@435 2149 void fldcw(AddressLiteral src);
duke@435 2150
duke@435 2151 void fld_s(int index) { Assembler::fld_s(index); }
duke@435 2152 void fld_s(Address src) { Assembler::fld_s(src); }
duke@435 2153 void fld_s(AddressLiteral src);
duke@435 2154
duke@435 2155 void fld_d(Address src) { Assembler::fld_d(src); }
duke@435 2156 void fld_d(AddressLiteral src);
duke@435 2157
duke@435 2158 void fld_x(Address src) { Assembler::fld_x(src); }
duke@435 2159 void fld_x(AddressLiteral src);
duke@435 2160
twisti@2350 2161 void fmul_s(Address src) { Assembler::fmul_s(src); }
twisti@2350 2162 void fmul_s(AddressLiteral src) { Assembler::fmul_s(as_Address(src)); }
twisti@2350 2163
duke@435 2164 void ldmxcsr(Address src) { Assembler::ldmxcsr(src); }
duke@435 2165 void ldmxcsr(AddressLiteral src);
duke@435 2166
never@739 2167 private:
never@739 2168 // these are private because users should be doing movflt/movdbl
never@739 2169
duke@435 2170 void movss(Address dst, XMMRegister src) { Assembler::movss(dst, src); }
duke@435 2171 void movss(XMMRegister dst, XMMRegister src) { Assembler::movss(dst, src); }
duke@435 2172 void movss(XMMRegister dst, Address src) { Assembler::movss(dst, src); }
duke@435 2173 void movss(XMMRegister dst, AddressLiteral src);
duke@435 2174
never@739 2175 void movlpd(XMMRegister dst, Address src) {Assembler::movlpd(dst, src); }
never@739 2176 void movlpd(XMMRegister dst, AddressLiteral src);
never@739 2177
never@739 2178 public:
never@739 2179
twisti@2350 2180 void addsd(XMMRegister dst, XMMRegister src) { Assembler::addsd(dst, src); }
twisti@2350 2181 void addsd(XMMRegister dst, Address src) { Assembler::addsd(dst, src); }
twisti@2350 2182 void addsd(XMMRegister dst, AddressLiteral src) { Assembler::addsd(dst, as_Address(src)); }
twisti@2350 2183
twisti@2350 2184 void addss(XMMRegister dst, XMMRegister src) { Assembler::addss(dst, src); }
twisti@2350 2185 void addss(XMMRegister dst, Address src) { Assembler::addss(dst, src); }
twisti@2350 2186 void addss(XMMRegister dst, AddressLiteral src) { Assembler::addss(dst, as_Address(src)); }
twisti@2350 2187
twisti@2350 2188 void divsd(XMMRegister dst, XMMRegister src) { Assembler::divsd(dst, src); }
twisti@2350 2189 void divsd(XMMRegister dst, Address src) { Assembler::divsd(dst, src); }
twisti@2350 2190 void divsd(XMMRegister dst, AddressLiteral src) { Assembler::divsd(dst, as_Address(src)); }
twisti@2350 2191
twisti@2350 2192 void divss(XMMRegister dst, XMMRegister src) { Assembler::divss(dst, src); }
twisti@2350 2193 void divss(XMMRegister dst, Address src) { Assembler::divss(dst, src); }
twisti@2350 2194 void divss(XMMRegister dst, AddressLiteral src) { Assembler::divss(dst, as_Address(src)); }
twisti@2350 2195
phh@2423 2196 void movsd(XMMRegister dst, XMMRegister src) { Assembler::movsd(dst, src); }
phh@2423 2197 void movsd(Address dst, XMMRegister src) { Assembler::movsd(dst, src); }
phh@2423 2198 void movsd(XMMRegister dst, Address src) { Assembler::movsd(dst, src); }
twisti@2350 2199 void movsd(XMMRegister dst, AddressLiteral src) { Assembler::movsd(dst, as_Address(src)); }
twisti@2350 2200
twisti@2350 2201 void mulsd(XMMRegister dst, XMMRegister src) { Assembler::mulsd(dst, src); }
twisti@2350 2202 void mulsd(XMMRegister dst, Address src) { Assembler::mulsd(dst, src); }
twisti@2350 2203 void mulsd(XMMRegister dst, AddressLiteral src) { Assembler::mulsd(dst, as_Address(src)); }
twisti@2350 2204
twisti@2350 2205 void mulss(XMMRegister dst, XMMRegister src) { Assembler::mulss(dst, src); }
twisti@2350 2206 void mulss(XMMRegister dst, Address src) { Assembler::mulss(dst, src); }
twisti@2350 2207 void mulss(XMMRegister dst, AddressLiteral src) { Assembler::mulss(dst, as_Address(src)); }
twisti@2350 2208
twisti@2350 2209 void sqrtsd(XMMRegister dst, XMMRegister src) { Assembler::sqrtsd(dst, src); }
twisti@2350 2210 void sqrtsd(XMMRegister dst, Address src) { Assembler::sqrtsd(dst, src); }
twisti@2350 2211 void sqrtsd(XMMRegister dst, AddressLiteral src) { Assembler::sqrtsd(dst, as_Address(src)); }
twisti@2350 2212
twisti@2350 2213 void sqrtss(XMMRegister dst, XMMRegister src) { Assembler::sqrtss(dst, src); }
twisti@2350 2214 void sqrtss(XMMRegister dst, Address src) { Assembler::sqrtss(dst, src); }
twisti@2350 2215 void sqrtss(XMMRegister dst, AddressLiteral src) { Assembler::sqrtss(dst, as_Address(src)); }
twisti@2350 2216
twisti@2350 2217 void subsd(XMMRegister dst, XMMRegister src) { Assembler::subsd(dst, src); }
twisti@2350 2218 void subsd(XMMRegister dst, Address src) { Assembler::subsd(dst, src); }
twisti@2350 2219 void subsd(XMMRegister dst, AddressLiteral src) { Assembler::subsd(dst, as_Address(src)); }
twisti@2350 2220
twisti@2350 2221 void subss(XMMRegister dst, XMMRegister src) { Assembler::subss(dst, src); }
twisti@2350 2222 void subss(XMMRegister dst, Address src) { Assembler::subss(dst, src); }
twisti@2350 2223 void subss(XMMRegister dst, AddressLiteral src) { Assembler::subss(dst, as_Address(src)); }
duke@435 2224
duke@435 2225 void ucomiss(XMMRegister dst, XMMRegister src) { Assembler::ucomiss(dst, src); }
duke@435 2226 void ucomiss(XMMRegister dst, Address src) { Assembler::ucomiss(dst, src); }
duke@435 2227 void ucomiss(XMMRegister dst, AddressLiteral src);
duke@435 2228
duke@435 2229 void ucomisd(XMMRegister dst, XMMRegister src) { Assembler::ucomisd(dst, src); }
duke@435 2230 void ucomisd(XMMRegister dst, Address src) { Assembler::ucomisd(dst, src); }
duke@435 2231 void ucomisd(XMMRegister dst, AddressLiteral src);
duke@435 2232
duke@435 2233 // Bitwise Logical XOR of Packed Double-Precision Floating-Point Values
duke@435 2234 void xorpd(XMMRegister dst, XMMRegister src) { Assembler::xorpd(dst, src); }
duke@435 2235 void xorpd(XMMRegister dst, Address src) { Assembler::xorpd(dst, src); }
duke@435 2236 void xorpd(XMMRegister dst, AddressLiteral src);
duke@435 2237
duke@435 2238 // Bitwise Logical XOR of Packed Single-Precision Floating-Point Values
duke@435 2239 void xorps(XMMRegister dst, XMMRegister src) { Assembler::xorps(dst, src); }
duke@435 2240 void xorps(XMMRegister dst, Address src) { Assembler::xorps(dst, src); }
duke@435 2241 void xorps(XMMRegister dst, AddressLiteral src);
duke@435 2242
duke@435 2243 // Data
duke@435 2244
never@739 2245 void cmov(Condition cc, Register dst, Register src) { LP64_ONLY(cmovq(cc, dst, src)) NOT_LP64(cmovl(cc, dst, src)); }
never@739 2246
never@739 2247 void cmovptr(Condition cc, Register dst, Address src) { LP64_ONLY(cmovq(cc, dst, src)) NOT_LP64(cmovl(cc, dst, src)); }
never@739 2248 void cmovptr(Condition cc, Register dst, Register src) { LP64_ONLY(cmovq(cc, dst, src)) NOT_LP64(cmovl(cc, dst, src)); }
never@739 2249
duke@435 2250 void movoop(Register dst, jobject obj);
duke@435 2251 void movoop(Address dst, jobject obj);
duke@435 2252
duke@435 2253 void movptr(ArrayAddress dst, Register src);
duke@435 2254 // can this do an lea?
duke@435 2255 void movptr(Register dst, ArrayAddress src);
duke@435 2256
never@739 2257 void movptr(Register dst, Address src);
never@739 2258
duke@435 2259 void movptr(Register dst, AddressLiteral src);
duke@435 2260
never@739 2261 void movptr(Register dst, intptr_t src);
never@739 2262 void movptr(Register dst, Register src);
never@739 2263 void movptr(Address dst, intptr_t src);
never@739 2264
never@739 2265 void movptr(Address dst, Register src);
never@739 2266
never@739 2267 #ifdef _LP64
never@739 2268 // Generally the next two are only used for moving NULL
never@739 2269 // Although there are situations in initializing the mark word where
never@739 2270 // they could be used. They are dangerous.
never@739 2271
never@739 2272 // They only exist on LP64 so that int32_t and intptr_t are not the same
never@739 2273 // and we have ambiguous declarations.
never@739 2274
never@739 2275 void movptr(Address dst, int32_t imm32);
never@739 2276 void movptr(Register dst, int32_t imm32);
never@739 2277 #endif // _LP64
never@739 2278
duke@435 2279 // to avoid hiding movl
duke@435 2280 void mov32(AddressLiteral dst, Register src);
duke@435 2281 void mov32(Register dst, AddressLiteral src);
never@739 2282
duke@435 2283 // to avoid hiding movb
duke@435 2284 void movbyte(ArrayAddress dst, int src);
duke@435 2285
duke@435 2286 // Can push value or effective address
duke@435 2287 void pushptr(AddressLiteral src);
duke@435 2288
never@739 2289 void pushptr(Address src) { LP64_ONLY(pushq(src)) NOT_LP64(pushl(src)); }
never@739 2290 void popptr(Address src) { LP64_ONLY(popq(src)) NOT_LP64(popl(src)); }
never@739 2291
never@739 2292 void pushoop(jobject obj);
never@739 2293
never@739 2294 // sign extend as need a l to ptr sized element
never@739 2295 void movl2ptr(Register dst, Address src) { LP64_ONLY(movslq(dst, src)) NOT_LP64(movl(dst, src)); }
never@739 2296 void movl2ptr(Register dst, Register src) { LP64_ONLY(movslq(dst, src)) NOT_LP64(if (dst != src) movl(dst, src)); }
never@739 2297
kvn@1421 2298 // IndexOf strings.
kvn@2602 2299 // Small strings are loaded through stack if they cross page boundary.
kvn@1421 2300 void string_indexof(Register str1, Register str2,
kvn@2602 2301 Register cnt1, Register cnt2,
kvn@2602 2302 int int_cnt2, Register result,
kvn@1421 2303 XMMRegister vec, Register tmp);
kvn@1421 2304
kvn@2602 2305 // IndexOf for constant substrings with size >= 8 elements
kvn@2602 2306 // which don't need to be loaded through stack.
kvn@2602 2307 void string_indexofC8(Register str1, Register str2,
kvn@2602 2308 Register cnt1, Register cnt2,
kvn@2602 2309 int int_cnt2, Register result,
kvn@2602 2310 XMMRegister vec, Register tmp);
kvn@2602 2311
kvn@2602 2312 // Smallest code: we don't need to load through stack,
kvn@2602 2313 // check string tail.
kvn@2602 2314
kvn@1421 2315 // Compare strings.
kvn@1421 2316 void string_compare(Register str1, Register str2,
kvn@1421 2317 Register cnt1, Register cnt2, Register result,
never@2569 2318 XMMRegister vec1);
kvn@1421 2319
kvn@1421 2320 // Compare char[] arrays.
kvn@1421 2321 void char_arrays_equals(bool is_array_equ, Register ary1, Register ary2,
kvn@1421 2322 Register limit, Register result, Register chr,
kvn@1421 2323 XMMRegister vec1, XMMRegister vec2);
never@739 2324
never@2118 2325 // Fill primitive arrays
never@2118 2326 void generate_fill(BasicType t, bool aligned,
never@2118 2327 Register to, Register value, Register count,
never@2118 2328 Register rtmp, XMMRegister xtmp);
never@2118 2329
duke@435 2330 #undef VIRTUAL
duke@435 2331
duke@435 2332 };
duke@435 2333
duke@435 2334 /**
duke@435 2335 * class SkipIfEqual:
duke@435 2336 *
duke@435 2337 * Instantiating this class will result in assembly code being output that will
duke@435 2338 * jump around any code emitted between the creation of the instance and it's
duke@435 2339 * automatic destruction at the end of a scope block, depending on the value of
duke@435 2340 * the flag passed to the constructor, which will be checked at run-time.
duke@435 2341 */
duke@435 2342 class SkipIfEqual {
duke@435 2343 private:
duke@435 2344 MacroAssembler* _masm;
duke@435 2345 Label _label;
duke@435 2346
duke@435 2347 public:
duke@435 2348 SkipIfEqual(MacroAssembler*, const bool* flag_addr, bool value);
duke@435 2349 ~SkipIfEqual();
duke@435 2350 };
duke@435 2351
duke@435 2352 #ifdef ASSERT
duke@435 2353 inline bool AbstractAssembler::pd_check_instruction_mark() { return true; }
duke@435 2354 #endif
stefank@2314 2355
stefank@2314 2356 #endif // CPU_X86_VM_ASSEMBLER_X86_HPP

mercurial