annotate src/cpu/x86/vm/x86_64.ad @ 8379:bd72804c91d6

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