annotate src/cpu/x86/vm/x86_64.ad @ 5259:7944aba7ba41

8015107: NPG: Use consistent naming for metaspace concepts Reviewed-by: coleenp, mgerdin, hseigel
author ehelin
date Mon, 12 Aug 2013 17:37:02 +0200
parents 740e263c80c6
children 190899198332 c9ccd7b85f20
rev   line source
duke@0 1 //
drchase@4509 2 // Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
duke@0 3 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@0 4 //
duke@0 5 // This code is free software; you can redistribute it and/or modify it
duke@0 6 // under the terms of the GNU General Public License version 2 only, as
duke@0 7 // published by the Free Software Foundation.
duke@0 8 //
duke@0 9 // This code is distributed in the hope that it will be useful, but WITHOUT
duke@0 10 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@0 11 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@0 12 // version 2 for more details (a copy is included in the LICENSE file that
duke@0 13 // accompanied this code).
duke@0 14 //
duke@0 15 // You should have received a copy of the GNU General Public License version
duke@0 16 // 2 along with this work; if not, write to the Free Software Foundation,
duke@0 17 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@0 18 //
trims@1472 19 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
trims@1472 20 // or visit www.oracle.com if you need additional information or have any
trims@1472 21 // questions.
duke@0 22 //
duke@0 23 //
duke@0 24
duke@0 25 // AMD64 Architecture Description File
duke@0 26
duke@0 27 //----------REGISTER DEFINITION BLOCK------------------------------------------
duke@0 28 // This information is used by the matcher and the register allocator to
duke@0 29 // describe individual registers and classes of registers within the target
duke@0 30 // archtecture.
duke@0 31
duke@0 32 register %{
duke@0 33 //----------Architecture Description Register Definitions----------------------
duke@0 34 // General Registers
duke@0 35 // "reg_def" name ( register save type, C convention save type,
duke@0 36 // ideal register type, encoding );
duke@0 37 // Register Save Types:
duke@0 38 //
duke@0 39 // NS = No-Save: The register allocator assumes that these registers
duke@0 40 // can be used without saving upon entry to the method, &
duke@0 41 // that they do not need to be saved at call sites.
duke@0 42 //
duke@0 43 // SOC = Save-On-Call: The register allocator assumes that these registers
duke@0 44 // can be used without saving upon entry to the method,
duke@0 45 // but that they must be saved at call sites.
duke@0 46 //
duke@0 47 // SOE = Save-On-Entry: The register allocator assumes that these registers
duke@0 48 // must be saved before using them upon entry to the
duke@0 49 // method, but they do not need to be saved at call
duke@0 50 // sites.
duke@0 51 //
duke@0 52 // AS = Always-Save: The register allocator assumes that these registers
duke@0 53 // must be saved before using them upon entry to the
duke@0 54 // method, & that they must be saved at call sites.
duke@0 55 //
duke@0 56 // Ideal Register Type is used to determine how to save & restore a
duke@0 57 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get
duke@0 58 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI.
duke@0 59 //
duke@0 60 // The encoding number is the actual bit-pattern placed into the opcodes.
duke@0 61
duke@0 62 // General Registers
duke@0 63 // R8-R15 must be encoded with REX. (RSP, RBP, RSI, RDI need REX when
duke@0 64 // used as byte registers)
duke@0 65
duke@0 66 // Previously set RBX, RSI, and RDI as save-on-entry for java code
duke@0 67 // Turn off SOE in java-code due to frequent use of uncommon-traps.
duke@0 68 // Now that allocator is better, turn on RSI and RDI as SOE registers.
duke@0 69
duke@0 70 reg_def RAX (SOC, SOC, Op_RegI, 0, rax->as_VMReg());
duke@0 71 reg_def RAX_H(SOC, SOC, Op_RegI, 0, rax->as_VMReg()->next());
duke@0 72
duke@0 73 reg_def RCX (SOC, SOC, Op_RegI, 1, rcx->as_VMReg());
duke@0 74 reg_def RCX_H(SOC, SOC, Op_RegI, 1, rcx->as_VMReg()->next());
duke@0 75
duke@0 76 reg_def RDX (SOC, SOC, Op_RegI, 2, rdx->as_VMReg());
duke@0 77 reg_def RDX_H(SOC, SOC, Op_RegI, 2, rdx->as_VMReg()->next());
duke@0 78
duke@0 79 reg_def RBX (SOC, SOE, Op_RegI, 3, rbx->as_VMReg());
duke@0 80 reg_def RBX_H(SOC, SOE, Op_RegI, 3, rbx->as_VMReg()->next());
duke@0 81
duke@0 82 reg_def RSP (NS, NS, Op_RegI, 4, rsp->as_VMReg());
duke@0 83 reg_def RSP_H(NS, NS, Op_RegI, 4, rsp->as_VMReg()->next());
duke@0 84
duke@0 85 // now that adapter frames are gone RBP is always saved and restored by the prolog/epilog code
duke@0 86 reg_def RBP (NS, SOE, Op_RegI, 5, rbp->as_VMReg());
duke@0 87 reg_def RBP_H(NS, SOE, Op_RegI, 5, rbp->as_VMReg()->next());
duke@0 88
duke@0 89 #ifdef _WIN64
duke@0 90
duke@0 91 reg_def RSI (SOC, SOE, Op_RegI, 6, rsi->as_VMReg());
duke@0 92 reg_def RSI_H(SOC, SOE, Op_RegI, 6, rsi->as_VMReg()->next());
duke@0 93
duke@0 94 reg_def RDI (SOC, SOE, Op_RegI, 7, rdi->as_VMReg());
duke@0 95 reg_def RDI_H(SOC, SOE, Op_RegI, 7, rdi->as_VMReg()->next());
duke@0 96
duke@0 97 #else
duke@0 98
duke@0 99 reg_def RSI (SOC, SOC, Op_RegI, 6, rsi->as_VMReg());
duke@0 100 reg_def RSI_H(SOC, SOC, Op_RegI, 6, rsi->as_VMReg()->next());
duke@0 101
duke@0 102 reg_def RDI (SOC, SOC, Op_RegI, 7, rdi->as_VMReg());
duke@0 103 reg_def RDI_H(SOC, SOC, Op_RegI, 7, rdi->as_VMReg()->next());
duke@0 104
duke@0 105 #endif
duke@0 106
duke@0 107 reg_def R8 (SOC, SOC, Op_RegI, 8, r8->as_VMReg());
duke@0 108 reg_def R8_H (SOC, SOC, Op_RegI, 8, r8->as_VMReg()->next());
duke@0 109
duke@0 110 reg_def R9 (SOC, SOC, Op_RegI, 9, r9->as_VMReg());
duke@0 111 reg_def R9_H (SOC, SOC, Op_RegI, 9, r9->as_VMReg()->next());
duke@0 112
duke@0 113 reg_def R10 (SOC, SOC, Op_RegI, 10, r10->as_VMReg());
duke@0 114 reg_def R10_H(SOC, SOC, Op_RegI, 10, r10->as_VMReg()->next());
duke@0 115
duke@0 116 reg_def R11 (SOC, SOC, Op_RegI, 11, r11->as_VMReg());
duke@0 117 reg_def R11_H(SOC, SOC, Op_RegI, 11, r11->as_VMReg()->next());
duke@0 118
duke@0 119 reg_def R12 (SOC, SOE, Op_RegI, 12, r12->as_VMReg());
duke@0 120 reg_def R12_H(SOC, SOE, Op_RegI, 12, r12->as_VMReg()->next());
duke@0 121
duke@0 122 reg_def R13 (SOC, SOE, Op_RegI, 13, r13->as_VMReg());
duke@0 123 reg_def R13_H(SOC, SOE, Op_RegI, 13, r13->as_VMReg()->next());
duke@0 124
duke@0 125 reg_def R14 (SOC, SOE, Op_RegI, 14, r14->as_VMReg());
duke@0 126 reg_def R14_H(SOC, SOE, Op_RegI, 14, r14->as_VMReg()->next());
duke@0 127
duke@0 128 reg_def R15 (SOC, SOE, Op_RegI, 15, r15->as_VMReg());
duke@0 129 reg_def R15_H(SOC, SOE, Op_RegI, 15, r15->as_VMReg()->next());
duke@0 130
duke@0 131
duke@0 132 // Floating Point Registers
duke@0 133
duke@0 134 // Specify priority of register selection within phases of register
duke@0 135 // allocation. Highest priority is first. A useful heuristic is to
duke@0 136 // give registers a low priority when they are required by machine
duke@0 137 // instructions, like EAX and EDX on I486, and choose no-save registers
duke@0 138 // before save-on-call, & save-on-call before save-on-entry. Registers
duke@0 139 // which participate in fixed calling sequences should come last.
duke@0 140 // Registers which are used as pairs must fall on an even boundary.
duke@0 141
duke@0 142 alloc_class chunk0(R10, R10_H,
duke@0 143 R11, R11_H,
duke@0 144 R8, R8_H,
duke@0 145 R9, R9_H,
duke@0 146 R12, R12_H,
duke@0 147 RCX, RCX_H,
duke@0 148 RBX, RBX_H,
duke@0 149 RDI, RDI_H,
duke@0 150 RDX, RDX_H,
duke@0 151 RSI, RSI_H,
duke@0 152 RAX, RAX_H,
duke@0 153 RBP, RBP_H,
duke@0 154 R13, R13_H,
duke@0 155 R14, R14_H,
duke@0 156 R15, R15_H,
duke@0 157 RSP, RSP_H);
duke@0 158
duke@0 159
duke@0 160 //----------Architecture Description Register Classes--------------------------
duke@0 161 // Several register classes are automatically defined based upon information in
duke@0 162 // this architecture description.
duke@0 163 // 1) reg_class inline_cache_reg ( /* as def'd in frame section */ )
duke@0 164 // 2) reg_class compiler_method_oop_reg ( /* as def'd in frame section */ )
duke@0 165 // 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ )
duke@0 166 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ )
duke@0 167 //
duke@0 168
duke@0 169 // Class for all pointer registers (including RSP)
duke@0 170 reg_class any_reg(RAX, RAX_H,
duke@0 171 RDX, RDX_H,
duke@0 172 RBP, RBP_H,
duke@0 173 RDI, RDI_H,
duke@0 174 RSI, RSI_H,
duke@0 175 RCX, RCX_H,
duke@0 176 RBX, RBX_H,
duke@0 177 RSP, RSP_H,
duke@0 178 R8, R8_H,
duke@0 179 R9, R9_H,
duke@0 180 R10, R10_H,
duke@0 181 R11, R11_H,
duke@0 182 R12, R12_H,
duke@0 183 R13, R13_H,
duke@0 184 R14, R14_H,
duke@0 185 R15, R15_H);
duke@0 186
duke@0 187 // Class for all pointer registers except RSP
duke@0 188 reg_class ptr_reg(RAX, RAX_H,
duke@0 189 RDX, RDX_H,
duke@0 190 RBP, RBP_H,
duke@0 191 RDI, RDI_H,
duke@0 192 RSI, RSI_H,
duke@0 193 RCX, RCX_H,
duke@0 194 RBX, RBX_H,
duke@0 195 R8, R8_H,
duke@0 196 R9, R9_H,
duke@0 197 R10, R10_H,
duke@0 198 R11, R11_H,
duke@0 199 R13, R13_H,
duke@0 200 R14, R14_H);
duke@0 201
duke@0 202 // Class for all pointer registers except RAX and RSP
duke@0 203 reg_class ptr_no_rax_reg(RDX, RDX_H,
duke@0 204 RBP, RBP_H,
duke@0 205 RDI, RDI_H,
duke@0 206 RSI, RSI_H,
duke@0 207 RCX, RCX_H,
duke@0 208 RBX, RBX_H,
duke@0 209 R8, R8_H,
duke@0 210 R9, R9_H,
duke@0 211 R10, R10_H,
duke@0 212 R11, R11_H,
duke@0 213 R13, R13_H,
duke@0 214 R14, R14_H);
duke@0 215
duke@0 216 reg_class ptr_no_rbp_reg(RDX, RDX_H,
duke@0 217 RAX, RAX_H,
duke@0 218 RDI, RDI_H,
duke@0 219 RSI, RSI_H,
duke@0 220 RCX, RCX_H,
duke@0 221 RBX, RBX_H,
duke@0 222 R8, R8_H,
duke@0 223 R9, R9_H,
duke@0 224 R10, R10_H,
duke@0 225 R11, R11_H,
duke@0 226 R13, R13_H,
duke@0 227 R14, R14_H);
duke@0 228
duke@0 229 // Class for all pointer registers except RAX, RBX and RSP
duke@0 230 reg_class ptr_no_rax_rbx_reg(RDX, RDX_H,
duke@0 231 RBP, RBP_H,
duke@0 232 RDI, RDI_H,
duke@0 233 RSI, RSI_H,
duke@0 234 RCX, RCX_H,
duke@0 235 R8, R8_H,
duke@0 236 R9, R9_H,
duke@0 237 R10, R10_H,
duke@0 238 R11, R11_H,
duke@0 239 R13, R13_H,
duke@0 240 R14, R14_H);
duke@0 241
duke@0 242 // Singleton class for RAX pointer register
duke@0 243 reg_class ptr_rax_reg(RAX, RAX_H);
duke@0 244
duke@0 245 // Singleton class for RBX pointer register
duke@0 246 reg_class ptr_rbx_reg(RBX, RBX_H);
duke@0 247
duke@0 248 // Singleton class for RSI pointer register
duke@0 249 reg_class ptr_rsi_reg(RSI, RSI_H);
duke@0 250
duke@0 251 // Singleton class for RDI pointer register
duke@0 252 reg_class ptr_rdi_reg(RDI, RDI_H);
duke@0 253
duke@0 254 // Singleton class for RBP pointer register
duke@0 255 reg_class ptr_rbp_reg(RBP, RBP_H);
duke@0 256
duke@0 257 // Singleton class for stack pointer
duke@0 258 reg_class ptr_rsp_reg(RSP, RSP_H);
duke@0 259
duke@0 260 // Singleton class for TLS pointer
duke@0 261 reg_class ptr_r15_reg(R15, R15_H);
duke@0 262
duke@0 263 // Class for all long registers (except RSP)
duke@0 264 reg_class long_reg(RAX, RAX_H,
duke@0 265 RDX, RDX_H,
duke@0 266 RBP, RBP_H,
duke@0 267 RDI, RDI_H,
duke@0 268 RSI, RSI_H,
duke@0 269 RCX, RCX_H,
duke@0 270 RBX, RBX_H,
duke@0 271 R8, R8_H,
duke@0 272 R9, R9_H,
duke@0 273 R10, R10_H,
duke@0 274 R11, R11_H,
duke@0 275 R13, R13_H,
duke@0 276 R14, R14_H);
duke@0 277
duke@0 278 // Class for all long registers except RAX, RDX (and RSP)
duke@0 279 reg_class long_no_rax_rdx_reg(RBP, RBP_H,
duke@0 280 RDI, RDI_H,
duke@0 281 RSI, RSI_H,
duke@0 282 RCX, RCX_H,
duke@0 283 RBX, RBX_H,
duke@0 284 R8, R8_H,
duke@0 285 R9, R9_H,
duke@0 286 R10, R10_H,
duke@0 287 R11, R11_H,
duke@0 288 R13, R13_H,
duke@0 289 R14, R14_H);
duke@0 290
duke@0 291 // Class for all long registers except RCX (and RSP)
duke@0 292 reg_class long_no_rcx_reg(RBP, RBP_H,
duke@0 293 RDI, RDI_H,
duke@0 294 RSI, RSI_H,
duke@0 295 RAX, RAX_H,
duke@0 296 RDX, RDX_H,
duke@0 297 RBX, RBX_H,
duke@0 298 R8, R8_H,
duke@0 299 R9, R9_H,
duke@0 300 R10, R10_H,
duke@0 301 R11, R11_H,
duke@0 302 R13, R13_H,
duke@0 303 R14, R14_H);
duke@0 304
duke@0 305 // Class for all long registers except RAX (and RSP)
duke@0 306 reg_class long_no_rax_reg(RBP, RBP_H,
duke@0 307 RDX, RDX_H,
duke@0 308 RDI, RDI_H,
duke@0 309 RSI, RSI_H,
duke@0 310 RCX, RCX_H,
duke@0 311 RBX, RBX_H,
duke@0 312 R8, R8_H,
duke@0 313 R9, R9_H,
duke@0 314 R10, R10_H,
duke@0 315 R11, R11_H,
duke@0 316 R13, R13_H,
duke@0 317 R14, R14_H);
duke@0 318
duke@0 319 // Singleton class for RAX long register
duke@0 320 reg_class long_rax_reg(RAX, RAX_H);
duke@0 321
duke@0 322 // Singleton class for RCX long register
duke@0 323 reg_class long_rcx_reg(RCX, RCX_H);
duke@0 324
duke@0 325 // Singleton class for RDX long register
duke@0 326 reg_class long_rdx_reg(RDX, RDX_H);
duke@0 327
duke@0 328 // Class for all int registers (except RSP)
duke@0 329 reg_class int_reg(RAX,
duke@0 330 RDX,
duke@0 331 RBP,
duke@0 332 RDI,
duke@0 333 RSI,
duke@0 334 RCX,
duke@0 335 RBX,
duke@0 336 R8,
duke@0 337 R9,
duke@0 338 R10,
duke@0 339 R11,
duke@0 340 R13,
duke@0 341 R14);
duke@0 342
duke@0 343 // Class for all int registers except RCX (and RSP)
duke@0 344 reg_class int_no_rcx_reg(RAX,
duke@0 345 RDX,
duke@0 346 RBP,
duke@0 347 RDI,
duke@0 348 RSI,
duke@0 349 RBX,
duke@0 350 R8,
duke@0 351 R9,
duke@0 352 R10,
duke@0 353 R11,
duke@0 354 R13,
duke@0 355 R14);
duke@0 356
duke@0 357 // Class for all int registers except RAX, RDX (and RSP)
duke@0 358 reg_class int_no_rax_rdx_reg(RBP,
never@304 359 RDI,
duke@0 360 RSI,
duke@0 361 RCX,
duke@0 362 RBX,
duke@0 363 R8,
duke@0 364 R9,
duke@0 365 R10,
duke@0 366 R11,
duke@0 367 R13,
duke@0 368 R14);
duke@0 369
duke@0 370 // Singleton class for RAX int register
duke@0 371 reg_class int_rax_reg(RAX);
duke@0 372
duke@0 373 // Singleton class for RBX int register
duke@0 374 reg_class int_rbx_reg(RBX);
duke@0 375
duke@0 376 // Singleton class for RCX int register
duke@0 377 reg_class int_rcx_reg(RCX);
duke@0 378
duke@0 379 // Singleton class for RCX int register
duke@0 380 reg_class int_rdx_reg(RDX);
duke@0 381
duke@0 382 // Singleton class for RCX int register
duke@0 383 reg_class int_rdi_reg(RDI);
duke@0 384
duke@0 385 // Singleton class for instruction pointer
duke@0 386 // reg_class ip_reg(RIP);
duke@0 387
kvn@3447 388 %}
duke@0 389
duke@0 390 //----------SOURCE BLOCK-------------------------------------------------------
duke@0 391 // This is a block of C++ code which provides values, functions, and
duke@0 392 // definitions necessary in the rest of the architecture description
duke@0 393 source %{
never@304 394 #define RELOC_IMM64 Assembler::imm_operand
duke@0 395 #define RELOC_DISP32 Assembler::disp32_operand
duke@0 396
duke@0 397 #define __ _masm.
duke@0 398
twisti@1137 399 static int preserve_SP_size() {
kvn@2953 400 return 3; // rex.w, op, rm(reg/reg)
twisti@1137 401 }
kvn@4438 402 static int clear_avx_size() {
kvn@4438 403 return (Compile::current()->max_vector_size() > 16) ? 3 : 0; // vzeroupper
kvn@4438 404 }
twisti@1137 405
duke@0 406 // !!!!! Special hack to get all types of calls to specify the byte offset
duke@0 407 // from the start of the call to the point where the return address
duke@0 408 // will point.
duke@0 409 int MachCallStaticJavaNode::ret_addr_offset()
duke@0 410 {
twisti@1137 411 int offset = 5; // 5 bytes from start of call to where return address points
kvn@4438 412 offset += clear_avx_size();
twisti@1137 413 if (_method_handle_invoke)
twisti@1137 414 offset += preserve_SP_size();
twisti@1137 415 return offset;
duke@0 416 }
duke@0 417
duke@0 418 int MachCallDynamicJavaNode::ret_addr_offset()
duke@0 419 {
kvn@4438 420 int offset = 15; // 15 bytes from start of call to where return address points
kvn@4438 421 offset += clear_avx_size();
kvn@4438 422 return offset;
duke@0 423 }
duke@0 424
kvn@4438 425 int MachCallRuntimeNode::ret_addr_offset() {
kvn@4438 426 int offset = 13; // movq r10,#addr; callq (r10)
kvn@4438 427 offset += clear_avx_size();
kvn@4438 428 return offset;
kvn@4438 429 }
duke@0 430
iveresov@2251 431 // Indicate if the safepoint node needs the polling page as an input,
iveresov@2251 432 // it does if the polling page is more than disp32 away.
duke@0 433 bool SafePointNode::needs_polling_address_input()
duke@0 434 {
iveresov@2251 435 return Assembler::is_polling_page_far();
duke@0 436 }
duke@0 437
duke@0 438 //
duke@0 439 // Compute padding required for nodes which need alignment
duke@0 440 //
duke@0 441
duke@0 442 // The address of the call instruction needs to be 4-byte aligned to
duke@0 443 // ensure that it does not span a cache line so that it can be patched.
duke@0 444 int CallStaticJavaDirectNode::compute_padding(int current_offset) const
duke@0 445 {
kvn@4438 446 current_offset += clear_avx_size(); // skip vzeroupper
duke@0 447 current_offset += 1; // skip call opcode byte
duke@0 448 return round_to(current_offset, alignment_required()) - current_offset;
duke@0 449 }
duke@0 450
duke@0 451 // The address of the call instruction needs to be 4-byte aligned to
duke@0 452 // ensure that it does not span a cache line so that it can be patched.
twisti@1137 453 int CallStaticJavaHandleNode::compute_padding(int current_offset) const
twisti@1137 454 {
twisti@1137 455 current_offset += preserve_SP_size(); // skip mov rbp, rsp
kvn@4438 456 current_offset += clear_avx_size(); // skip vzeroupper
twisti@1137 457 current_offset += 1; // skip call opcode byte
twisti@1137 458 return round_to(current_offset, alignment_required()) - current_offset;
twisti@1137 459 }
twisti@1137 460
twisti@1137 461 // The address of the call instruction needs to be 4-byte aligned to
twisti@1137 462 // ensure that it does not span a cache line so that it can be patched.
duke@0 463 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const
duke@0 464 {
kvn@4438 465 current_offset += clear_avx_size(); // skip vzeroupper
duke@0 466 current_offset += 11; // skip movq instruction + call opcode byte
duke@0 467 return round_to(current_offset, alignment_required()) - current_offset;
duke@0 468 }
duke@0 469
duke@0 470 // EMIT_RM()
twisti@1668 471 void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) {
duke@0 472 unsigned char c = (unsigned char) ((f1 << 6) | (f2 << 3) | f3);
twisti@1668 473 cbuf.insts()->emit_int8(c);
duke@0 474 }
duke@0 475
duke@0 476 // EMIT_CC()
twisti@1668 477 void emit_cc(CodeBuffer &cbuf, int f1, int f2) {
duke@0 478 unsigned char c = (unsigned char) (f1 | f2);
twisti@1668 479 cbuf.insts()->emit_int8(c);
duke@0 480 }
duke@0 481
duke@0 482 // EMIT_OPCODE()
twisti@1668 483 void emit_opcode(CodeBuffer &cbuf, int code) {
twisti@1668 484 cbuf.insts()->emit_int8((unsigned char) code);
duke@0 485 }
duke@0 486
duke@0 487 // EMIT_OPCODE() w/ relocation information
duke@0 488 void emit_opcode(CodeBuffer &cbuf,
duke@0 489 int code, relocInfo::relocType reloc, int offset, int format)
duke@0 490 {
twisti@1668 491 cbuf.relocate(cbuf.insts_mark() + offset, reloc, format);
duke@0 492 emit_opcode(cbuf, code);
duke@0 493 }
duke@0 494
duke@0 495 // EMIT_D8()
twisti@1668 496 void emit_d8(CodeBuffer &cbuf, int d8) {
twisti@1668 497 cbuf.insts()->emit_int8((unsigned char) d8);
duke@0 498 }
duke@0 499
duke@0 500 // EMIT_D16()
twisti@1668 501 void emit_d16(CodeBuffer &cbuf, int d16) {
twisti@1668 502 cbuf.insts()->emit_int16(d16);
duke@0 503 }
duke@0 504
duke@0 505 // EMIT_D32()
twisti@1668 506 void emit_d32(CodeBuffer &cbuf, int d32) {
twisti@1668 507 cbuf.insts()->emit_int32(d32);
duke@0 508 }
duke@0 509
duke@0 510 // EMIT_D64()
twisti@1668 511 void emit_d64(CodeBuffer &cbuf, int64_t d64) {
twisti@1668 512 cbuf.insts()->emit_int64(d64);
duke@0 513 }
duke@0 514
duke@0 515 // emit 32 bit value and construct relocation entry from relocInfo::relocType
duke@0 516 void emit_d32_reloc(CodeBuffer& cbuf,
duke@0 517 int d32,
duke@0 518 relocInfo::relocType reloc,
duke@0 519 int format)
duke@0 520 {
duke@0 521 assert(reloc != relocInfo::external_word_type, "use 2-arg emit_d32_reloc");
twisti@1668 522 cbuf.relocate(cbuf.insts_mark(), reloc, format);
twisti@1668 523 cbuf.insts()->emit_int32(d32);
duke@0 524 }
duke@0 525
duke@0 526 // emit 32 bit value and construct relocation entry from RelocationHolder
twisti@1668 527 void emit_d32_reloc(CodeBuffer& cbuf, int d32, RelocationHolder const& rspec, int format) {
duke@0 528 #ifdef ASSERT
duke@0 529 if (rspec.reloc()->type() == relocInfo::oop_type &&
duke@0 530 d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) {
coleenp@3602 531 assert(Universe::heap()->is_in_reserved((address)(intptr_t)d32), "should be real oop");
jrose@989 532 assert(oop((intptr_t)d32)->is_oop() && (ScavengeRootsInCode || !oop((intptr_t)d32)->is_scavengable()), "cannot embed scavengable oops in code");
duke@0 533 }
duke@0 534 #endif
twisti@1668 535 cbuf.relocate(cbuf.insts_mark(), rspec, format);
twisti@1668 536 cbuf.insts()->emit_int32(d32);
duke@0 537 }
duke@0 538
duke@0 539 void emit_d32_reloc(CodeBuffer& cbuf, address addr) {
twisti@1668 540 address next_ip = cbuf.insts_end() + 4;
duke@0 541 emit_d32_reloc(cbuf, (int) (addr - next_ip),
duke@0 542 external_word_Relocation::spec(addr),
duke@0 543 RELOC_DISP32);
duke@0 544 }
duke@0 545
duke@0 546
duke@0 547 // emit 64 bit value and construct relocation entry from relocInfo::relocType
twisti@1668 548 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, relocInfo::relocType reloc, int format) {
twisti@1668 549 cbuf.relocate(cbuf.insts_mark(), reloc, format);
twisti@1668 550 cbuf.insts()->emit_int64(d64);
duke@0 551 }
duke@0 552
duke@0 553 // emit 64 bit value and construct relocation entry from RelocationHolder
twisti@1668 554 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, RelocationHolder const& rspec, int format) {
duke@0 555 #ifdef ASSERT
duke@0 556 if (rspec.reloc()->type() == relocInfo::oop_type &&
duke@0 557 d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) {
coleenp@3602 558 assert(Universe::heap()->is_in_reserved((address)d64), "should be real oop");
jrose@989 559 assert(oop(d64)->is_oop() && (ScavengeRootsInCode || !oop(d64)->is_scavengable()),
jrose@989 560 "cannot embed scavengable oops in code");
duke@0 561 }
duke@0 562 #endif
twisti@1668 563 cbuf.relocate(cbuf.insts_mark(), rspec, format);
twisti@1668 564 cbuf.insts()->emit_int64(d64);
duke@0 565 }
duke@0 566
duke@0 567 // Access stack slot for load or store
duke@0 568 void store_to_stackslot(CodeBuffer &cbuf, int opcode, int rm_field, int disp)
duke@0 569 {
duke@0 570 emit_opcode(cbuf, opcode); // (e.g., FILD [RSP+src])
duke@0 571 if (-0x80 <= disp && disp < 0x80) {
duke@0 572 emit_rm(cbuf, 0x01, rm_field, RSP_enc); // R/M byte
duke@0 573 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte
duke@0 574 emit_d8(cbuf, disp); // Displacement // R/M byte
duke@0 575 } else {
duke@0 576 emit_rm(cbuf, 0x02, rm_field, RSP_enc); // R/M byte
duke@0 577 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte
duke@0 578 emit_d32(cbuf, disp); // Displacement // R/M byte
duke@0 579 }
duke@0 580 }
duke@0 581
duke@0 582 // rRegI ereg, memory mem) %{ // emit_reg_mem
duke@0 583 void encode_RegMem(CodeBuffer &cbuf,
duke@0 584 int reg,
coleenp@3602 585 int base, int index, int scale, int disp, relocInfo::relocType disp_reloc)
duke@0 586 {
coleenp@3602 587 assert(disp_reloc == relocInfo::none, "cannot have disp");
duke@0 588 int regenc = reg & 7;
duke@0 589 int baseenc = base & 7;
duke@0 590 int indexenc = index & 7;
duke@0 591
duke@0 592 // There is no index & no scale, use form without SIB byte
duke@0 593 if (index == 0x4 && scale == 0 && base != RSP_enc && base != R12_enc) {
duke@0 594 // If no displacement, mode is 0x0; unless base is [RBP] or [R13]
duke@0 595 if (disp == 0 && base != RBP_enc && base != R13_enc) {
duke@0 596 emit_rm(cbuf, 0x0, regenc, baseenc); // *
coleenp@3602 597 } else if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) {
duke@0 598 // If 8-bit displacement, mode 0x1
duke@0 599 emit_rm(cbuf, 0x1, regenc, baseenc); // *
duke@0 600 emit_d8(cbuf, disp);
duke@0 601 } else {
duke@0 602 // If 32-bit displacement
duke@0 603 if (base == -1) { // Special flag for absolute address
duke@0 604 emit_rm(cbuf, 0x0, regenc, 0x5); // *
coleenp@3602 605 if (disp_reloc != relocInfo::none) {
duke@0 606 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32);
duke@0 607 } else {
duke@0 608 emit_d32(cbuf, disp);
duke@0 609 }
duke@0 610 } else {
duke@0 611 // Normal base + offset
duke@0 612 emit_rm(cbuf, 0x2, regenc, baseenc); // *
coleenp@3602 613 if (disp_reloc != relocInfo::none) {
duke@0 614 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32);
duke@0 615 } else {
duke@0 616 emit_d32(cbuf, disp);
duke@0 617 }
duke@0 618 }
duke@0 619 }
duke@0 620 } else {
duke@0 621 // Else, encode with the SIB byte
duke@0 622 // If no displacement, mode is 0x0; unless base is [RBP] or [R13]
duke@0 623 if (disp == 0 && base != RBP_enc && base != R13_enc) {
duke@0 624 // If no displacement
duke@0 625 emit_rm(cbuf, 0x0, regenc, 0x4); // *
duke@0 626 emit_rm(cbuf, scale, indexenc, baseenc);
duke@0 627 } else {
coleenp@3602 628 if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) {
duke@0 629 // If 8-bit displacement, mode 0x1
duke@0 630 emit_rm(cbuf, 0x1, regenc, 0x4); // *
duke@0 631 emit_rm(cbuf, scale, indexenc, baseenc);
duke@0 632 emit_d8(cbuf, disp);
duke@0 633 } else {
duke@0 634 // If 32-bit displacement
duke@0 635 if (base == 0x04 ) {
duke@0 636 emit_rm(cbuf, 0x2, regenc, 0x4);
duke@0 637 emit_rm(cbuf, scale, indexenc, 0x04); // XXX is this valid???
duke@0 638 } else {
duke@0 639 emit_rm(cbuf, 0x2, regenc, 0x4);
duke@0 640 emit_rm(cbuf, scale, indexenc, baseenc); // *
duke@0 641 }
coleenp@3602 642 if (disp_reloc != relocInfo::none) {
duke@0 643 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32);
duke@0 644 } else {
duke@0 645 emit_d32(cbuf, disp);
duke@0 646 }
duke@0 647 }
duke@0 648 }
duke@0 649 }
duke@0 650 }
duke@0 651
never@2545 652 // This could be in MacroAssembler but it's fairly C2 specific
never@2545 653 void emit_cmpfp_fixup(MacroAssembler& _masm) {
never@2545 654 Label exit;
never@2545 655 __ jccb(Assembler::noParity, exit);
never@2545 656 __ pushf();
kvn@2953 657 //
kvn@2953 658 // comiss/ucomiss instructions set ZF,PF,CF flags and
kvn@2953 659 // zero OF,AF,SF for NaN values.
kvn@2953 660 // Fixup flags by zeroing ZF,PF so that compare of NaN
kvn@2953 661 // values returns 'less than' result (CF is set).
kvn@2953 662 // Leave the rest of flags unchanged.
kvn@2953 663 //
kvn@2953 664 // 7 6 5 4 3 2 1 0
kvn@2953 665 // |S|Z|r|A|r|P|r|C| (r - reserved bit)
kvn@2953 666 // 0 0 1 0 1 0 1 1 (0x2B)
kvn@2953 667 //
never@2545 668 __ andq(Address(rsp, 0), 0xffffff2b);
never@2545 669 __ popf();
never@2545 670 __ bind(exit);
kvn@2953 671 }
kvn@2953 672
kvn@2953 673 void emit_cmpfp3(MacroAssembler& _masm, Register dst) {
kvn@2953 674 Label done;
kvn@2953 675 __ movl(dst, -1);
kvn@2953 676 __ jcc(Assembler::parity, done);
kvn@2953 677 __ jcc(Assembler::below, done);
kvn@2953 678 __ setb(Assembler::notEqual, dst);
kvn@2953 679 __ movzbl(dst, dst);
kvn@2953 680 __ bind(done);
never@2545 681 }
never@2545 682
duke@0 683
duke@0 684 //=============================================================================
twisti@1915 685 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty;
twisti@1915 686
twisti@2875 687 int Compile::ConstantTable::calculate_table_base_offset() const {
twisti@2875 688 return 0; // absolute addressing, no offset
twisti@2875 689 }
twisti@2875 690
twisti@1915 691 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
twisti@1915 692 // Empty encoding
twisti@1915 693 }
twisti@1915 694
twisti@1915 695 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const {
twisti@1915 696 return 0;
twisti@1915 697 }
twisti@1915 698
twisti@1915 699 #ifndef PRODUCT
twisti@1915 700 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
twisti@1915 701 st->print("# MachConstantBaseNode (empty encoding)");
twisti@1915 702 }
twisti@1915 703 #endif
twisti@1915 704
twisti@1915 705
twisti@1915 706 //=============================================================================
duke@0 707 #ifndef PRODUCT
kvn@3139 708 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
duke@0 709 Compile* C = ra_->C;
duke@0 710
duke@0 711 int framesize = C->frame_slots() << LogBytesPerInt;
duke@0 712 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
kvn@3139 713 // Remove wordSize for return addr which is already pushed.
kvn@3139 714 framesize -= wordSize;
kvn@3139 715
duke@0 716 if (C->need_stack_bang(framesize)) {
kvn@3139 717 framesize -= wordSize;
kvn@3139 718 st->print("# stack bang");
kvn@3139 719 st->print("\n\t");
kvn@3139 720 st->print("pushq rbp\t# Save rbp");
kvn@3139 721 if (framesize) {
kvn@3139 722 st->print("\n\t");
kvn@3139 723 st->print("subq rsp, #%d\t# Create frame",framesize);
kvn@3139 724 }
kvn@3139 725 } else {
kvn@3139 726 st->print("subq rsp, #%d\t# Create frame",framesize);
kvn@3139 727 st->print("\n\t");
kvn@3139 728 framesize -= wordSize;
kvn@3139 729 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize);
duke@0 730 }
duke@0 731
duke@0 732 if (VerifyStackAtCalls) {
kvn@3139 733 st->print("\n\t");
kvn@3139 734 framesize -= wordSize;
kvn@3139 735 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize);
kvn@3139 736 #ifdef ASSERT
kvn@3139 737 st->print("\n\t");
kvn@3139 738 st->print("# stack alignment check");
kvn@3139 739 #endif
duke@0 740 }
kvn@3139 741 st->cr();
duke@0 742 }
duke@0 743 #endif
duke@0 744
kvn@3139 745 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
duke@0 746 Compile* C = ra_->C;
kvn@3139 747 MacroAssembler _masm(&cbuf);
duke@0 748
duke@0 749 int framesize = C->frame_slots() << LogBytesPerInt;
kvn@3139 750
kvn@3139 751 __ verified_entry(framesize, C->need_stack_bang(framesize), false);
duke@0 752
twisti@1668 753 C->set_frame_complete(cbuf.insts_size());
duke@0 754
twisti@2875 755 if (C->has_mach_constant_base_node()) {
twisti@2875 756 // NOTE: We set the table base offset here because users might be
twisti@2875 757 // emitted before MachConstantBaseNode.
twisti@2875 758 Compile::ConstantTable& constant_table = C->constant_table();
twisti@2875 759 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset());
twisti@2875 760 }
duke@0 761 }
duke@0 762
duke@0 763 uint MachPrologNode::size(PhaseRegAlloc* ra_) const
duke@0 764 {
duke@0 765 return MachNode::size(ra_); // too many variables; just compute it
duke@0 766 // the hard way
duke@0 767 }
duke@0 768
duke@0 769 int MachPrologNode::reloc() const
duke@0 770 {
duke@0 771 return 0; // a large enough number
duke@0 772 }
duke@0 773
duke@0 774 //=============================================================================
duke@0 775 #ifndef PRODUCT
duke@0 776 void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const
duke@0 777 {
duke@0 778 Compile* C = ra_->C;
kvn@4438 779 if (C->max_vector_size() > 16) {
kvn@4438 780 st->print("vzeroupper");
kvn@4438 781 st->cr(); st->print("\t");
kvn@4438 782 }
kvn@4438 783
duke@0 784 int framesize = C->frame_slots() << LogBytesPerInt;
duke@0 785 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
duke@0 786 // Remove word for return adr already pushed
duke@0 787 // and RBP
duke@0 788 framesize -= 2*wordSize;
duke@0 789
duke@0 790 if (framesize) {
iveresov@2251 791 st->print_cr("addq rsp, %d\t# Destroy frame", framesize);
duke@0 792 st->print("\t");
duke@0 793 }
duke@0 794
iveresov@2251 795 st->print_cr("popq rbp");
duke@0 796 if (do_polling() && C->is_method_compilation()) {
duke@0 797 st->print("\t");
iveresov@2251 798 if (Assembler::is_polling_page_far()) {
iveresov@2251 799 st->print_cr("movq rscratch1, #polling_page_address\n\t"
iveresov@2251 800 "testl rax, [rscratch1]\t"
iveresov@2251 801 "# Safepoint: poll for GC");
iveresov@2251 802 } else {
iveresov@2251 803 st->print_cr("testl rax, [rip + #offset_to_poll_page]\t"
iveresov@2251 804 "# Safepoint: poll for GC");
iveresov@2251 805 }
duke@0 806 }
duke@0 807 }
duke@0 808 #endif
duke@0 809
duke@0 810 void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
duke@0 811 {
duke@0 812 Compile* C = ra_->C;
kvn@4438 813 if (C->max_vector_size() > 16) {
kvn@4438 814 // Clear upper bits of YMM registers when current compiled code uses
kvn@4438 815 // wide vectors to avoid AVX <-> SSE transition penalty during call.
kvn@4438 816 MacroAssembler _masm(&cbuf);
kvn@4438 817 __ vzeroupper();
kvn@4438 818 }
kvn@4438 819
duke@0 820 int framesize = C->frame_slots() << LogBytesPerInt;
duke@0 821 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
duke@0 822 // Remove word for return adr already pushed
duke@0 823 // and RBP
duke@0 824 framesize -= 2*wordSize;
duke@0 825
duke@0 826 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here
duke@0 827
duke@0 828 if (framesize) {
duke@0 829 emit_opcode(cbuf, Assembler::REX_W);
duke@0 830 if (framesize < 0x80) {
duke@0 831 emit_opcode(cbuf, 0x83); // addq rsp, #framesize
duke@0 832 emit_rm(cbuf, 0x3, 0x00, RSP_enc);
duke@0 833 emit_d8(cbuf, framesize);
duke@0 834 } else {
duke@0 835 emit_opcode(cbuf, 0x81); // addq rsp, #framesize
duke@0 836 emit_rm(cbuf, 0x3, 0x00, RSP_enc);
duke@0 837 emit_d32(cbuf, framesize);
duke@0 838 }
duke@0 839 }
duke@0 840
duke@0 841 // popq rbp
duke@0 842 emit_opcode(cbuf, 0x58 | RBP_enc);
duke@0 843
duke@0 844 if (do_polling() && C->is_method_compilation()) {
iveresov@2251 845 MacroAssembler _masm(&cbuf);
iveresov@2251 846 AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type);
iveresov@2251 847 if (Assembler::is_polling_page_far()) {
iveresov@2251 848 __ lea(rscratch1, polling_page);
iveresov@2251 849 __ relocate(relocInfo::poll_return_type);
iveresov@2251 850 __ testl(rax, Address(rscratch1, 0));
iveresov@2251 851 } else {
iveresov@2251 852 __ testl(rax, polling_page);
iveresov@2251 853 }
duke@0 854 }
duke@0 855 }
duke@0 856
duke@0 857 uint MachEpilogNode::size(PhaseRegAlloc* ra_) const
duke@0 858 {
iveresov@2251 859 return MachNode::size(ra_); // too many variables; just compute it
iveresov@2251 860 // the hard way
duke@0 861 }
duke@0 862
duke@0 863 int MachEpilogNode::reloc() const
duke@0 864 {
duke@0 865 return 2; // a large enough number
duke@0 866 }
duke@0 867
duke@0 868 const Pipeline* MachEpilogNode::pipeline() const
duke@0 869 {
duke@0 870 return MachNode::pipeline_class();
duke@0 871 }
duke@0 872
duke@0 873 int MachEpilogNode::safepoint_offset() const
duke@0 874 {
duke@0 875 return 0;
duke@0 876 }
duke@0 877
duke@0 878 //=============================================================================
duke@0 879
duke@0 880 enum RC {
duke@0 881 rc_bad,
duke@0 882 rc_int,
duke@0 883 rc_float,
duke@0 884 rc_stack
duke@0 885 };
duke@0 886
duke@0 887 static enum RC rc_class(OptoReg::Name reg)
duke@0 888 {
duke@0 889 if( !OptoReg::is_valid(reg) ) return rc_bad;
duke@0 890
duke@0 891 if (OptoReg::is_stack(reg)) return rc_stack;
duke@0 892
duke@0 893 VMReg r = OptoReg::as_VMReg(reg);
duke@0 894
duke@0 895 if (r->is_Register()) return rc_int;
duke@0 896
duke@0 897 assert(r->is_XMMRegister(), "must be");
duke@0 898 return rc_float;
duke@0 899 }
duke@0 900
kvn@3447 901 // Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad.
kvn@3447 902 static int vec_mov_helper(CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo,
kvn@3447 903 int src_hi, int dst_hi, uint ireg, outputStream* st);
kvn@3447 904
kvn@3447 905 static int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load,
kvn@3447 906 int stack_offset, int reg, uint ireg, outputStream* st);
kvn@3447 907
kvn@3447 908 static void vec_stack_to_stack_helper(CodeBuffer *cbuf, int src_offset,
kvn@3447 909 int dst_offset, uint ireg, outputStream* st) {
kvn@3447 910 if (cbuf) {
kvn@3447 911 MacroAssembler _masm(cbuf);
kvn@3447 912 switch (ireg) {
kvn@3447 913 case Op_VecS:
kvn@3447 914 __ movq(Address(rsp, -8), rax);
kvn@3447 915 __ movl(rax, Address(rsp, src_offset));
kvn@3447 916 __ movl(Address(rsp, dst_offset), rax);
kvn@3447 917 __ movq(rax, Address(rsp, -8));
kvn@3447 918 break;
kvn@3447 919 case Op_VecD:
kvn@3447 920 __ pushq(Address(rsp, src_offset));
kvn@3447 921 __ popq (Address(rsp, dst_offset));
kvn@3447 922 break;
kvn@3447 923 case Op_VecX:
kvn@3447 924 __ pushq(Address(rsp, src_offset));
kvn@3447 925 __ popq (Address(rsp, dst_offset));
kvn@3447 926 __ pushq(Address(rsp, src_offset+8));
kvn@3447 927 __ popq (Address(rsp, dst_offset+8));
kvn@3447 928 break;
kvn@3447 929 case Op_VecY:
kvn@3447 930 __ vmovdqu(Address(rsp, -32), xmm0);
kvn@3447 931 __ vmovdqu(xmm0, Address(rsp, src_offset));
kvn@3447 932 __ vmovdqu(Address(rsp, dst_offset), xmm0);
kvn@3447 933 __ vmovdqu(xmm0, Address(rsp, -32));
kvn@3447 934 break;
kvn@3447 935 default:
kvn@3447 936 ShouldNotReachHere();
kvn@3447 937 }
kvn@3447 938 #ifndef PRODUCT
kvn@3447 939 } else {
kvn@3447 940 switch (ireg) {
kvn@3447 941 case Op_VecS:
kvn@3447 942 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t"
kvn@3447 943 "movl rax, [rsp + #%d]\n\t"
kvn@3447 944 "movl [rsp + #%d], rax\n\t"
kvn@3447 945 "movq rax, [rsp - #8]",
kvn@3447 946 src_offset, dst_offset);
kvn@3447 947 break;
kvn@3447 948 case Op_VecD:
kvn@3447 949 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t"
kvn@3447 950 "popq [rsp + #%d]",
kvn@3447 951 src_offset, dst_offset);
kvn@3447 952 break;
kvn@3447 953 case Op_VecX:
kvn@3447 954 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t"
kvn@3447 955 "popq [rsp + #%d]\n\t"
kvn@3447 956 "pushq [rsp + #%d]\n\t"
kvn@3447 957 "popq [rsp + #%d]",
kvn@3447 958 src_offset, dst_offset, src_offset+8, dst_offset+8);
kvn@3447 959 break;
kvn@3447 960 case Op_VecY:
kvn@3447 961 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t"
kvn@3447 962 "vmovdqu xmm0, [rsp + #%d]\n\t"
kvn@3447 963 "vmovdqu [rsp + #%d], xmm0\n\t"
kvn@3447 964 "vmovdqu xmm0, [rsp - #32]",
kvn@3447 965 src_offset, dst_offset);
kvn@3447 966 break;
kvn@3447 967 default:
kvn@3447 968 ShouldNotReachHere();
kvn@3447 969 }
kvn@3447 970 #endif
kvn@3447 971 }
kvn@3447 972 }
kvn@3447 973
duke@0 974 uint MachSpillCopyNode::implementation(CodeBuffer* cbuf,
duke@0 975 PhaseRegAlloc* ra_,
duke@0 976 bool do_size,
kvn@3447 977 outputStream* st) const {
kvn@3447 978 assert(cbuf != NULL || st != NULL, "sanity");
duke@0 979 // Get registers to move
duke@0 980 OptoReg::Name src_second = ra_->get_reg_second(in(1));
duke@0 981 OptoReg::Name src_first = ra_->get_reg_first(in(1));
duke@0 982 OptoReg::Name dst_second = ra_->get_reg_second(this);
duke@0 983 OptoReg::Name dst_first = ra_->get_reg_first(this);
duke@0 984
duke@0 985 enum RC src_second_rc = rc_class(src_second);
duke@0 986 enum RC src_first_rc = rc_class(src_first);
duke@0 987 enum RC dst_second_rc = rc_class(dst_second);
duke@0 988 enum RC dst_first_rc = rc_class(dst_first);
duke@0 989
duke@0 990 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first),
duke@0 991 "must move at least 1 register" );
duke@0 992
duke@0 993 if (src_first == dst_first && src_second == dst_second) {
duke@0 994 // Self copy, no move
duke@0 995 return 0;
kvn@3447 996 }
kvn@3447 997 if (bottom_type()->isa_vect() != NULL) {
kvn@3447 998 uint ireg = ideal_reg();
kvn@3447 999 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity");
kvn@3447 1000 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY), "sanity");
kvn@3447 1001 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) {
kvn@3447 1002 // mem -> mem
kvn@3447 1003 int src_offset = ra_->reg2offset(src_first);
kvn@3447 1004 int dst_offset = ra_->reg2offset(dst_first);
kvn@3447 1005 vec_stack_to_stack_helper(cbuf, src_offset, dst_offset, ireg, st);
kvn@3447 1006 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) {
kvn@3447 1007 vec_mov_helper(cbuf, false, src_first, dst_first, src_second, dst_second, ireg, st);
kvn@3447 1008 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) {
kvn@3447 1009 int stack_offset = ra_->reg2offset(dst_first);
kvn@3447 1010 vec_spill_helper(cbuf, false, false, stack_offset, src_first, ireg, st);
kvn@3447 1011 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) {
kvn@3447 1012 int stack_offset = ra_->reg2offset(src_first);
kvn@3447 1013 vec_spill_helper(cbuf, false, true, stack_offset, dst_first, ireg, st);
kvn@3447 1014 } else {
kvn@3447 1015 ShouldNotReachHere();
kvn@3447 1016 }
kvn@3447 1017 return 0;
kvn@3447 1018 }
kvn@3447 1019 if (src_first_rc == rc_stack) {
duke@0 1020 // mem ->
duke@0 1021 if (dst_first_rc == rc_stack) {
duke@0 1022 // mem -> mem
duke@0 1023 assert(src_second != dst_first, "overlap");
duke@0 1024 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
duke@0 1025 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
duke@0 1026 // 64-bit
duke@0 1027 int src_offset = ra_->reg2offset(src_first);
duke@0 1028 int dst_offset = ra_->reg2offset(dst_first);
duke@0 1029 if (cbuf) {
kvn@3447 1030 MacroAssembler _masm(cbuf);
kvn@3447 1031 __ pushq(Address(rsp, src_offset));
kvn@3447 1032 __ popq (Address(rsp, dst_offset));
duke@0 1033 #ifndef PRODUCT
kvn@3447 1034 } else {
duke@0 1035 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t"
kvn@3447 1036 "popq [rsp + #%d]",
kvn@3447 1037 src_offset, dst_offset);
duke@0 1038 #endif
duke@0 1039 }
duke@0 1040 } else {
duke@0 1041 // 32-bit
duke@0 1042 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
duke@0 1043 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
duke@0 1044 // No pushl/popl, so:
duke@0 1045 int src_offset = ra_->reg2offset(src_first);
duke@0 1046 int dst_offset = ra_->reg2offset(dst_first);
duke@0 1047 if (cbuf) {
kvn@3447 1048 MacroAssembler _masm(cbuf);
kvn@3447 1049 __ movq(Address(rsp, -8), rax);
kvn@3447 1050 __ movl(rax, Address(rsp, src_offset));
kvn@3447 1051 __ movl(Address(rsp, dst_offset), rax);
kvn@3447 1052 __ movq(rax, Address(rsp, -8));
duke@0 1053 #ifndef PRODUCT
kvn@3447 1054 } else {
duke@0 1055 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t"
kvn@3447 1056 "movl rax, [rsp + #%d]\n\t"
kvn@3447 1057 "movl [rsp + #%d], rax\n\t"
kvn@3447 1058 "movq rax, [rsp - #8]",
kvn@3447 1059 src_offset, dst_offset);
duke@0 1060 #endif
duke@0 1061 }
duke@0 1062 }
kvn@3447 1063 return 0;
duke@0 1064 } else if (dst_first_rc == rc_int) {
duke@0 1065 // mem -> gpr
duke@0 1066 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
duke@0 1067 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
duke@0 1068 // 64-bit
duke@0 1069 int offset = ra_->reg2offset(src_first);
duke@0 1070 if (cbuf) {
kvn@3447 1071 MacroAssembler _masm(cbuf);
kvn@3447 1072 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset));
duke@0 1073 #ifndef PRODUCT
kvn@3447 1074 } else {
duke@0 1075 st->print("movq %s, [rsp + #%d]\t# spill",
duke@0 1076 Matcher::regName[dst_first],
duke@0 1077 offset);
duke@0 1078 #endif
duke@0 1079 }
duke@0 1080 } else {
duke@0 1081 // 32-bit
duke@0 1082 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
duke@0 1083 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
duke@0 1084 int offset = ra_->reg2offset(src_first);
duke@0 1085 if (cbuf) {
kvn@3447 1086 MacroAssembler _masm(cbuf);
kvn@3447 1087 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset));
duke@0 1088 #ifndef PRODUCT
kvn@3447 1089 } else {
duke@0 1090 st->print("movl %s, [rsp + #%d]\t# spill",
duke@0 1091 Matcher::regName[dst_first],
duke@0 1092 offset);
duke@0 1093 #endif
duke@0 1094 }
duke@0 1095 }
kvn@3447 1096 return 0;
duke@0 1097 } else if (dst_first_rc == rc_float) {
duke@0 1098 // mem-> xmm
duke@0 1099 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
duke@0 1100 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
duke@0 1101 // 64-bit
duke@0 1102 int offset = ra_->reg2offset(src_first);
duke@0 1103 if (cbuf) {
kvn@2953 1104 MacroAssembler _masm(cbuf);
kvn@2953 1105 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset));
duke@0 1106 #ifndef PRODUCT
kvn@3447 1107 } else {
duke@0 1108 st->print("%s %s, [rsp + #%d]\t# spill",
duke@0 1109 UseXmmLoadAndClearUpper ? "movsd " : "movlpd",
duke@0 1110 Matcher::regName[dst_first],
duke@0 1111 offset);
duke@0 1112 #endif
duke@0 1113 }
duke@0 1114 } else {
duke@0 1115 // 32-bit
duke@0 1116 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
duke@0 1117 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
duke@0 1118 int offset = ra_->reg2offset(src_first);
duke@0 1119 if (cbuf) {
kvn@2953 1120 MacroAssembler _masm(cbuf);
kvn@2953 1121 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset));
duke@0 1122 #ifndef PRODUCT
kvn@3447 1123 } else {
duke@0 1124 st->print("movss %s, [rsp + #%d]\t# spill",
duke@0 1125 Matcher::regName[dst_first],
duke@0 1126 offset);
duke@0 1127 #endif
duke@0 1128 }
duke@0 1129 }
kvn@3447 1130 return 0;
duke@0 1131 }
duke@0 1132 } else if (src_first_rc == rc_int) {
duke@0 1133 // gpr ->
duke@0 1134 if (dst_first_rc == rc_stack) {
duke@0 1135 // gpr -> mem
duke@0 1136 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
duke@0 1137 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
duke@0 1138 // 64-bit
duke@0 1139 int offset = ra_->reg2offset(dst_first);
duke@0 1140 if (cbuf) {
kvn@3447 1141 MacroAssembler _masm(cbuf);
kvn@3447 1142 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first]));
duke@0 1143 #ifndef PRODUCT
kvn@3447 1144 } else {
duke@0 1145 st->print("movq [rsp + #%d], %s\t# spill",
duke@0 1146 offset,
duke@0 1147 Matcher::regName[src_first]);
duke@0 1148 #endif
duke@0 1149 }
duke@0 1150 } else {
duke@0 1151 // 32-bit
duke@0 1152 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
duke@0 1153 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
duke@0 1154 int offset = ra_->reg2offset(dst_first);
duke@0 1155 if (cbuf) {
kvn@3447 1156 MacroAssembler _masm(cbuf);
kvn@3447 1157 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first]));
duke@0 1158 #ifndef PRODUCT
kvn@3447 1159 } else {
duke@0 1160 st->print("movl [rsp + #%d], %s\t# spill",
duke@0 1161 offset,
duke@0 1162 Matcher::regName[src_first]);
duke@0 1163 #endif
duke@0 1164 }
duke@0 1165 }
kvn@3447 1166 return 0;
duke@0 1167 } else if (dst_first_rc == rc_int) {
duke@0 1168 // gpr -> gpr
duke@0 1169 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
duke@0 1170 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
duke@0 1171 // 64-bit
duke@0 1172 if (cbuf) {
kvn@3447 1173 MacroAssembler _masm(cbuf);
kvn@3447 1174 __ movq(as_Register(Matcher::_regEncode[dst_first]),
kvn@3447 1175 as_Register(Matcher::_regEncode[src_first]));
duke@0 1176 #ifndef PRODUCT
kvn@3447 1177 } else {
duke@0 1178 st->print("movq %s, %s\t# spill",
duke@0 1179 Matcher::regName[dst_first],
duke@0 1180 Matcher::regName[src_first]);
duke@0 1181 #endif
duke@0 1182 }
kvn@3447 1183 return 0;
duke@0 1184 } else {
duke@0 1185 // 32-bit
duke@0 1186 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
duke@0 1187 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
duke@0 1188 if (cbuf) {
kvn@3447 1189 MacroAssembler _masm(cbuf);
kvn@3447 1190 __ movl(as_Register(Matcher::_regEncode[dst_first]),
kvn@3447 1191 as_Register(Matcher::_regEncode[src_first]));
duke@0 1192 #ifndef PRODUCT
kvn@3447 1193 } else {
duke@0 1194 st->print("movl %s, %s\t# spill",
duke@0 1195 Matcher::regName[dst_first],
duke@0 1196 Matcher::regName[src_first]);
duke@0 1197 #endif
duke@0 1198 }
kvn@3447 1199 return 0;
duke@0 1200 }
duke@0 1201 } else if (dst_first_rc == rc_float) {
duke@0 1202 // gpr -> xmm
duke@0 1203 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
duke@0 1204 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
duke@0 1205 // 64-bit
duke@0 1206 if (cbuf) {
kvn@2953 1207 MacroAssembler _masm(cbuf);
kvn@2953 1208 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first]));
duke@0 1209 #ifndef PRODUCT
kvn@3447 1210 } else {
duke@0 1211 st->print("movdq %s, %s\t# spill",
duke@0 1212 Matcher::regName[dst_first],
duke@0 1213 Matcher::regName[src_first]);
duke@0 1214 #endif
duke@0 1215 }
duke@0 1216 } else {
duke@0 1217 // 32-bit
duke@0 1218 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
duke@0 1219 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
duke@0 1220 if (cbuf) {
kvn@2953 1221 MacroAssembler _masm(cbuf);
kvn@2953 1222 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first]));
duke@0 1223 #ifndef PRODUCT
kvn@3447 1224 } else {
duke@0 1225 st->print("movdl %s, %s\t# spill",
duke@0 1226 Matcher::regName[dst_first],
duke@0 1227 Matcher::regName[src_first]);
duke@0 1228 #endif
duke@0 1229 }
duke@0 1230 }
kvn@3447 1231 return 0;
duke@0 1232 }
duke@0 1233 } else if (src_first_rc == rc_float) {
duke@0 1234 // xmm ->
duke@0 1235 if (dst_first_rc == rc_stack) {
duke@0 1236 // xmm -> mem
duke@0 1237 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
duke@0 1238 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
duke@0 1239 // 64-bit
duke@0 1240 int offset = ra_->reg2offset(dst_first);
duke@0 1241 if (cbuf) {
kvn@2953 1242 MacroAssembler _masm(cbuf);
kvn@2953 1243 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first]));
duke@0 1244 #ifndef PRODUCT
kvn@3447 1245 } else {
duke@0 1246 st->print("movsd [rsp + #%d], %s\t# spill",
duke@0 1247 offset,
duke@0 1248 Matcher::regName[src_first]);
duke@0 1249 #endif
duke@0 1250 }
duke@0 1251 } else {
duke@0 1252 // 32-bit
duke@0 1253 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
duke@0 1254 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
duke@0 1255 int offset = ra_->reg2offset(dst_first);
duke@0 1256 if (cbuf) {
kvn@2953 1257 MacroAssembler _masm(cbuf);
kvn@2953 1258 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first]));
duke@0 1259 #ifndef PRODUCT
kvn@3447 1260 } else {
duke@0 1261 st->print("movss [rsp + #%d], %s\t# spill",
duke@0 1262 offset,
duke@0 1263 Matcher::regName[src_first]);
duke@0 1264 #endif
duke@0 1265 }
duke@0 1266 }
kvn@3447 1267 return 0;
duke@0 1268 } else if (dst_first_rc == rc_int) {
duke@0 1269 // xmm -> gpr
duke@0 1270 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
duke@0 1271 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
duke@0 1272 // 64-bit
duke@0 1273 if (cbuf) {
kvn@2953 1274 MacroAssembler _masm(cbuf);
kvn@2953 1275 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first]));
duke@0 1276 #ifndef PRODUCT
kvn@3447 1277 } else {
duke@0 1278 st->print("movdq %s, %s\t# spill",
duke@0 1279 Matcher::regName[dst_first],
duke@0 1280 Matcher::regName[src_first]);
duke@0 1281 #endif
duke@0 1282 }
duke@0 1283 } else {
duke@0 1284 // 32-bit
duke@0 1285 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
duke@0 1286 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
duke@0 1287 if (cbuf) {
kvn@2953 1288 MacroAssembler _masm(cbuf);
kvn@2953 1289 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first]));
duke@0 1290 #ifndef PRODUCT
kvn@3447 1291 } else {
duke@0 1292 st->print("movdl %s, %s\t# spill",
duke@0 1293 Matcher::regName[dst_first],
duke@0 1294 Matcher::regName[src_first]);
duke@0 1295 #endif
duke@0 1296 }
duke@0 1297 }
kvn@3447 1298 return 0;
duke@0 1299 } else if (dst_first_rc == rc_float) {
duke@0 1300 // xmm -> xmm
duke@0 1301 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
duke@0 1302 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
duke@0 1303 // 64-bit
duke@0 1304 if (cbuf) {
kvn@2953 1305 MacroAssembler _masm(cbuf);
kvn@2953 1306 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first]));
duke@0 1307 #ifndef PRODUCT
kvn@3447 1308 } else {
duke@0 1309 st->print("%s %s, %s\t# spill",
duke@0 1310 UseXmmRegToRegMoveAll ? "movapd" : "movsd ",
duke@0 1311 Matcher::regName[dst_first],
duke@0 1312 Matcher::regName[src_first]);
duke@0 1313 #endif
duke@0 1314 }
duke@0 1315 } else {
duke@0 1316 // 32-bit
duke@0 1317 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
duke@0 1318 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
duke@0 1319 if (cbuf) {
kvn@2953 1320 MacroAssembler _masm(cbuf);
kvn@2953 1321 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first]));
duke@0 1322 #ifndef PRODUCT
kvn@3447 1323 } else {
duke@0 1324 st->print("%s %s, %s\t# spill",
duke@0 1325 UseXmmRegToRegMoveAll ? "movaps" : "movss ",
duke@0 1326 Matcher::regName[dst_first],
duke@0 1327 Matcher::regName[src_first]);
duke@0 1328 #endif
duke@0 1329 }
duke@0 1330 }
kvn@3447 1331 return 0;
duke@0 1332 }
duke@0 1333 }
duke@0 1334
duke@0 1335 assert(0," foo ");
duke@0 1336 Unimplemented();
duke@0 1337 return 0;
duke@0 1338 }
duke@0 1339
duke@0 1340 #ifndef PRODUCT
kvn@3447 1341 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const {
duke@0 1342 implementation(NULL, ra_, false, st);
duke@0 1343 }
duke@0 1344 #endif
duke@0 1345
kvn@3447 1346 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
duke@0 1347 implementation(&cbuf, ra_, false, NULL);
duke@0 1348 }
duke@0 1349
kvn@3447 1350 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
kvn@3447 1351 return MachNode::size(ra_);
duke@0 1352 }
duke@0 1353
duke@0 1354 //=============================================================================
duke@0 1355 #ifndef PRODUCT
duke@0 1356 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const
duke@0 1357 {
duke@0 1358 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
duke@0 1359 int reg = ra_->get_reg_first(this);
duke@0 1360 st->print("leaq %s, [rsp + #%d]\t# box lock",
duke@0 1361 Matcher::regName[reg], offset);
duke@0 1362 }
duke@0 1363 #endif
duke@0 1364
duke@0 1365 void BoxLockNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
duke@0 1366 {
duke@0 1367 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
duke@0 1368 int reg = ra_->get_encode(this);
duke@0 1369 if (offset >= 0x80) {
duke@0 1370 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR);
duke@0 1371 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset]
duke@0 1372 emit_rm(cbuf, 0x2, reg & 7, 0x04);
duke@0 1373 emit_rm(cbuf, 0x0, 0x04, RSP_enc);
duke@0 1374 emit_d32(cbuf, offset);
duke@0 1375 } else {
duke@0 1376 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR);
duke@0 1377 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset]
duke@0 1378 emit_rm(cbuf, 0x1, reg & 7, 0x04);
duke@0 1379 emit_rm(cbuf, 0x0, 0x04, RSP_enc);
duke@0 1380 emit_d8(cbuf, offset);
duke@0 1381 }
duke@0 1382 }
duke@0 1383
duke@0 1384 uint BoxLockNode::size(PhaseRegAlloc *ra_) const
duke@0 1385 {
duke@0 1386 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
duke@0 1387 return (offset < 0x80) ? 5 : 8; // REX
duke@0 1388 }
duke@0 1389
duke@0 1390 //=============================================================================
duke@0 1391 #ifndef PRODUCT
duke@0 1392 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
duke@0 1393 {
ehelin@5259 1394 if (UseCompressedClassPointers) {
kvn@1491 1395 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
hseigel@5093 1396 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1");
kvn@1491 1397 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check");
coleenp@113 1398 } else {
kvn@1491 1399 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t"
kvn@1491 1400 "# Inline cache check");
coleenp@113 1401 }
duke@0 1402 st->print_cr("\tjne SharedRuntime::_ic_miss_stub");
kvn@1491 1403 st->print_cr("\tnop\t# nops to align entry point");
duke@0 1404 }
duke@0 1405 #endif
duke@0 1406
duke@0 1407 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
duke@0 1408 {
duke@0 1409 MacroAssembler masm(&cbuf);
twisti@1668 1410 uint insts_size = cbuf.insts_size();
ehelin@5259 1411 if (UseCompressedClassPointers) {
coleenp@113 1412 masm.load_klass(rscratch1, j_rarg0);
never@304 1413 masm.cmpptr(rax, rscratch1);
coleenp@113 1414 } else {
never@304 1415 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes()));
coleenp@113 1416 }
duke@0 1417
duke@0 1418 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
duke@0 1419
duke@0 1420 /* WARNING these NOPs are critical so that verified entry point is properly
kvn@1491 1421 4 bytes aligned for patching by NativeJump::patch_verified_entry() */
twisti@1668 1422 int nops_cnt = 4 - ((cbuf.insts_size() - insts_size) & 0x3);
kvn@1491 1423 if (OptoBreakpoint) {
duke@0 1424 // Leave space for int3
kvn@1491 1425 nops_cnt -= 1;
duke@0 1426 }
kvn@1491 1427 nops_cnt &= 0x3; // Do not add nops if code is aligned.
kvn@1491 1428 if (nops_cnt > 0)
kvn@1491 1429 masm.nop(nops_cnt);
duke@0 1430 }
duke@0 1431
duke@0 1432 uint MachUEPNode::size(PhaseRegAlloc* ra_) const
duke@0 1433 {
kvn@1491 1434 return MachNode::size(ra_); // too many variables; just compute it
kvn@1491 1435 // the hard way
duke@0 1436 }
duke@0 1437
duke@0 1438
duke@0 1439 //=============================================================================
duke@0 1440 uint size_exception_handler()
duke@0 1441 {
duke@0 1442 // NativeCall instruction size is the same as NativeJump.
duke@0 1443 // Note that this value is also credited (in output.cpp) to
duke@0 1444 // the size of the code section.
duke@0 1445 return NativeJump::instruction_size;
duke@0 1446 }
duke@0 1447
duke@0 1448 // Emit exception handler code.
duke@0 1449 int emit_exception_handler(CodeBuffer& cbuf)
duke@0 1450 {
duke@0 1451
twisti@1668 1452 // Note that the code buffer's insts_mark is always relative to insts.
duke@0 1453 // That's why we must use the macroassembler to generate a handler.
duke@0 1454 MacroAssembler _masm(&cbuf);
duke@0 1455 address base =
duke@0 1456 __ start_a_stub(size_exception_handler());
duke@0 1457 if (base == NULL) return 0; // CodeBuffer::expand failed
duke@0 1458 int offset = __ offset();
twisti@1668 1459 __ jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point()));
duke@0 1460 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow");
duke@0 1461 __ end_a_stub();
duke@0 1462 return offset;
duke@0 1463 }
duke@0 1464
duke@0 1465 uint size_deopt_handler()
duke@0 1466 {
duke@0 1467 // three 5 byte instructions
duke@0 1468 return 15;
duke@0 1469 }
duke@0 1470
duke@0 1471 // Emit deopt handler code.
duke@0 1472 int emit_deopt_handler(CodeBuffer& cbuf)
duke@0 1473 {
duke@0 1474
twisti@1668 1475 // Note that the code buffer's insts_mark is always relative to insts.
duke@0 1476 // That's why we must use the macroassembler to generate a handler.
duke@0 1477 MacroAssembler _masm(&cbuf);
duke@0 1478 address base =
duke@0 1479 __ start_a_stub(size_deopt_handler());
duke@0 1480 if (base == NULL) return 0; // CodeBuffer::expand failed
duke@0 1481 int offset = __ offset();
duke@0 1482 address the_pc = (address) __ pc();
duke@0 1483 Label next;
duke@0 1484 // push a "the_pc" on the stack without destroying any registers
duke@0 1485 // as they all may be live.
duke@0 1486
duke@0 1487 // push address of "next"
duke@0 1488 __ call(next, relocInfo::none); // reloc none is fine since it is a disp32
duke@0 1489 __ bind(next);
duke@0 1490 // adjust it so it matches "the_pc"
never@304 1491 __ subptr(Address(rsp, 0), __ offset() - offset);
duke@0 1492 __ jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack()));
duke@0 1493 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
duke@0 1494 __ end_a_stub();
duke@0 1495 return offset;
duke@0 1496 }
duke@0 1497
duke@0 1498 int Matcher::regnum_to_fpu_offset(int regnum)
duke@0 1499 {
duke@0 1500 return regnum - 32; // The FP registers are in the second chunk
duke@0 1501 }
duke@0 1502
duke@0 1503 // This is UltraSparc specific, true just means we have fast l2f conversion
duke@0 1504 const bool Matcher::convL2FSupported(void) {
duke@0 1505 return true;
duke@0 1506 }
duke@0 1507
duke@0 1508 // Is this branch offset short enough that a short branch can be used?
duke@0 1509 //
duke@0 1510 // NOTE: If the platform does not provide any short branch variants, then
duke@0 1511 // this method should return false for offset 0.
kvn@2614 1512 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
kvn@2614 1513 // The passed offset is relative to address of the branch.
kvn@2614 1514 // On 86 a branch displacement is calculated relative to address
kvn@2614 1515 // of a next instruction.
kvn@2614 1516 offset -= br_size;
kvn@2614 1517
never@415 1518 // the short version of jmpConUCF2 contains multiple branches,
never@415 1519 // making the reach slightly less
never@415 1520 if (rule == jmpConUCF2_rule)
never@415 1521 return (-126 <= offset && offset <= 125);
never@415 1522 return (-128 <= offset && offset <= 127);
duke@0 1523 }
duke@0 1524
duke@0 1525 const bool Matcher::isSimpleConstant64(jlong value) {
duke@0 1526 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?.
duke@0 1527 //return value == (int) value; // Cf. storeImmL and immL32.
duke@0 1528
duke@0 1529 // Probably always true, even if a temp register is required.
duke@0 1530 return true;
duke@0 1531 }
duke@0 1532
duke@0 1533 // The ecx parameter to rep stosq for the ClearArray node is in words.
duke@0 1534 const bool Matcher::init_array_count_is_in_bytes = false;
duke@0 1535
duke@0 1536 // Threshold size for cleararray.
duke@0 1537 const int Matcher::init_array_short_size = 8 * BytesPerLong;
duke@0 1538
kvn@2808 1539 // No additional cost for CMOVL.
kvn@2808 1540 const int Matcher::long_cmove_cost() { return 0; }
kvn@2808 1541
kvn@2808 1542 // No CMOVF/CMOVD with SSE2
kvn@2808 1543 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; }
kvn@2808 1544
duke@0 1545 // Should the Matcher clone shifts on addressing modes, expecting them
duke@0 1546 // to be subsumed into complex addressing expressions or compute them
duke@0 1547 // into registers? True for Intel but false for most RISCs
duke@0 1548 const bool Matcher::clone_shift_expressions = true;
duke@0 1549
roland@2248 1550 // Do we need to mask the count passed to shift instructions or does
roland@2248 1551 // the cpu only look at the lower 5/6 bits anyway?
roland@2248 1552 const bool Matcher::need_masked_shift_count = false;
roland@2248 1553
kvn@1495 1554 bool Matcher::narrow_oop_use_complex_address() {
kvn@1495 1555 assert(UseCompressedOops, "only for compressed oops code");
kvn@1495 1556 return (LogMinObjAlignmentInBytes <= 3);
kvn@1495 1557 }
kvn@1495 1558
roland@3724 1559 bool Matcher::narrow_klass_use_complex_address() {
ehelin@5259 1560 assert(UseCompressedClassPointers, "only for compressed klass code");
roland@3724 1561 return (LogKlassAlignmentInBytes <= 3);
roland@3724 1562 }
roland@3724 1563
duke@0 1564 // Is it better to copy float constants, or load them directly from
duke@0 1565 // memory? Intel can load a float constant from a direct address,
duke@0 1566 // requiring no extra registers. Most RISCs will have to materialize
duke@0 1567 // an address into a register first, so they would do better to copy
duke@0 1568 // the constant from stack.
duke@0 1569 const bool Matcher::rematerialize_float_constants = true; // XXX
duke@0 1570
duke@0 1571 // If CPU can load and store mis-aligned doubles directly then no
duke@0 1572 // fixup is needed. Else we split the double into 2 integer pieces
duke@0 1573 // and move it piece-by-piece. Only happens when passing doubles into
duke@0 1574 // C code as the Java calling convention forces doubles to be aligned.
duke@0 1575 const bool Matcher::misaligned_doubles_ok = true;
duke@0 1576
duke@0 1577 // No-op on amd64
duke@0 1578 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {}
duke@0 1579
duke@0 1580 // Advertise here if the CPU requires explicit rounding operations to
duke@0 1581 // implement the UseStrictFP mode.
duke@0 1582 const bool Matcher::strict_fp_requires_explicit_rounding = true;
duke@0 1583
kvn@1274 1584 // Are floats conerted to double when stored to stack during deoptimization?
kvn@1274 1585 // On x64 it is stored without convertion so we can use normal access.
kvn@1274 1586 bool Matcher::float_in_double() { return false; }
kvn@1274 1587
duke@0 1588 // Do ints take an entire long register or just half?
duke@0 1589 const bool Matcher::int_in_long = true;
duke@0 1590
duke@0 1591 // Return whether or not this register is ever used as an argument.
duke@0 1592 // This function is used on startup to build the trampoline stubs in
duke@0 1593 // generateOptoStub. Registers not mentioned will be killed by the VM
duke@0 1594 // call in the trampoline, and arguments in those registers not be
duke@0 1595 // available to the callee.
duke@0 1596 bool Matcher::can_be_java_arg(int reg)
duke@0 1597 {
duke@0 1598 return
kvn@3447 1599 reg == RDI_num || reg == RDI_H_num ||
kvn@3447 1600 reg == RSI_num || reg == RSI_H_num ||
kvn@3447 1601 reg == RDX_num || reg == RDX_H_num ||
kvn@3447 1602 reg == RCX_num || reg == RCX_H_num ||
kvn@3447 1603 reg == R8_num || reg == R8_H_num ||
kvn@3447 1604 reg == R9_num || reg == R9_H_num ||
kvn@3447 1605 reg == R12_num || reg == R12_H_num ||
kvn@3447 1606 reg == XMM0_num || reg == XMM0b_num ||
kvn@3447 1607 reg == XMM1_num || reg == XMM1b_num ||
kvn@3447 1608 reg == XMM2_num || reg == XMM2b_num ||
kvn@3447 1609 reg == XMM3_num || reg == XMM3b_num ||
kvn@3447 1610 reg == XMM4_num || reg == XMM4b_num ||
kvn@3447 1611 reg == XMM5_num || reg == XMM5b_num ||
kvn@3447 1612 reg == XMM6_num || reg == XMM6b_num ||
kvn@3447 1613 reg == XMM7_num || reg == XMM7b_num;
duke@0 1614 }
duke@0 1615
duke@0 1616 bool Matcher::is_spillable_arg(int reg)
duke@0 1617 {
duke@0 1618 return can_be_java_arg(reg);
duke@0 1619 }
duke@0 1620
kvn@1834 1621 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) {
kvn@1834 1622 // In 64 bit mode a code which use multiply when
kvn@1834 1623 // devisor is constant is faster than hardware
kvn@1834 1624 // DIV instruction (it uses MulHiL).
kvn@1834 1625 return false;
kvn@1834 1626 }
kvn@1834 1627
duke@0 1628 // Register for DIVI projection of divmodI
duke@0 1629 RegMask Matcher::divI_proj_mask() {
roland@2882 1630 return INT_RAX_REG_mask();
duke@0 1631 }
duke@0 1632
duke@0 1633 // Register for MODI projection of divmodI
duke@0 1634 RegMask Matcher::modI_proj_mask() {
roland@2882 1635 return INT_RDX_REG_mask();
duke@0 1636 }
duke@0 1637
duke@0 1638 // Register for DIVL projection of divmodL
duke@0 1639 RegMask Matcher::divL_proj_mask() {
roland@2882 1640 return LONG_RAX_REG_mask();
duke@0 1641 }
duke@0 1642
duke@0 1643 // Register for MODL projection of divmodL
duke@0 1644 RegMask Matcher::modL_proj_mask() {
roland@2882 1645 return LONG_RDX_REG_mask();
duke@0 1646 }
duke@0 1647
twisti@1137 1648 const RegMask Matcher::method_handle_invoke_SP_save_mask() {
roland@2882 1649 return PTR_RBP_REG_mask();
twisti@1137 1650 }
twisti@1137 1651
duke@0 1652 %}
duke@0 1653
duke@0 1654 //----------ENCODING BLOCK-----------------------------------------------------
duke@0 1655 // This block specifies the encoding classes used by the compiler to
duke@0 1656 // output byte streams. Encoding classes are parameterized macros
duke@0 1657 // used by Machine Instruction Nodes in order to generate the bit
duke@0 1658 // encoding of the instruction. Operands specify their base encoding
duke@0 1659 // interface with the interface keyword. There are currently
duke@0 1660 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, &
duke@0 1661 // COND_INTER. REG_INTER causes an operand to generate a function
duke@0 1662 // which returns its register number when queried. CONST_INTER causes
duke@0 1663 // an operand to generate a function which returns the value of the
duke@0 1664 // constant when queried. MEMORY_INTER causes an operand to generate
duke@0 1665 // four functions which return the Base Register, the Index Register,
duke@0 1666 // the Scale Value, and the Offset Value of the operand when queried.
duke@0 1667 // COND_INTER causes an operand to generate six functions which return
duke@0 1668 // the encoding code (ie - encoding bits for the instruction)
duke@0 1669 // associated with each basic boolean condition for a conditional
duke@0 1670 // instruction.
duke@0 1671 //
duke@0 1672 // Instructions specify two basic values for encoding. Again, a
duke@0 1673 // function is available to check if the constant displacement is an
duke@0 1674 // oop. They use the ins_encode keyword to specify their encoding
duke@0 1675 // classes (which must be a sequence of enc_class names, and their
duke@0 1676 // parameters, specified in the encoding block), and they use the
duke@0 1677 // opcode keyword to specify, in order, their primary, secondary, and
duke@0 1678 // tertiary opcode. Only the opcode sections which a particular
duke@0 1679 // instruction needs for encoding need to be specified.
duke@0 1680 encode %{
duke@0 1681 // Build emit functions for each basic byte or larger field in the
duke@0 1682 // intel encoding scheme (opcode, rm, sib, immediate), and call them
duke@0 1683 // from C++ code in the enc_class source block. Emit functions will
duke@0 1684 // live in the main source block for now. In future, we can
duke@0 1685 // generalize this by adding a syntax that specifies the sizes of
duke@0 1686 // fields in an order, so that the adlc can build the emit functions
duke@0 1687 // automagically
duke@0 1688
duke@0 1689 // Emit primary opcode
duke@0 1690 enc_class OpcP
duke@0 1691 %{
duke@0 1692 emit_opcode(cbuf, $primary);
duke@0 1693 %}
duke@0 1694
duke@0 1695 // Emit secondary opcode
duke@0 1696 enc_class OpcS
duke@0 1697 %{
duke@0 1698 emit_opcode(cbuf, $secondary);
duke@0 1699 %}
duke@0 1700
duke@0 1701 // Emit tertiary opcode
duke@0 1702 enc_class OpcT
duke@0 1703 %{
duke@0 1704 emit_opcode(cbuf, $tertiary);
duke@0 1705 %}
duke@0 1706
duke@0 1707 // Emit opcode directly
duke@0 1708 enc_class Opcode(immI d8)
duke@0 1709 %{
duke@0 1710 emit_opcode(cbuf, $d8$$constant);
duke@0 1711 %}
duke@0 1712
duke@0 1713 // Emit size prefix
duke@0 1714 enc_class SizePrefix
duke@0 1715 %{
duke@0 1716 emit_opcode(cbuf, 0x66);
duke@0 1717 %}
duke@0 1718
duke@0 1719 enc_class reg(rRegI reg)
duke@0 1720 %{
duke@0 1721 emit_rm(cbuf, 0x3, 0, $reg$$reg & 7);
duke@0 1722 %}
duke@0 1723
duke@0 1724 enc_class reg_reg(rRegI dst, rRegI src)
duke@0 1725 %{
duke@0 1726 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7);
duke@0 1727 %}
duke@0 1728
duke@0 1729 enc_class opc_reg_reg(immI opcode, rRegI dst, rRegI src)
duke@0 1730 %{
duke@0 1731 emit_opcode(cbuf, $opcode$$constant);
duke@0 1732 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7);
duke@0 1733 %}
duke@0 1734
duke@0 1735 enc_class cdql_enc(no_rax_rdx_RegI div)
duke@0 1736 %{
duke@0 1737 // Full implementation of Java idiv and irem; checks for
duke@0 1738 // special case as described in JVM spec., p.243 & p.271.
duke@0 1739 //
duke@0 1740 // normal case special case
duke@0 1741 //
duke@0 1742 // input : rax: dividend min_int
duke@0 1743 // reg: divisor -1
duke@0 1744 //
duke@0 1745 // output: rax: quotient (= rax idiv reg) min_int
duke@0 1746 // rdx: remainder (= rax irem reg) 0
duke@0 1747 //
duke@0 1748 // Code sequnce:
duke@0 1749 //
duke@0 1750 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax
duke@0 1751 // 5: 75 07/08 jne e <normal>
duke@0 1752 // 7: 33 d2 xor %edx,%edx
duke@0 1753 // [div >= 8 -> offset + 1]
duke@0 1754 // [REX_B]
duke@0 1755 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div
duke@0 1756 // c: 74 03/04 je 11 <done>
duke@0 1757 // 000000000000000e <normal>:
duke@0 1758 // e: 99 cltd
duke@0 1759 // [div >= 8 -> offset + 1]
duke@0 1760 // [REX_B]
duke@0 1761 // f: f7 f9 idiv $div
duke@0 1762 // 0000000000000011 <done>:
duke@0 1763
duke@0 1764 // cmp $0x80000000,%eax
duke@0 1765 emit_opcode(cbuf, 0x3d);
duke@0 1766 emit_d8(cbuf, 0x00);
duke@0 1767 emit_d8(cbuf, 0x00);
duke@0 1768 emit_d8(cbuf, 0x00);
duke@0 1769 emit_d8(cbuf, 0x80);
duke@0 1770
duke@0 1771 // jne e <normal>
duke@0 1772 emit_opcode(cbuf, 0x75);
duke@0 1773 emit_d8(cbuf, $div$$reg < 8 ? 0x07 : 0x08);
duke@0 1774
duke@0 1775 // xor %edx,%edx
duke@0 1776 emit_opcode(cbuf, 0x33);
duke@0 1777 emit_d8(cbuf, 0xD2);
duke@0 1778
duke@0 1779 // cmp $0xffffffffffffffff,%ecx
duke@0 1780 if ($div$$reg >= 8) {
duke@0 1781 emit_opcode(cbuf, Assembler::REX_B);
duke@0 1782 }
duke@0 1783 emit_opcode(cbuf, 0x83);
duke@0 1784 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7);
duke@0 1785 emit_d8(cbuf, 0xFF);
duke@0 1786
duke@0 1787 // je 11 <done>
duke@0 1788 emit_opcode(cbuf, 0x74);
duke@0 1789 emit_d8(cbuf, $div$$reg < 8 ? 0x03 : 0x04);
duke@0 1790
duke@0 1791 // <normal>
duke@0 1792 // cltd
duke@0 1793 emit_opcode(cbuf, 0x99);
duke@0 1794
duke@0 1795 // idivl (note: must be emitted by the user of this rule)
duke@0 1796 // <done>
duke@0 1797 %}
duke@0 1798
duke@0 1799 enc_class cdqq_enc(no_rax_rdx_RegL div)
duke@0 1800 %{
duke@0 1801 // Full implementation of Java ldiv and lrem; checks for
duke@0 1802 // special case as described in JVM spec., p.243 & p.271.
duke@0 1803 //
duke@0 1804 // normal case special case
duke@0 1805 //
duke@0 1806 // input : rax: dividend min_long
duke@0 1807 // reg: divisor -1
duke@0 1808 //
duke@0 1809 // output: rax: quotient (= rax idiv reg) min_long
duke@0 1810 // rdx: remainder (= rax irem reg) 0
duke@0 1811 //
duke@0 1812 // Code sequnce:
duke@0 1813 //
duke@0 1814 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx
duke@0 1815 // 7: 00 00 80
duke@0 1816 // a: 48 39 d0 cmp %rdx,%rax
duke@0 1817 // d: 75 08 jne 17 <normal>
duke@0 1818 // f: 33 d2 xor %edx,%edx
duke@0 1819 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div
duke@0 1820 // 15: 74 05 je 1c <done>
duke@0 1821 // 0000000000000017 <normal>:
duke@0 1822 // 17: 48 99 cqto
duke@0 1823 // 19: 48 f7 f9 idiv $div
duke@0 1824 // 000000000000001c <done>:
duke@0 1825
duke@0 1826 // mov $0x8000000000000000,%rdx
duke@0 1827 emit_opcode(cbuf, Assembler::REX_W);
duke@0 1828 emit_opcode(cbuf, 0xBA);
duke@0 1829 emit_d8(cbuf, 0x00);
duke@0 1830 emit_d8(cbuf, 0x00);
duke@0 1831 emit_d8(cbuf, 0x00);
duke@0 1832 emit_d8(cbuf, 0x00);
duke@0 1833 emit_d8(cbuf, 0x00);
duke@0 1834 emit_d8(cbuf, 0x00);
duke@0 1835 emit_d8(cbuf, 0x00);
duke@0 1836 emit_d8(cbuf, 0x80);
duke@0 1837
duke@0 1838 // cmp %rdx,%rax
duke@0 1839 emit_opcode(cbuf, Assembler::REX_W);
duke@0 1840 emit_opcode(cbuf, 0x39);
duke@0 1841 emit_d8(cbuf, 0xD0);
duke@0 1842
duke@0 1843 // jne 17 <normal>
duke@0 1844 emit_opcode(cbuf, 0x75);
duke@0 1845 emit_d8(cbuf, 0x08);
duke@0 1846
duke@0 1847 // xor %edx,%edx
duke@0 1848 emit_opcode(cbuf, 0x33);
duke@0 1849 emit_d8(cbuf, 0xD2);
duke@0 1850
duke@0 1851 // cmp $0xffffffffffffffff,$div
duke@0 1852 emit_opcode(cbuf, $div$$reg < 8 ? Assembler::REX_W : Assembler::REX_WB);
duke@0 1853 emit_opcode(cbuf, 0x83);
duke@0 1854 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7);
duke@0 1855 emit_d8(cbuf, 0xFF);
duke@0 1856
duke@0 1857 // je 1e <done>
duke@0 1858 emit_opcode(cbuf, 0x74);
duke@0 1859 emit_d8(cbuf, 0x05);
duke@0 1860
duke@0 1861 // <normal>
duke@0 1862 // cqto
duke@0 1863 emit_opcode(cbuf, Assembler::REX_W);
duke@0 1864 emit_opcode(cbuf, 0x99);
duke@0 1865
duke@0 1866 // idivq (note: must be emitted by the user of this rule)
duke@0 1867 // <done>
duke@0 1868 %}
duke@0 1869
duke@0 1870 // Opcde enc_class for 8/32 bit immediate instructions with sign-extension
duke@0 1871 enc_class OpcSE(immI imm)
duke@0 1872 %{
duke@0 1873 // Emit primary opcode and set sign-extend bit
duke@0 1874 // Check for 8-bit immediate, and set sign extend bit in opcode
duke@0 1875 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) {
duke@0 1876 emit_opcode(cbuf, $primary | 0x02);
duke@0 1877 } else {
duke@0 1878 // 32-bit immediate
duke@0 1879 emit_opcode(cbuf, $primary);
duke@0 1880 }
duke@0 1881 %}
duke@0 1882
duke@0 1883 enc_class OpcSErm(rRegI dst, immI imm)
duke@0 1884 %{
duke@0 1885 // OpcSEr/m
duke@0 1886 int dstenc = $dst$$reg;
duke@0 1887 if (dstenc >= 8) {
duke@0 1888 emit_opcode(cbuf, Assembler::REX_B);
duke@0 1889 dstenc -= 8;
duke@0 1890 }
duke@0 1891 // Emit primary opcode and set sign-extend bit
duke@0 1892 // Check for 8-bit immediate, and set sign extend bit in opcode
duke@0 1893 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) {
duke@0 1894 emit_opcode(cbuf, $primary | 0x02);
duke@0 1895 } else {
duke@0 1896 // 32-bit immediate
duke@0 1897 emit_opcode(cbuf, $primary);
duke@0 1898 }
duke@0 1899 // Emit r/m byte with secondary opcode, after primary opcode.
duke@0 1900 emit_rm(cbuf, 0x3, $secondary, dstenc);
duke@0 1901 %}
duke@0 1902
duke@0 1903 enc_class OpcSErm_wide(rRegL dst, immI imm)
duke@0 1904 %{
duke@0 1905 // OpcSEr/m
duke@0 1906 int dstenc = $dst$$reg;
duke@0 1907 if (dstenc < 8) {
duke@0 1908 emit_opcode(cbuf, Assembler::REX_W);
duke@0 1909 } else {
duke@0 1910 emit_opcode(cbuf, Assembler::REX_WB);
duke@0 1911 dstenc -= 8;
duke@0 1912 }
duke@0 1913 // Emit primary opcode and set sign-extend bit
duke@0 1914 // Check for 8-bit immediate, and set sign extend bit in opcode
duke@0 1915 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) {
duke@0 1916 emit_opcode(cbuf, $primary | 0x02);
duke@0 1917 } else {
duke@0 1918 // 32-bit immediate
duke@0 1919 emit_opcode(cbuf, $primary);
duke@0 1920 }
duke@0 1921 // Emit r/m byte with secondary opcode, after primary opcode.
duke@0 1922 emit_rm(cbuf, 0x3, $secondary, dstenc);
duke@0 1923 %}
duke@0 1924
duke@0 1925 enc_class Con8or32(immI imm)
duke@0 1926 %{
duke@0 1927 // Check for 8-bit immediate, and set sign extend bit in opcode
duke@0 1928 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) {
duke@0 1929 $$$emit8$imm$$constant;
duke@0 1930 } else {
duke@0 1931 // 32-bit immediate
duke@0 1932 $$$emit32$imm$$constant;
duke@0 1933 }
duke@0 1934 %}
duke@0 1935
duke@0 1936 enc_class opc2_reg(rRegI dst)
duke@0 1937 %{
duke@0 1938 // BSWAP
duke@0 1939 emit_cc(cbuf, $secondary, $dst$$reg);
duke@0 1940 %}
duke@0 1941
duke@0 1942 enc_class opc3_reg(rRegI dst)
duke@0 1943 %{
duke@0 1944 // BSWAP
duke@0 1945 emit_cc(cbuf, $tertiary, $dst$$reg);
duke@0 1946 %}
duke@0 1947
duke@0 1948 enc_class reg_opc(rRegI div)
duke@0 1949 %{
duke@0 1950 // INC, DEC, IDIV, IMOD, JMP indirect, ...
duke@0 1951 emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7);
duke@0 1952 %}
duke@0 1953
duke@0 1954 enc_class enc_cmov(cmpOp cop)
duke@0 1955 %{
duke@0 1956 // CMOV
duke@0 1957 $$$emit8$primary;
duke@0 1958 emit_cc(cbuf, $secondary, $cop$$cmpcode);
duke@0 1959 %}
duke@0 1960
duke@0 1961 enc_class enc_PartialSubtypeCheck()
duke@0 1962 %{
duke@0 1963 Register Rrdi = as_Register(RDI_enc); // result register
duke@0 1964 Register Rrax = as_Register(RAX_enc); // super class
duke@0 1965 Register Rrcx = as_Register(RCX_enc); // killed
duke@0 1966 Register Rrsi = as_Register(RSI_enc); // sub class
jrose@644 1967 Label miss;
jrose@644 1968 const bool set_cond_codes = true;
duke@0 1969
duke@0 1970 MacroAssembler _masm(&cbuf);
jrose@644 1971 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi,
jrose@644 1972 NULL, &miss,
jrose@644 1973 /*set_cond_codes:*/ true);
duke@0 1974 if ($primary) {
never@304 1975 __ xorptr(Rrdi, Rrdi);
duke@0 1976 }
duke@0 1977 __ bind(miss);
duke@0 1978 %}
duke@0 1979
kvn@4438 1980 enc_class clear_avx %{
kvn@4438 1981 debug_only(int off0 = cbuf.insts_size());
kvn@4438 1982 if (ra_->C->max_vector_size() > 16) {
kvn@4438 1983 // Clear upper bits of YMM registers when current compiled code uses
kvn@4438 1984 // wide vectors to avoid AVX <-> SSE transition penalty during call.
kvn@4438 1985 MacroAssembler _masm(&cbuf);
kvn@4438 1986 __ vzeroupper();
kvn@4438 1987 }
kvn@4438 1988 debug_only(int off1 = cbuf.insts_size());
kvn@4438 1989 assert(off1 - off0 == clear_avx_size(), "correct size prediction");
kvn@4438 1990 %}
kvn@4438 1991
kvn@4438 1992 enc_class Java_To_Runtime(method meth) %{
kvn@4438 1993 // No relocation needed
kvn@4438 1994 MacroAssembler _masm(&cbuf);
kvn@4438 1995 __ mov64(r10, (int64_t) $meth$$method);
kvn@4438 1996 __ call(r10);
kvn@4438 1997 %}
kvn@4438 1998
duke@0 1999 enc_class Java_To_Interpreter(method meth)
duke@0 2000 %{
duke@0 2001 // CALL Java_To_Interpreter
duke@0 2002 // This is the instruction starting address for relocation info.
twisti@1668 2003 cbuf.set_insts_mark();
duke@0 2004 $$$emit8$primary;
duke@0 2005 // CALL directly to the runtime
duke@0 2006 emit_d32_reloc(cbuf,
twisti@1668 2007 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4),
duke@0 2008 runtime_call_Relocation::spec(),
duke@0 2009 RELOC_DISP32);
duke@0 2010 %}
duke@0 2011
duke@0 2012 enc_class Java_Static_Call(method meth)
duke@0 2013 %{
duke@0 2014 // JAVA STATIC CALL
duke@0 2015 // CALL to fixup routine. Fixup routine uses ScopeDesc info to
duke@0 2016 // determine who we intended to call.
twisti@1668 2017 cbuf.set_insts_mark();
duke@0 2018 $$$emit8$primary;
duke@0 2019
duke@0 2020 if (!_method) {
duke@0 2021 emit_d32_reloc(cbuf,
twisti@1668 2022 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4),
duke@0 2023 runtime_call_Relocation::spec(),
duke@0 2024 RELOC_DISP32);
duke@0 2025 } else if (_optimized_virtual) {
duke@0 2026 emit_d32_reloc(cbuf,
twisti@1668 2027 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4),
duke@0 2028 opt_virtual_call_Relocation::spec(),
duke@0 2029 RELOC_DISP32);
duke@0 2030 } else {
duke@0 2031 emit_d32_reloc(cbuf,
twisti@1668 2032 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4),
duke@0 2033 static_call_Relocation::spec(),
duke@0 2034 RELOC_DISP32);
duke@0 2035 }
duke@0 2036 if (_method) {
dlong@4565 2037 // Emit stub for static call.
dlong@4565 2038 CompiledStaticCall::emit_to_interp_stub(cbuf);
duke@0 2039 }
duke@0 2040 %}
duke@0 2041
coleenp@3602 2042 enc_class Java_Dynamic_Call(method meth) %{
coleenp@3602 2043 MacroAssembler _masm(&cbuf);
coleenp@3602 2044 __ ic_call((address)$meth$$method);
duke@0 2045 %}
duke@0 2046
duke@0 2047 enc_class Java_Compiled_Call(method meth)
duke@0 2048 %{
duke@0 2049 // JAVA COMPILED CALL
coleenp@3602 2050 int disp = in_bytes(Method:: from_compiled_offset());
duke@0 2051
duke@0 2052 // XXX XXX offset is 128 is 1.5 NON-PRODUCT !!!
duke@0 2053 // assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small");
duke@0 2054
duke@0 2055 // callq *disp(%rax)
twisti@1668 2056 cbuf.set_insts_mark();
duke@0 2057 $$$emit8$primary;
duke@0 2058 if (disp < 0x80) {
duke@0 2059 emit_rm(cbuf, 0x01, $secondary, RAX_enc); // R/M byte
duke@0 2060 emit_d8(cbuf, disp); // Displacement
duke@0 2061 } else {
duke@0 2062 emit_rm(cbuf, 0x02, $secondary, RAX_enc); // R/M byte
duke@0 2063 emit_d32(cbuf, disp); // Displacement
duke@0 2064 }
duke@0 2065 %}
duke@0 2066
duke@0 2067 enc_class reg_opc_imm(rRegI dst, immI8 shift)
duke@0 2068 %{
duke@0 2069 // SAL, SAR, SHR
duke@0 2070 int dstenc = $dst$$reg;
duke@0 2071 if (dstenc >= 8) {
duke@0 2072 emit_opcode(cbuf, Assembler::REX_B);
duke@0 2073 dstenc -= 8;
duke@0 2074 }
duke@0 2075 $$$emit8$primary;
duke@0 2076 emit_rm(cbuf, 0x3, $secondary, dstenc);
duke@0 2077 $$$emit8$shift$$constant;
duke@0 2078 %}
duke@0 2079
duke@0 2080 enc_class reg_opc_imm_wide(rRegL dst, immI8 shift)
duke@0 2081 %{
duke@0 2082 // SAL, SAR, SHR
duke@0 2083 int dstenc = $dst$$reg;
duke@0 2084 if (dstenc < 8) {
duke@0 2085 emit_opcode(cbuf, Assembler::REX_W);
duke@0 2086 } else {
duke@0 2087 emit_opcode(cbuf, Assembler::REX_WB);
duke@0 2088 dstenc -= 8;
duke@0 2089 }
duke@0 2090 $$$emit8$primary;
duke@0 2091 emit_rm(cbuf, 0x3, $secondary, dstenc);
duke@0 2092 $$$emit8$shift$$constant;
duke@0 2093 %}
duke@0 2094
duke@0 2095 enc_class load_immI(rRegI dst, immI src)
duke@0 2096 %{
duke@0 2097 int dstenc = $dst$$reg;
duke@0 2098 if (dstenc >= 8) {
duke@0 2099 emit_opcode(cbuf, Assembler::REX_B);
duke@0 2100 dstenc -= 8;
duke@0 2101 }
duke@0 2102 emit_opcode(cbuf, 0xB8 | dstenc);
duke@0 2103 $$$emit32$src$$constant;
duke@0 2104 %}
duke@0 2105
duke@0 2106 enc_class load_immL(rRegL dst, immL src)
duke@0 2107 %{
duke@0 2108 int dstenc = $dst$$reg;
duke@0 2109 if (dstenc < 8) {
duke@0 2110 emit_opcode(cbuf, Assembler::REX_W);
duke@0 2111 } else {
duke@0 2112 emit_opcode(cbuf, Assembler::REX_WB);
duke@0 2113 dstenc -= 8;
duke@0 2114 }
duke@0 2115 emit_opcode(cbuf, 0xB8 | dstenc);
duke@0 2116 emit_d64(cbuf, $src$$constant);
duke@0 2117 %}
duke@0 2118
duke@0 2119 enc_class load_immUL32(rRegL dst, immUL32 src)
duke@0 2120 %{
duke@0 2121 // same as load_immI, but this time we care about zeroes in the high word
duke@0 2122 int dstenc = $dst$$reg;
duke@0 2123 if (dstenc >= 8) {
duke@0 2124 emit_opcode(cbuf, Assembler::REX_B);
duke@0 2125 dstenc -= 8;
duke@0 2126 }
duke@0 2127 emit_opcode(cbuf, 0xB8 | dstenc);
duke@0 2128 $$$emit32$src$$constant;
duke@0 2129 %}
duke@0 2130
duke@0 2131 enc_class load_immL32(rRegL dst, immL32 src)
duke@0 2132 %{
duke@0 2133 int dstenc = $dst$$reg;
duke@0 2134 if (dstenc < 8) {
duke@0 2135 emit_opcode(cbuf, Assembler::REX_W);
duke@0 2136 } else {
duke@0 2137 emit_opcode(cbuf, Assembler::REX_WB);
duke@0 2138 dstenc -= 8;
duke@0 2139 }
duke@0 2140 emit_opcode(cbuf, 0xC7);
duke@0 2141 emit_rm(cbuf, 0x03, 0x00, dstenc);
duke@0 2142 $$$emit32$src$$constant;
duke@0 2143 %}
duke@0 2144
duke@0 2145 enc_class load_immP31(rRegP dst, immP32 src)
duke@0 2146 %{
duke@0 2147 // same as load_immI, but this time we care about zeroes in the high word
duke@0 2148 int dstenc = $dst$$reg;
duke@0 2149 if (dstenc >= 8) {
duke@0 2150 emit_opcode(cbuf, Assembler::REX_B);
duke@0 2151 dstenc -= 8;
duke@0 2152 }
duke@0 2153 emit_opcode(cbuf, 0xB8 | dstenc);
duke@0 2154 $$$emit32$src$$constant;
duke@0 2155 %}
duke@0 2156
duke@0 2157 enc_class load_immP(rRegP dst, immP src)
duke@0 2158 %{
duke@0 2159 int dstenc = $dst$$reg;
duke@0 2160 if (dstenc < 8) {
duke@0 2161 emit_opcode(cbuf, Assembler::REX_W);
duke@0 2162 } else {
duke@0 2163 emit_opcode(cbuf, Assembler::REX_WB);
duke@0 2164 dstenc -= 8;
duke@0 2165 }
duke@0 2166 emit_opcode(cbuf, 0xB8 | dstenc);
duke@0 2167 // This next line should be generated from ADLC
coleenp@3602 2168 if ($src->constant_reloc() != relocInfo::none) {
coleenp@3602 2169 emit_d64_reloc(cbuf, $src$$constant, $src->constant_reloc(), RELOC_IMM64);
duke@0 2170 } else {
duke@0 2171 emit_d64(cbuf, $src$$constant);
duke@0 2172 }
duke@0 2173 %}
duke@0 2174
duke@0 2175 enc_class Con32(immI src)
duke@0 2176 %{
duke@0 2177 // Output immediate
duke@0 2178 $$$emit32$src$$constant;
duke@0 2179 %}
duke@0 2180
duke@0 2181 enc_class Con32F_as_bits(immF src)
duke@0 2182 %{
duke@0 2183 // Output Float immediate bits
duke@0 2184 jfloat jf = $src$$constant;
duke@0 2185 jint jf_as_bits = jint_cast(jf);
duke@0 2186 emit_d32(cbuf, jf_as_bits);
duke@0 2187 %}
duke@0 2188
duke@0 2189 enc_class Con16(immI src)
duke@0 2190 %{
duke@0 2191 // Output immediate
duke@0 2192 $$$emit16$src$$constant;
duke@0 2193 %}
duke@0 2194
duke@0 2195 // How is this different from Con32??? XXX
duke@0 2196 enc_class Con_d32(immI src)
duke@0 2197 %{
duke@0 2198 emit_d32(cbuf,$src$$constant);
duke@0 2199 %}
duke@0 2200
duke@0 2201 enc_class conmemref (rRegP t1) %{ // Con32(storeImmI)
duke@0 2202 // Output immediate memory reference
duke@0 2203 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 );
duke@0 2204 emit_d32(cbuf, 0x00);
duke@0 2205 %}
duke@0 2206
duke@0 2207 enc_class lock_prefix()
duke@0 2208 %{
duke@0 2209 if (os::is_MP()) {
duke@0 2210 emit_opcode(cbuf, 0xF0); // lock
duke@0 2211 }
duke@0 2212 %}
duke@0 2213
duke@0 2214 enc_class REX_mem(memory mem)
duke@0 2215 %{
duke@0 2216 if ($mem$$base >= 8) {
duke@0 2217 if ($mem$$index < 8) {
duke@0 2218 emit_opcode(cbuf, Assembler::REX_B);
duke@0 2219 } else {
duke@0 2220 emit_opcode(cbuf, Assembler::REX_XB);
duke@0 2221 }
duke@0 2222 } else {
duke@0 2223 if ($mem$$index >= 8) {
duke@0 2224 emit_opcode(cbuf, Assembler::REX_X);
duke@0 2225 }
duke@0 2226 }
duke@0 2227 %}
duke@0 2228
duke@0 2229 enc_class REX_mem_wide(memory mem)
duke@0 2230 %{
duke@0 2231 if ($mem$$base >= 8) {
duke@0 2232 if ($mem$$index < 8) {
duke@0 2233 emit_opcode(cbuf, Assembler::REX_WB);
duke@0 2234 } else {
duke@0 2235 emit_opcode(cbuf, Assembler::REX_WXB);
duke@0 2236 }
duke@0 2237 } else {
duke@0 2238 if ($mem$$index < 8) {
duke@0 2239 emit_opcode(cbuf, Assembler::REX_W);
duke@0 2240 } else {
duke@0 2241 emit_opcode(cbuf, Assembler::REX_WX);
duke@0 2242 }
duke@0 2243 }
duke@0 2244 %}
duke@0 2245
duke@0 2246 // for byte regs
duke@0 2247 enc_class REX_breg(rRegI reg)
duke@0 2248 %{
duke@0 2249 if ($reg$$reg >= 4) {
duke@0 2250 emit_opcode(cbuf, $reg$$reg < 8 ? Assembler::REX : Assembler::REX_B);
duke@0 2251 }
duke@0 2252 %}
duke@0 2253
duke@0 2254 // for byte regs
duke@0 2255 enc_class REX_reg_breg(rRegI dst, rRegI src)
duke@0 2256 %{
duke@0 2257 if ($dst$$reg < 8) {
duke@0 2258 if ($src$$reg >= 4) {
duke@0 2259 emit_opcode(cbuf, $src$$reg < 8 ? Assembler::REX : Assembler::REX_B);
duke@0 2260 }
duke@0 2261 } else {
duke@0 2262 if ($src$$reg < 8) {
duke@0 2263 emit_opcode(cbuf, Assembler::REX_R);
duke@0 2264 } else {
duke@0 2265 emit_opcode(cbuf, Assembler::REX_RB);
duke@0 2266 }
duke@0 2267 }
duke@0 2268 %}
duke@0 2269
duke@0 2270 // for byte regs
duke@0 2271 enc_class REX_breg_mem(rRegI reg, memory mem)
duke@0 2272 %{
duke@0 2273 if ($reg$$reg < 8) {
duke@0 2274 if ($mem$$base < 8) {
duke@0 2275 if ($mem$$index >= 8) {
duke@0 2276 emit_opcode(cbuf, Assembler::REX_X);
duke@0 2277 } else if ($reg$$reg >= 4) {
duke@0 2278 emit_opcode(cbuf, Assembler::REX);
duke@0 2279 }
duke@0 2280 } else {
duke@0 2281 if ($mem$$index < 8) {
duke@0 2282 emit_opcode(cbuf, Assembler::REX_B);
duke@0 2283 } else {
duke@0 2284 emit_opcode(cbuf, Assembler::REX_XB);
duke@0 2285 }
duke@0 2286 }
duke@0 2287 } else {
duke@0 2288 if ($mem$$base < 8) {
duke@0 2289 if ($mem$$index < 8) {
duke@0 2290 emit_opcode(cbuf, Assembler::REX_R);
duke@0 2291 } else {
duke@0 2292 emit_opcode(cbuf, Assembler::REX_RX);
duke@0 2293 }
duke@0 2294 } else {
duke@0 2295 if ($mem$$index < 8) {
duke@0 2296 emit_opcode(cbuf, Assembler::REX_RB);
duke@0 2297 } else {
duke@0 2298 emit_opcode(cbuf, Assembler::REX_RXB);
duke@0 2299 }
duke@0 2300 }
duke@0 2301 }
duke@0 2302 %}
duke@0 2303
duke@0 2304 enc_class REX_reg(rRegI reg)
duke@0 2305 %{
duke@0 2306 if ($reg$$reg >= 8) {
duke@0 2307 emit_opcode(cbuf, Assembler::REX_B);
duke@0 2308 }
duke@0 2309 %}
duke@0 2310
duke@0 2311 enc_class REX_reg_wide(rRegI reg)
duke@0 2312 %{
duke@0 2313 if ($reg$$reg < 8) {
duke@0 2314 emit_opcode(cbuf, Assembler::REX_W);
duke@0 2315 } else {
duke@0 2316 emit_opcode(cbuf, Assembler::REX_WB);
duke@0 2317 }
duke@0 2318 %}
duke@0 2319
duke@0 2320 enc_class REX_reg_reg(rRegI dst, rRegI src)
duke@0 2321 %{
duke@0 2322 if ($dst$$reg < 8) {
duke@0 2323 if ($src$$reg >= 8) {
duke@0 2324 emit_opcode(cbuf, Assembler::REX_B);
duke@0 2325 }
duke@0 2326 } else {
duke@0 2327 if ($src$$reg < 8) {
duke@0 2328 emit_opcode(cbuf, Assembler::REX_R);
duke@0 2329 } else {
duke@0 2330 emit_opcode(cbuf, Assembler::REX_RB);
duke@0 2331 }
duke@0 2332 }
duke@0 2333 %}
duke@0 2334
duke@0 2335 enc_class REX_reg_reg_wide(rRegI dst, rRegI src)
duke@0 2336 %{
duke@0 2337 if ($dst$$reg < 8) {
duke@0 2338 if ($src$$reg < 8) {
duke@0 2339 emit_opcode(cbuf, Assembler::REX_W);
duke@0 2340 } else {
duke@0 2341 emit_opcode(cbuf, Assembler::REX_WB);
duke@0 2342 }
duke@0 2343 } else {
duke@0 2344 if ($src$$reg < 8) {
duke@0 2345 emit_opcode(cbuf, Assembler::REX_WR);
duke@0 2346 } else {
duke@0 2347 emit_opcode(cbuf, Assembler::REX_WRB);
duke@0 2348 }
duke@0 2349 }
duke@0 2350 %}
duke@0 2351
duke@0 2352 enc_class REX_reg_mem(rRegI reg, memory mem)
duke@0 2353 %{
duke@0 2354 if ($reg$$reg < 8) {
duke@0 2355 if ($mem$$base < 8) {
duke@0 2356 if ($mem$$index >= 8) {
duke@0 2357 emit_opcode(cbuf, Assembler::REX_X);
duke@0 2358 }
duke@0 2359 } else {
duke@0 2360 if ($mem$$index < 8) {
duke@0 2361 emit_opcode(cbuf, Assembler::REX_B);
duke@0 2362 } else {
duke@0 2363 emit_opcode(cbuf, Assembler::REX_XB);
duke@0 2364 }
duke@0 2365 }
duke@0 2366 } else {
duke@0 2367 if ($mem$$base < 8) {
duke@0 2368 if ($mem$$index < 8) {
duke@0 2369 emit_opcode(cbuf, Assembler::REX_R);
duke@0 2370 } else {
duke@0 2371 emit_opcode(cbuf, Assembler::REX_RX);
duke@0 2372 }
duke@0 2373 } else {
duke@0 2374 if ($mem$$index < 8) {
duke@0 2375 emit_opcode(cbuf, Assembler::REX_RB);
duke@0 2376 } else {
duke@0 2377 emit_opcode(cbuf, Assembler::REX_RXB);
duke@0 2378 }
duke@0 2379 }
duke@0 2380 }
duke@0 2381 %}
duke@0 2382
duke@0 2383 enc_class REX_reg_mem_wide(rRegL reg, memory mem)
duke@0 2384 %{
duke@0 2385 if ($reg$$reg < 8) {
duke@0 2386 if ($mem$$base < 8) {
duke@0 2387 if ($mem$$index < 8) {
duke@0 2388 emit_opcode(cbuf, Assembler::REX_W);
duke@0 2389 } else {
duke@0 2390 emit_opcode(cbuf, Assembler::REX_WX);
duke@0 2391 }
duke@0 2392 } else {
duke@0 2393 if ($mem$$index < 8) {
duke@0 2394 emit_opcode(cbuf, Assembler::REX_WB);
duke@0 2395 } else {
duke@0 2396 emit_opcode(cbuf, Assembler::REX_WXB);
duke@0 2397 }
duke@0 2398 }
duke@0 2399 } else {
duke@0 2400 if ($mem$$base < 8) {
duke@0 2401 if ($mem$$index < 8) {
duke@0 2402 emit_opcode(cbuf, Assembler::REX_WR);
duke@0 2403 } else {
duke@0 2404 emit_opcode(cbuf, Assembler::REX_WRX);
duke@0 2405 }
duke@0 2406 } else {
duke@0 2407 if ($mem$$index < 8) {
duke@0 2408 emit_opcode(cbuf, Assembler::REX_WRB);
duke@0 2409 } else {
duke@0 2410 emit_opcode(cbuf, Assembler::REX_WRXB);
duke@0 2411 }
duke@0 2412 }
duke@0 2413 }
duke@0 2414 %}
duke@0 2415
duke@0 2416 enc_class reg_mem(rRegI ereg, memory mem)
duke@0 2417 %{
duke@0 2418 // High registers handle in encode_RegMem
duke@0 2419 int reg = $ereg$$reg;
duke@0 2420 int base = $mem$$base;
duke@0 2421 int index = $mem$$index;
duke@0 2422 int scale = $mem$$scale;
duke@0 2423 int disp = $mem$$disp;
coleenp@3602 2424 relocInfo::relocType disp_reloc = $mem->disp_reloc();
coleenp@3602 2425
coleenp@3602 2426 encode_RegMem(cbuf, reg, base, index, scale, disp, disp_reloc);
duke@0 2427 %}
duke@0 2428
duke@0 2429 enc_class RM_opc_mem(immI rm_opcode, memory mem)
duke@0 2430 %{
duke@0 2431 int rm_byte_opcode = $rm_opcode$$constant;
duke@0 2432
duke@0 2433 // High registers handle in encode_RegMem
duke@0 2434 int base = $mem$$base;
duke@0 2435 int index = $mem$$index;
duke@0 2436 int scale = $mem$$scale;
duke@0 2437 int displace = $mem$$disp;
duke@0 2438
coleenp@3602 2439 relocInfo::relocType disp_reloc = $mem->disp_reloc(); // disp-as-oop when
duke@0 2440 // working with static
duke@0 2441 // globals
duke@0 2442 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace,
coleenp@3602 2443 disp_reloc);
duke@0 2444 %}
duke@0 2445
duke@0 2446 enc_class reg_lea(rRegI dst, rRegI src0, immI src1)
duke@0 2447 %{
duke@0 2448 int reg_encoding = $dst$$reg;
duke@0 2449 int base = $src0$$reg; // 0xFFFFFFFF indicates no base
duke@0 2450 int index = 0x04; // 0x04 indicates no index
duke@0 2451 int scale = 0x00; // 0x00 indicates no scale
duke@0 2452 int displace = $src1$$constant; // 0x00 indicates no displacement
coleenp@3602 2453 relocInfo::relocType disp_reloc = relocInfo::none;
duke@0 2454 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace,
coleenp@3602 2455 disp_reloc);
duke@0 2456 %}
duke@0 2457
duke@0 2458 enc_class neg_reg(rRegI dst)
duke@0 2459 %{
duke@0 2460 int dstenc = $dst$$reg;
duke@0 2461 if (dstenc >= 8) {
duke@0 2462 emit_opcode(cbuf, Assembler::REX_B);
duke@0 2463 dstenc -= 8;
duke@0 2464 }
duke@0 2465 // NEG $dst
duke@0 2466 emit_opcode(cbuf, 0xF7);
duke@0 2467 emit_rm(cbuf, 0x3, 0x03, dstenc);
duke@0 2468 %}
duke@0 2469
duke@0 2470 enc_class neg_reg_wide(rRegI dst)
duke@0 2471 %{
duke@0 2472 int dstenc = $dst$$reg;
duke@0 2473 if (dstenc < 8) {
duke@0 2474 emit_opcode(cbuf, Assembler::REX_W);
duke@0 2475 } else {
duke@0 2476 emit_opcode(cbuf, Assembler::REX_WB);
duke@0 2477 dstenc -= 8;
duke@0 2478 }
duke@0 2479 // NEG $dst
duke@0 2480 emit_opcode(cbuf, 0xF7);
duke@0 2481 emit_rm(cbuf, 0x3, 0x03, dstenc);
duke@0 2482 %}
duke@0 2483
duke@0 2484 enc_class setLT_reg(rRegI dst)
duke@0 2485 %{
duke@0 2486 int dstenc = $dst$$reg;
duke@0 2487 if (dstenc >= 8) {
duke@0 2488 emit_opcode(cbuf, Assembler::REX_B);
duke@0 2489 dstenc -= 8;
duke@0 2490 } else if (dstenc >= 4) {
duke@0 2491 emit_opcode(cbuf, Assembler::REX);
duke@0 2492 }
duke@0 2493 // SETLT $dst
duke@0 2494 emit_opcode(cbuf, 0x0F);
duke@0 2495 emit_opcode(cbuf, 0x9C);
duke@0 2496 emit_rm(cbuf, 0x3, 0x0, dstenc);
duke@0 2497 %}
duke@0 2498
duke@0 2499 enc_class setNZ_reg(rRegI dst)
duke@0 2500 %{
duke@0 2501 int dstenc = $dst$$reg;
duke@0 2502 if (dstenc >= 8) {
duke@0 2503 emit_opcode(cbuf, Assembler::REX_B);
duke@0 2504 dstenc -= 8;
duke@0 2505 } else if (dstenc >= 4) {
duke@0 2506 emit_opcode(cbuf, Assembler::REX);
duke@0 2507 }
duke@0 2508 // SETNZ $dst
duke@0 2509 emit_opcode(cbuf, 0x0F);
duke@0 2510 emit_opcode(cbuf, 0x95);
duke@0 2511 emit_rm(cbuf, 0x3, 0x0, dstenc);
duke@0 2512 %}
duke@0 2513
duke@0 2514
duke@0 2515 // Compare the lonogs and set -1, 0, or 1 into dst
duke@0 2516 enc_class cmpl3_flag(rRegL src1, rRegL src2, rRegI dst)
duke@0 2517 %{
duke@0 2518 int src1enc = $src1$$reg;
duke@0 2519 int src2enc = $src2$$reg;
duke@0 2520 int dstenc = $dst$$reg;
duke@0 2521
duke@0 2522 // cmpq $src1, $src2
duke@0 2523 if (src1enc < 8) {
duke@0 2524 if (src2enc < 8) {
duke@0 2525 emit_opcode(cbuf, Assembler::REX_W);
duke@0 2526 } else {
duke@0 2527 emit_opcode(cbuf, Assembler::REX_WB);
duke@0 2528 }
duke@0 2529 } else {
duke@0 2530 if (src2enc < 8) {
duke@0 2531 emit_opcode(cbuf, Assembler::REX_WR);
duke@0 2532 } else {
duke@0 2533 emit_opcode(cbuf, Assembler::REX_WRB);
duke@0 2534 }
duke@0 2535 }
duke@0 2536 emit_opcode(cbuf, 0x3B);
duke@0 2537 emit_rm(cbuf, 0x3, src1enc & 7, src2enc & 7);
duke@0 2538
duke@0 2539 // movl $dst, -1
duke@0 2540 if (dstenc >= 8) {
duke@0 2541 emit_opcode(cbuf, Assembler::REX_B);
duke@0 2542 }
duke@0 2543 emit_opcode(cbuf, 0xB8 | (dstenc & 7));
duke@0 2544 emit_d32(cbuf, -1);
duke@0 2545
duke@0 2546 // jl,s done
duke@0 2547 emit_opcode(cbuf, 0x7C);
duke@0 2548 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08);
duke@0 2549
duke@0 2550 // setne $dst
duke@0 2551 if (dstenc >= 4) {
duke@0 2552 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B);
duke@0 2553 }
duke@0 2554 emit_opcode(cbuf, 0x0F);
duke@0 2555 emit_opcode(cbuf, 0x95);
duke@0 2556 emit_opcode(cbuf, 0xC0 | (dstenc & 7));
duke@0 2557
duke@0 2558 // movzbl $dst, $dst
duke@0 2559 if (dstenc >= 4) {
duke@0 2560 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB);
duke@0 2561 }
duke@0 2562 emit_opcode(cbuf, 0x0F);
duke@0 2563 emit_opcode(cbuf, 0xB6);
duke@0 2564 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7);
duke@0 2565 %}
duke@0 2566
duke@0 2567 enc_class Push_ResultXD(regD dst) %{
kvn@2953 2568 MacroAssembler _masm(&cbuf);
kvn@2953 2569 __ fstp_d(Address(rsp, 0));
kvn@2953 2570 __ movdbl($dst$$XMMRegister, Address(rsp, 0));
kvn@2953 2571 __ addptr(rsp, 8);
duke@0 2572 %}
duke@0 2573
duke@0 2574 enc_class Push_SrcXD(regD src) %{
duke@0 2575 MacroAssembler _masm(&cbuf);
kvn@2953 2576 __ subptr(rsp, 8);
kvn@2953 2577 __ movdbl(Address(rsp, 0), $src$$XMMRegister);
kvn@2953 2578 __ fld_d(Address(rsp, 0));
kvn@2953 2579 %}
kvn@2953 2580
duke@0 2581
duke@0 2582 // obj: object to lock
duke@0 2583 // box: box address (header location) -- killed
duke@0 2584 // tmp: rax -- killed
duke@0 2585 // scr: rbx -- killed
duke@0 2586 //
duke@0 2587 // What follows is a direct transliteration of fast_lock() and fast_unlock()
duke@0 2588 // from i486.ad. See that file for comments.
duke@0 2589 // TODO: where possible switch from movq (r, 0) to movl(r,0) and
duke@0 2590 // use the shorter encoding. (Movl clears the high-order 32-bits).
duke@0 2591
duke@0 2592
duke@0 2593 enc_class Fast_Lock(rRegP obj, rRegP box, rax_RegI tmp, rRegP scr)
duke@0 2594 %{
duke@0 2595 Register objReg = as_Register((int)$obj$$reg);
duke@0 2596 Register boxReg = as_Register((int)$box$$reg);
duke@0 2597 Register tmpReg = as_Register($tmp$$reg);
duke@0 2598 Register scrReg = as_Register($scr$$reg);
duke@0 2599 MacroAssembler masm(&cbuf);
duke@0 2600
duke@0 2601 // Verify uniqueness of register assignments -- necessary but not sufficient
duke@0 2602 assert (objReg != boxReg && objReg != tmpReg &&
duke@0 2603 objReg != scrReg && tmpReg != scrReg, "invariant") ;
duke@0 2604
duke@0 2605 if (_counters != NULL) {
duke@0 2606 masm.atomic_incl(ExternalAddress((address) _counters->total_entry_count_addr()));
duke@0 2607 }
duke@0 2608 if (EmitSync & 1) {
never@304 2609 // Without cast to int32_t a movptr will destroy r10 which is typically obj
iveresov@2251 2610 masm.movptr (Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ;
iveresov@2251 2611 masm.cmpptr(rsp, (int32_t)NULL_WORD) ;
duke@0 2612 } else
duke@0 2613 if (EmitSync & 2) {
duke@0 2614 Label DONE_LABEL;
duke@0 2615 if (UseBiasedLocking) {
duke@0 2616 // Note: tmpReg maps to the swap_reg argument and scrReg to the tmp_reg argument.
duke@0 2617 masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, _counters);
duke@0 2618 }
never@304 2619 // QQQ was movl...
never@304 2620 masm.movptr(tmpReg, 0x1);
never@304 2621 masm.orptr(tmpReg, Address(objReg, 0));
never@304 2622 masm.movptr(Address(boxReg, 0), tmpReg);
duke@0 2623 if (os::is_MP()) {
duke@0 2624 masm.lock();
duke@0 2625 }
never@304 2626 masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg
duke@0 2627 masm.jcc(Assembler::equal, DONE_LABEL);
duke@0 2628
duke@0 2629 // Recursive locking
never@304 2630 masm.subptr(tmpReg, rsp);
never@304 2631 masm.andptr(tmpReg, 7 - os::vm_page_size());
never@304 2632 masm.movptr(Address(boxReg, 0), tmpReg);
duke@0 2633
duke@0 2634 masm.bind(DONE_LABEL);
duke@0 2635 masm.nop(); // avoid branch to branch
duke@0 2636 } else {
duke@0 2637 Label DONE_LABEL, IsInflated, Egress;
duke@0 2638
iveresov@2251 2639 masm.movptr(tmpReg, Address(objReg, 0)) ;
never@304 2640 masm.testl (tmpReg, 0x02) ; // inflated vs stack-locked|neutral|biased
iveresov@2251 2641 masm.jcc (Assembler::notZero, IsInflated) ;
iveresov@2251 2642
duke@0 2643 // it's stack-locked, biased or neutral
duke@0 2644 // TODO: optimize markword triage order to reduce the number of
duke@0 2645 // conditional branches in the most common cases.
duke@0 2646 // Beware -- there's a subtle invariant that fetch of the markword
duke@0 2647 // at [FETCH], below, will never observe a biased encoding (*101b).
duke@0 2648 // If this invariant is not held we'll suffer exclusion (safety) failure.
duke@0 2649
kvn@420 2650 if (UseBiasedLocking && !UseOptoBiasInlining) {
duke@0 2651 masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, true, DONE_LABEL, NULL, _counters);
never@304 2652 masm.movptr(tmpReg, Address(objReg, 0)) ; // [FETCH]
duke@0 2653 }
duke@0 2654
never@304 2655 // was q will it destroy high?
iveresov@2251 2656 masm.orl (tmpReg, 1) ;
iveresov@2251 2657 masm.movptr(Address(boxReg, 0), tmpReg) ;
iveresov@2251 2658 if (os::is_MP()) { masm.lock(); }
never@304 2659 masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg
duke@0 2660 if (_counters != NULL) {
duke@0 2661 masm.cond_inc32(Assembler::equal,
duke@0 2662 ExternalAddress((address) _counters->fast_path_entry_count_addr()));
duke@0 2663 }
duke@0 2664 masm.jcc (Assembler::equal, DONE_LABEL);
duke@0 2665
duke@0 2666 // Recursive locking
never@304 2667 masm.subptr(tmpReg, rsp);
never@304 2668 masm.andptr(tmpReg, 7 - os::vm_page_size());
never@304 2669 masm.movptr(Address(boxReg, 0), tmpReg);
duke@0 2670 if (_counters != NULL) {
duke@0 2671 masm.cond_inc32(Assembler::equal,
duke@0 2672 ExternalAddress((address) _counters->fast_path_entry_count_addr()));
duke@0 2673 }
duke@0 2674 masm.jmp (DONE_LABEL) ;
duke@0 2675
duke@0 2676 masm.bind (IsInflated) ;
duke@0 2677 // It's inflated
duke@0 2678
duke@0 2679 // TODO: someday avoid the ST-before-CAS penalty by
duke@0 2680 // relocating (deferring) the following ST.
duke@0 2681 // We should also think about trying a CAS without having
duke@0 2682 // fetched _owner. If the CAS is successful we may
duke@0 2683 // avoid an RTO->RTS upgrade on the $line.
never@304 2684 // Without cast to int32_t a movptr will destroy r10 which is typically obj
iveresov@2251 2685 masm.movptr(Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ;
iveresov@2251 2686
iveresov@2251 2687 masm.mov (boxReg, tmpReg) ;
iveresov@2251 2688 masm.movptr (tmpReg, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
iveresov@2251 2689 masm.testptr(tmpReg, tmpReg) ;
iveresov@2251 2690 masm.jcc (Assembler::notZero, DONE_LABEL) ;
duke@0 2691
duke@0 2692 // It's inflated and appears unlocked
iveresov@2251 2693 if (os::is_MP()) { masm.lock(); }
iveresov@2251 2694 masm.cmpxchgptr(r15_thread, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
duke@0 2695 // Intentional fall-through into DONE_LABEL ...
duke@0 2696
duke@0 2697 masm.bind (DONE_LABEL) ;
duke@0 2698 masm.nop () ; // avoid jmp to jmp
duke@0 2699 }
duke@0 2700 %}
duke@0 2701
duke@0 2702 // obj: object to unlock
duke@0 2703 // box: box address (displaced header location), killed
duke@0 2704 // RBX: killed tmp; cannot be obj nor box
duke@0 2705 enc_class Fast_Unlock(rRegP obj, rax_RegP box, rRegP tmp)
duke@0 2706 %{
duke@0 2707
duke@0 2708 Register objReg = as_Register($obj$$reg);
duke@0 2709 Register boxReg = as_Register($box$$reg);
duke@0 2710 Register tmpReg = as_Register($tmp$$reg);
duke@0 2711 MacroAssembler masm(&cbuf);
duke@0 2712
iveresov@2251 2713 if (EmitSync & 4) {
iveresov@2251 2714 masm.cmpptr(rsp, 0) ;
duke@0 2715 } else
duke@0 2716 if (EmitSync & 8) {
duke@0 2717 Label DONE_LABEL;
duke@0 2718 if (UseBiasedLocking) {
duke@0 2719 masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL);
duke@0 2720 }
duke@0 2721
duke@0 2722 // Check whether the displaced header is 0
duke@0 2723 //(=> recursive unlock)
never@304 2724 masm.movptr(tmpReg, Address(boxReg, 0));
never@304 2725 masm.testptr(tmpReg, tmpReg);
duke@0 2726 masm.jcc(Assembler::zero, DONE_LABEL);
duke@0 2727
duke@0 2728 // If not recursive lock, reset the header to displaced header
duke@0 2729 if (os::is_MP()) {
duke@0 2730 masm.lock();
duke@0 2731 }
never@304 2732 masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box
duke@0 2733 masm.bind(DONE_LABEL);
duke@0 2734 masm.nop(); // avoid branch to branch
duke@0 2735 } else {
duke@0 2736 Label DONE_LABEL, Stacked, CheckSucc ;
duke@0 2737
kvn@420 2738 if (UseBiasedLocking && !UseOptoBiasInlining) {
duke@0 2739 masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL);
duke@0 2740 }
iveresov@2251 2741
iveresov@2251 2742 masm.movptr(tmpReg, Address(objReg, 0)) ;
iveresov@2251 2743 masm.cmpptr(Address(boxReg, 0), (int32_t)NULL_WORD) ;
iveresov@2251 2744 masm.jcc (Assembler::zero, DONE_LABEL) ;
iveresov@2251 2745 masm.testl (tmpReg, 0x02) ;
iveresov@2251 2746 masm.jcc (Assembler::zero, Stacked) ;
iveresov@2251 2747
duke@0 2748 // It's inflated
iveresov@2251 2749 masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
iveresov@2251 2750 masm.xorptr(boxReg, r15_thread) ;
iveresov@2251 2751 masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ;
iveresov@2251 2752 masm.jcc (Assembler::notZero, DONE_LABEL) ;
iveresov@2251 2753 masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ;
iveresov@2251 2754 masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ;
iveresov@2251 2755 masm.jcc (Assembler::notZero, CheckSucc) ;
iveresov@2251 2756 masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ;
iveresov@2251 2757 masm.jmp (DONE_LABEL) ;
iveresov@2251 2758
iveresov@2251 2759 if ((EmitSync & 65536) == 0) {
duke@0 2760 Label LSuccess, LGoSlowPath ;
duke@0 2761 masm.bind (CheckSucc) ;
never@304 2762 masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ;
duke@0 2763 masm.jcc (Assembler::zero, LGoSlowPath) ;
duke@0 2764
duke@0 2765 // I'd much rather use lock:andl m->_owner, 0 as it's faster than the
duke@0 2766 // the explicit ST;MEMBAR combination, but masm doesn't currently support
duke@0 2767 // "ANDQ M,IMM". Don't use MFENCE here. lock:add to TOS, xchg, etc
duke@0 2768 // are all faster when the write buffer is populated.
never@304 2769 masm.movptr (Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ;
duke@0 2770 if (os::is_MP()) {
never@304 2771 masm.lock () ; masm.addl (Address(rsp, 0), 0) ;
duke@0 2772 }
never@304 2773 masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ;
duke@0 2774 masm.jcc (Assembler::notZero, LSuccess) ;
duke@0 2775
never@304 2776 masm.movptr (boxReg, (int32_t)NULL_WORD) ; // box is really EAX
duke@0 2777 if (os::is_MP()) { masm.lock(); }
never@304 2778 masm.cmpxchgptr(r15_thread, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2));
duke@0 2779 masm.jcc (Assembler::notEqual, LSuccess) ;
duke@0 2780 // Intentional fall-through into slow-path
duke@0 2781
duke@0 2782 masm.bind (LGoSlowPath) ;
duke@0 2783 masm.orl (boxReg, 1) ; // set ICC.ZF=0 to indicate failure
duke@0 2784 masm.jmp (DONE_LABEL) ;
duke@0 2785
duke@0 2786 masm.bind (LSuccess) ;
duke@0 2787 masm.testl (boxReg, 0) ; // set ICC.ZF=1 to indicate success
duke@0 2788 masm.jmp (DONE_LABEL) ;
duke@0 2789 }
duke@0 2790
iveresov@2251 2791 masm.bind (Stacked) ;
never@304 2792 masm.movptr(tmpReg, Address (boxReg, 0)) ; // re-fetch
iveresov@2251 2793 if (os::is_MP()) { masm.lock(); }
never@304 2794 masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box
duke@0 2795
duke@0 2796 if (EmitSync & 65536) {
duke@0 2797 masm.bind (CheckSucc) ;
duke@0 2798 }
duke@0 2799 masm.bind(DONE_LABEL);
duke@0 2800 if (EmitSync & 32768) {
duke@0 2801 masm.nop(); // avoid branch to branch
duke@0 2802 }
duke@0 2803 }
duke@0 2804 %}
duke@0 2805
rasbold@169 2806
duke@0 2807 enc_class enc_rethrow()
duke@0 2808 %{
twisti@1668 2809 cbuf.set_insts_mark();
duke@0 2810 emit_opcode(cbuf, 0xE9); // jmp entry
duke@0 2811 emit_d32_reloc(cbuf,
twisti@1668 2812 (int) (OptoRuntime::rethrow_stub() - cbuf.insts_end() - 4),
duke@0 2813 runtime_call_Relocation::spec(),
duke@0 2814 RELOC_DISP32);
duke@0 2815 %}
duke@0 2816
duke@0 2817 %}
duke@0 2818
duke@0 2819
coleenp@113 2820
duke@0 2821 //----------FRAME--------------------------------------------------------------
duke@0 2822 // Definition of frame structure and management information.
duke@0 2823 //
duke@0 2824 // S T A C K L A Y O U T Allocators stack-slot number
duke@0 2825 // | (to get allocators register number
duke@0 2826 // G Owned by | | v add OptoReg::stack0())
duke@0 2827 // r CALLER | |
duke@0 2828 // o | +--------+ pad to even-align allocators stack-slot
duke@0 2829 // w V | pad0 | numbers; owned by CALLER
duke@0 2830 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned
duke@0 2831 // h ^ | in | 5
duke@0 2832 // | | args | 4 Holes in incoming args owned by SELF
duke@0 2833 // | | | | 3
duke@0 2834 // | | +--------+
duke@0 2835 // V | | old out| Empty on Intel, window on Sparc
duke@0 2836 // | old |preserve| Must be even aligned.
duke@0 2837 // | SP-+--------+----> Matcher::_old_SP, even aligned
duke@0 2838 // | | in | 3 area for Intel ret address
duke@0 2839 // Owned by |preserve| Empty on Sparc.
duke@0 2840 // SELF +--------+
duke@0 2841 // | | pad2 | 2 pad to align old SP
duke@0 2842 // | +--------+ 1
duke@0 2843 // | | locks | 0
duke@0 2844 // | +--------+----> OptoReg::stack0(), even aligned
duke@0 2845 // | | pad1 | 11 pad to align new SP
duke@0 2846 // | +--------+
duke@0 2847 // | | | 10
duke@0 2848 // | | spills | 9 spills
duke@0 2849 // V | | 8 (pad0 slot for callee)
duke@0 2850 // -----------+--------+----> Matcher::_out_arg_limit, unaligned
duke@0 2851 // ^ | out | 7
duke@0 2852 // | | args | 6 Holes in outgoing args owned by CALLEE
duke@0 2853 // Owned by +--------+
duke@0 2854 // CALLEE | new out| 6 Empty on Intel, window on Sparc
duke@0 2855 // | new |preserve| Must be even-aligned.
duke@0 2856 // | SP-+--------+----> Matcher::_new_SP, even aligned
duke@0 2857 // | | |
duke@0 2858 //
duke@0 2859 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is
duke@0 2860 // known from SELF's arguments and the Java calling convention.
duke@0 2861 // Region 6-7 is determined per call site.
duke@0 2862 // Note 2: If the calling convention leaves holes in the incoming argument
duke@0 2863 // area, those holes are owned by SELF. Holes in the outgoing area
duke@0 2864 // are owned by the CALLEE. Holes should not be nessecary in the
duke@0 2865 // incoming area, as the Java calling convention is completely under
duke@0 2866 // the control of the AD file. Doubles can be sorted and packed to
duke@0 2867 // avoid holes. Holes in the outgoing arguments may be nessecary for
duke@0 2868 // varargs C calling conventions.
duke@0 2869 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is
duke@0 2870 // even aligned with pad0 as needed.
duke@0 2871 // Region 6 is even aligned. Region 6-7 is NOT even aligned;
duke@0 2872 // region 6-11 is even aligned; it may be padded out more so that
duke@0 2873 // the region from SP to FP meets the minimum stack alignment.
duke@0 2874 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack
duke@0 2875 // alignment. Region 11, pad1, may be dynamically extended so that
duke@0 2876 // SP meets the minimum alignment.
duke@0 2877
duke@0 2878 frame
duke@0 2879 %{
duke@0 2880 // What direction does stack grow in (assumed to be same for C & Java)
duke@0 2881 stack_direction(TOWARDS_LOW);
duke@0 2882
duke@0 2883 // These three registers define part of the calling convention
duke@0 2884 // between compiled code and the interpreter.
duke@0 2885 inline_cache_reg(RAX); // Inline Cache Register
duke@0 2886 interpreter_method_oop_reg(RBX); // Method Oop Register when
duke@0 2887 // calling interpreter
duke@0 2888
duke@0 2889 // Optional: name the operand used by cisc-spilling to access
duke@0 2890 // [stack_pointer + offset]
duke@0 2891 cisc_spilling_operand_name(indOffset32);
duke@0 2892
duke@0 2893 // Number of stack slots consumed by locking an object
duke@0 2894 sync_stack_slots(2);
duke@0 2895
duke@0 2896 // Compiled code's Frame Pointer
duke@0 2897 frame_pointer(RSP);
duke@0 2898
duke@0 2899 // Interpreter stores its frame pointer in a register which is
duke@0 2900 // stored to the stack by I2CAdaptors.
duke@0 2901 // I2CAdaptors convert from interpreted java to compiled java.
duke@0 2902 interpreter_frame_pointer(RBP);
duke@0 2903
duke@0 2904 // Stack alignment requirement
duke@0 2905 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes)
duke@0 2906
duke@0 2907 // Number of stack slots between incoming argument block and the start of
duke@0 2908 // a new frame. The PROLOG must add this many slots to the stack. The
duke@0 2909 // EPILOG must remove this many slots. amd64 needs two slots for
duke@0 2910 // return address.
duke@0 2911 in_preserve_stack_slots(4 + 2 * VerifyStackAtCalls);
duke@0 2912
duke@0 2913 // Number of outgoing stack slots killed above the out_preserve_stack_slots
duke@0 2914 // for calls to C. Supports the var-args backing area for register parms.
duke@0 2915 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt);
duke@0 2916
duke@0 2917 // The after-PROLOG location of the return address. Location of
duke@0 2918 // return address specifies a type (REG or STACK) and a number
duke@0 2919 // representing the register number (i.e. - use a register name) or
duke@0 2920 // stack slot.
duke@0 2921 // Ret Addr is on stack in slot 0 if no locks or verification or alignment.
duke@0 2922 // Otherwise, it is above the locks and verification slot and alignment word
duke@0 2923 return_addr(STACK - 2 +
kvn@3142 2924 round_to((Compile::current()->in_preserve_stack_slots() +
kvn@3142 2925 Compile::current()->fixed_slots()),
kvn@3142 2926 stack_alignment_in_slots()));
duke@0 2927
duke@0 2928 // Body of function which returns an integer array locating
duke@0 2929 // arguments either in registers or in stack slots. Passed an array
duke@0 2930 // of ideal registers called "sig" and a "length" count. Stack-slot
duke@0 2931 // offsets are based on outgoing arguments, i.e. a CALLER setting up
duke@0 2932 // arguments for a CALLEE. Incoming stack arguments are
duke@0 2933 // automatically biased by the preserve_stack_slots field above.
duke@0 2934
duke@0 2935 calling_convention
duke@0 2936 %{
duke@0 2937 // No difference between ingoing/outgoing just pass false
duke@0 2938 SharedRuntime::java_calling_convention(sig_bt, regs, length, false);
duke@0 2939 %}
duke@0 2940
duke@0 2941 c_calling_convention
duke@0 2942 %{
duke@0 2943 // This is obviously always outgoing
duke@0 2944 (void) SharedRuntime::c_calling_convention(sig_bt, regs, length);
duke@0 2945 %}
duke@0 2946
duke@0 2947 // Location of compiled Java return values. Same as C for now.
duke@0 2948 return_value
duke@0 2949 %{
duke@0 2950 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL,
duke@0 2951 "only return normal values");
duke@0 2952
duke@0 2953 static const int lo[Op_RegL + 1] = {
duke@0 2954 0,
duke@0 2955 0,
coleenp@113 2956 RAX_num, // Op_RegN
duke@0 2957 RAX_num, // Op_RegI
duke@0 2958 RAX_num, // Op_RegP
duke@0 2959 XMM0_num, // Op_RegF
duke@0 2960 XMM0_num, // Op_RegD
duke@0 2961 RAX_num // Op_RegL
duke@0 2962 };
duke@0 2963 static const int hi[Op_RegL + 1] = {
duke@0 2964 0,
duke@0 2965 0,
coleenp@113 2966 OptoReg::Bad, // Op_RegN
duke@0 2967 OptoReg::Bad, // Op_RegI
duke@0 2968 RAX_H_num, // Op_RegP
duke@0 2969 OptoReg::Bad, // Op_RegF
kvn@3447 2970 XMM0b_num, // Op_RegD
duke@0 2971 RAX_H_num // Op_RegL
duke@0 2972 };
kvn@3447 2973 // Excluded flags and vector registers.
kvn@3447 2974 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 5, "missing type");
duke@0 2975 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]);
duke@0 2976 %}
duke@0 2977 %}
duke@0 2978
duke@0 2979 //----------ATTRIBUTES---------------------------------------------------------
duke@0 2980 //----------Operand Attributes-------------------------------------------------
duke@0 2981 op_attrib op_cost(0); // Required cost attribute
duke@0 2982
duke@0 2983 //----------Instruction Attributes---------------------------------------------
duke@0 2984 ins_attrib ins_cost(100); // Required cost attribute
duke@0 2985 ins_attrib ins_size(8); // Required size attribute (in bits)
duke@0 2986 ins_attrib ins_short_branch(0); // Required flag: is this instruction
duke@0 2987 // a non-matching short branch variant
duke@0 2988 // of some long branch?
duke@0 2989 ins_attrib ins_alignment(1); // Required alignment attribute (must
duke@0 2990 // be a power of 2) specifies the
duke@0 2991 // alignment that some part of the
duke@0 2992 // instruction (not necessarily the
duke@0 2993 // start) requires. If > 1, a
duke@0 2994 // compute_padding() function must be
duke@0 2995 // provided for the instruction
duke@0 2996
duke@0 2997 //----------OPERANDS-----------------------------------------------------------
duke@0 2998 // Operand definitions must precede instruction definitions for correct parsing
duke@0 2999 // in the ADLC because operands constitute user defined types which are used in
duke@0 3000 // instruction definitions.
duke@0 3001
duke@0 3002 //----------Simple Operands----------------------------------------------------
duke@0 3003 // Immediate Operands
duke@0 3004 // Integer Immediate
duke@0 3005 operand immI()
duke@0 3006 %{
duke@0 3007 match(ConI);
duke@0 3008
duke@0 3009 op_cost(10);
duke@0 3010 format %{ %}
duke@0 3011 interface(CONST_INTER);
duke@0 3012 %}
duke@0 3013
duke@0 3014 // Constant for test vs zero
duke@0 3015 operand immI0()
duke@0 3016 %{
duke@0 3017 predicate(n->get_int() == 0);
duke@0 3018 match(ConI);
duke@0 3019
duke@0 3020 op_cost(0);
duke@0 3021 format %{ %}
duke@0 3022 interface(CONST_INTER);
duke@0 3023 %}
duke@0 3024
duke@0 3025 // Constant for increment
duke@0 3026 operand immI1()
duke@0 3027 %{
duke@0 3028 predicate(n->get_int() == 1);
duke@0 3029 match(ConI);
duke@0 3030
duke@0 3031 op_cost(0);
duke@0 3032 format %{ %}
duke@0 3033 interface(CONST_INTER);
duke@0 3034 %}
duke@0 3035
duke@0 3036 // Constant for decrement
duke@0 3037 operand immI_M1()
duke@0 3038 %{
duke@0 3039 predicate(n->get_int() == -1);
duke@0 3040 match(ConI);
duke@0 3041
duke@0 3042 op_cost(0);
duke@0 3043 format %{ %}
duke@0 3044 interface(CONST_INTER);
duke@0 3045 %}
duke@0 3046
duke@0 3047 // Valid scale values for addressing modes
duke@0 3048 operand immI2()
duke@0 3049 %{
duke@0 3050 predicate(0 <= n->get_int() && (n->get_int() <= 3));
duke@0 3051 match(ConI);
duke@0 3052
duke@0 3053 format %{ %}
duke@0 3054 interface(CONST_INTER);
duke@0 3055 %}
duke@0 3056
duke@0 3057 operand immI8()
duke@0 3058 %{
duke@0 3059 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80));
duke@0 3060 match(ConI);
duke@0 3061
duke@0 3062 op_cost(5);
duke@0 3063 format %{ %}
duke@0 3064 interface(CONST_INTER);
duke@0 3065 %}
duke@0 3066
duke@0 3067 operand immI16()
duke@0 3068 %{
duke@0 3069 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767));
duke@0 3070 match(ConI);
duke@0 3071
duke@0 3072 op_cost(10);
duke@0 3073 format %{ %}
duke@0 3074 interface(CONST_INTER);
duke@0 3075 %}
duke@0 3076
duke@0 3077 // Constant for long shifts
duke@0 3078 operand immI_32()
duke@0 3079 %{
duke@0 3080 predicate( n->get_int() == 32 );
duke@0 3081 match(ConI);
duke@0 3082
duke@0 3083 op_cost(0);
duke@0 3084 format %{ %}
duke@0 3085 interface(CONST_INTER);
duke@0 3086 %}
duke@0 3087
duke@0 3088 // Constant for long shifts
duke@0 3089 operand immI_64()
duke@0 3090 %{
duke@0 3091 predicate( n->get_int() == 64 );
duke@0 3092 match(ConI);
duke@0 3093
duke@0 3094 op_cost(0);
duke@0 3095 format %{ %}
duke@0 3096 interface(CONST_INTER);
duke@0 3097 %}
duke@0 3098
duke@0 3099 // Pointer Immediate
duke@0 3100 operand immP()
duke@0 3101 %{
duke@0 3102 match(ConP);
duke@0 3103
duke@0 3104 op_cost(10);
duke@0 3105 format %{ %}
duke@0 3106 interface(CONST_INTER);
duke@0 3107 %}
duke@0 3108
duke@0 3109 // NULL Pointer Immediate
duke@0 3110 operand immP0()
duke@0 3111 %{
duke@0 3112 predicate(n->get_ptr() == 0);
duke@0 3113 match(ConP);
duke@0 3114
duke@0 3115 op_cost(5);
duke@0 3116 format %{ %}
duke@0 3117 interface(CONST_INTER);
duke@0 3118 %}
duke@0 3119
coleenp@113 3120 // Pointer Immediate
coleenp@113 3121 operand immN() %{
coleenp@113 3122 match(ConN);
coleenp@113 3123
coleenp@113 3124 op_cost(10);
coleenp@113 3125 format %{ %}
coleenp@113 3126 interface(CONST_INTER);
coleenp@113 3127 %}
coleenp@113 3128
roland@3724 3129 operand immNKlass() %{
roland@3724 3130 match(ConNKlass);
roland@3724 3131
roland@3724 3132 op_cost(10);
roland@3724 3133 format %{ %}
roland@3724 3134 interface(CONST_INTER);
roland@3724 3135 %}
roland@3724 3136
coleenp@113 3137 // NULL Pointer Immediate
coleenp@113 3138 operand immN0() %{
coleenp@113 3139 predicate(n->get_narrowcon() == 0);
coleenp@113 3140 match(ConN);
coleenp@113 3141
coleenp@113 3142 op_cost(5);
coleenp@113 3143 format %{ %}
coleenp@113 3144 interface(CONST_INTER);
coleenp@113 3145 %}
coleenp@113 3146
duke@0 3147 operand immP31()
duke@0 3148 %{
coleenp@3602 3149 predicate(n->as_Type()->type()->reloc() == relocInfo::none
duke@0 3150 && (n->get_ptr() >> 31) == 0);
duke@0 3151 match(ConP);
duke@0 3152
duke@0 3153 op_cost(5);
duke@0 3154 format %{ %}
duke@0 3155 interface(CONST_INTER);
duke@0 3156 %}
duke@0 3157
coleenp@113 3158
duke@0 3159 // Long Immediate
duke@0 3160 operand immL()
duke@0 3161 %{
duke@0 3162 match(ConL);
duke@0 3163
duke@0 3164 op_cost(20);
duke@0 3165 format %{ %}
duke@0 3166 interface(CONST_INTER);
duke@0 3167 %}
duke@0 3168
duke@0 3169 // Long Immediate 8-bit
duke@0 3170 operand immL8()
duke@0 3171 %{
duke@0 3172 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L);
duke@0 3173 match(ConL);
duke@0 3174
duke@0 3175 op_cost(5);
duke@0 3176 format %{ %}
duke@0 3177 interface(CONST_INTER);
duke@0 3178 %}
duke@0 3179
duke@0 3180 // Long Immediate 32-bit unsigned
duke@0 3181 operand immUL32()
duke@0 3182 %{
duke@0 3183 predicate(n->get_long() == (unsigned int) (n->get_long()));
duke@0 3184 match(ConL);
duke@0 3185
duke@0 3186 op_cost(10);
duke@0 3187 format %{ %}
duke@0 3188 interface(CONST_INTER);
duke@0 3189 %}
duke@0 3190
duke@0 3191 // Long Immediate 32-bit signed
duke@0 3192 operand immL32()
duke@0 3193 %{
duke@0 3194 predicate(n->get_long() == (int) (n->get_long()));
duke@0 3195 match(ConL);
duke@0 3196
duke@0 3197 op_cost(15);
duke@0 3198 format %{ %}
duke@0 3199 interface(CONST_INTER);
duke@0 3200 %}
duke@0 3201
duke@0 3202 // Long Immediate zero
duke@0 3203 operand immL0()
duke@0 3204 %{
duke@0 3205 predicate(n->get_long() == 0L);
duke@0 3206 match(ConL);
duke@0 3207
duke@0 3208 op_cost(10);
duke@0 3209 format %{ %}
duke@0 3210 interface(CONST_INTER);
duke@0 3211 %}
duke@0 3212
duke@0 3213 // Constant for increment
duke@0 3214 operand immL1()
duke@0 3215 %{
duke@0 3216 predicate(n->get_long() == 1);
duke@0 3217 match(ConL);
duke@0 3218
duke@0 3219 format %{ %}
duke@0 3220 interface(CONST_INTER);
duke@0 3221 %}
duke@0 3222
duke@0 3223 // Constant for decrement
duke@0 3224 operand immL_M1()
duke@0 3225 %{
duke@0 3226 predicate(n->get_long() == -1);
duke@0 3227 match(ConL);
duke@0 3228
duke@0 3229 format %{ %}
duke@0 3230 interface(CONST_INTER);
duke@0 3231 %}
duke@0 3232
duke@0 3233 // Long Immediate: the value 10
duke@0 3234 operand immL10()
duke@0 3235 %{
duke@0 3236 predicate(n->get_long() == 10);
duke@0 3237 match(ConL);
duke@0 3238
duke@0 3239 format %{ %}
duke@0 3240 interface(CONST_INTER);
duke@0 3241 %}
duke@0 3242
duke@0 3243 // Long immediate from 0 to 127.
duke@0 3244 // Used for a shorter form of long mul by 10.
duke@0 3245 operand immL_127()
duke@0 3246 %{
duke@0 3247 predicate(0 <= n->get_long() && n->get_long() < 0x80);
duke@0 3248 match(ConL);
duke@0 3249
duke@0 3250 op_cost(10);
duke@0 3251 format %{ %}
duke@0 3252 interface(CONST_INTER);
duke@0 3253 %}
duke@0 3254
duke@0 3255 // Long Immediate: low 32-bit mask
duke@0 3256 operand immL_32bits()
duke@0 3257 %{
duke@0 3258 predicate(n->get_long() == 0xFFFFFFFFL);
duke@0 3259 match(ConL);
duke@0 3260 op_cost(20);
duke@0 3261
duke@0 3262 format %{ %}
duke@0 3263 interface(CONST_INTER);
duke@0 3264 %}
duke@0 3265
duke@0 3266 // Float Immediate zero
duke@0 3267 operand immF0()
duke@0 3268 %{
duke@0 3269 predicate(jint_cast(n->getf()) == 0);
duke@0 3270 match(ConF);
duke@0 3271
duke@0 3272 op_cost(5);
duke@0 3273 format %{ %}
duke@0 3274 interface(CONST_INTER);
duke@0 3275 %}
duke@0 3276
duke@0 3277 // Float Immediate
duke@0 3278 operand immF()
duke@0 3279 %{
duke@0 3280 match(ConF);
duke@0 3281
duke@0 3282 op_cost(15);
duke@0 3283 format %{ %}
duke@0 3284 interface(CONST_INTER);
duke@0 3285 %}
duke@0 3286
duke@0 3287 // Double Immediate zero
duke@0 3288 operand immD0()
duke@0 3289 %{
duke@0 3290 predicate(jlong_cast(n->getd()) == 0);
duke@0 3291 match(ConD);
duke@0 3292
duke@0 3293 op_cost(5);
duke@0 3294 format %{ %}
duke@0 3295 interface(CONST_INTER);
duke@0 3296 %}
duke@0 3297
duke@0 3298 // Double Immediate
duke@0 3299 operand immD()
duke@0 3300 %{
duke@0 3301 match(ConD);
duke@0 3302
duke@0 3303 op_cost(15);
duke@0 3304 format %{ %}
duke@0 3305 interface(CONST_INTER);
duke@0 3306 %}
duke@0 3307
duke@0 3308 // Immediates for special shifts (sign extend)
duke@0 3309
duke@0 3310 // Constants for increment
duke@0 3311 operand immI_16()
duke@0 3312 %{
duke@0 3313 predicate(n->get_int() == 16);
duke@0 3314 match(ConI);
duke@0 3315
duke@0 3316 format %{ %}
duke@0 3317 interface(CONST_INTER);
duke@0 3318 %}
duke@0 3319
duke@0 3320 operand immI_24()
duke@0 3321 %{
duke@0 3322 predicate(n->get_int() == 24);
duke@0 3323 match(ConI);
duke@0 3324
duke@0 3325 format %{ %}
duke@0 3326 interface(CONST_INTER);
duke@0 3327 %}
duke@0 3328
duke@0 3329 // Constant for byte-wide masking
duke@0 3330 operand immI_255()
duke@0 3331 %{
duke@0 3332 predicate(n->get_int() == 255);
duke@0 3333 match(ConI);
duke@0 3334
duke@0 3335 format %{ %}
duke@0 3336 interface(CONST_INTER);
duke@0 3337 %}
duke@0 3338
duke@0 3339 // Constant for short-wide masking
duke@0 3340 operand immI_65535()
duke@0 3341 %{
duke@0 3342 predicate(n->get_int() == 65535);
duke@0 3343 match(ConI);
duke@0 3344
duke@0 3345 format %{ %}
duke@0 3346 interface(CONST_INTER);
duke@0 3347 %}
duke@0 3348
duke@0 3349 // Constant for byte-wide masking
duke@0 3350 operand immL_255()
duke@0 3351 %{
duke@0 3352 predicate(n->get_long() == 255);
duke@0 3353 match(ConL);
duke@0 3354
duke@0 3355 format %{ %}
duke@0 3356 interface(CONST_INTER);
duke@0 3357 %}
duke@0 3358
duke@0 3359 // Constant for short-wide masking
duke@0 3360 operand immL_65535()
duke@0 3361 %{
duke@0 3362 predicate(n->get_long() == 65535);
duke@0 3363 match(ConL);
duke@0 3364
duke@0 3365 format %{ %}
duke@0 3366 interface(CONST_INTER);
duke@0 3367 %}
duke@0 3368
duke@0 3369 // Register Operands
duke@0 3370 // Integer Register
duke@0 3371 operand rRegI()
duke@0 3372 %{
duke@0 3373 constraint(ALLOC_IN_RC(int_reg));
duke@0 3374 match(RegI);
duke@0 3375
duke@0 3376 match(rax_RegI);
duke@0 3377 match(rbx_RegI);
duke@0 3378 match(rcx_RegI);
duke@0 3379 match(rdx_RegI);
duke@0 3380 match(rdi_RegI);
duke@0 3381
duke@0 3382 format %{ %}
duke@0 3383 interface(REG_INTER);
duke@0 3384 %}
duke@0 3385
duke@0 3386 // Special Registers
duke@0 3387 operand rax_RegI()
duke@0 3388 %{
duke@0 3389 constraint(ALLOC_IN_RC(int_rax_reg));
duke@0 3390 match(RegI);
duke@0 3391 match(rRegI);
duke@0 3392
duke@0 3393 format %{ "RAX" %}
duke@0 3394 interface(REG_INTER);
duke@0 3395 %}
duke@0 3396
duke@0 3397 // Special Registers
duke@0 3398 operand rbx_RegI()
duke@0 3399 %{
duke@0 3400 constraint(ALLOC_IN_RC(int_rbx_reg));
duke@0 3401 match(RegI);
duke@0 3402 match(rRegI);
duke@0 3403
duke@0 3404 format %{ "RBX" %}
duke@0 3405 interface(REG_INTER);
duke@0 3406 %}
duke@0 3407
duke@0 3408 operand rcx_RegI()
duke@0 3409 %{
duke@0 3410 constraint(ALLOC_IN_RC(int_rcx_reg));
duke@0 3411 match(RegI);
duke@0 3412 match(rRegI);
duke@0 3413
duke@0 3414 format %{ "RCX" %}
duke@0 3415 interface(REG_INTER);
duke@0 3416 %}
duke@0 3417
duke@0 3418 operand rdx_RegI()
duke@0 3419 %{
duke@0 3420 constraint(ALLOC_IN_RC(int_rdx_reg));
duke@0 3421 match(RegI);
duke@0 3422 match(rRegI);
duke@0 3423
duke@0 3424 format %{ "RDX" %}
duke@0 3425 interface(REG_INTER);
duke@0 3426 %}
duke@0 3427
duke@0 3428 operand rdi_RegI()
duke@0 3429 %{
duke@0 3430 constraint(ALLOC_IN_RC(int_rdi_reg));
duke@0 3431 match(RegI);
duke@0 3432 match(rRegI);
duke@0 3433
duke@0 3434 format %{ "RDI" %}
duke@0 3435 interface(REG_INTER);
duke@0 3436 %}
duke@0 3437
duke@0 3438 operand no_rcx_RegI()
duke@0 3439 %{
duke@0 3440 constraint(ALLOC_IN_RC(int_no_rcx_reg));
duke@0 3441 match(RegI);
duke@0 3442 match(rax_RegI);
duke@0 3443 match(rbx_RegI);
duke@0 3444 match(rdx_RegI);
duke@0 3445 match(rdi_RegI);
duke@0 3446
duke@0 3447 format %{ %}
duke@0 3448 interface(REG_INTER);
duke@0 3449 %}
duke@0 3450
duke@0 3451 operand no_rax_rdx_RegI()
duke@0 3452 %{
duke@0 3453 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg));
duke@0 3454 match(RegI);
duke@0 3455 match(rbx_RegI);
duke@0 3456 match(rcx_RegI);
duke@0 3457 match(rdi_RegI);
duke@0 3458
duke@0 3459 format %{ %}
duke@0 3460 interface(REG_INTER);
duke@0 3461 %}
duke@0 3462
duke@0 3463 // Pointer Register
duke@0 3464 operand any_RegP()
duke@0 3465 %{
duke@0 3466 constraint(ALLOC_IN_RC(any_reg));
duke@0 3467 match(RegP);
duke@0 3468 match(rax_RegP);
duke@0 3469 match(rbx_RegP);
duke@0 3470 match(rdi_RegP);
duke@0 3471 match(rsi_RegP);
duke@0 3472 match(rbp_RegP);
duke@0 3473 match(r15_RegP);
duke@0 3474 match(rRegP);
duke@0 3475
duke@0 3476 format %{ %}
duke@0 3477 interface(REG_INTER);
duke@0 3478 %}
duke@0 3479
duke@0 3480 operand rRegP()
duke@0 3481 %{
duke@0 3482 constraint(ALLOC_IN_RC(ptr_reg));
duke@0 3483 match(RegP);
duke@0 3484 match(rax_RegP);
duke@0 3485 match(rbx_RegP);
duke@0 3486 match(rdi_RegP);
duke@0 3487 match(rsi_RegP);
duke@0 3488 match(rbp_RegP);
duke@0 3489 match(r15_RegP); // See Q&A below about r15_RegP.
duke@0 3490
duke@0 3491 format %{ %}
duke@0 3492 interface(REG_INTER);
duke@0 3493 %}
duke@0 3494
coleenp@113 3495 operand rRegN() %{
coleenp@113 3496 constraint(ALLOC_IN_RC(int_reg));
coleenp@113 3497 match(RegN);
coleenp@113 3498
coleenp@113 3499 format %{ %}
coleenp@113 3500 interface(REG_INTER);
coleenp@113 3501 %}
coleenp@113 3502
duke@0 3503 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP?
duke@0 3504 // Answer: Operand match rules govern the DFA as it processes instruction inputs.
duke@0 3505 // It's fine for an instruction input which expects rRegP to match a r15_RegP.
duke@0 3506 // The output of an instruction is controlled by the allocator, which respects
duke@0 3507 // register class masks, not match rules. Unless an instruction mentions
duke@0 3508 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered
duke@0 3509 // by the allocator as an input.
duke@0 3510
duke@0 3511 operand no_rax_RegP()
duke@0 3512 %{
duke@0 3513 constraint(ALLOC_IN_RC(ptr_no_rax_reg));
duke@0 3514 match(RegP);
duke@0 3515 match(rbx_RegP);
duke@0 3516 match(rsi_RegP);
duke@0 3517 match(rdi_RegP);
duke@0 3518
duke@0 3519 format %{ %}
duke@0 3520 interface(REG_INTER);
duke@0 3521 %}
duke@0 3522
duke@0 3523 operand no_rbp_RegP()
duke@0 3524 %{
duke@0 3525 constraint(ALLOC_IN_RC(ptr_no_rbp_reg));
duke@0 3526 match(RegP);
duke@0 3527 match(rbx_RegP);
duke@0 3528 match(rsi_RegP);
duke@0 3529 match(rdi_RegP);
duke@0 3530
duke@0 3531 format %{ %}
duke@0 3532 interface(REG_INTER);
duke@0 3533 %}
duke@0 3534
duke@0 3535 operand no_rax_rbx_RegP()
duke@0 3536 %{
duke@0 3537 constraint(ALLOC_IN_RC(ptr_no_rax_rbx_reg));
duke@0 3538 match(RegP);
duke@0 3539 match(rsi_RegP);
duke@0 3540 match(rdi_RegP);
duke@0 3541
duke@0 3542 format %{ %}
duke@0 3543 interface(REG_INTER);
duke@0 3544 %}
duke@0 3545
duke@0 3546 // Special Registers
duke@0 3547 // Return a pointer value
duke@0 3548 operand rax_RegP()
duke@0 3549 %{
duke@0 3550 constraint(ALLOC_IN_RC(ptr_rax_reg));
duke@0 3551 match(RegP);
duke@0 3552 match(rRegP);
duke@0 3553
duke@0 3554 format %{ %}
duke@0 3555 interface(REG_INTER);
duke@0 3556 %}
duke@0 3557
coleenp@113 3558 // Special Registers
coleenp@113 3559 // Return a compressed pointer value
coleenp@113 3560 operand rax_RegN()
coleenp@113 3561 %{
coleenp@113 3562 constraint(ALLOC_IN_RC(int_rax_reg));
coleenp@113 3563 match(RegN);
coleenp@113 3564 match(rRegN);
coleenp@113 3565
coleenp@113 3566 format %{ %}
coleenp@113 3567 interface(REG_INTER);
coleenp@113 3568 %}
coleenp@113 3569
duke@0 3570 // Used in AtomicAdd
duke@0 3571 operand rbx_RegP()
duke@0 3572 %{
duke@0 3573 constraint(ALLOC_IN_RC(ptr_rbx_reg));
duke@0 3574 match(RegP);
duke@0 3575 match(rRegP);
duke@0 3576
duke@0 3577 format %{ %}
duke@0 3578 interface(REG_INTER);
duke@0 3579 %}
duke@0 3580
duke@0 3581 operand rsi_RegP()
duke@0 3582 %{
duke@0 3583 constraint(ALLOC_IN_RC(ptr_rsi_reg));
duke@0 3584 match(RegP);
duke@0 3585 match(rRegP);
duke@0 3586
duke@0 3587 format %{ %}
duke@0 3588 interface(REG_INTER);
duke@0 3589 %}
duke@0 3590
duke@0 3591 // Used in rep stosq
duke@0 3592 operand rdi_RegP()
duke@0 3593 %{
duke@0 3594 constraint(ALLOC_IN_RC(ptr_rdi_reg));
duke@0 3595 match(RegP);
duke@0 3596 match(rRegP);
duke@0 3597
duke@0 3598 format %{ %}
duke@0 3599 interface(REG_INTER);
duke@0 3600 %}
duke@0 3601
duke@0 3602 operand rbp_RegP()
duke@0 3603 %{
duke@0 3604 constraint(ALLOC_IN_RC(ptr_rbp_reg));
duke@0 3605 match(RegP);
duke@0 3606 match(rRegP);
duke@0 3607
duke@0 3608 format %{ %}
duke@0 3609 interface(REG_INTER);
duke@0 3610 %}
duke@0 3611
duke@0 3612 operand r15_RegP()
duke@0 3613 %{
duke@0 3614 constraint(ALLOC_IN_RC(ptr_r15_reg));
duke@0 3615 match(RegP);
duke@0 3616 match(rRegP);
duke@0 3617
duke@0 3618 format %{ %}
duke@0 3619 interface(REG_INTER);
duke@0 3620 %}
duke@0 3621
duke@0 3622 operand rRegL()
duke@0 3623 %{
duke@0 3624 constraint(ALLOC_IN_RC(long_reg));
duke@0 3625 match(RegL);
duke@0 3626 match(rax_RegL);
duke@0 3627 match(rdx_RegL);
duke@0 3628
duke@0 3629 format %{ %}
duke@0 3630 interface(REG_INTER);
duke@0 3631 %}
duke@0 3632
duke@0 3633 // Special Registers
duke@0 3634 operand no_rax_rdx_RegL()
duke@0 3635 %{
duke@0 3636 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg));
duke@0 3637 match(RegL);
duke@0 3638 match(rRegL);
duke@0 3639
duke@0 3640 format %{ %}
duke@0 3641 interface(REG_INTER);
duke@0 3642 %}
duke@0 3643
duke@0 3644 operand no_rax_RegL()
duke@0 3645 %{
duke@0 3646 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg));
duke@0 3647 match(RegL);
duke@0 3648 match(rRegL);
duke@0 3649 match(rdx_RegL);
duke@0 3650
duke@0 3651 format %{ %}
duke@0 3652 interface(REG_INTER);
duke@0 3653 %}
duke@0 3654
duke@0 3655 operand no_rcx_RegL()
duke@0 3656 %{
duke@0 3657 constraint(ALLOC_IN_RC(long_no_rcx_reg));
duke@0 3658 match(RegL);
duke@0 3659 match(rRegL);
duke@0 3660
duke@0 3661 format %{ %}
duke@0 3662 interface(REG_INTER);
duke@0 3663 %}
duke@0 3664
duke@0 3665 operand rax_RegL()
duke@0 3666 %{
duke@0 3667 constraint(ALLOC_IN_RC(long_rax_reg));
duke@0 3668 match(RegL);
duke@0 3669 match(rRegL);
duke@0 3670
duke@0 3671 format %{ "RAX" %}
duke@0 3672 interface(REG_INTER);
duke@0 3673 %}
duke@0 3674
duke@0 3675 operand rcx_RegL()
duke@0 3676 %{
duke@0 3677 constraint(ALLOC_IN_RC(long_rcx_reg));
duke@0 3678 match(RegL);
duke@0 3679 match(rRegL);
duke@0 3680
duke@0 3681 format %{ %}
duke@0 3682 interface(REG_INTER);
duke@0 3683 %}
duke@0 3684
duke@0 3685 operand rdx_RegL()
duke@0 3686 %{
duke@0 3687 constraint(ALLOC_IN_RC(long_rdx_reg));
duke@0 3688 match(RegL);
duke@0 3689 match(rRegL);
duke@0 3690
duke@0 3691 format %{ %}
duke@0 3692 interface(REG_INTER);
duke@0 3693 %}
duke@0 3694
duke@0 3695 // Flags register, used as output of compare instructions
duke@0 3696 operand rFlagsReg()
duke@0 3697 %{
duke@0 3698 constraint(ALLOC_IN_RC(int_flags));
duke@0 3699 match(RegFlags);
duke@0 3700
duke@0 3701 format %{ "RFLAGS" %}
duke@0 3702 interface(REG_INTER);
duke@0 3703 %}
duke@0 3704
duke@0 3705 // Flags register, used as output of FLOATING POINT compare instructions
duke@0 3706 operand rFlagsRegU()
duke@0 3707 %{
duke@0 3708 constraint(ALLOC_IN_RC(int_flags));
duke@0 3709 match(RegFlags);
duke@0 3710
duke@0 3711 format %{ "RFLAGS_U" %}
duke@0 3712 interface(REG_INTER);
duke@0 3713 %}
duke@0 3714
never@415 3715 operand rFlagsRegUCF() %{
never@415 3716 constraint(ALLOC_IN_RC(int_flags));
never@415 3717 match(RegFlags);
never@415 3718 predicate(false);
never@415 3719
never@415 3720 format %{ "RFLAGS_U_CF" %}
never@415 3721 interface(REG_INTER);
never@415 3722 %}
never@415 3723
duke@0 3724 // Float register operands
duke@0 3725 operand regF()
duke@0 3726 %{
duke@0 3727 constraint(ALLOC_IN_RC(float_reg));
duke@0 3728 match(RegF);
duke@0 3729
duke@0 3730 format %{ %}
duke@0 3731 interface(REG_INTER);
duke@0 3732 %}
duke@0 3733
duke@0 3734 // Double register operands
iveresov@2251 3735 operand regD()
duke@0 3736 %{
duke@0 3737 constraint(ALLOC_IN_RC(double_reg));
duke@0 3738 match(RegD);
duke@0 3739
duke@0 3740 format %{ %}
duke@0 3741 interface(REG_INTER);
duke@0 3742 %}
duke@0 3743
duke@0 3744 //----------Memory Operands----------------------------------------------------
duke@0 3745 // Direct Memory Operand
duke@0 3746 // operand direct(immP addr)
duke@0 3747 // %{
duke@0 3748 // match(addr);
duke@0 3749
duke@0 3750 // format %{ "[$addr]" %}
duke@0 3751 // interface(MEMORY_INTER) %{
duke@0 3752 // base(0xFFFFFFFF);
duke@0 3753 // index(0x4);
duke@0 3754 // scale(0x0);
duke@0 3755 // disp($addr);
duke@0 3756 // %}
duke@0 3757 // %}
duke@0 3758
duke@0 3759 // Indirect Memory Operand
duke@0 3760 operand indirect(any_RegP reg)
duke@0 3761 %{
duke@0 3762 constraint(ALLOC_IN_RC(ptr_reg));
duke@0 3763 match(reg);
duke@0 3764
duke@0 3765 format %{ "[$reg]" %}
duke@0 3766 interface(MEMORY_INTER) %{
duke@0 3767 base($reg);
duke@0 3768 index(0x4);
duke@0 3769 scale(0x0);
duke@0 3770 disp(0x0);
duke@0 3771 %}
duke@0 3772 %}
duke@0 3773
duke@0 3774 // Indirect Memory Plus Short Offset Operand
duke@0 3775 operand indOffset8(any_RegP reg, immL8 off)
duke@0 3776 %{
duke@0 3777 constraint(ALLOC_IN_RC(ptr_reg));
duke@0 3778 match(AddP reg off);
duke@0 3779
duke@0 3780 format %{ "[$reg + $off (8-bit)]" %}
duke@0 3781 interface(MEMORY_INTER) %{
duke@0 3782 base($reg);
duke@0 3783 index(0x4);
duke@0 3784 scale(0x0);
duke@0 3785 disp($off);
duke@0 3786 %}
duke@0 3787 %}
duke@0 3788
duke@0 3789 // Indirect Memory Plus Long Offset Operand
duke@0 3790 operand indOffset32(any_RegP reg, immL32 off)
duke@0 3791 %{
duke@0 3792 constraint(ALLOC_IN_RC(ptr_reg));
duke@0 3793 match(AddP reg off);
duke@0 3794
duke@0 3795 format %{ "[$reg + $off (32-bit)]" %}
duke@0 3796 interface(MEMORY_INTER) %{
duke@0 3797 base($reg);
duke@0 3798 index(0x4);
duke@0 3799 scale(0x0);
duke@0 3800 disp($off);
duke@0 3801 %}
duke@0 3802 %}
duke@0 3803
duke@0 3804 // Indirect Memory Plus Index Register Plus Offset Operand
duke@0 3805 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off)
duke@0 3806 %{
duke@0 3807 constraint(ALLOC_IN_RC(ptr_reg));
duke@0 3808 match(AddP (AddP reg lreg) off);
duke@0 3809
duke@0 3810 op_cost(10);
duke@0 3811 format %{"[$reg + $off + $lreg]" %}
duke@0 3812 interface(MEMORY_INTER) %{
duke@0 3813 base($reg);
duke@0 3814 index($lreg);
duke@0 3815 scale(0x0);
duke@0 3816 disp($off);
duke@0 3817 %}
duke@0 3818 %}
duke@0 3819
duke@0 3820 // Indirect Memory Plus Index Register Plus Offset Operand
duke@0 3821 operand indIndex(any_RegP reg, rRegL lreg)
duke@0 3822 %{
duke@0 3823 constraint(ALLOC_IN_RC(ptr_reg));
duke@0 3824 match(AddP reg lreg);
duke@0 3825
duke@0 3826 op_cost(10);
duke@0 3827 format %{"[$reg + $lreg]" %}
duke@0 3828 interface(MEMORY_INTER) %{
duke@0 3829 base($reg);
duke@0 3830 index($lreg);
duke@0 3831 scale(0x0);
duke@0 3832 disp(0x0);
duke@0 3833 %}
duke@0 3834 %}
duke@0 3835
duke@0 3836 // Indirect Memory Times Scale Plus Index Register
duke@0 3837 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale)
duke@0 3838 %{
duke@0 3839 constraint(ALLOC_IN_RC(ptr_reg));
duke@0 3840 match(AddP reg (LShiftL lreg scale));
duke@0 3841
duke@0 3842 op_cost(10);
duke@0 3843 format %{"[$reg + $lreg << $scale]" %}
duke@0 3844 interface(MEMORY_INTER) %{
duke@0 3845 base($reg);
duke@0 3846 index($lreg);
duke@0 3847 scale($scale);
duke@0 3848 disp(0x0);
duke@0 3849 %}
duke@0 3850 %}
duke@0 3851
duke@0 3852 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand
duke@0 3853 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale)
duke@0 3854 %{
duke@0 3855 constraint(ALLOC_IN_RC(ptr_reg));
duke@0 3856 match(AddP (AddP reg (LShiftL lreg scale)) off);
duke@0 3857