annotate src/cpu/x86/vm/x86_64.ad @ 3139:fd8114661503

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