1// 2// Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. 3// Copyright (c) 2012, 2016 SAP SE. All rights reserved. 4// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5// 6// This code is free software; you can redistribute it and/or modify it 7// under the terms of the GNU General Public License version 2 only, as 8// published by the Free Software Foundation. 9// 10// This code is distributed in the hope that it will be useful, but WITHOUT 11// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13// version 2 for more details (a copy is included in the LICENSE file that 14// accompanied this code). 15// 16// You should have received a copy of the GNU General Public License version 17// 2 along with this work; if not, write to the Free Software Foundation, 18// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19// 20// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21// or visit www.oracle.com if you need additional information or have any 22// questions. 23// 24// 25 26// 27// PPC64 Architecture Description File 28// 29 30//----------REGISTER DEFINITION BLOCK------------------------------------------ 31// This information is used by the matcher and the register allocator to 32// describe individual registers and classes of registers within the target 33// architecture. 34register %{ 35//----------Architecture Description Register Definitions---------------------- 36// General Registers 37// "reg_def" name (register save type, C convention save type, 38// ideal register type, encoding); 39// 40// Register Save Types: 41// 42// NS = No-Save: The register allocator assumes that these registers 43// can be used without saving upon entry to the method, & 44// that they do not need to be saved at call sites. 45// 46// SOC = Save-On-Call: The register allocator assumes that these registers 47// can be used without saving upon entry to the method, 48// but that they must be saved at call sites. 49// These are called "volatiles" on ppc. 50// 51// SOE = Save-On-Entry: The register allocator assumes that these registers 52// must be saved before using them upon entry to the 53// method, but they do not need to be saved at call 54// sites. 55// These are called "nonvolatiles" on ppc. 56// 57// AS = Always-Save: The register allocator assumes that these registers 58// must be saved before using them upon entry to the 59// method, & that they must be saved at call sites. 60// 61// Ideal Register Type is used to determine how to save & restore a 62// register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get 63// spilled with LoadP/StoreP. If the register supports both, use Op_RegI. 64// 65// The encoding number is the actual bit-pattern placed into the opcodes. 66// 67// PPC64 register definitions, based on the 64-bit PowerPC ELF ABI 68// Supplement Version 1.7 as of 2003-10-29. 69// 70// For each 64-bit register we must define two registers: the register 71// itself, e.g. R3, and a corresponding virtual other (32-bit-)'half', 72// e.g. R3_H, which is needed by the allocator, but is not used 73// for stores, loads, etc. 74 75// ---------------------------- 76// Integer/Long Registers 77// ---------------------------- 78 79 // PPC64 has 32 64-bit integer registers. 80 81 // types: v = volatile, nv = non-volatile, s = system 82 reg_def R0 ( SOC, SOC, Op_RegI, 0, R0->as_VMReg() ); // v used in prologs 83 reg_def R0_H ( SOC, SOC, Op_RegI, 99, R0->as_VMReg()->next() ); 84 reg_def R1 ( NS, NS, Op_RegI, 1, R1->as_VMReg() ); // s SP 85 reg_def R1_H ( NS, NS, Op_RegI, 99, R1->as_VMReg()->next() ); 86 reg_def R2 ( SOC, SOC, Op_RegI, 2, R2->as_VMReg() ); // v TOC 87 reg_def R2_H ( SOC, SOC, Op_RegI, 99, R2->as_VMReg()->next() ); 88 reg_def R3 ( SOC, SOC, Op_RegI, 3, R3->as_VMReg() ); // v iarg1 & iret 89 reg_def R3_H ( SOC, SOC, Op_RegI, 99, R3->as_VMReg()->next() ); 90 reg_def R4 ( SOC, SOC, Op_RegI, 4, R4->as_VMReg() ); // iarg2 91 reg_def R4_H ( SOC, SOC, Op_RegI, 99, R4->as_VMReg()->next() ); 92 reg_def R5 ( SOC, SOC, Op_RegI, 5, R5->as_VMReg() ); // v iarg3 93 reg_def R5_H ( SOC, SOC, Op_RegI, 99, R5->as_VMReg()->next() ); 94 reg_def R6 ( SOC, SOC, Op_RegI, 6, R6->as_VMReg() ); // v iarg4 95 reg_def R6_H ( SOC, SOC, Op_RegI, 99, R6->as_VMReg()->next() ); 96 reg_def R7 ( SOC, SOC, Op_RegI, 7, R7->as_VMReg() ); // v iarg5 97 reg_def R7_H ( SOC, SOC, Op_RegI, 99, R7->as_VMReg()->next() ); 98 reg_def R8 ( SOC, SOC, Op_RegI, 8, R8->as_VMReg() ); // v iarg6 99 reg_def R8_H ( SOC, SOC, Op_RegI, 99, R8->as_VMReg()->next() ); 100 reg_def R9 ( SOC, SOC, Op_RegI, 9, R9->as_VMReg() ); // v iarg7 101 reg_def R9_H ( SOC, SOC, Op_RegI, 99, R9->as_VMReg()->next() ); 102 reg_def R10 ( SOC, SOC, Op_RegI, 10, R10->as_VMReg() ); // v iarg8 103 reg_def R10_H( SOC, SOC, Op_RegI, 99, R10->as_VMReg()->next()); 104 reg_def R11 ( SOC, SOC, Op_RegI, 11, R11->as_VMReg() ); // v ENV / scratch 105 reg_def R11_H( SOC, SOC, Op_RegI, 99, R11->as_VMReg()->next()); 106 reg_def R12 ( SOC, SOC, Op_RegI, 12, R12->as_VMReg() ); // v scratch 107 reg_def R12_H( SOC, SOC, Op_RegI, 99, R12->as_VMReg()->next()); 108 reg_def R13 ( NS, NS, Op_RegI, 13, R13->as_VMReg() ); // s system thread id 109 reg_def R13_H( NS, NS, Op_RegI, 99, R13->as_VMReg()->next()); 110 reg_def R14 ( SOC, SOE, Op_RegI, 14, R14->as_VMReg() ); // nv 111 reg_def R14_H( SOC, SOE, Op_RegI, 99, R14->as_VMReg()->next()); 112 reg_def R15 ( SOC, SOE, Op_RegI, 15, R15->as_VMReg() ); // nv 113 reg_def R15_H( SOC, SOE, Op_RegI, 99, R15->as_VMReg()->next()); 114 reg_def R16 ( SOC, SOE, Op_RegI, 16, R16->as_VMReg() ); // nv 115 reg_def R16_H( SOC, SOE, Op_RegI, 99, R16->as_VMReg()->next()); 116 reg_def R17 ( SOC, SOE, Op_RegI, 17, R17->as_VMReg() ); // nv 117 reg_def R17_H( SOC, SOE, Op_RegI, 99, R17->as_VMReg()->next()); 118 reg_def R18 ( SOC, SOE, Op_RegI, 18, R18->as_VMReg() ); // nv 119 reg_def R18_H( SOC, SOE, Op_RegI, 99, R18->as_VMReg()->next()); 120 reg_def R19 ( SOC, SOE, Op_RegI, 19, R19->as_VMReg() ); // nv 121 reg_def R19_H( SOC, SOE, Op_RegI, 99, R19->as_VMReg()->next()); 122 reg_def R20 ( SOC, SOE, Op_RegI, 20, R20->as_VMReg() ); // nv 123 reg_def R20_H( SOC, SOE, Op_RegI, 99, R20->as_VMReg()->next()); 124 reg_def R21 ( SOC, SOE, Op_RegI, 21, R21->as_VMReg() ); // nv 125 reg_def R21_H( SOC, SOE, Op_RegI, 99, R21->as_VMReg()->next()); 126 reg_def R22 ( SOC, SOE, Op_RegI, 22, R22->as_VMReg() ); // nv 127 reg_def R22_H( SOC, SOE, Op_RegI, 99, R22->as_VMReg()->next()); 128 reg_def R23 ( SOC, SOE, Op_RegI, 23, R23->as_VMReg() ); // nv 129 reg_def R23_H( SOC, SOE, Op_RegI, 99, R23->as_VMReg()->next()); 130 reg_def R24 ( SOC, SOE, Op_RegI, 24, R24->as_VMReg() ); // nv 131 reg_def R24_H( SOC, SOE, Op_RegI, 99, R24->as_VMReg()->next()); 132 reg_def R25 ( SOC, SOE, Op_RegI, 25, R25->as_VMReg() ); // nv 133 reg_def R25_H( SOC, SOE, Op_RegI, 99, R25->as_VMReg()->next()); 134 reg_def R26 ( SOC, SOE, Op_RegI, 26, R26->as_VMReg() ); // nv 135 reg_def R26_H( SOC, SOE, Op_RegI, 99, R26->as_VMReg()->next()); 136 reg_def R27 ( SOC, SOE, Op_RegI, 27, R27->as_VMReg() ); // nv 137 reg_def R27_H( SOC, SOE, Op_RegI, 99, R27->as_VMReg()->next()); 138 reg_def R28 ( SOC, SOE, Op_RegI, 28, R28->as_VMReg() ); // nv 139 reg_def R28_H( SOC, SOE, Op_RegI, 99, R28->as_VMReg()->next()); 140 reg_def R29 ( SOC, SOE, Op_RegI, 29, R29->as_VMReg() ); // nv 141 reg_def R29_H( SOC, SOE, Op_RegI, 99, R29->as_VMReg()->next()); 142 reg_def R30 ( SOC, SOE, Op_RegI, 30, R30->as_VMReg() ); // nv 143 reg_def R30_H( SOC, SOE, Op_RegI, 99, R30->as_VMReg()->next()); 144 reg_def R31 ( SOC, SOE, Op_RegI, 31, R31->as_VMReg() ); // nv 145 reg_def R31_H( SOC, SOE, Op_RegI, 99, R31->as_VMReg()->next()); 146 147 148// ---------------------------- 149// Float/Double Registers 150// ---------------------------- 151 152 // Double Registers 153 // The rules of ADL require that double registers be defined in pairs. 154 // Each pair must be two 32-bit values, but not necessarily a pair of 155 // single float registers. In each pair, ADLC-assigned register numbers 156 // must be adjacent, with the lower number even. Finally, when the 157 // CPU stores such a register pair to memory, the word associated with 158 // the lower ADLC-assigned number must be stored to the lower address. 159 160 // PPC64 has 32 64-bit floating-point registers. Each can store a single 161 // or double precision floating-point value. 162 163 // types: v = volatile, nv = non-volatile, s = system 164 reg_def F0 ( SOC, SOC, Op_RegF, 0, F0->as_VMReg() ); // v scratch 165 reg_def F0_H ( SOC, SOC, Op_RegF, 99, F0->as_VMReg()->next() ); 166 reg_def F1 ( SOC, SOC, Op_RegF, 1, F1->as_VMReg() ); // v farg1 & fret 167 reg_def F1_H ( SOC, SOC, Op_RegF, 99, F1->as_VMReg()->next() ); 168 reg_def F2 ( SOC, SOC, Op_RegF, 2, F2->as_VMReg() ); // v farg2 169 reg_def F2_H ( SOC, SOC, Op_RegF, 99, F2->as_VMReg()->next() ); 170 reg_def F3 ( SOC, SOC, Op_RegF, 3, F3->as_VMReg() ); // v farg3 171 reg_def F3_H ( SOC, SOC, Op_RegF, 99, F3->as_VMReg()->next() ); 172 reg_def F4 ( SOC, SOC, Op_RegF, 4, F4->as_VMReg() ); // v farg4 173 reg_def F4_H ( SOC, SOC, Op_RegF, 99, F4->as_VMReg()->next() ); 174 reg_def F5 ( SOC, SOC, Op_RegF, 5, F5->as_VMReg() ); // v farg5 175 reg_def F5_H ( SOC, SOC, Op_RegF, 99, F5->as_VMReg()->next() ); 176 reg_def F6 ( SOC, SOC, Op_RegF, 6, F6->as_VMReg() ); // v farg6 177 reg_def F6_H ( SOC, SOC, Op_RegF, 99, F6->as_VMReg()->next() ); 178 reg_def F7 ( SOC, SOC, Op_RegF, 7, F7->as_VMReg() ); // v farg7 179 reg_def F7_H ( SOC, SOC, Op_RegF, 99, F7->as_VMReg()->next() ); 180 reg_def F8 ( SOC, SOC, Op_RegF, 8, F8->as_VMReg() ); // v farg8 181 reg_def F8_H ( SOC, SOC, Op_RegF, 99, F8->as_VMReg()->next() ); 182 reg_def F9 ( SOC, SOC, Op_RegF, 9, F9->as_VMReg() ); // v farg9 183 reg_def F9_H ( SOC, SOC, Op_RegF, 99, F9->as_VMReg()->next() ); 184 reg_def F10 ( SOC, SOC, Op_RegF, 10, F10->as_VMReg() ); // v farg10 185 reg_def F10_H( SOC, SOC, Op_RegF, 99, F10->as_VMReg()->next()); 186 reg_def F11 ( SOC, SOC, Op_RegF, 11, F11->as_VMReg() ); // v farg11 187 reg_def F11_H( SOC, SOC, Op_RegF, 99, F11->as_VMReg()->next()); 188 reg_def F12 ( SOC, SOC, Op_RegF, 12, F12->as_VMReg() ); // v farg12 189 reg_def F12_H( SOC, SOC, Op_RegF, 99, F12->as_VMReg()->next()); 190 reg_def F13 ( SOC, SOC, Op_RegF, 13, F13->as_VMReg() ); // v farg13 191 reg_def F13_H( SOC, SOC, Op_RegF, 99, F13->as_VMReg()->next()); 192 reg_def F14 ( SOC, SOE, Op_RegF, 14, F14->as_VMReg() ); // nv 193 reg_def F14_H( SOC, SOE, Op_RegF, 99, F14->as_VMReg()->next()); 194 reg_def F15 ( SOC, SOE, Op_RegF, 15, F15->as_VMReg() ); // nv 195 reg_def F15_H( SOC, SOE, Op_RegF, 99, F15->as_VMReg()->next()); 196 reg_def F16 ( SOC, SOE, Op_RegF, 16, F16->as_VMReg() ); // nv 197 reg_def F16_H( SOC, SOE, Op_RegF, 99, F16->as_VMReg()->next()); 198 reg_def F17 ( SOC, SOE, Op_RegF, 17, F17->as_VMReg() ); // nv 199 reg_def F17_H( SOC, SOE, Op_RegF, 99, F17->as_VMReg()->next()); 200 reg_def F18 ( SOC, SOE, Op_RegF, 18, F18->as_VMReg() ); // nv 201 reg_def F18_H( SOC, SOE, Op_RegF, 99, F18->as_VMReg()->next()); 202 reg_def F19 ( SOC, SOE, Op_RegF, 19, F19->as_VMReg() ); // nv 203 reg_def F19_H( SOC, SOE, Op_RegF, 99, F19->as_VMReg()->next()); 204 reg_def F20 ( SOC, SOE, Op_RegF, 20, F20->as_VMReg() ); // nv 205 reg_def F20_H( SOC, SOE, Op_RegF, 99, F20->as_VMReg()->next()); 206 reg_def F21 ( SOC, SOE, Op_RegF, 21, F21->as_VMReg() ); // nv 207 reg_def F21_H( SOC, SOE, Op_RegF, 99, F21->as_VMReg()->next()); 208 reg_def F22 ( SOC, SOE, Op_RegF, 22, F22->as_VMReg() ); // nv 209 reg_def F22_H( SOC, SOE, Op_RegF, 99, F22->as_VMReg()->next()); 210 reg_def F23 ( SOC, SOE, Op_RegF, 23, F23->as_VMReg() ); // nv 211 reg_def F23_H( SOC, SOE, Op_RegF, 99, F23->as_VMReg()->next()); 212 reg_def F24 ( SOC, SOE, Op_RegF, 24, F24->as_VMReg() ); // nv 213 reg_def F24_H( SOC, SOE, Op_RegF, 99, F24->as_VMReg()->next()); 214 reg_def F25 ( SOC, SOE, Op_RegF, 25, F25->as_VMReg() ); // nv 215 reg_def F25_H( SOC, SOE, Op_RegF, 99, F25->as_VMReg()->next()); 216 reg_def F26 ( SOC, SOE, Op_RegF, 26, F26->as_VMReg() ); // nv 217 reg_def F26_H( SOC, SOE, Op_RegF, 99, F26->as_VMReg()->next()); 218 reg_def F27 ( SOC, SOE, Op_RegF, 27, F27->as_VMReg() ); // nv 219 reg_def F27_H( SOC, SOE, Op_RegF, 99, F27->as_VMReg()->next()); 220 reg_def F28 ( SOC, SOE, Op_RegF, 28, F28->as_VMReg() ); // nv 221 reg_def F28_H( SOC, SOE, Op_RegF, 99, F28->as_VMReg()->next()); 222 reg_def F29 ( SOC, SOE, Op_RegF, 29, F29->as_VMReg() ); // nv 223 reg_def F29_H( SOC, SOE, Op_RegF, 99, F29->as_VMReg()->next()); 224 reg_def F30 ( SOC, SOE, Op_RegF, 30, F30->as_VMReg() ); // nv 225 reg_def F30_H( SOC, SOE, Op_RegF, 99, F30->as_VMReg()->next()); 226 reg_def F31 ( SOC, SOE, Op_RegF, 31, F31->as_VMReg() ); // nv 227 reg_def F31_H( SOC, SOE, Op_RegF, 99, F31->as_VMReg()->next()); 228 229// ---------------------------- 230// Special Registers 231// ---------------------------- 232 233// Condition Codes Flag Registers 234 235 // PPC64 has 8 condition code "registers" which are all contained 236 // in the CR register. 237 238 // types: v = volatile, nv = non-volatile, s = system 239 reg_def CCR0(SOC, SOC, Op_RegFlags, 0, CCR0->as_VMReg()); // v 240 reg_def CCR1(SOC, SOC, Op_RegFlags, 1, CCR1->as_VMReg()); // v 241 reg_def CCR2(SOC, SOC, Op_RegFlags, 2, CCR2->as_VMReg()); // nv 242 reg_def CCR3(SOC, SOC, Op_RegFlags, 3, CCR3->as_VMReg()); // nv 243 reg_def CCR4(SOC, SOC, Op_RegFlags, 4, CCR4->as_VMReg()); // nv 244 reg_def CCR5(SOC, SOC, Op_RegFlags, 5, CCR5->as_VMReg()); // v 245 reg_def CCR6(SOC, SOC, Op_RegFlags, 6, CCR6->as_VMReg()); // v 246 reg_def CCR7(SOC, SOC, Op_RegFlags, 7, CCR7->as_VMReg()); // v 247 248 // Special registers of PPC64 249 250 reg_def SR_XER( SOC, SOC, Op_RegP, 0, SR_XER->as_VMReg()); // v 251 reg_def SR_LR( SOC, SOC, Op_RegP, 1, SR_LR->as_VMReg()); // v 252 reg_def SR_CTR( SOC, SOC, Op_RegP, 2, SR_CTR->as_VMReg()); // v 253 reg_def SR_VRSAVE( SOC, SOC, Op_RegP, 3, SR_VRSAVE->as_VMReg()); // v 254 reg_def SR_SPEFSCR(SOC, SOC, Op_RegP, 4, SR_SPEFSCR->as_VMReg()); // v 255 reg_def SR_PPR( SOC, SOC, Op_RegP, 5, SR_PPR->as_VMReg()); // v 256 257 258// ---------------------------- 259// Specify priority of register selection within phases of register 260// allocation. Highest priority is first. A useful heuristic is to 261// give registers a low priority when they are required by machine 262// instructions, like EAX and EDX on I486, and choose no-save registers 263// before save-on-call, & save-on-call before save-on-entry. Registers 264// which participate in fixed calling sequences should come last. 265// Registers which are used as pairs must fall on an even boundary. 266 267// It's worth about 1% on SPEC geomean to get this right. 268 269// Chunk0, chunk1, and chunk2 form the MachRegisterNumbers enumeration 270// in adGlobals_ppc.hpp which defines the <register>_num values, e.g. 271// R3_num. Therefore, R3_num may not be (and in reality is not) 272// the same as R3->encoding()! Furthermore, we cannot make any 273// assumptions on ordering, e.g. R3_num may be less than R2_num. 274// Additionally, the function 275// static enum RC rc_class(OptoReg::Name reg ) 276// maps a given <register>_num value to its chunk type (except for flags) 277// and its current implementation relies on chunk0 and chunk1 having a 278// size of 64 each. 279 280// If you change this allocation class, please have a look at the 281// default values for the parameters RoundRobinIntegerRegIntervalStart 282// and RoundRobinFloatRegIntervalStart 283 284alloc_class chunk0 ( 285 // Chunk0 contains *all* 64 integer registers halves. 286 287 // "non-volatile" registers 288 R14, R14_H, 289 R15, R15_H, 290 R17, R17_H, 291 R18, R18_H, 292 R19, R19_H, 293 R20, R20_H, 294 R21, R21_H, 295 R22, R22_H, 296 R23, R23_H, 297 R24, R24_H, 298 R25, R25_H, 299 R26, R26_H, 300 R27, R27_H, 301 R28, R28_H, 302 R29, R29_H, 303 R30, R30_H, 304 R31, R31_H, 305 306 // scratch/special registers 307 R11, R11_H, 308 R12, R12_H, 309 310 // argument registers 311 R10, R10_H, 312 R9, R9_H, 313 R8, R8_H, 314 R7, R7_H, 315 R6, R6_H, 316 R5, R5_H, 317 R4, R4_H, 318 R3, R3_H, 319 320 // special registers, not available for allocation 321 R16, R16_H, // R16_thread 322 R13, R13_H, // system thread id 323 R2, R2_H, // may be used for TOC 324 R1, R1_H, // SP 325 R0, R0_H // R0 (scratch) 326); 327 328// If you change this allocation class, please have a look at the 329// default values for the parameters RoundRobinIntegerRegIntervalStart 330// and RoundRobinFloatRegIntervalStart 331 332alloc_class chunk1 ( 333 // Chunk1 contains *all* 64 floating-point registers halves. 334 335 // scratch register 336 F0, F0_H, 337 338 // argument registers 339 F13, F13_H, 340 F12, F12_H, 341 F11, F11_H, 342 F10, F10_H, 343 F9, F9_H, 344 F8, F8_H, 345 F7, F7_H, 346 F6, F6_H, 347 F5, F5_H, 348 F4, F4_H, 349 F3, F3_H, 350 F2, F2_H, 351 F1, F1_H, 352 353 // non-volatile registers 354 F14, F14_H, 355 F15, F15_H, 356 F16, F16_H, 357 F17, F17_H, 358 F18, F18_H, 359 F19, F19_H, 360 F20, F20_H, 361 F21, F21_H, 362 F22, F22_H, 363 F23, F23_H, 364 F24, F24_H, 365 F25, F25_H, 366 F26, F26_H, 367 F27, F27_H, 368 F28, F28_H, 369 F29, F29_H, 370 F30, F30_H, 371 F31, F31_H 372); 373 374alloc_class chunk2 ( 375 // Chunk2 contains *all* 8 condition code registers. 376 377 CCR0, 378 CCR1, 379 CCR2, 380 CCR3, 381 CCR4, 382 CCR5, 383 CCR6, 384 CCR7 385); 386 387alloc_class chunk3 ( 388 // special registers 389 // These registers are not allocated, but used for nodes generated by postalloc expand. 390 SR_XER, 391 SR_LR, 392 SR_CTR, 393 SR_VRSAVE, 394 SR_SPEFSCR, 395 SR_PPR 396); 397 398//-------Architecture Description Register Classes----------------------- 399 400// Several register classes are automatically defined based upon 401// information in this architecture description. 402 403// 1) reg_class inline_cache_reg ( as defined in frame section ) 404// 2) reg_class compiler_method_oop_reg ( as defined in frame section ) 405// 2) reg_class interpreter_method_oop_reg ( as defined in frame section ) 406// 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 407// 408 409// ---------------------------- 410// 32 Bit Register Classes 411// ---------------------------- 412 413// We specify registers twice, once as read/write, and once read-only. 414// We use the read-only registers for source operands. With this, we 415// can include preset read only registers in this class, as a hard-coded 416// '0'-register. (We used to simulate this on ppc.) 417 418// 32 bit registers that can be read and written i.e. these registers 419// can be dest (or src) of normal instructions. 420reg_class bits32_reg_rw( 421/*R0*/ // R0 422/*R1*/ // SP 423 R2, // TOC 424 R3, 425 R4, 426 R5, 427 R6, 428 R7, 429 R8, 430 R9, 431 R10, 432 R11, 433 R12, 434/*R13*/ // system thread id 435 R14, 436 R15, 437/*R16*/ // R16_thread 438 R17, 439 R18, 440 R19, 441 R20, 442 R21, 443 R22, 444 R23, 445 R24, 446 R25, 447 R26, 448 R27, 449 R28, 450/*R29,*/ // global TOC 451 R30, 452 R31 453); 454 455// 32 bit registers that can only be read i.e. these registers can 456// only be src of all instructions. 457reg_class bits32_reg_ro( 458/*R0*/ // R0 459/*R1*/ // SP 460 R2 // TOC 461 R3, 462 R4, 463 R5, 464 R6, 465 R7, 466 R8, 467 R9, 468 R10, 469 R11, 470 R12, 471/*R13*/ // system thread id 472 R14, 473 R15, 474/*R16*/ // R16_thread 475 R17, 476 R18, 477 R19, 478 R20, 479 R21, 480 R22, 481 R23, 482 R24, 483 R25, 484 R26, 485 R27, 486 R28, 487/*R29,*/ 488 R30, 489 R31 490); 491 492reg_class rscratch1_bits32_reg(R11); 493reg_class rscratch2_bits32_reg(R12); 494reg_class rarg1_bits32_reg(R3); 495reg_class rarg2_bits32_reg(R4); 496reg_class rarg3_bits32_reg(R5); 497reg_class rarg4_bits32_reg(R6); 498 499// ---------------------------- 500// 64 Bit Register Classes 501// ---------------------------- 502// 64-bit build means 64-bit pointers means hi/lo pairs 503 504reg_class rscratch1_bits64_reg(R11_H, R11); 505reg_class rscratch2_bits64_reg(R12_H, R12); 506reg_class rarg1_bits64_reg(R3_H, R3); 507reg_class rarg2_bits64_reg(R4_H, R4); 508reg_class rarg3_bits64_reg(R5_H, R5); 509reg_class rarg4_bits64_reg(R6_H, R6); 510// Thread register, 'written' by tlsLoadP, see there. 511reg_class thread_bits64_reg(R16_H, R16); 512 513reg_class r19_bits64_reg(R19_H, R19); 514 515// 64 bit registers that can be read and written i.e. these registers 516// can be dest (or src) of normal instructions. 517reg_class bits64_reg_rw( 518/*R0_H, R0*/ // R0 519/*R1_H, R1*/ // SP 520 R2_H, R2, // TOC 521 R3_H, R3, 522 R4_H, R4, 523 R5_H, R5, 524 R6_H, R6, 525 R7_H, R7, 526 R8_H, R8, 527 R9_H, R9, 528 R10_H, R10, 529 R11_H, R11, 530 R12_H, R12, 531/*R13_H, R13*/ // system thread id 532 R14_H, R14, 533 R15_H, R15, 534/*R16_H, R16*/ // R16_thread 535 R17_H, R17, 536 R18_H, R18, 537 R19_H, R19, 538 R20_H, R20, 539 R21_H, R21, 540 R22_H, R22, 541 R23_H, R23, 542 R24_H, R24, 543 R25_H, R25, 544 R26_H, R26, 545 R27_H, R27, 546 R28_H, R28, 547/*R29_H, R29,*/ 548 R30_H, R30, 549 R31_H, R31 550); 551 552// 64 bit registers used excluding r2, r11 and r12 553// Used to hold the TOC to avoid collisions with expanded LeafCall which uses 554// r2, r11 and r12 internally. 555reg_class bits64_reg_leaf_call( 556/*R0_H, R0*/ // R0 557/*R1_H, R1*/ // SP 558/*R2_H, R2*/ // TOC 559 R3_H, R3, 560 R4_H, R4, 561 R5_H, R5, 562 R6_H, R6, 563 R7_H, R7, 564 R8_H, R8, 565 R9_H, R9, 566 R10_H, R10, 567/*R11_H, R11*/ 568/*R12_H, R12*/ 569/*R13_H, R13*/ // system thread id 570 R14_H, R14, 571 R15_H, R15, 572/*R16_H, R16*/ // R16_thread 573 R17_H, R17, 574 R18_H, R18, 575 R19_H, R19, 576 R20_H, R20, 577 R21_H, R21, 578 R22_H, R22, 579 R23_H, R23, 580 R24_H, R24, 581 R25_H, R25, 582 R26_H, R26, 583 R27_H, R27, 584 R28_H, R28, 585/*R29_H, R29,*/ 586 R30_H, R30, 587 R31_H, R31 588); 589 590// Used to hold the TOC to avoid collisions with expanded DynamicCall 591// which uses r19 as inline cache internally and expanded LeafCall which uses 592// r2, r11 and r12 internally. 593reg_class bits64_constant_table_base( 594/*R0_H, R0*/ // R0 595/*R1_H, R1*/ // SP 596/*R2_H, R2*/ // TOC 597 R3_H, R3, 598 R4_H, R4, 599 R5_H, R5, 600 R6_H, R6, 601 R7_H, R7, 602 R8_H, R8, 603 R9_H, R9, 604 R10_H, R10, 605/*R11_H, R11*/ 606/*R12_H, R12*/ 607/*R13_H, R13*/ // system thread id 608 R14_H, R14, 609 R15_H, R15, 610/*R16_H, R16*/ // R16_thread 611 R17_H, R17, 612 R18_H, R18, 613/*R19_H, R19*/ 614 R20_H, R20, 615 R21_H, R21, 616 R22_H, R22, 617 R23_H, R23, 618 R24_H, R24, 619 R25_H, R25, 620 R26_H, R26, 621 R27_H, R27, 622 R28_H, R28, 623/*R29_H, R29,*/ 624 R30_H, R30, 625 R31_H, R31 626); 627 628// 64 bit registers that can only be read i.e. these registers can 629// only be src of all instructions. 630reg_class bits64_reg_ro( 631/*R0_H, R0*/ // R0 632 R1_H, R1, 633 R2_H, R2, // TOC 634 R3_H, R3, 635 R4_H, R4, 636 R5_H, R5, 637 R6_H, R6, 638 R7_H, R7, 639 R8_H, R8, 640 R9_H, R9, 641 R10_H, R10, 642 R11_H, R11, 643 R12_H, R12, 644/*R13_H, R13*/ // system thread id 645 R14_H, R14, 646 R15_H, R15, 647 R16_H, R16, // R16_thread 648 R17_H, R17, 649 R18_H, R18, 650 R19_H, R19, 651 R20_H, R20, 652 R21_H, R21, 653 R22_H, R22, 654 R23_H, R23, 655 R24_H, R24, 656 R25_H, R25, 657 R26_H, R26, 658 R27_H, R27, 659 R28_H, R28, 660/*R29_H, R29,*/ // TODO: let allocator handle TOC!! 661 R30_H, R30, 662 R31_H, R31 663); 664 665 666// ---------------------------- 667// Special Class for Condition Code Flags Register 668 669reg_class int_flags( 670/*CCR0*/ // scratch 671/*CCR1*/ // scratch 672/*CCR2*/ // nv! 673/*CCR3*/ // nv! 674/*CCR4*/ // nv! 675 CCR5, 676 CCR6, 677 CCR7 678); 679 680reg_class int_flags_ro( 681 CCR0, 682 CCR1, 683 CCR2, 684 CCR3, 685 CCR4, 686 CCR5, 687 CCR6, 688 CCR7 689); 690 691reg_class int_flags_CR0(CCR0); 692reg_class int_flags_CR1(CCR1); 693reg_class int_flags_CR6(CCR6); 694reg_class ctr_reg(SR_CTR); 695 696// ---------------------------- 697// Float Register Classes 698// ---------------------------- 699 700reg_class flt_reg( 701 F0, 702 F1, 703 F2, 704 F3, 705 F4, 706 F5, 707 F6, 708 F7, 709 F8, 710 F9, 711 F10, 712 F11, 713 F12, 714 F13, 715 F14, // nv! 716 F15, // nv! 717 F16, // nv! 718 F17, // nv! 719 F18, // nv! 720 F19, // nv! 721 F20, // nv! 722 F21, // nv! 723 F22, // nv! 724 F23, // nv! 725 F24, // nv! 726 F25, // nv! 727 F26, // nv! 728 F27, // nv! 729 F28, // nv! 730 F29, // nv! 731 F30, // nv! 732 F31 // nv! 733); 734 735// Double precision float registers have virtual `high halves' that 736// are needed by the allocator. 737reg_class dbl_reg( 738 F0, F0_H, 739 F1, F1_H, 740 F2, F2_H, 741 F3, F3_H, 742 F4, F4_H, 743 F5, F5_H, 744 F6, F6_H, 745 F7, F7_H, 746 F8, F8_H, 747 F9, F9_H, 748 F10, F10_H, 749 F11, F11_H, 750 F12, F12_H, 751 F13, F13_H, 752 F14, F14_H, // nv! 753 F15, F15_H, // nv! 754 F16, F16_H, // nv! 755 F17, F17_H, // nv! 756 F18, F18_H, // nv! 757 F19, F19_H, // nv! 758 F20, F20_H, // nv! 759 F21, F21_H, // nv! 760 F22, F22_H, // nv! 761 F23, F23_H, // nv! 762 F24, F24_H, // nv! 763 F25, F25_H, // nv! 764 F26, F26_H, // nv! 765 F27, F27_H, // nv! 766 F28, F28_H, // nv! 767 F29, F29_H, // nv! 768 F30, F30_H, // nv! 769 F31, F31_H // nv! 770); 771 772 %} 773 774//----------DEFINITION BLOCK--------------------------------------------------- 775// Define name --> value mappings to inform the ADLC of an integer valued name 776// Current support includes integer values in the range [0, 0x7FFFFFFF] 777// Format: 778// int_def <name> ( <int_value>, <expression>); 779// Generated Code in ad_<arch>.hpp 780// #define <name> (<expression>) 781// // value == <int_value> 782// Generated code in ad_<arch>.cpp adlc_verification() 783// assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>"); 784// 785definitions %{ 786 // The default cost (of an ALU instruction). 787 int_def DEFAULT_COST_LOW ( 30, 30); 788 int_def DEFAULT_COST ( 100, 100); 789 int_def HUGE_COST (1000000, 1000000); 790 791 // Memory refs 792 int_def MEMORY_REF_COST_LOW ( 200, DEFAULT_COST * 2); 793 int_def MEMORY_REF_COST ( 300, DEFAULT_COST * 3); 794 795 // Branches are even more expensive. 796 int_def BRANCH_COST ( 900, DEFAULT_COST * 9); 797 int_def CALL_COST ( 1300, DEFAULT_COST * 13); 798%} 799 800 801//----------SOURCE BLOCK------------------------------------------------------- 802// This is a block of C++ code which provides values, functions, and 803// definitions necessary in the rest of the architecture description. 804source_hpp %{ 805 // Header information of the source block. 806 // Method declarations/definitions which are used outside 807 // the ad-scope can conveniently be defined here. 808 // 809 // To keep related declarations/definitions/uses close together, 810 // we switch between source %{ }% and source_hpp %{ }% freely as needed. 811 812 // Returns true if Node n is followed by a MemBar node that 813 // will do an acquire. If so, this node must not do the acquire 814 // operation. 815 bool followed_by_acquire(const Node *n); 816%} 817 818source %{ 819 820// Should the Matcher clone shifts on addressing modes, expecting them 821// to be subsumed into complex addressing expressions or compute them 822// into registers? 823bool Matcher::clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { 824 return clone_base_plus_offset_address(m, mstack, address_visited); 825} 826 827void Compile::reshape_address(AddPNode* addp) { 828} 829 830// Optimize load-acquire. 831// 832// Check if acquire is unnecessary due to following operation that does 833// acquire anyways. 834// Walk the pattern: 835// 836// n: Load.acq 837// | 838// MemBarAcquire 839// | | 840// Proj(ctrl) Proj(mem) 841// | | 842// MemBarRelease/Volatile 843// 844bool followed_by_acquire(const Node *load) { 845 assert(load->is_Load(), "So far implemented only for loads."); 846 847 // Find MemBarAcquire. 848 const Node *mba = NULL; 849 for (DUIterator_Fast imax, i = load->fast_outs(imax); i < imax; i++) { 850 const Node *out = load->fast_out(i); 851 if (out->Opcode() == Op_MemBarAcquire) { 852 if (out->in(0) == load) continue; // Skip control edge, membar should be found via precedence edge. 853 mba = out; 854 break; 855 } 856 } 857 if (!mba) return false; 858 859 // Find following MemBar node. 860 // 861 // The following node must be reachable by control AND memory 862 // edge to assure no other operations are in between the two nodes. 863 // 864 // So first get the Proj node, mem_proj, to use it to iterate forward. 865 Node *mem_proj = NULL; 866 for (DUIterator_Fast imax, i = mba->fast_outs(imax); i < imax; i++) { 867 mem_proj = mba->fast_out(i); // Throw out-of-bounds if proj not found 868 assert(mem_proj->is_Proj(), "only projections here"); 869 ProjNode *proj = mem_proj->as_Proj(); 870 if (proj->_con == TypeFunc::Memory && 871 !Compile::current()->node_arena()->contains(mem_proj)) // Unmatched old-space only 872 break; 873 } 874 assert(mem_proj->as_Proj()->_con == TypeFunc::Memory, "Graph broken"); 875 876 // Search MemBar behind Proj. If there are other memory operations 877 // behind the Proj we lost. 878 for (DUIterator_Fast jmax, j = mem_proj->fast_outs(jmax); j < jmax; j++) { 879 Node *x = mem_proj->fast_out(j); 880 // Proj might have an edge to a store or load node which precedes the membar. 881 if (x->is_Mem()) return false; 882 883 // On PPC64 release and volatile are implemented by an instruction 884 // that also has acquire semantics. I.e. there is no need for an 885 // acquire before these. 886 int xop = x->Opcode(); 887 if (xop == Op_MemBarRelease || xop == Op_MemBarVolatile) { 888 // Make sure we're not missing Call/Phi/MergeMem by checking 889 // control edges. The control edge must directly lead back 890 // to the MemBarAcquire 891 Node *ctrl_proj = x->in(0); 892 if (ctrl_proj->is_Proj() && ctrl_proj->in(0) == mba) { 893 return true; 894 } 895 } 896 } 897 898 return false; 899} 900 901#define __ _masm. 902 903// Tertiary op of a LoadP or StoreP encoding. 904#define REGP_OP true 905 906// **************************************************************************** 907 908// REQUIRED FUNCTIONALITY 909 910// !!!!! Special hack to get all type of calls to specify the byte offset 911// from the start of the call to the point where the return address 912// will point. 913 914// PPC port: Removed use of lazy constant construct. 915 916int MachCallStaticJavaNode::ret_addr_offset() { 917 // It's only a single branch-and-link instruction. 918 return 4; 919} 920 921int MachCallDynamicJavaNode::ret_addr_offset() { 922 // Offset is 4 with postalloc expanded calls (bl is one instruction). We use 923 // postalloc expanded calls if we use inline caches and do not update method data. 924 if (UseInlineCaches) 925 return 4; 926 927 int vtable_index = this->_vtable_index; 928 if (vtable_index < 0) { 929 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 930 assert(vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 931 return 12; 932 } else { 933 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 934 return 24; 935 } 936} 937 938int MachCallRuntimeNode::ret_addr_offset() { 939#if defined(ABI_ELFv2) 940 return 28; 941#else 942 return 40; 943#endif 944} 945 946//============================================================================= 947 948// condition code conversions 949 950static int cc_to_boint(int cc) { 951 return Assembler::bcondCRbiIs0 | (cc & 8); 952} 953 954static int cc_to_inverse_boint(int cc) { 955 return Assembler::bcondCRbiIs0 | (8-(cc & 8)); 956} 957 958static int cc_to_biint(int cc, int flags_reg) { 959 return (flags_reg << 2) | (cc & 3); 960} 961 962//============================================================================= 963 964// Compute padding required for nodes which need alignment. The padding 965// is the number of bytes (not instructions) which will be inserted before 966// the instruction. The padding must match the size of a NOP instruction. 967 968// Currently not used on this platform. 969 970//============================================================================= 971 972// Indicate if the safepoint node needs the polling page as an input. 973bool SafePointNode::needs_polling_address_input() { 974 // The address is loaded from thread by a seperate node. 975 return true; 976} 977 978//============================================================================= 979 980// Emit an interrupt that is caught by the debugger (for debugging compiler). 981void emit_break(CodeBuffer &cbuf) { 982 MacroAssembler _masm(&cbuf); 983 __ illtrap(); 984} 985 986#ifndef PRODUCT 987void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 988 st->print("BREAKPOINT"); 989} 990#endif 991 992void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 993 emit_break(cbuf); 994} 995 996uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 997 return MachNode::size(ra_); 998} 999 1000//============================================================================= 1001 1002void emit_nop(CodeBuffer &cbuf) { 1003 MacroAssembler _masm(&cbuf); 1004 __ nop(); 1005} 1006 1007static inline void emit_long(CodeBuffer &cbuf, int value) { 1008 *((int*)(cbuf.insts_end())) = value; 1009 cbuf.set_insts_end(cbuf.insts_end() + BytesPerInstWord); 1010} 1011 1012//============================================================================= 1013 1014%} // interrupt source 1015 1016source_hpp %{ // Header information of the source block. 1017 1018//-------------------------------------------------------------- 1019//---< Used for optimization in Compile::Shorten_branches >--- 1020//-------------------------------------------------------------- 1021 1022class CallStubImpl { 1023 1024 public: 1025 1026 // Emit call stub, compiled java to interpreter. 1027 static void emit_trampoline_stub(MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset); 1028 1029 // Size of call trampoline stub. 1030 // This doesn't need to be accurate to the byte, but it 1031 // must be larger than or equal to the real size of the stub. 1032 static uint size_call_trampoline() { 1033 return MacroAssembler::trampoline_stub_size; 1034 } 1035 1036 // number of relocations needed by a call trampoline stub 1037 static uint reloc_call_trampoline() { 1038 return 5; 1039 } 1040 1041}; 1042 1043%} // end source_hpp 1044 1045source %{ 1046 1047// Emit a trampoline stub for a call to a target which is too far away. 1048// 1049// code sequences: 1050// 1051// call-site: 1052// branch-and-link to <destination> or <trampoline stub> 1053// 1054// Related trampoline stub for this call-site in the stub section: 1055// load the call target from the constant pool 1056// branch via CTR (LR/link still points to the call-site above) 1057 1058void CallStubImpl::emit_trampoline_stub(MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset) { 1059 address stub = __ emit_trampoline_stub(destination_toc_offset, insts_call_instruction_offset); 1060 if (stub == NULL) { 1061 ciEnv::current()->record_out_of_memory_failure(); 1062 } 1063} 1064 1065//============================================================================= 1066 1067// Emit an inline branch-and-link call and a related trampoline stub. 1068// 1069// code sequences: 1070// 1071// call-site: 1072// branch-and-link to <destination> or <trampoline stub> 1073// 1074// Related trampoline stub for this call-site in the stub section: 1075// load the call target from the constant pool 1076// branch via CTR (LR/link still points to the call-site above) 1077// 1078 1079typedef struct { 1080 int insts_call_instruction_offset; 1081 int ret_addr_offset; 1082} EmitCallOffsets; 1083 1084// Emit a branch-and-link instruction that branches to a trampoline. 1085// - Remember the offset of the branch-and-link instruction. 1086// - Add a relocation at the branch-and-link instruction. 1087// - Emit a branch-and-link. 1088// - Remember the return pc offset. 1089EmitCallOffsets emit_call_with_trampoline_stub(MacroAssembler &_masm, address entry_point, relocInfo::relocType rtype) { 1090 EmitCallOffsets offsets = { -1, -1 }; 1091 const int start_offset = __ offset(); 1092 offsets.insts_call_instruction_offset = __ offset(); 1093 1094 // No entry point given, use the current pc. 1095 if (entry_point == NULL) entry_point = __ pc(); 1096 1097 // Put the entry point as a constant into the constant pool. 1098 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 1099 if (entry_point_toc_addr == NULL) { 1100 ciEnv::current()->record_out_of_memory_failure(); 1101 return offsets; 1102 } 1103 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 1104 1105 // Emit the trampoline stub which will be related to the branch-and-link below. 1106 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, offsets.insts_call_instruction_offset); 1107 if (ciEnv::current()->failing()) { return offsets; } // Code cache may be full. 1108 __ relocate(rtype); 1109 1110 // Note: At this point we do not have the address of the trampoline 1111 // stub, and the entry point might be too far away for bl, so __ pc() 1112 // serves as dummy and the bl will be patched later. 1113 __ bl((address) __ pc()); 1114 1115 offsets.ret_addr_offset = __ offset() - start_offset; 1116 1117 return offsets; 1118} 1119 1120//============================================================================= 1121 1122// Factory for creating loadConL* nodes for large/small constant pool. 1123 1124static inline jlong replicate_immF(float con) { 1125 // Replicate float con 2 times and pack into vector. 1126 int val = *((int*)&con); 1127 jlong lval = val; 1128 lval = (lval << 32) | (lval & 0xFFFFFFFFl); 1129 return lval; 1130} 1131 1132//============================================================================= 1133 1134const RegMask& MachConstantBaseNode::_out_RegMask = BITS64_CONSTANT_TABLE_BASE_mask(); 1135int Compile::ConstantTable::calculate_table_base_offset() const { 1136 return 0; // absolute addressing, no offset 1137} 1138 1139bool MachConstantBaseNode::requires_postalloc_expand() const { return true; } 1140void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 1141 iRegPdstOper *op_dst = new iRegPdstOper(); 1142 MachNode *m1 = new loadToc_hiNode(); 1143 MachNode *m2 = new loadToc_loNode(); 1144 1145 m1->add_req(NULL); 1146 m2->add_req(NULL, m1); 1147 m1->_opnds[0] = op_dst; 1148 m2->_opnds[0] = op_dst; 1149 m2->_opnds[1] = op_dst; 1150 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 1151 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 1152 nodes->push(m1); 1153 nodes->push(m2); 1154} 1155 1156void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1157 // Is postalloc expanded. 1158 ShouldNotReachHere(); 1159} 1160 1161uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 1162 return 0; 1163} 1164 1165#ifndef PRODUCT 1166void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1167 st->print("-- \t// MachConstantBaseNode (empty encoding)"); 1168} 1169#endif 1170 1171//============================================================================= 1172 1173#ifndef PRODUCT 1174void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1175 Compile* C = ra_->C; 1176 const long framesize = C->frame_slots() << LogBytesPerInt; 1177 1178 st->print("PROLOG\n\t"); 1179 if (C->need_stack_bang(framesize)) { 1180 st->print("stack_overflow_check\n\t"); 1181 } 1182 1183 if (!false /* TODO: PPC port C->is_frameless_method()*/) { 1184 st->print("save return pc\n\t"); 1185 st->print("push frame %ld\n\t", -framesize); 1186 } 1187} 1188#endif 1189 1190// Macro used instead of the common __ to emulate the pipes of PPC. 1191// Instead of e.g. __ ld(...) one hase to write ___(ld) ld(...) This enables the 1192// micro scheduler to cope with "hand written" assembler like in the prolog. Though 1193// still no scheduling of this code is possible, the micro scheduler is aware of the 1194// code and can update its internal data. The following mechanism is used to achieve this: 1195// The micro scheduler calls size() of each compound node during scheduling. size() does a 1196// dummy emit and only during this dummy emit C->hb_scheduling() is not NULL. 1197#if 0 // TODO: PPC port 1198#define ___(op) if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1199 C->hb_scheduling()->_pdScheduling->PdEmulatePipe(ppc64Opcode_##op); \ 1200 _masm. 1201#define ___stop if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1202 C->hb_scheduling()->_pdScheduling->PdEmulatePipe(archOpcode_none) 1203#define ___advance if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1204 C->hb_scheduling()->_pdScheduling->advance_offset 1205#else 1206#define ___(op) if (UsePower6SchedulerPPC64) \ 1207 Unimplemented(); \ 1208 _masm. 1209#define ___stop if (UsePower6SchedulerPPC64) \ 1210 Unimplemented() 1211#define ___advance if (UsePower6SchedulerPPC64) \ 1212 Unimplemented() 1213#endif 1214 1215void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1216 Compile* C = ra_->C; 1217 MacroAssembler _masm(&cbuf); 1218 1219 const long framesize = C->frame_size_in_bytes(); 1220 assert(framesize % (2 * wordSize) == 0, "must preserve 2*wordSize alignment"); 1221 1222 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; 1223 1224 const Register return_pc = R20; // Must match return_addr() in frame section. 1225 const Register callers_sp = R21; 1226 const Register push_frame_temp = R22; 1227 const Register toc_temp = R23; 1228 assert_different_registers(R11, return_pc, callers_sp, push_frame_temp, toc_temp); 1229 1230 if (method_is_frameless) { 1231 // Add nop at beginning of all frameless methods to prevent any 1232 // oop instructions from getting overwritten by make_not_entrant 1233 // (patching attempt would fail). 1234 ___(nop) nop(); 1235 } else { 1236 // Get return pc. 1237 ___(mflr) mflr(return_pc); 1238 } 1239 1240 // Calls to C2R adapters often do not accept exceptional returns. 1241 // We require that their callers must bang for them. But be 1242 // careful, because some VM calls (such as call site linkage) can 1243 // use several kilobytes of stack. But the stack safety zone should 1244 // account for that. See bugs 4446381, 4468289, 4497237. 1245 1246 int bangsize = C->bang_size_in_bytes(); 1247 assert(bangsize >= framesize || bangsize <= 0, "stack bang size incorrect"); 1248 if (C->need_stack_bang(bangsize) && UseStackBanging) { 1249 // Unfortunately we cannot use the function provided in 1250 // assembler.cpp as we have to emulate the pipes. So I had to 1251 // insert the code of generate_stack_overflow_check(), see 1252 // assembler.cpp for some illuminative comments. 1253 const int page_size = os::vm_page_size(); 1254 int bang_end = JavaThread::stack_shadow_zone_size(); 1255 1256 // This is how far the previous frame's stack banging extended. 1257 const int bang_end_safe = bang_end; 1258 1259 if (bangsize > page_size) { 1260 bang_end += bangsize; 1261 } 1262 1263 int bang_offset = bang_end_safe; 1264 1265 while (bang_offset <= bang_end) { 1266 // Need at least one stack bang at end of shadow zone. 1267 1268 // Again I had to copy code, this time from assembler_ppc.cpp, 1269 // bang_stack_with_offset - see there for comments. 1270 1271 // Stack grows down, caller passes positive offset. 1272 assert(bang_offset > 0, "must bang with positive offset"); 1273 1274 long stdoffset = -bang_offset; 1275 1276 if (Assembler::is_simm(stdoffset, 16)) { 1277 // Signed 16 bit offset, a simple std is ok. 1278 if (UseLoadInstructionsForStackBangingPPC64) { 1279 ___(ld) ld(R0, (int)(signed short)stdoffset, R1_SP); 1280 } else { 1281 ___(std) std(R0, (int)(signed short)stdoffset, R1_SP); 1282 } 1283 } else if (Assembler::is_simm(stdoffset, 31)) { 1284 // Use largeoffset calculations for addis & ld/std. 1285 const int hi = MacroAssembler::largeoffset_si16_si16_hi(stdoffset); 1286 const int lo = MacroAssembler::largeoffset_si16_si16_lo(stdoffset); 1287 1288 Register tmp = R11; 1289 ___(addis) addis(tmp, R1_SP, hi); 1290 if (UseLoadInstructionsForStackBangingPPC64) { 1291 ___(ld) ld(R0, lo, tmp); 1292 } else { 1293 ___(std) std(R0, lo, tmp); 1294 } 1295 } else { 1296 ShouldNotReachHere(); 1297 } 1298 1299 bang_offset += page_size; 1300 } 1301 // R11 trashed 1302 } // C->need_stack_bang(framesize) && UseStackBanging 1303 1304 unsigned int bytes = (unsigned int)framesize; 1305 long offset = Assembler::align_addr(bytes, frame::alignment_in_bytes); 1306 ciMethod *currMethod = C->method(); 1307 1308 // Optimized version for most common case. 1309 if (UsePower6SchedulerPPC64 && 1310 !method_is_frameless && Assembler::is_simm((int)(-offset), 16) && 1311 !(false /* ConstantsALot TODO: PPC port*/)) { 1312 ___(or) mr(callers_sp, R1_SP); 1313 ___(std) std(return_pc, _abi(lr), R1_SP); 1314 ___(stdu) stdu(R1_SP, -offset, R1_SP); 1315 return; 1316 } 1317 1318 if (!method_is_frameless) { 1319 // Get callers sp. 1320 ___(or) mr(callers_sp, R1_SP); 1321 1322 // Push method's frame, modifies SP. 1323 assert(Assembler::is_uimm(framesize, 32U), "wrong type"); 1324 // The ABI is already accounted for in 'framesize' via the 1325 // 'out_preserve' area. 1326 Register tmp = push_frame_temp; 1327 // Had to insert code of push_frame((unsigned int)framesize, push_frame_temp). 1328 if (Assembler::is_simm(-offset, 16)) { 1329 ___(stdu) stdu(R1_SP, -offset, R1_SP); 1330 } else { 1331 long x = -offset; 1332 // Had to insert load_const(tmp, -offset). 1333 ___(addis) lis( tmp, (int)((signed short)(((x >> 32) & 0xffff0000) >> 16))); 1334 ___(ori) ori( tmp, tmp, ((x >> 32) & 0x0000ffff)); 1335 ___(rldicr) sldi(tmp, tmp, 32); 1336 ___(oris) oris(tmp, tmp, (x & 0xffff0000) >> 16); 1337 ___(ori) ori( tmp, tmp, (x & 0x0000ffff)); 1338 1339 ___(stdux) stdux(R1_SP, R1_SP, tmp); 1340 } 1341 } 1342#if 0 // TODO: PPC port 1343 // For testing large constant pools, emit a lot of constants to constant pool. 1344 // "Randomize" const_size. 1345 if (ConstantsALot) { 1346 const int num_consts = const_size(); 1347 for (int i = 0; i < num_consts; i++) { 1348 __ long_constant(0xB0B5B00BBABE); 1349 } 1350 } 1351#endif 1352 if (!method_is_frameless) { 1353 // Save return pc. 1354 ___(std) std(return_pc, _abi(lr), callers_sp); 1355 } 1356 1357 C->set_frame_complete(cbuf.insts_size()); 1358} 1359#undef ___ 1360#undef ___stop 1361#undef ___advance 1362 1363uint MachPrologNode::size(PhaseRegAlloc *ra_) const { 1364 // Variable size. determine dynamically. 1365 return MachNode::size(ra_); 1366} 1367 1368int MachPrologNode::reloc() const { 1369 // Return number of relocatable values contained in this instruction. 1370 return 1; // 1 reloc entry for load_const(toc). 1371} 1372 1373//============================================================================= 1374 1375#ifndef PRODUCT 1376void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1377 Compile* C = ra_->C; 1378 1379 st->print("EPILOG\n\t"); 1380 st->print("restore return pc\n\t"); 1381 st->print("pop frame\n\t"); 1382 1383 if (do_polling() && C->is_method_compilation()) { 1384 st->print("touch polling page\n\t"); 1385 } 1386} 1387#endif 1388 1389void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1390 Compile* C = ra_->C; 1391 MacroAssembler _masm(&cbuf); 1392 1393 const long framesize = ((long)C->frame_slots()) << LogBytesPerInt; 1394 assert(framesize >= 0, "negative frame-size?"); 1395 1396 const bool method_needs_polling = do_polling() && C->is_method_compilation(); 1397 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; 1398 const Register return_pc = R31; // Must survive C-call to enable_stack_reserved_zone(). 1399 const Register polling_page = R12; 1400 1401 if (!method_is_frameless) { 1402 // Restore return pc relative to callers' sp. 1403 __ ld(return_pc, ((int)framesize) + _abi(lr), R1_SP); 1404 } 1405 1406 if (method_needs_polling) { 1407 if (LoadPollAddressFromThread) { 1408 // TODO: PPC port __ ld(polling_page, in_bytes(JavaThread::poll_address_offset()), R16_thread); 1409 Unimplemented(); 1410 } else { 1411 __ load_const_optimized(polling_page, (long)(address) os::get_polling_page()); // TODO: PPC port: get_standard_polling_page() 1412 } 1413 } 1414 1415 if (!method_is_frameless) { 1416 // Move return pc to LR. 1417 __ mtlr(return_pc); 1418 // Pop frame (fixed frame-size). 1419 __ addi(R1_SP, R1_SP, (int)framesize); 1420 } 1421 1422 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1423 __ reserved_stack_check(return_pc); 1424 } 1425 1426 if (method_needs_polling) { 1427 // We need to mark the code position where the load from the safepoint 1428 // polling page was emitted as relocInfo::poll_return_type here. 1429 __ relocate(relocInfo::poll_return_type); 1430 __ load_from_polling_page(polling_page); 1431 } 1432} 1433 1434uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 1435 // Variable size. Determine dynamically. 1436 return MachNode::size(ra_); 1437} 1438 1439int MachEpilogNode::reloc() const { 1440 // Return number of relocatable values contained in this instruction. 1441 return 1; // 1 for load_from_polling_page. 1442} 1443 1444const Pipeline * MachEpilogNode::pipeline() const { 1445 return MachNode::pipeline_class(); 1446} 1447 1448// This method seems to be obsolete. It is declared in machnode.hpp 1449// and defined in all *.ad files, but it is never called. Should we 1450// get rid of it? 1451int MachEpilogNode::safepoint_offset() const { 1452 assert(do_polling(), "no return for this epilog node"); 1453 return 0; 1454} 1455 1456#if 0 // TODO: PPC port 1457void MachLoadPollAddrLateNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1458 MacroAssembler _masm(&cbuf); 1459 if (LoadPollAddressFromThread) { 1460 _masm.ld(R11, in_bytes(JavaThread::poll_address_offset()), R16_thread); 1461 } else { 1462 _masm.nop(); 1463 } 1464} 1465 1466uint MachLoadPollAddrLateNode::size(PhaseRegAlloc* ra_) const { 1467 if (LoadPollAddressFromThread) { 1468 return 4; 1469 } else { 1470 return 4; 1471 } 1472} 1473 1474#ifndef PRODUCT 1475void MachLoadPollAddrLateNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1476 st->print_cr(" LD R11, PollAddressOffset, R16_thread \t// LoadPollAddressFromThread"); 1477} 1478#endif 1479 1480const RegMask &MachLoadPollAddrLateNode::out_RegMask() const { 1481 return RSCRATCH1_BITS64_REG_mask(); 1482} 1483#endif // PPC port 1484 1485// ============================================================================= 1486 1487// Figure out which register class each belongs in: rc_int, rc_float or 1488// rc_stack. 1489enum RC { rc_bad, rc_int, rc_float, rc_stack }; 1490 1491static enum RC rc_class(OptoReg::Name reg) { 1492 // Return the register class for the given register. The given register 1493 // reg is a <register>_num value, which is an index into the MachRegisterNumbers 1494 // enumeration in adGlobals_ppc.hpp. 1495 1496 if (reg == OptoReg::Bad) return rc_bad; 1497 1498 // We have 64 integer register halves, starting at index 0. 1499 if (reg < 64) return rc_int; 1500 1501 // We have 64 floating-point register halves, starting at index 64. 1502 if (reg < 64+64) return rc_float; 1503 1504 // Between float regs & stack are the flags regs. 1505 assert(OptoReg::is_stack(reg), "blow up if spilling flags"); 1506 1507 return rc_stack; 1508} 1509 1510static int ld_st_helper(CodeBuffer *cbuf, const char *op_str, uint opcode, int reg, int offset, 1511 bool do_print, Compile* C, outputStream *st) { 1512 1513 assert(opcode == Assembler::LD_OPCODE || 1514 opcode == Assembler::STD_OPCODE || 1515 opcode == Assembler::LWZ_OPCODE || 1516 opcode == Assembler::STW_OPCODE || 1517 opcode == Assembler::LFD_OPCODE || 1518 opcode == Assembler::STFD_OPCODE || 1519 opcode == Assembler::LFS_OPCODE || 1520 opcode == Assembler::STFS_OPCODE, 1521 "opcode not supported"); 1522 1523 if (cbuf) { 1524 int d = 1525 (Assembler::LD_OPCODE == opcode || Assembler::STD_OPCODE == opcode) ? 1526 Assembler::ds(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/) 1527 : Assembler::d1(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); // Makes no difference in opt build. 1528 emit_long(*cbuf, opcode | Assembler::rt(Matcher::_regEncode[reg]) | d | Assembler::ra(R1_SP)); 1529 } 1530#ifndef PRODUCT 1531 else if (do_print) { 1532 st->print("%-7s %s, [R1_SP + #%d+%d] \t// spill copy", 1533 op_str, 1534 Matcher::regName[reg], 1535 offset, 0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); 1536 } 1537#endif 1538 return 4; // size 1539} 1540 1541uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 1542 Compile* C = ra_->C; 1543 1544 // Get registers to move. 1545 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 1546 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 1547 OptoReg::Name dst_hi = ra_->get_reg_second(this); 1548 OptoReg::Name dst_lo = ra_->get_reg_first(this); 1549 1550 enum RC src_hi_rc = rc_class(src_hi); 1551 enum RC src_lo_rc = rc_class(src_lo); 1552 enum RC dst_hi_rc = rc_class(dst_hi); 1553 enum RC dst_lo_rc = rc_class(dst_lo); 1554 1555 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 1556 if (src_hi != OptoReg::Bad) 1557 assert((src_lo&1)==0 && src_lo+1==src_hi && 1558 (dst_lo&1)==0 && dst_lo+1==dst_hi, 1559 "expected aligned-adjacent pairs"); 1560 // Generate spill code! 1561 int size = 0; 1562 1563 if (src_lo == dst_lo && src_hi == dst_hi) 1564 return size; // Self copy, no move. 1565 1566 // -------------------------------------- 1567 // Memory->Memory Spill. Use R0 to hold the value. 1568 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1569 int src_offset = ra_->reg2offset(src_lo); 1570 int dst_offset = ra_->reg2offset(dst_lo); 1571 if (src_hi != OptoReg::Bad) { 1572 assert(src_hi_rc==rc_stack && dst_hi_rc==rc_stack, 1573 "expected same type of move for high parts"); 1574 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, R0_num, src_offset, !do_size, C, st); 1575 if (!cbuf && !do_size) st->print("\n\t"); 1576 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, R0_num, dst_offset, !do_size, C, st); 1577 } else { 1578 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, R0_num, src_offset, !do_size, C, st); 1579 if (!cbuf && !do_size) st->print("\n\t"); 1580 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, R0_num, dst_offset, !do_size, C, st); 1581 } 1582 return size; 1583 } 1584 1585 // -------------------------------------- 1586 // Check for float->int copy; requires a trip through memory. 1587 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) { 1588 Unimplemented(); 1589 } 1590 1591 // -------------------------------------- 1592 // Check for integer reg-reg copy. 1593 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) { 1594 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]); 1595 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]); 1596 size = (Rsrc != Rdst) ? 4 : 0; 1597 1598 if (cbuf) { 1599 MacroAssembler _masm(cbuf); 1600 if (size) { 1601 __ mr(Rdst, Rsrc); 1602 } 1603 } 1604#ifndef PRODUCT 1605 else if (!do_size) { 1606 if (size) { 1607 st->print("%-7s %s, %s \t// spill copy", "MR", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1608 } else { 1609 st->print("%-7s %s, %s \t// spill copy", "MR-NOP", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1610 } 1611 } 1612#endif 1613 return size; 1614 } 1615 1616 // Check for integer store. 1617 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) { 1618 int dst_offset = ra_->reg2offset(dst_lo); 1619 if (src_hi != OptoReg::Bad) { 1620 assert(src_hi_rc==rc_int && dst_hi_rc==rc_stack, 1621 "expected same type of move for high parts"); 1622 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, src_lo, dst_offset, !do_size, C, st); 1623 } else { 1624 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, src_lo, dst_offset, !do_size, C, st); 1625 } 1626 return size; 1627 } 1628 1629 // Check for integer load. 1630 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) { 1631 int src_offset = ra_->reg2offset(src_lo); 1632 if (src_hi != OptoReg::Bad) { 1633 assert(dst_hi_rc==rc_int && src_hi_rc==rc_stack, 1634 "expected same type of move for high parts"); 1635 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, dst_lo, src_offset, !do_size, C, st); 1636 } else { 1637 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, dst_lo, src_offset, !do_size, C, st); 1638 } 1639 return size; 1640 } 1641 1642 // Check for float reg-reg copy. 1643 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1644 if (cbuf) { 1645 MacroAssembler _masm(cbuf); 1646 FloatRegister Rsrc = as_FloatRegister(Matcher::_regEncode[src_lo]); 1647 FloatRegister Rdst = as_FloatRegister(Matcher::_regEncode[dst_lo]); 1648 __ fmr(Rdst, Rsrc); 1649 } 1650#ifndef PRODUCT 1651 else if (!do_size) { 1652 st->print("%-7s %s, %s \t// spill copy", "FMR", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1653 } 1654#endif 1655 return 4; 1656 } 1657 1658 // Check for float store. 1659 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1660 int dst_offset = ra_->reg2offset(dst_lo); 1661 if (src_hi != OptoReg::Bad) { 1662 assert(src_hi_rc==rc_float && dst_hi_rc==rc_stack, 1663 "expected same type of move for high parts"); 1664 size += ld_st_helper(cbuf, "STFD", Assembler::STFD_OPCODE, src_lo, dst_offset, !do_size, C, st); 1665 } else { 1666 size += ld_st_helper(cbuf, "STFS", Assembler::STFS_OPCODE, src_lo, dst_offset, !do_size, C, st); 1667 } 1668 return size; 1669 } 1670 1671 // Check for float load. 1672 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) { 1673 int src_offset = ra_->reg2offset(src_lo); 1674 if (src_hi != OptoReg::Bad) { 1675 assert(dst_hi_rc==rc_float && src_hi_rc==rc_stack, 1676 "expected same type of move for high parts"); 1677 size += ld_st_helper(cbuf, "LFD ", Assembler::LFD_OPCODE, dst_lo, src_offset, !do_size, C, st); 1678 } else { 1679 size += ld_st_helper(cbuf, "LFS ", Assembler::LFS_OPCODE, dst_lo, src_offset, !do_size, C, st); 1680 } 1681 return size; 1682 } 1683 1684 // -------------------------------------------------------------------- 1685 // Check for hi bits still needing moving. Only happens for misaligned 1686 // arguments to native calls. 1687 if (src_hi == dst_hi) 1688 return size; // Self copy; no move. 1689 1690 assert(src_hi_rc != rc_bad && dst_hi_rc != rc_bad, "src_hi & dst_hi cannot be Bad"); 1691 ShouldNotReachHere(); // Unimplemented 1692 return 0; 1693} 1694 1695#ifndef PRODUCT 1696void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1697 if (!ra_) 1698 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 1699 else 1700 implementation(NULL, ra_, false, st); 1701} 1702#endif 1703 1704void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1705 implementation(&cbuf, ra_, false, NULL); 1706} 1707 1708uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1709 return implementation(NULL, ra_, true, NULL); 1710} 1711 1712#if 0 // TODO: PPC port 1713ArchOpcode MachSpillCopyNode_archOpcode(MachSpillCopyNode *n, PhaseRegAlloc *ra_) { 1714#ifndef PRODUCT 1715 if (ra_->node_regs_max_index() == 0) return archOpcode_undefined; 1716#endif 1717 assert(ra_->node_regs_max_index() != 0, ""); 1718 1719 // Get registers to move. 1720 OptoReg::Name src_hi = ra_->get_reg_second(n->in(1)); 1721 OptoReg::Name src_lo = ra_->get_reg_first(n->in(1)); 1722 OptoReg::Name dst_hi = ra_->get_reg_second(n); 1723 OptoReg::Name dst_lo = ra_->get_reg_first(n); 1724 1725 enum RC src_lo_rc = rc_class(src_lo); 1726 enum RC dst_lo_rc = rc_class(dst_lo); 1727 1728 if (src_lo == dst_lo && src_hi == dst_hi) 1729 return ppc64Opcode_none; // Self copy, no move. 1730 1731 // -------------------------------------- 1732 // Memory->Memory Spill. Use R0 to hold the value. 1733 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1734 return ppc64Opcode_compound; 1735 } 1736 1737 // -------------------------------------- 1738 // Check for float->int copy; requires a trip through memory. 1739 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) { 1740 Unimplemented(); 1741 } 1742 1743 // -------------------------------------- 1744 // Check for integer reg-reg copy. 1745 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) { 1746 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]); 1747 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]); 1748 if (Rsrc == Rdst) { 1749 return ppc64Opcode_none; 1750 } else { 1751 return ppc64Opcode_or; 1752 } 1753 } 1754 1755 // Check for integer store. 1756 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) { 1757 if (src_hi != OptoReg::Bad) { 1758 return ppc64Opcode_std; 1759 } else { 1760 return ppc64Opcode_stw; 1761 } 1762 } 1763 1764 // Check for integer load. 1765 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) { 1766 if (src_hi != OptoReg::Bad) { 1767 return ppc64Opcode_ld; 1768 } else { 1769 return ppc64Opcode_lwz; 1770 } 1771 } 1772 1773 // Check for float reg-reg copy. 1774 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1775 return ppc64Opcode_fmr; 1776 } 1777 1778 // Check for float store. 1779 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1780 if (src_hi != OptoReg::Bad) { 1781 return ppc64Opcode_stfd; 1782 } else { 1783 return ppc64Opcode_stfs; 1784 } 1785 } 1786 1787 // Check for float load. 1788 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) { 1789 if (src_hi != OptoReg::Bad) { 1790 return ppc64Opcode_lfd; 1791 } else { 1792 return ppc64Opcode_lfs; 1793 } 1794 } 1795 1796 // -------------------------------------------------------------------- 1797 // Check for hi bits still needing moving. Only happens for misaligned 1798 // arguments to native calls. 1799 if (src_hi == dst_hi) { 1800 return ppc64Opcode_none; // Self copy; no move. 1801 } 1802 1803 ShouldNotReachHere(); 1804 return ppc64Opcode_undefined; 1805} 1806#endif // PPC port 1807 1808#ifndef PRODUCT 1809void MachNopNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1810 st->print("NOP \t// %d nops to pad for loops.", _count); 1811} 1812#endif 1813 1814void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *) const { 1815 MacroAssembler _masm(&cbuf); 1816 // _count contains the number of nops needed for padding. 1817 for (int i = 0; i < _count; i++) { 1818 __ nop(); 1819 } 1820} 1821 1822uint MachNopNode::size(PhaseRegAlloc *ra_) const { 1823 return _count * 4; 1824} 1825 1826#ifndef PRODUCT 1827void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1828 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1829 char reg_str[128]; 1830 ra_->dump_register(this, reg_str); 1831 st->print("ADDI %s, SP, %d \t// box node", reg_str, offset); 1832} 1833#endif 1834 1835void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1836 MacroAssembler _masm(&cbuf); 1837 1838 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1839 int reg = ra_->get_encode(this); 1840 1841 if (Assembler::is_simm(offset, 16)) { 1842 __ addi(as_Register(reg), R1, offset); 1843 } else { 1844 ShouldNotReachHere(); 1845 } 1846} 1847 1848uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 1849 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 1850 return 4; 1851} 1852 1853#ifndef PRODUCT 1854void MachUEPNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1855 st->print_cr("---- MachUEPNode ----"); 1856 st->print_cr("..."); 1857} 1858#endif 1859 1860void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1861 // This is the unverified entry point. 1862 MacroAssembler _masm(&cbuf); 1863 1864 // Inline_cache contains a klass. 1865 Register ic_klass = as_Register(Matcher::inline_cache_reg_encode()); 1866 Register receiver_klass = R12_scratch2; // tmp 1867 1868 assert_different_registers(ic_klass, receiver_klass, R11_scratch1, R3_ARG1); 1869 assert(R11_scratch1 == R11, "need prologue scratch register"); 1870 1871 // Check for NULL argument if we don't have implicit null checks. 1872 if (!ImplicitNullChecks || !os::zero_page_read_protected()) { 1873 if (TrapBasedNullChecks) { 1874 __ trap_null_check(R3_ARG1); 1875 } else { 1876 Label valid; 1877 __ cmpdi(CCR0, R3_ARG1, 0); 1878 __ bne_predict_taken(CCR0, valid); 1879 // We have a null argument, branch to ic_miss_stub. 1880 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), 1881 relocInfo::runtime_call_type); 1882 __ bind(valid); 1883 } 1884 } 1885 // Assume argument is not NULL, load klass from receiver. 1886 __ load_klass(receiver_klass, R3_ARG1); 1887 1888 if (TrapBasedICMissChecks) { 1889 __ trap_ic_miss_check(receiver_klass, ic_klass); 1890 } else { 1891 Label valid; 1892 __ cmpd(CCR0, receiver_klass, ic_klass); 1893 __ beq_predict_taken(CCR0, valid); 1894 // We have an unexpected klass, branch to ic_miss_stub. 1895 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), 1896 relocInfo::runtime_call_type); 1897 __ bind(valid); 1898 } 1899 1900 // Argument is valid and klass is as expected, continue. 1901} 1902 1903#if 0 // TODO: PPC port 1904// Optimize UEP code on z (save a load_const() call in main path). 1905int MachUEPNode::ep_offset() { 1906 return 0; 1907} 1908#endif 1909 1910uint MachUEPNode::size(PhaseRegAlloc *ra_) const { 1911 // Variable size. Determine dynamically. 1912 return MachNode::size(ra_); 1913} 1914 1915//============================================================================= 1916 1917%} // interrupt source 1918 1919source_hpp %{ // Header information of the source block. 1920 1921class HandlerImpl { 1922 1923 public: 1924 1925 static int emit_exception_handler(CodeBuffer &cbuf); 1926 static int emit_deopt_handler(CodeBuffer& cbuf); 1927 1928 static uint size_exception_handler() { 1929 // The exception_handler is a b64_patchable. 1930 return MacroAssembler::b64_patchable_size; 1931 } 1932 1933 static uint size_deopt_handler() { 1934 // The deopt_handler is a bl64_patchable. 1935 return MacroAssembler::bl64_patchable_size; 1936 } 1937 1938}; 1939 1940%} // end source_hpp 1941 1942source %{ 1943 1944int HandlerImpl::emit_exception_handler(CodeBuffer &cbuf) { 1945 MacroAssembler _masm(&cbuf); 1946 1947 address base = __ start_a_stub(size_exception_handler()); 1948 if (base == NULL) return 0; // CodeBuffer::expand failed 1949 1950 int offset = __ offset(); 1951 __ b64_patchable((address)OptoRuntime::exception_blob()->content_begin(), 1952 relocInfo::runtime_call_type); 1953 assert(__ offset() - offset == (int)size_exception_handler(), "must be fixed size"); 1954 __ end_a_stub(); 1955 1956 return offset; 1957} 1958 1959// The deopt_handler is like the exception handler, but it calls to 1960// the deoptimization blob instead of jumping to the exception blob. 1961int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) { 1962 MacroAssembler _masm(&cbuf); 1963 1964 address base = __ start_a_stub(size_deopt_handler()); 1965 if (base == NULL) return 0; // CodeBuffer::expand failed 1966 1967 int offset = __ offset(); 1968 __ bl64_patchable((address)SharedRuntime::deopt_blob()->unpack(), 1969 relocInfo::runtime_call_type); 1970 assert(__ offset() - offset == (int) size_deopt_handler(), "must be fixed size"); 1971 __ end_a_stub(); 1972 1973 return offset; 1974} 1975 1976//============================================================================= 1977 1978// Use a frame slots bias for frameless methods if accessing the stack. 1979static int frame_slots_bias(int reg_enc, PhaseRegAlloc* ra_) { 1980 if (as_Register(reg_enc) == R1_SP) { 1981 return 0; // TODO: PPC port ra_->C->frame_slots_sp_bias_in_bytes(); 1982 } 1983 return 0; 1984} 1985 1986const bool Matcher::match_rule_supported(int opcode) { 1987 if (!has_match_rule(opcode)) 1988 return false; 1989 1990 switch (opcode) { 1991 case Op_SqrtD: 1992 return VM_Version::has_fsqrt(); 1993 case Op_CountLeadingZerosI: 1994 case Op_CountLeadingZerosL: 1995 case Op_CountTrailingZerosI: 1996 case Op_CountTrailingZerosL: 1997 if (!UseCountLeadingZerosInstructionsPPC64) 1998 return false; 1999 break; 2000 2001 case Op_PopCountI: 2002 case Op_PopCountL: 2003 return (UsePopCountInstruction && VM_Version::has_popcntw()); 2004 2005 case Op_StrComp: 2006 return SpecialStringCompareTo; 2007 case Op_StrEquals: 2008 return SpecialStringEquals; 2009 case Op_StrIndexOf: 2010 return SpecialStringIndexOf; 2011 case Op_StrIndexOfChar: 2012 return SpecialStringIndexOf; 2013 } 2014 2015 return true; // Per default match rules are supported. 2016} 2017 2018const bool Matcher::match_rule_supported_vector(int opcode, int vlen) { 2019 2020 // TODO 2021 // identify extra cases that we might want to provide match rules for 2022 // e.g. Op_ vector nodes and other intrinsics while guarding with vlen 2023 bool ret_value = match_rule_supported(opcode); 2024 // Add rules here. 2025 2026 return ret_value; // Per default match rules are supported. 2027} 2028 2029const bool Matcher::has_predicated_vectors(void) { 2030 return false; 2031} 2032 2033const int Matcher::float_pressure(int default_pressure_threshold) { 2034 return default_pressure_threshold; 2035} 2036 2037int Matcher::regnum_to_fpu_offset(int regnum) { 2038 // No user for this method? 2039 Unimplemented(); 2040 return 999; 2041} 2042 2043const bool Matcher::convL2FSupported(void) { 2044 // fcfids can do the conversion (>= Power7). 2045 // fcfid + frsp showed rounding problem when result should be 0x3f800001. 2046 return VM_Version::has_fcfids(); // False means that conversion is done by runtime call. 2047} 2048 2049// Vector width in bytes. 2050const int Matcher::vector_width_in_bytes(BasicType bt) { 2051 assert(MaxVectorSize == 8, ""); 2052 return 8; 2053} 2054 2055// Vector ideal reg. 2056const int Matcher::vector_ideal_reg(int size) { 2057 assert(MaxVectorSize == 8 && size == 8, ""); 2058 return Op_RegL; 2059} 2060 2061const int Matcher::vector_shift_count_ideal_reg(int size) { 2062 fatal("vector shift is not supported"); 2063 return Node::NotAMachineReg; 2064} 2065 2066// Limits on vector size (number of elements) loaded into vector. 2067const int Matcher::max_vector_size(const BasicType bt) { 2068 assert(is_java_primitive(bt), "only primitive type vectors"); 2069 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2070} 2071 2072const int Matcher::min_vector_size(const BasicType bt) { 2073 return max_vector_size(bt); // Same as max. 2074} 2075 2076// PPC doesn't support misaligned vectors store/load. 2077const bool Matcher::misaligned_vectors_ok() { 2078 return false; 2079} 2080 2081// PPC AES support not yet implemented 2082const bool Matcher::pass_original_key_for_aes() { 2083 return false; 2084} 2085 2086// RETURNS: whether this branch offset is short enough that a short 2087// branch can be used. 2088// 2089// If the platform does not provide any short branch variants, then 2090// this method should return `false' for offset 0. 2091// 2092// `Compile::Fill_buffer' will decide on basis of this information 2093// whether to do the pass `Compile::Shorten_branches' at all. 2094// 2095// And `Compile::Shorten_branches' will decide on basis of this 2096// information whether to replace particular branch sites by short 2097// ones. 2098bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 2099 // Is the offset within the range of a ppc64 pc relative branch? 2100 bool b; 2101 2102 const int safety_zone = 3 * BytesPerInstWord; 2103 b = Assembler::is_simm((offset<0 ? offset-safety_zone : offset+safety_zone), 2104 29 - 16 + 1 + 2); 2105 return b; 2106} 2107 2108const bool Matcher::isSimpleConstant64(jlong value) { 2109 // Probably always true, even if a temp register is required. 2110 return true; 2111} 2112/* TODO: PPC port 2113// Make a new machine dependent decode node (with its operands). 2114MachTypeNode *Matcher::make_decode_node() { 2115 assert(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0, 2116 "This method is only implemented for unscaled cOops mode so far"); 2117 MachTypeNode *decode = new decodeN_unscaledNode(); 2118 decode->set_opnd_array(0, new iRegPdstOper()); 2119 decode->set_opnd_array(1, new iRegNsrcOper()); 2120 return decode; 2121} 2122*/ 2123 2124// false => size gets scaled to BytesPerLong, ok. 2125const bool Matcher::init_array_count_is_in_bytes = false; 2126 2127// Use conditional move (CMOVL) on Power7. 2128const int Matcher::long_cmove_cost() { return 0; } // this only makes long cmoves more expensive than int cmoves 2129 2130// Suppress CMOVF. Conditional move available (sort of) on PPC64 only from P7 onwards. Not exploited yet. 2131// fsel doesn't accept a condition register as input, so this would be slightly different. 2132const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 2133 2134// Power6 requires postalloc expand (see block.cpp for description of postalloc expand). 2135const bool Matcher::require_postalloc_expand = true; 2136 2137// Do we need to mask the count passed to shift instructions or does 2138// the cpu only look at the lower 5/6 bits anyway? 2139// PowerPC requires masked shift counts. 2140const bool Matcher::need_masked_shift_count = true; 2141 2142// This affects two different things: 2143// - how Decode nodes are matched 2144// - how ImplicitNullCheck opportunities are recognized 2145// If true, the matcher will try to remove all Decodes and match them 2146// (as operands) into nodes. NullChecks are not prepared to deal with 2147// Decodes by final_graph_reshaping(). 2148// If false, final_graph_reshaping() forces the decode behind the Cmp 2149// for a NullCheck. The matcher matches the Decode node into a register. 2150// Implicit_null_check optimization moves the Decode along with the 2151// memory operation back up before the NullCheck. 2152bool Matcher::narrow_oop_use_complex_address() { 2153 // TODO: PPC port if (MatchDecodeNodes) return true; 2154 return false; 2155} 2156 2157bool Matcher::narrow_klass_use_complex_address() { 2158 NOT_LP64(ShouldNotCallThis()); 2159 assert(UseCompressedClassPointers, "only for compressed klass code"); 2160 // TODO: PPC port if (MatchDecodeNodes) return true; 2161 return false; 2162} 2163 2164bool Matcher::const_oop_prefer_decode() { 2165 // Prefer ConN+DecodeN over ConP in simple compressed oops mode. 2166 return Universe::narrow_oop_base() == NULL; 2167} 2168 2169bool Matcher::const_klass_prefer_decode() { 2170 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 2171 return Universe::narrow_klass_base() == NULL; 2172} 2173 2174// Is it better to copy float constants, or load them directly from memory? 2175// Intel can load a float constant from a direct address, requiring no 2176// extra registers. Most RISCs will have to materialize an address into a 2177// register first, so they would do better to copy the constant from stack. 2178const bool Matcher::rematerialize_float_constants = false; 2179 2180// If CPU can load and store mis-aligned doubles directly then no fixup is 2181// needed. Else we split the double into 2 integer pieces and move it 2182// piece-by-piece. Only happens when passing doubles into C code as the 2183// Java calling convention forces doubles to be aligned. 2184const bool Matcher::misaligned_doubles_ok = true; 2185 2186void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) { 2187 Unimplemented(); 2188} 2189 2190// Advertise here if the CPU requires explicit rounding operations 2191// to implement the UseStrictFP mode. 2192const bool Matcher::strict_fp_requires_explicit_rounding = false; 2193 2194// Do floats take an entire double register or just half? 2195// 2196// A float occupies a ppc64 double register. For the allocator, a 2197// ppc64 double register appears as a pair of float registers. 2198bool Matcher::float_in_double() { return true; } 2199 2200// Do ints take an entire long register or just half? 2201// The relevant question is how the int is callee-saved: 2202// the whole long is written but de-opt'ing will have to extract 2203// the relevant 32 bits. 2204const bool Matcher::int_in_long = true; 2205 2206// Constants for c2c and c calling conventions. 2207 2208const MachRegisterNumbers iarg_reg[8] = { 2209 R3_num, R4_num, R5_num, R6_num, 2210 R7_num, R8_num, R9_num, R10_num 2211}; 2212 2213const MachRegisterNumbers farg_reg[13] = { 2214 F1_num, F2_num, F3_num, F4_num, 2215 F5_num, F6_num, F7_num, F8_num, 2216 F9_num, F10_num, F11_num, F12_num, 2217 F13_num 2218}; 2219 2220const int num_iarg_registers = sizeof(iarg_reg) / sizeof(iarg_reg[0]); 2221 2222const int num_farg_registers = sizeof(farg_reg) / sizeof(farg_reg[0]); 2223 2224// Return whether or not this register is ever used as an argument. This 2225// function is used on startup to build the trampoline stubs in generateOptoStub. 2226// Registers not mentioned will be killed by the VM call in the trampoline, and 2227// arguments in those registers not be available to the callee. 2228bool Matcher::can_be_java_arg(int reg) { 2229 // We return true for all registers contained in iarg_reg[] and 2230 // farg_reg[] and their virtual halves. 2231 // We must include the virtual halves in order to get STDs and LDs 2232 // instead of STWs and LWs in the trampoline stubs. 2233 2234 if ( reg == R3_num || reg == R3_H_num 2235 || reg == R4_num || reg == R4_H_num 2236 || reg == R5_num || reg == R5_H_num 2237 || reg == R6_num || reg == R6_H_num 2238 || reg == R7_num || reg == R7_H_num 2239 || reg == R8_num || reg == R8_H_num 2240 || reg == R9_num || reg == R9_H_num 2241 || reg == R10_num || reg == R10_H_num) 2242 return true; 2243 2244 if ( reg == F1_num || reg == F1_H_num 2245 || reg == F2_num || reg == F2_H_num 2246 || reg == F3_num || reg == F3_H_num 2247 || reg == F4_num || reg == F4_H_num 2248 || reg == F5_num || reg == F5_H_num 2249 || reg == F6_num || reg == F6_H_num 2250 || reg == F7_num || reg == F7_H_num 2251 || reg == F8_num || reg == F8_H_num 2252 || reg == F9_num || reg == F9_H_num 2253 || reg == F10_num || reg == F10_H_num 2254 || reg == F11_num || reg == F11_H_num 2255 || reg == F12_num || reg == F12_H_num 2256 || reg == F13_num || reg == F13_H_num) 2257 return true; 2258 2259 return false; 2260} 2261 2262bool Matcher::is_spillable_arg(int reg) { 2263 return can_be_java_arg(reg); 2264} 2265 2266bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2267 return false; 2268} 2269 2270// Register for DIVI projection of divmodI. 2271RegMask Matcher::divI_proj_mask() { 2272 ShouldNotReachHere(); 2273 return RegMask(); 2274} 2275 2276// Register for MODI projection of divmodI. 2277RegMask Matcher::modI_proj_mask() { 2278 ShouldNotReachHere(); 2279 return RegMask(); 2280} 2281 2282// Register for DIVL projection of divmodL. 2283RegMask Matcher::divL_proj_mask() { 2284 ShouldNotReachHere(); 2285 return RegMask(); 2286} 2287 2288// Register for MODL projection of divmodL. 2289RegMask Matcher::modL_proj_mask() { 2290 ShouldNotReachHere(); 2291 return RegMask(); 2292} 2293 2294const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2295 return RegMask(); 2296} 2297 2298const bool Matcher::convi2l_type_required = true; 2299 2300%} 2301 2302//----------ENCODING BLOCK----------------------------------------------------- 2303// This block specifies the encoding classes used by the compiler to output 2304// byte streams. Encoding classes are parameterized macros used by 2305// Machine Instruction Nodes in order to generate the bit encoding of the 2306// instruction. Operands specify their base encoding interface with the 2307// interface keyword. There are currently supported four interfaces, 2308// REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an 2309// operand to generate a function which returns its register number when 2310// queried. CONST_INTER causes an operand to generate a function which 2311// returns the value of the constant when queried. MEMORY_INTER causes an 2312// operand to generate four functions which return the Base Register, the 2313// Index Register, the Scale Value, and the Offset Value of the operand when 2314// queried. COND_INTER causes an operand to generate six functions which 2315// return the encoding code (ie - encoding bits for the instruction) 2316// associated with each basic boolean condition for a conditional instruction. 2317// 2318// Instructions specify two basic values for encoding. Again, a function 2319// is available to check if the constant displacement is an oop. They use the 2320// ins_encode keyword to specify their encoding classes (which must be 2321// a sequence of enc_class names, and their parameters, specified in 2322// the encoding block), and they use the 2323// opcode keyword to specify, in order, their primary, secondary, and 2324// tertiary opcode. Only the opcode sections which a particular instruction 2325// needs for encoding need to be specified. 2326encode %{ 2327 enc_class enc_unimplemented %{ 2328 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2329 MacroAssembler _masm(&cbuf); 2330 __ unimplemented("Unimplemented mach node encoding in AD file.", 13); 2331 %} 2332 2333 enc_class enc_untested %{ 2334#ifdef ASSERT 2335 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2336 MacroAssembler _masm(&cbuf); 2337 __ untested("Untested mach node encoding in AD file."); 2338#else 2339 // TODO: PPC port $archOpcode(ppc64Opcode_none); 2340#endif 2341 %} 2342 2343 enc_class enc_lbz(iRegIdst dst, memory mem) %{ 2344 // TODO: PPC port $archOpcode(ppc64Opcode_lbz); 2345 MacroAssembler _masm(&cbuf); 2346 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2347 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2348 %} 2349 2350 // Load acquire. 2351 enc_class enc_lbz_ac(iRegIdst dst, memory mem) %{ 2352 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2353 MacroAssembler _masm(&cbuf); 2354 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2355 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2356 __ twi_0($dst$$Register); 2357 __ isync(); 2358 %} 2359 2360 enc_class enc_lhz(iRegIdst dst, memory mem) %{ 2361 // TODO: PPC port $archOpcode(ppc64Opcode_lhz); 2362 2363 MacroAssembler _masm(&cbuf); 2364 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2365 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2366 %} 2367 2368 // Load acquire. 2369 enc_class enc_lhz_ac(iRegIdst dst, memory mem) %{ 2370 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2371 2372 MacroAssembler _masm(&cbuf); 2373 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2374 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2375 __ twi_0($dst$$Register); 2376 __ isync(); 2377 %} 2378 2379 enc_class enc_lwz(iRegIdst dst, memory mem) %{ 2380 // TODO: PPC port $archOpcode(ppc64Opcode_lwz); 2381 2382 MacroAssembler _masm(&cbuf); 2383 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2384 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2385 %} 2386 2387 // Load acquire. 2388 enc_class enc_lwz_ac(iRegIdst dst, memory mem) %{ 2389 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2390 2391 MacroAssembler _masm(&cbuf); 2392 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2393 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2394 __ twi_0($dst$$Register); 2395 __ isync(); 2396 %} 2397 2398 enc_class enc_ld(iRegLdst dst, memoryAlg4 mem) %{ 2399 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2400 MacroAssembler _masm(&cbuf); 2401 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2402 // Operand 'ds' requires 4-alignment. 2403 assert((Idisp & 0x3) == 0, "unaligned offset"); 2404 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2405 %} 2406 2407 // Load acquire. 2408 enc_class enc_ld_ac(iRegLdst dst, memoryAlg4 mem) %{ 2409 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2410 MacroAssembler _masm(&cbuf); 2411 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2412 // Operand 'ds' requires 4-alignment. 2413 assert((Idisp & 0x3) == 0, "unaligned offset"); 2414 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2415 __ twi_0($dst$$Register); 2416 __ isync(); 2417 %} 2418 2419 enc_class enc_lfd(RegF dst, memory mem) %{ 2420 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 2421 MacroAssembler _masm(&cbuf); 2422 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2423 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 2424 %} 2425 2426 enc_class enc_load_long_constL(iRegLdst dst, immL src, iRegLdst toc) %{ 2427 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2428 2429 MacroAssembler _masm(&cbuf); 2430 int toc_offset = 0; 2431 2432 address const_toc_addr; 2433 // Create a non-oop constant, no relocation needed. 2434 // If it is an IC, it has a virtual_call_Relocation. 2435 const_toc_addr = __ long_constant((jlong)$src$$constant); 2436 if (const_toc_addr == NULL) { 2437 ciEnv::current()->record_out_of_memory_failure(); 2438 return; 2439 } 2440 2441 // Get the constant's TOC offset. 2442 toc_offset = __ offset_to_method_toc(const_toc_addr); 2443 2444 // Keep the current instruction offset in mind. 2445 ((loadConLNode*)this)->_cbuf_insts_offset = __ offset(); 2446 2447 __ ld($dst$$Register, toc_offset, $toc$$Register); 2448 %} 2449 2450 enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{ 2451 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 2452 2453 MacroAssembler _masm(&cbuf); 2454 2455 if (!ra_->C->in_scratch_emit_size()) { 2456 address const_toc_addr; 2457 // Create a non-oop constant, no relocation needed. 2458 // If it is an IC, it has a virtual_call_Relocation. 2459 const_toc_addr = __ long_constant((jlong)$src$$constant); 2460 if (const_toc_addr == NULL) { 2461 ciEnv::current()->record_out_of_memory_failure(); 2462 return; 2463 } 2464 2465 // Get the constant's TOC offset. 2466 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 2467 // Store the toc offset of the constant. 2468 ((loadConL_hiNode*)this)->_const_toc_offset = toc_offset; 2469 2470 // Also keep the current instruction offset in mind. 2471 ((loadConL_hiNode*)this)->_cbuf_insts_offset = __ offset(); 2472 } 2473 2474 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 2475 %} 2476 2477%} // encode 2478 2479source %{ 2480 2481typedef struct { 2482 loadConL_hiNode *_large_hi; 2483 loadConL_loNode *_large_lo; 2484 loadConLNode *_small; 2485 MachNode *_last; 2486} loadConLNodesTuple; 2487 2488loadConLNodesTuple loadConLNodesTuple_create(PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2489 OptoReg::Name reg_second, OptoReg::Name reg_first) { 2490 loadConLNodesTuple nodes; 2491 2492 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2493 if (large_constant_pool) { 2494 // Create new nodes. 2495 loadConL_hiNode *m1 = new loadConL_hiNode(); 2496 loadConL_loNode *m2 = new loadConL_loNode(); 2497 2498 // inputs for new nodes 2499 m1->add_req(NULL, toc); 2500 m2->add_req(NULL, m1); 2501 2502 // operands for new nodes 2503 m1->_opnds[0] = new iRegLdstOper(); // dst 2504 m1->_opnds[1] = immSrc; // src 2505 m1->_opnds[2] = new iRegPdstOper(); // toc 2506 m2->_opnds[0] = new iRegLdstOper(); // dst 2507 m2->_opnds[1] = immSrc; // src 2508 m2->_opnds[2] = new iRegLdstOper(); // base 2509 2510 // Initialize ins_attrib TOC fields. 2511 m1->_const_toc_offset = -1; 2512 m2->_const_toc_offset_hi_node = m1; 2513 2514 // Initialize ins_attrib instruction offset. 2515 m1->_cbuf_insts_offset = -1; 2516 2517 // register allocation for new nodes 2518 ra_->set_pair(m1->_idx, reg_second, reg_first); 2519 ra_->set_pair(m2->_idx, reg_second, reg_first); 2520 2521 // Create result. 2522 nodes._large_hi = m1; 2523 nodes._large_lo = m2; 2524 nodes._small = NULL; 2525 nodes._last = nodes._large_lo; 2526 assert(m2->bottom_type()->isa_long(), "must be long"); 2527 } else { 2528 loadConLNode *m2 = new loadConLNode(); 2529 2530 // inputs for new nodes 2531 m2->add_req(NULL, toc); 2532 2533 // operands for new nodes 2534 m2->_opnds[0] = new iRegLdstOper(); // dst 2535 m2->_opnds[1] = immSrc; // src 2536 m2->_opnds[2] = new iRegPdstOper(); // toc 2537 2538 // Initialize ins_attrib instruction offset. 2539 m2->_cbuf_insts_offset = -1; 2540 2541 // register allocation for new nodes 2542 ra_->set_pair(m2->_idx, reg_second, reg_first); 2543 2544 // Create result. 2545 nodes._large_hi = NULL; 2546 nodes._large_lo = NULL; 2547 nodes._small = m2; 2548 nodes._last = nodes._small; 2549 assert(m2->bottom_type()->isa_long(), "must be long"); 2550 } 2551 2552 return nodes; 2553} 2554 2555%} // source 2556 2557encode %{ 2558 // Postalloc expand emitter for loading a long constant from the method's TOC. 2559 // Enc_class needed as consttanttablebase is not supported by postalloc 2560 // expand. 2561 enc_class postalloc_expand_load_long_constant(iRegLdst dst, immL src, iRegLdst toc) %{ 2562 // Create new nodes. 2563 loadConLNodesTuple loadConLNodes = 2564 loadConLNodesTuple_create(ra_, n_toc, op_src, 2565 ra_->get_reg_second(this), ra_->get_reg_first(this)); 2566 2567 // Push new nodes. 2568 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 2569 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 2570 2571 // some asserts 2572 assert(nodes->length() >= 1, "must have created at least 1 node"); 2573 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 2574 %} 2575 2576 enc_class enc_load_long_constP(iRegLdst dst, immP src, iRegLdst toc) %{ 2577 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2578 2579 MacroAssembler _masm(&cbuf); 2580 int toc_offset = 0; 2581 2582 intptr_t val = $src$$constant; 2583 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 2584 address const_toc_addr; 2585 if (constant_reloc == relocInfo::oop_type) { 2586 // Create an oop constant and a corresponding relocation. 2587 AddressLiteral a = __ allocate_oop_address((jobject)val); 2588 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2589 __ relocate(a.rspec()); 2590 } else if (constant_reloc == relocInfo::metadata_type) { 2591 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 2592 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2593 __ relocate(a.rspec()); 2594 } else { 2595 // Create a non-oop constant, no relocation needed. 2596 const_toc_addr = __ long_constant((jlong)$src$$constant); 2597 } 2598 2599 if (const_toc_addr == NULL) { 2600 ciEnv::current()->record_out_of_memory_failure(); 2601 return; 2602 } 2603 // Get the constant's TOC offset. 2604 toc_offset = __ offset_to_method_toc(const_toc_addr); 2605 2606 __ ld($dst$$Register, toc_offset, $toc$$Register); 2607 %} 2608 2609 enc_class enc_load_long_constP_hi(iRegLdst dst, immP src, iRegLdst toc) %{ 2610 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 2611 2612 MacroAssembler _masm(&cbuf); 2613 if (!ra_->C->in_scratch_emit_size()) { 2614 intptr_t val = $src$$constant; 2615 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 2616 address const_toc_addr; 2617 if (constant_reloc == relocInfo::oop_type) { 2618 // Create an oop constant and a corresponding relocation. 2619 AddressLiteral a = __ allocate_oop_address((jobject)val); 2620 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2621 __ relocate(a.rspec()); 2622 } else if (constant_reloc == relocInfo::metadata_type) { 2623 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 2624 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2625 __ relocate(a.rspec()); 2626 } else { // non-oop pointers, e.g. card mark base, heap top 2627 // Create a non-oop constant, no relocation needed. 2628 const_toc_addr = __ long_constant((jlong)$src$$constant); 2629 } 2630 2631 if (const_toc_addr == NULL) { 2632 ciEnv::current()->record_out_of_memory_failure(); 2633 return; 2634 } 2635 // Get the constant's TOC offset. 2636 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 2637 // Store the toc offset of the constant. 2638 ((loadConP_hiNode*)this)->_const_toc_offset = toc_offset; 2639 } 2640 2641 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 2642 %} 2643 2644 // Postalloc expand emitter for loading a ptr constant from the method's TOC. 2645 // Enc_class needed as consttanttablebase is not supported by postalloc 2646 // expand. 2647 enc_class postalloc_expand_load_ptr_constant(iRegPdst dst, immP src, iRegLdst toc) %{ 2648 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2649 if (large_constant_pool) { 2650 // Create new nodes. 2651 loadConP_hiNode *m1 = new loadConP_hiNode(); 2652 loadConP_loNode *m2 = new loadConP_loNode(); 2653 2654 // inputs for new nodes 2655 m1->add_req(NULL, n_toc); 2656 m2->add_req(NULL, m1); 2657 2658 // operands for new nodes 2659 m1->_opnds[0] = new iRegPdstOper(); // dst 2660 m1->_opnds[1] = op_src; // src 2661 m1->_opnds[2] = new iRegPdstOper(); // toc 2662 m2->_opnds[0] = new iRegPdstOper(); // dst 2663 m2->_opnds[1] = op_src; // src 2664 m2->_opnds[2] = new iRegLdstOper(); // base 2665 2666 // Initialize ins_attrib TOC fields. 2667 m1->_const_toc_offset = -1; 2668 m2->_const_toc_offset_hi_node = m1; 2669 2670 // Register allocation for new nodes. 2671 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2672 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2673 2674 nodes->push(m1); 2675 nodes->push(m2); 2676 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 2677 } else { 2678 loadConPNode *m2 = new loadConPNode(); 2679 2680 // inputs for new nodes 2681 m2->add_req(NULL, n_toc); 2682 2683 // operands for new nodes 2684 m2->_opnds[0] = new iRegPdstOper(); // dst 2685 m2->_opnds[1] = op_src; // src 2686 m2->_opnds[2] = new iRegPdstOper(); // toc 2687 2688 // Register allocation for new nodes. 2689 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2690 2691 nodes->push(m2); 2692 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 2693 } 2694 %} 2695 2696 // Enc_class needed as consttanttablebase is not supported by postalloc 2697 // expand. 2698 enc_class postalloc_expand_load_float_constant(regF dst, immF src, iRegLdst toc) %{ 2699 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2700 2701 MachNode *m2; 2702 if (large_constant_pool) { 2703 m2 = new loadConFCompNode(); 2704 } else { 2705 m2 = new loadConFNode(); 2706 } 2707 // inputs for new nodes 2708 m2->add_req(NULL, n_toc); 2709 2710 // operands for new nodes 2711 m2->_opnds[0] = op_dst; 2712 m2->_opnds[1] = op_src; 2713 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 2714 2715 // register allocation for new nodes 2716 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2717 nodes->push(m2); 2718 %} 2719 2720 // Enc_class needed as consttanttablebase is not supported by postalloc 2721 // expand. 2722 enc_class postalloc_expand_load_double_constant(regD dst, immD src, iRegLdst toc) %{ 2723 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2724 2725 MachNode *m2; 2726 if (large_constant_pool) { 2727 m2 = new loadConDCompNode(); 2728 } else { 2729 m2 = new loadConDNode(); 2730 } 2731 // inputs for new nodes 2732 m2->add_req(NULL, n_toc); 2733 2734 // operands for new nodes 2735 m2->_opnds[0] = op_dst; 2736 m2->_opnds[1] = op_src; 2737 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 2738 2739 // register allocation for new nodes 2740 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2741 nodes->push(m2); 2742 %} 2743 2744 enc_class enc_stw(iRegIsrc src, memory mem) %{ 2745 // TODO: PPC port $archOpcode(ppc64Opcode_stw); 2746 MacroAssembler _masm(&cbuf); 2747 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2748 __ stw($src$$Register, Idisp, $mem$$base$$Register); 2749 %} 2750 2751 enc_class enc_std(iRegIsrc src, memoryAlg4 mem) %{ 2752 // TODO: PPC port $archOpcode(ppc64Opcode_std); 2753 MacroAssembler _masm(&cbuf); 2754 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2755 // Operand 'ds' requires 4-alignment. 2756 assert((Idisp & 0x3) == 0, "unaligned offset"); 2757 __ std($src$$Register, Idisp, $mem$$base$$Register); 2758 %} 2759 2760 enc_class enc_stfs(RegF src, memory mem) %{ 2761 // TODO: PPC port $archOpcode(ppc64Opcode_stfs); 2762 MacroAssembler _masm(&cbuf); 2763 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2764 __ stfs($src$$FloatRegister, Idisp, $mem$$base$$Register); 2765 %} 2766 2767 enc_class enc_stfd(RegF src, memory mem) %{ 2768 // TODO: PPC port $archOpcode(ppc64Opcode_stfd); 2769 MacroAssembler _masm(&cbuf); 2770 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2771 __ stfd($src$$FloatRegister, Idisp, $mem$$base$$Register); 2772 %} 2773 2774 // Use release_store for card-marking to ensure that previous 2775 // oop-stores are visible before the card-mark change. 2776 enc_class enc_cms_card_mark(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 2777 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2778 // FIXME: Implement this as a cmove and use a fixed condition code 2779 // register which is written on every transition to compiled code, 2780 // e.g. in call-stub and when returning from runtime stubs. 2781 // 2782 // Proposed code sequence for the cmove implementation: 2783 // 2784 // Label skip_release; 2785 // __ beq(CCRfixed, skip_release); 2786 // __ release(); 2787 // __ bind(skip_release); 2788 // __ stb(card mark); 2789 2790 MacroAssembler _masm(&cbuf); 2791 Label skip_storestore; 2792 2793#if 0 // TODO: PPC port 2794 // Check CMSCollectorCardTableModRefBSExt::_requires_release and do the 2795 // StoreStore barrier conditionally. 2796 __ lwz(R0, 0, $releaseFieldAddr$$Register); 2797 __ cmpwi($crx$$CondRegister, R0, 0); 2798 __ beq_predict_taken($crx$$CondRegister, skip_storestore); 2799#endif 2800 __ li(R0, 0); 2801 __ membar(Assembler::StoreStore); 2802#if 0 // TODO: PPC port 2803 __ bind(skip_storestore); 2804#endif 2805 2806 // Do the store. 2807 if ($mem$$index == 0) { 2808 __ stb(R0, $mem$$disp, $mem$$base$$Register); 2809 } else { 2810 assert(0 == $mem$$disp, "no displacement possible with indexed load/stores on ppc"); 2811 __ stbx(R0, $mem$$base$$Register, $mem$$index$$Register); 2812 } 2813 %} 2814 2815 enc_class postalloc_expand_encode_oop(iRegNdst dst, iRegPdst src, flagsReg crx) %{ 2816 2817 if (VM_Version::has_isel()) { 2818 // use isel instruction with Power 7 2819 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 2820 encodeP_subNode *n_sub_base = new encodeP_subNode(); 2821 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 2822 cond_set_0_oopNode *n_cond_set = new cond_set_0_oopNode(); 2823 2824 n_compare->add_req(n_region, n_src); 2825 n_compare->_opnds[0] = op_crx; 2826 n_compare->_opnds[1] = op_src; 2827 n_compare->_opnds[2] = new immL16Oper(0); 2828 2829 n_sub_base->add_req(n_region, n_src); 2830 n_sub_base->_opnds[0] = op_dst; 2831 n_sub_base->_opnds[1] = op_src; 2832 n_sub_base->_bottom_type = _bottom_type; 2833 2834 n_shift->add_req(n_region, n_sub_base); 2835 n_shift->_opnds[0] = op_dst; 2836 n_shift->_opnds[1] = op_dst; 2837 n_shift->_bottom_type = _bottom_type; 2838 2839 n_cond_set->add_req(n_region, n_compare, n_shift); 2840 n_cond_set->_opnds[0] = op_dst; 2841 n_cond_set->_opnds[1] = op_crx; 2842 n_cond_set->_opnds[2] = op_dst; 2843 n_cond_set->_bottom_type = _bottom_type; 2844 2845 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 2846 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2847 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2848 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2849 2850 nodes->push(n_compare); 2851 nodes->push(n_sub_base); 2852 nodes->push(n_shift); 2853 nodes->push(n_cond_set); 2854 2855 } else { 2856 // before Power 7 2857 moveRegNode *n_move = new moveRegNode(); 2858 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 2859 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 2860 cond_sub_baseNode *n_sub_base = new cond_sub_baseNode(); 2861 2862 n_move->add_req(n_region, n_src); 2863 n_move->_opnds[0] = op_dst; 2864 n_move->_opnds[1] = op_src; 2865 ra_->set_oop(n_move, true); // Until here, 'n_move' still produces an oop. 2866 2867 n_compare->add_req(n_region, n_src); 2868 n_compare->add_prec(n_move); 2869 2870 n_compare->_opnds[0] = op_crx; 2871 n_compare->_opnds[1] = op_src; 2872 n_compare->_opnds[2] = new immL16Oper(0); 2873 2874 n_sub_base->add_req(n_region, n_compare, n_src); 2875 n_sub_base->_opnds[0] = op_dst; 2876 n_sub_base->_opnds[1] = op_crx; 2877 n_sub_base->_opnds[2] = op_src; 2878 n_sub_base->_bottom_type = _bottom_type; 2879 2880 n_shift->add_req(n_region, n_sub_base); 2881 n_shift->_opnds[0] = op_dst; 2882 n_shift->_opnds[1] = op_dst; 2883 n_shift->_bottom_type = _bottom_type; 2884 2885 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2886 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 2887 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2888 ra_->set_pair(n_move->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2889 2890 nodes->push(n_move); 2891 nodes->push(n_compare); 2892 nodes->push(n_sub_base); 2893 nodes->push(n_shift); 2894 } 2895 2896 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 2897 %} 2898 2899 enc_class postalloc_expand_encode_oop_not_null(iRegNdst dst, iRegPdst src) %{ 2900 2901 encodeP_subNode *n1 = new encodeP_subNode(); 2902 n1->add_req(n_region, n_src); 2903 n1->_opnds[0] = op_dst; 2904 n1->_opnds[1] = op_src; 2905 n1->_bottom_type = _bottom_type; 2906 2907 encodeP_shiftNode *n2 = new encodeP_shiftNode(); 2908 n2->add_req(n_region, n1); 2909 n2->_opnds[0] = op_dst; 2910 n2->_opnds[1] = op_dst; 2911 n2->_bottom_type = _bottom_type; 2912 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2913 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2914 2915 nodes->push(n1); 2916 nodes->push(n2); 2917 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 2918 %} 2919 2920 enc_class postalloc_expand_decode_oop(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 2921 decodeN_shiftNode *n_shift = new decodeN_shiftNode(); 2922 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 2923 2924 n_compare->add_req(n_region, n_src); 2925 n_compare->_opnds[0] = op_crx; 2926 n_compare->_opnds[1] = op_src; 2927 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 2928 2929 n_shift->add_req(n_region, n_src); 2930 n_shift->_opnds[0] = op_dst; 2931 n_shift->_opnds[1] = op_src; 2932 n_shift->_bottom_type = _bottom_type; 2933 2934 if (VM_Version::has_isel()) { 2935 // use isel instruction with Power 7 2936 2937 decodeN_addNode *n_add_base = new decodeN_addNode(); 2938 n_add_base->add_req(n_region, n_shift); 2939 n_add_base->_opnds[0] = op_dst; 2940 n_add_base->_opnds[1] = op_dst; 2941 n_add_base->_bottom_type = _bottom_type; 2942 2943 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 2944 n_cond_set->add_req(n_region, n_compare, n_add_base); 2945 n_cond_set->_opnds[0] = op_dst; 2946 n_cond_set->_opnds[1] = op_crx; 2947 n_cond_set->_opnds[2] = op_dst; 2948 n_cond_set->_bottom_type = _bottom_type; 2949 2950 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 2951 ra_->set_oop(n_cond_set, true); 2952 2953 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2954 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 2955 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2956 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2957 2958 nodes->push(n_compare); 2959 nodes->push(n_shift); 2960 nodes->push(n_add_base); 2961 nodes->push(n_cond_set); 2962 2963 } else { 2964 // before Power 7 2965 cond_add_baseNode *n_add_base = new cond_add_baseNode(); 2966 2967 n_add_base->add_req(n_region, n_compare, n_shift); 2968 n_add_base->_opnds[0] = op_dst; 2969 n_add_base->_opnds[1] = op_crx; 2970 n_add_base->_opnds[2] = op_dst; 2971 n_add_base->_bottom_type = _bottom_type; 2972 2973 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 2974 ra_->set_oop(n_add_base, true); 2975 2976 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2977 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 2978 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2979 2980 nodes->push(n_compare); 2981 nodes->push(n_shift); 2982 nodes->push(n_add_base); 2983 } 2984 %} 2985 2986 enc_class postalloc_expand_decode_oop_not_null(iRegPdst dst, iRegNsrc src) %{ 2987 decodeN_shiftNode *n1 = new decodeN_shiftNode(); 2988 n1->add_req(n_region, n_src); 2989 n1->_opnds[0] = op_dst; 2990 n1->_opnds[1] = op_src; 2991 n1->_bottom_type = _bottom_type; 2992 2993 decodeN_addNode *n2 = new decodeN_addNode(); 2994 n2->add_req(n_region, n1); 2995 n2->_opnds[0] = op_dst; 2996 n2->_opnds[1] = op_dst; 2997 n2->_bottom_type = _bottom_type; 2998 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2999 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3000 3001 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3002 ra_->set_oop(n2, true); 3003 3004 nodes->push(n1); 3005 nodes->push(n2); 3006 %} 3007 3008 enc_class enc_cmove_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src, cmpOp cmp) %{ 3009 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3010 3011 MacroAssembler _masm(&cbuf); 3012 int cc = $cmp$$cmpcode; 3013 int flags_reg = $crx$$reg; 3014 Label done; 3015 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3016 // Branch if not (cmp crx). 3017 __ bc(cc_to_inverse_boint(cc), cc_to_biint(cc, flags_reg), done); 3018 __ mr($dst$$Register, $src$$Register); 3019 // TODO PPC port __ endgroup_if_needed(_size == 12); 3020 __ bind(done); 3021 %} 3022 3023 enc_class enc_cmove_imm(iRegIdst dst, flagsRegSrc crx, immI16 src, cmpOp cmp) %{ 3024 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3025 3026 MacroAssembler _masm(&cbuf); 3027 Label done; 3028 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3029 // Branch if not (cmp crx). 3030 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 3031 __ li($dst$$Register, $src$$constant); 3032 // TODO PPC port __ endgroup_if_needed(_size == 12); 3033 __ bind(done); 3034 %} 3035 3036 // This enc_class is needed so that scheduler gets proper 3037 // input mapping for latency computation. 3038 enc_class enc_andc(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 3039 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 3040 MacroAssembler _masm(&cbuf); 3041 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 3042 %} 3043 3044 enc_class enc_convI2B_regI__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3045 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3046 3047 MacroAssembler _masm(&cbuf); 3048 3049 Label done; 3050 __ cmpwi($crx$$CondRegister, $src$$Register, 0); 3051 __ li($dst$$Register, $zero$$constant); 3052 __ beq($crx$$CondRegister, done); 3053 __ li($dst$$Register, $notzero$$constant); 3054 __ bind(done); 3055 %} 3056 3057 enc_class enc_convP2B_regP__cmove(iRegIdst dst, iRegPsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3058 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3059 3060 MacroAssembler _masm(&cbuf); 3061 3062 Label done; 3063 __ cmpdi($crx$$CondRegister, $src$$Register, 0); 3064 __ li($dst$$Register, $zero$$constant); 3065 __ beq($crx$$CondRegister, done); 3066 __ li($dst$$Register, $notzero$$constant); 3067 __ bind(done); 3068 %} 3069 3070 enc_class enc_cmove_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL mem ) %{ 3071 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3072 3073 MacroAssembler _masm(&cbuf); 3074 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3075 Label done; 3076 __ bso($crx$$CondRegister, done); 3077 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 3078 // TODO PPC port __ endgroup_if_needed(_size == 12); 3079 __ bind(done); 3080 %} 3081 3082 enc_class enc_bc(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3083 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3084 3085 MacroAssembler _masm(&cbuf); 3086 Label d; // dummy 3087 __ bind(d); 3088 Label* p = ($lbl$$label); 3089 // `p' is `NULL' when this encoding class is used only to 3090 // determine the size of the encoded instruction. 3091 Label& l = (NULL == p)? d : *(p); 3092 int cc = $cmp$$cmpcode; 3093 int flags_reg = $crx$$reg; 3094 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3095 int bhint = Assembler::bhintNoHint; 3096 3097 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3098 if (_prob <= PROB_NEVER) { 3099 bhint = Assembler::bhintIsNotTaken; 3100 } else if (_prob >= PROB_ALWAYS) { 3101 bhint = Assembler::bhintIsTaken; 3102 } 3103 } 3104 3105 __ bc(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3106 cc_to_biint(cc, flags_reg), 3107 l); 3108 %} 3109 3110 enc_class enc_bc_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3111 // The scheduler doesn't know about branch shortening, so we set the opcode 3112 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3113 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3114 3115 MacroAssembler _masm(&cbuf); 3116 Label d; // dummy 3117 __ bind(d); 3118 Label* p = ($lbl$$label); 3119 // `p' is `NULL' when this encoding class is used only to 3120 // determine the size of the encoded instruction. 3121 Label& l = (NULL == p)? d : *(p); 3122 int cc = $cmp$$cmpcode; 3123 int flags_reg = $crx$$reg; 3124 int bhint = Assembler::bhintNoHint; 3125 3126 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3127 if (_prob <= PROB_NEVER) { 3128 bhint = Assembler::bhintIsNotTaken; 3129 } else if (_prob >= PROB_ALWAYS) { 3130 bhint = Assembler::bhintIsTaken; 3131 } 3132 } 3133 3134 // Tell the conditional far branch to optimize itself when being relocated. 3135 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3136 cc_to_biint(cc, flags_reg), 3137 l, 3138 MacroAssembler::bc_far_optimize_on_relocate); 3139 %} 3140 3141 // Branch used with Power6 scheduling (can be shortened without changing the node). 3142 enc_class enc_bc_short_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3143 // The scheduler doesn't know about branch shortening, so we set the opcode 3144 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3145 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3146 3147 MacroAssembler _masm(&cbuf); 3148 Label d; // dummy 3149 __ bind(d); 3150 Label* p = ($lbl$$label); 3151 // `p' is `NULL' when this encoding class is used only to 3152 // determine the size of the encoded instruction. 3153 Label& l = (NULL == p)? d : *(p); 3154 int cc = $cmp$$cmpcode; 3155 int flags_reg = $crx$$reg; 3156 int bhint = Assembler::bhintNoHint; 3157 3158 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3159 if (_prob <= PROB_NEVER) { 3160 bhint = Assembler::bhintIsNotTaken; 3161 } else if (_prob >= PROB_ALWAYS) { 3162 bhint = Assembler::bhintIsTaken; 3163 } 3164 } 3165 3166#if 0 // TODO: PPC port 3167 if (_size == 8) { 3168 // Tell the conditional far branch to optimize itself when being relocated. 3169 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3170 cc_to_biint(cc, flags_reg), 3171 l, 3172 MacroAssembler::bc_far_optimize_on_relocate); 3173 } else { 3174 __ bc (Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3175 cc_to_biint(cc, flags_reg), 3176 l); 3177 } 3178#endif 3179 Unimplemented(); 3180 %} 3181 3182 // Postalloc expand emitter for loading a replicatef float constant from 3183 // the method's TOC. 3184 // Enc_class needed as consttanttablebase is not supported by postalloc 3185 // expand. 3186 enc_class postalloc_expand_load_replF_constant(iRegLdst dst, immF src, iRegLdst toc) %{ 3187 // Create new nodes. 3188 3189 // Make an operand with the bit pattern to load as float. 3190 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3191 3192 loadConLNodesTuple loadConLNodes = 3193 loadConLNodesTuple_create(ra_, n_toc, op_repl, 3194 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3195 3196 // Push new nodes. 3197 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 3198 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 3199 3200 assert(nodes->length() >= 1, "must have created at least 1 node"); 3201 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 3202 %} 3203 3204 // This enc_class is needed so that scheduler gets proper 3205 // input mapping for latency computation. 3206 enc_class enc_poll(immI dst, iRegLdst poll) %{ 3207 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 3208 // Fake operand dst needed for PPC scheduler. 3209 assert($dst$$constant == 0x0, "dst must be 0x0"); 3210 3211 MacroAssembler _masm(&cbuf); 3212 // Mark the code position where the load from the safepoint 3213 // polling page was emitted as relocInfo::poll_type. 3214 __ relocate(relocInfo::poll_type); 3215 __ load_from_polling_page($poll$$Register); 3216 %} 3217 3218 // A Java static call or a runtime call. 3219 // 3220 // Branch-and-link relative to a trampoline. 3221 // The trampoline loads the target address and does a long branch to there. 3222 // In case we call java, the trampoline branches to a interpreter_stub 3223 // which loads the inline cache and the real call target from the constant pool. 3224 // 3225 // This basically looks like this: 3226 // 3227 // >>>> consts -+ -+ 3228 // | |- offset1 3229 // [call target1] | <-+ 3230 // [IC cache] |- offset2 3231 // [call target2] <--+ 3232 // 3233 // <<<< consts 3234 // >>>> insts 3235 // 3236 // bl offset16 -+ -+ ??? // How many bits available? 3237 // | | 3238 // <<<< insts | | 3239 // >>>> stubs | | 3240 // | |- trampoline_stub_Reloc 3241 // trampoline stub: | <-+ 3242 // r2 = toc | 3243 // r2 = [r2 + offset1] | // Load call target1 from const section 3244 // mtctr r2 | 3245 // bctr |- static_stub_Reloc 3246 // comp_to_interp_stub: <---+ 3247 // r1 = toc 3248 // ICreg = [r1 + IC_offset] // Load IC from const section 3249 // r1 = [r1 + offset2] // Load call target2 from const section 3250 // mtctr r1 3251 // bctr 3252 // 3253 // <<<< stubs 3254 // 3255 // The call instruction in the code either 3256 // - Branches directly to a compiled method if the offset is encodable in instruction. 3257 // - Branches to the trampoline stub if the offset to the compiled method is not encodable. 3258 // - Branches to the compiled_to_interp stub if the target is interpreted. 3259 // 3260 // Further there are three relocations from the loads to the constants in 3261 // the constant section. 3262 // 3263 // Usage of r1 and r2 in the stubs allows to distinguish them. 3264 enc_class enc_java_static_call(method meth) %{ 3265 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3266 3267 MacroAssembler _masm(&cbuf); 3268 address entry_point = (address)$meth$$method; 3269 3270 if (!_method) { 3271 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3272 emit_call_with_trampoline_stub(_masm, entry_point, relocInfo::runtime_call_type); 3273 } else { 3274 // Remember the offset not the address. 3275 const int start_offset = __ offset(); 3276 3277 // The trampoline stub. 3278 // No entry point given, use the current pc. 3279 // Make sure branch fits into 3280 if (entry_point == 0) entry_point = __ pc(); 3281 3282 // Put the entry point as a constant into the constant pool. 3283 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 3284 if (entry_point_toc_addr == NULL) { 3285 ciEnv::current()->record_out_of_memory_failure(); 3286 return; 3287 } 3288 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 3289 3290 // Emit the trampoline stub which will be related to the branch-and-link below. 3291 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset); 3292 if (ciEnv::current()->failing()) { return; } // Code cache may be full. 3293 int method_index = resolved_method_index(cbuf); 3294 __ relocate(_optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 3295 : static_call_Relocation::spec(method_index)); 3296 3297 // The real call. 3298 // Note: At this point we do not have the address of the trampoline 3299 // stub, and the entry point might be too far away for bl, so __ pc() 3300 // serves as dummy and the bl will be patched later. 3301 cbuf.set_insts_mark(); 3302 __ bl(__ pc()); // Emits a relocation. 3303 3304 // The stub for call to interpreter. 3305 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); 3306 if (stub == NULL) { 3307 ciEnv::current()->record_failure("CodeCache is full"); 3308 return; 3309 } 3310 } 3311 %} 3312 3313 // Second node of expanded dynamic call - the call. 3314 enc_class enc_java_dynamic_call_sched(method meth) %{ 3315 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3316 3317 MacroAssembler _masm(&cbuf); 3318 3319 if (!ra_->C->in_scratch_emit_size()) { 3320 // Create a call trampoline stub for the given method. 3321 const address entry_point = !($meth$$method) ? 0 : (address)$meth$$method; 3322 const address entry_point_const = __ address_constant(entry_point, RelocationHolder::none); 3323 if (entry_point_const == NULL) { 3324 ciEnv::current()->record_out_of_memory_failure(); 3325 return; 3326 } 3327 const int entry_point_const_toc_offset = __ offset_to_method_toc(entry_point_const); 3328 CallStubImpl::emit_trampoline_stub(_masm, entry_point_const_toc_offset, __ offset()); 3329 if (ra_->C->env()->failing()) { return; } // Code cache may be full. 3330 3331 // Build relocation at call site with ic position as data. 3332 assert((_load_ic_hi_node != NULL && _load_ic_node == NULL) || 3333 (_load_ic_hi_node == NULL && _load_ic_node != NULL), 3334 "must have one, but can't have both"); 3335 assert((_load_ic_hi_node != NULL && _load_ic_hi_node->_cbuf_insts_offset != -1) || 3336 (_load_ic_node != NULL && _load_ic_node->_cbuf_insts_offset != -1), 3337 "must contain instruction offset"); 3338 const int virtual_call_oop_addr_offset = _load_ic_hi_node != NULL 3339 ? _load_ic_hi_node->_cbuf_insts_offset 3340 : _load_ic_node->_cbuf_insts_offset; 3341 const address virtual_call_oop_addr = __ addr_at(virtual_call_oop_addr_offset); 3342 assert(MacroAssembler::is_load_const_from_method_toc_at(virtual_call_oop_addr), 3343 "should be load from TOC"); 3344 int method_index = resolved_method_index(cbuf); 3345 __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr, method_index)); 3346 } 3347 3348 // At this point I do not have the address of the trampoline stub, 3349 // and the entry point might be too far away for bl. Pc() serves 3350 // as dummy and bl will be patched later. 3351 __ bl((address) __ pc()); 3352 %} 3353 3354 // postalloc expand emitter for virtual calls. 3355 enc_class postalloc_expand_java_dynamic_call_sched(method meth, iRegLdst toc) %{ 3356 3357 // Create the nodes for loading the IC from the TOC. 3358 loadConLNodesTuple loadConLNodes_IC = 3359 loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong)Universe::non_oop_word()), 3360 OptoReg::Name(R19_H_num), OptoReg::Name(R19_num)); 3361 3362 // Create the call node. 3363 CallDynamicJavaDirectSchedNode *call = new CallDynamicJavaDirectSchedNode(); 3364 call->_method_handle_invoke = _method_handle_invoke; 3365 call->_vtable_index = _vtable_index; 3366 call->_method = _method; 3367 call->_bci = _bci; 3368 call->_optimized_virtual = _optimized_virtual; 3369 call->_tf = _tf; 3370 call->_entry_point = _entry_point; 3371 call->_cnt = _cnt; 3372 call->_argsize = _argsize; 3373 call->_oop_map = _oop_map; 3374 call->_jvms = _jvms; 3375 call->_jvmadj = _jvmadj; 3376 call->_in_rms = _in_rms; 3377 call->_nesting = _nesting; 3378 call->_override_symbolic_info = _override_symbolic_info; 3379 3380 // New call needs all inputs of old call. 3381 // Req... 3382 for (uint i = 0; i < req(); ++i) { 3383 // The expanded node does not need toc any more. 3384 // Add the inline cache constant here instead. This expresses the 3385 // register of the inline cache must be live at the call. 3386 // Else we would have to adapt JVMState by -1. 3387 if (i == mach_constant_base_node_input()) { 3388 call->add_req(loadConLNodes_IC._last); 3389 } else { 3390 call->add_req(in(i)); 3391 } 3392 } 3393 // ...as well as prec 3394 for (uint i = req(); i < len(); ++i) { 3395 call->add_prec(in(i)); 3396 } 3397 3398 // Remember nodes loading the inline cache into r19. 3399 call->_load_ic_hi_node = loadConLNodes_IC._large_hi; 3400 call->_load_ic_node = loadConLNodes_IC._small; 3401 3402 // Operands for new nodes. 3403 call->_opnds[0] = _opnds[0]; 3404 call->_opnds[1] = _opnds[1]; 3405 3406 // Only the inline cache is associated with a register. 3407 assert(Matcher::inline_cache_reg() == OptoReg::Name(R19_num), "ic reg should be R19"); 3408 3409 // Push new nodes. 3410 if (loadConLNodes_IC._large_hi) nodes->push(loadConLNodes_IC._large_hi); 3411 if (loadConLNodes_IC._last) nodes->push(loadConLNodes_IC._last); 3412 nodes->push(call); 3413 %} 3414 3415 // Compound version of call dynamic 3416 // Toc is only passed so that it can be used in ins_encode statement. 3417 // In the code we have to use $constanttablebase. 3418 enc_class enc_java_dynamic_call(method meth, iRegLdst toc) %{ 3419 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3420 MacroAssembler _masm(&cbuf); 3421 int start_offset = __ offset(); 3422 3423 Register Rtoc = (ra_) ? $constanttablebase : R2_TOC; 3424#if 0 3425 int vtable_index = this->_vtable_index; 3426 if (_vtable_index < 0) { 3427 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 3428 assert(_vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 3429 Register ic_reg = as_Register(Matcher::inline_cache_reg_encode()); 3430 3431 // Virtual call relocation will point to ic load. 3432 address virtual_call_meta_addr = __ pc(); 3433 // Load a clear inline cache. 3434 AddressLiteral empty_ic((address) Universe::non_oop_word()); 3435 bool success = __ load_const_from_method_toc(ic_reg, empty_ic, Rtoc, /*fixed_size*/ true); 3436 if (!success) { 3437 ciEnv::current()->record_out_of_memory_failure(); 3438 return; 3439 } 3440 // CALL to fixup routine. Fixup routine uses ScopeDesc info 3441 // to determine who we intended to call. 3442 __ relocate(virtual_call_Relocation::spec(virtual_call_meta_addr)); 3443 emit_call_with_trampoline_stub(_masm, (address)$meth$$method, relocInfo::none); 3444 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3445 "Fix constant in ret_addr_offset()"); 3446 } else { 3447 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 3448 // Go thru the vtable. Get receiver klass. Receiver already 3449 // checked for non-null. If we'll go thru a C2I adapter, the 3450 // interpreter expects method in R19_method. 3451 3452 __ load_klass(R11_scratch1, R3); 3453 3454 int entry_offset = in_bytes(Klass::vtable_start_offset()) + _vtable_index * vtableEntry::size_in_bytes(); 3455 int v_off = entry_offset + vtableEntry::method_offset_in_bytes(); 3456 __ li(R19_method, v_off); 3457 __ ldx(R19_method/*method oop*/, R19_method/*method offset*/, R11_scratch1/*class*/); 3458 // NOTE: for vtable dispatches, the vtable entry will never be 3459 // null. However it may very well end up in handle_wrong_method 3460 // if the method is abstract for the particular class. 3461 __ ld(R11_scratch1, in_bytes(Method::from_compiled_offset()), R19_method); 3462 // Call target. Either compiled code or C2I adapter. 3463 __ mtctr(R11_scratch1); 3464 __ bctrl(); 3465 if (((MachCallDynamicJavaNode*)this)->ret_addr_offset() != __ offset() - start_offset) { 3466 tty->print(" %d, %d\n", ((MachCallDynamicJavaNode*)this)->ret_addr_offset(),__ offset() - start_offset); 3467 } 3468 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3469 "Fix constant in ret_addr_offset()"); 3470 } 3471#endif 3472 Unimplemented(); // ret_addr_offset not yet fixed. Depends on compressed oops (load klass!). 3473 %} 3474 3475 // a runtime call 3476 enc_class enc_java_to_runtime_call (method meth) %{ 3477 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3478 3479 MacroAssembler _masm(&cbuf); 3480 const address start_pc = __ pc(); 3481 3482#if defined(ABI_ELFv2) 3483 address entry= !($meth$$method) ? NULL : (address)$meth$$method; 3484 __ call_c(entry, relocInfo::runtime_call_type); 3485#else 3486 // The function we're going to call. 3487 FunctionDescriptor fdtemp; 3488 const FunctionDescriptor* fd = !($meth$$method) ? &fdtemp : (FunctionDescriptor*)$meth$$method; 3489 3490 Register Rtoc = R12_scratch2; 3491 // Calculate the method's TOC. 3492 __ calculate_address_from_global_toc(Rtoc, __ method_toc()); 3493 // Put entry, env, toc into the constant pool, this needs up to 3 constant 3494 // pool entries; call_c_using_toc will optimize the call. 3495 bool success = __ call_c_using_toc(fd, relocInfo::runtime_call_type, Rtoc); 3496 if (!success) { 3497 ciEnv::current()->record_out_of_memory_failure(); 3498 return; 3499 } 3500#endif 3501 3502 // Check the ret_addr_offset. 3503 assert(((MachCallRuntimeNode*)this)->ret_addr_offset() == __ last_calls_return_pc() - start_pc, 3504 "Fix constant in ret_addr_offset()"); 3505 %} 3506 3507 // Move to ctr for leaf call. 3508 // This enc_class is needed so that scheduler gets proper 3509 // input mapping for latency computation. 3510 enc_class enc_leaf_call_mtctr(iRegLsrc src) %{ 3511 // TODO: PPC port $archOpcode(ppc64Opcode_mtctr); 3512 MacroAssembler _masm(&cbuf); 3513 __ mtctr($src$$Register); 3514 %} 3515 3516 // Postalloc expand emitter for runtime leaf calls. 3517 enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{ 3518 loadConLNodesTuple loadConLNodes_Entry; 3519#if defined(ABI_ELFv2) 3520 jlong entry_address = (jlong) this->entry_point(); 3521 assert(entry_address, "need address here"); 3522 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3523 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3524#else 3525 // Get the struct that describes the function we are about to call. 3526 FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point(); 3527 assert(fd, "need fd here"); 3528 jlong entry_address = (jlong) fd->entry(); 3529 // new nodes 3530 loadConLNodesTuple loadConLNodes_Env; 3531 loadConLNodesTuple loadConLNodes_Toc; 3532 3533 // Create nodes and operands for loading the entry point. 3534 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3535 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3536 3537 3538 // Create nodes and operands for loading the env pointer. 3539 if (fd->env() != NULL) { 3540 loadConLNodes_Env = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->env()), 3541 OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3542 } else { 3543 loadConLNodes_Env._large_hi = NULL; 3544 loadConLNodes_Env._large_lo = NULL; 3545 loadConLNodes_Env._small = NULL; 3546 loadConLNodes_Env._last = new loadConL16Node(); 3547 loadConLNodes_Env._last->_opnds[0] = new iRegLdstOper(); 3548 loadConLNodes_Env._last->_opnds[1] = new immL16Oper(0); 3549 ra_->set_pair(loadConLNodes_Env._last->_idx, OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3550 } 3551 3552 // Create nodes and operands for loading the Toc point. 3553 loadConLNodes_Toc = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->toc()), 3554 OptoReg::Name(R2_H_num), OptoReg::Name(R2_num)); 3555#endif // ABI_ELFv2 3556 // mtctr node 3557 MachNode *mtctr = new CallLeafDirect_mtctrNode(); 3558 3559 assert(loadConLNodes_Entry._last != NULL, "entry must exist"); 3560 mtctr->add_req(0, loadConLNodes_Entry._last); 3561 3562 mtctr->_opnds[0] = new iRegLdstOper(); 3563 mtctr->_opnds[1] = new iRegLdstOper(); 3564 3565 // call node 3566 MachCallLeafNode *call = new CallLeafDirectNode(); 3567 3568 call->_opnds[0] = _opnds[0]; 3569 call->_opnds[1] = new methodOper((intptr_t) entry_address); // May get set later. 3570 3571 // Make the new call node look like the old one. 3572 call->_name = _name; 3573 call->_tf = _tf; 3574 call->_entry_point = _entry_point; 3575 call->_cnt = _cnt; 3576 call->_argsize = _argsize; 3577 call->_oop_map = _oop_map; 3578 guarantee(!_jvms, "You must clone the jvms and adapt the offsets by fix_jvms()."); 3579 call->_jvms = NULL; 3580 call->_jvmadj = _jvmadj; 3581 call->_in_rms = _in_rms; 3582 call->_nesting = _nesting; 3583 3584 3585 // New call needs all inputs of old call. 3586 // Req... 3587 for (uint i = 0; i < req(); ++i) { 3588 if (i != mach_constant_base_node_input()) { 3589 call->add_req(in(i)); 3590 } 3591 } 3592 3593 // These must be reqired edges, as the registers are live up to 3594 // the call. Else the constants are handled as kills. 3595 call->add_req(mtctr); 3596#if !defined(ABI_ELFv2) 3597 call->add_req(loadConLNodes_Env._last); 3598 call->add_req(loadConLNodes_Toc._last); 3599#endif 3600 3601 // ...as well as prec 3602 for (uint i = req(); i < len(); ++i) { 3603 call->add_prec(in(i)); 3604 } 3605 3606 // registers 3607 ra_->set1(mtctr->_idx, OptoReg::Name(SR_CTR_num)); 3608 3609 // Insert the new nodes. 3610 if (loadConLNodes_Entry._large_hi) nodes->push(loadConLNodes_Entry._large_hi); 3611 if (loadConLNodes_Entry._last) nodes->push(loadConLNodes_Entry._last); 3612#if !defined(ABI_ELFv2) 3613 if (loadConLNodes_Env._large_hi) nodes->push(loadConLNodes_Env._large_hi); 3614 if (loadConLNodes_Env._last) nodes->push(loadConLNodes_Env._last); 3615 if (loadConLNodes_Toc._large_hi) nodes->push(loadConLNodes_Toc._large_hi); 3616 if (loadConLNodes_Toc._last) nodes->push(loadConLNodes_Toc._last); 3617#endif 3618 nodes->push(mtctr); 3619 nodes->push(call); 3620 %} 3621%} 3622 3623//----------FRAME-------------------------------------------------------------- 3624// Definition of frame structure and management information. 3625 3626frame %{ 3627 // What direction does stack grow in (assumed to be same for native & Java). 3628 stack_direction(TOWARDS_LOW); 3629 3630 // These two registers define part of the calling convention between 3631 // compiled code and the interpreter. 3632 3633 // Inline Cache Register or method for I2C. 3634 inline_cache_reg(R19); // R19_method 3635 3636 // Method Oop Register when calling interpreter. 3637 interpreter_method_oop_reg(R19); // R19_method 3638 3639 // Optional: name the operand used by cisc-spilling to access 3640 // [stack_pointer + offset]. 3641 cisc_spilling_operand_name(indOffset); 3642 3643 // Number of stack slots consumed by a Monitor enter. 3644 sync_stack_slots((frame::jit_monitor_size / VMRegImpl::stack_slot_size)); 3645 3646 // Compiled code's Frame Pointer. 3647 frame_pointer(R1); // R1_SP 3648 3649 // Interpreter stores its frame pointer in a register which is 3650 // stored to the stack by I2CAdaptors. I2CAdaptors convert from 3651 // interpreted java to compiled java. 3652 // 3653 // R14_state holds pointer to caller's cInterpreter. 3654 interpreter_frame_pointer(R14); // R14_state 3655 3656 stack_alignment(frame::alignment_in_bytes); 3657 3658 in_preserve_stack_slots((frame::jit_in_preserve_size / VMRegImpl::stack_slot_size)); 3659 3660 // Number of outgoing stack slots killed above the 3661 // out_preserve_stack_slots for calls to C. Supports the var-args 3662 // backing area for register parms. 3663 // 3664 varargs_C_out_slots_killed(((frame::abi_reg_args_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size)); 3665 3666 // The after-PROLOG location of the return address. Location of 3667 // return address specifies a type (REG or STACK) and a number 3668 // representing the register number (i.e. - use a register name) or 3669 // stack slot. 3670 // 3671 // A: Link register is stored in stack slot ... 3672 // M: ... but it's in the caller's frame according to PPC-64 ABI. 3673 // J: Therefore, we make sure that the link register is also in R11_scratch1 3674 // at the end of the prolog. 3675 // B: We use R20, now. 3676 //return_addr(REG R20); 3677 3678 // G: After reading the comments made by all the luminaries on their 3679 // failure to tell the compiler where the return address really is, 3680 // I hardly dare to try myself. However, I'm convinced it's in slot 3681 // 4 what apparently works and saves us some spills. 3682 return_addr(STACK 4); 3683 3684 // This is the body of the function 3685 // 3686 // void Matcher::calling_convention(OptoRegPair* sig, // array of ideal regs 3687 // uint length, // length of array 3688 // bool is_outgoing) 3689 // 3690 // The `sig' array is to be updated. sig[j] represents the location 3691 // of the j-th argument, either a register or a stack slot. 3692 3693 // Comment taken from i486.ad: 3694 // Body of function which returns an integer array locating 3695 // arguments either in registers or in stack slots. Passed an array 3696 // of ideal registers called "sig" and a "length" count. Stack-slot 3697 // offsets are based on outgoing arguments, i.e. a CALLER setting up 3698 // arguments for a CALLEE. Incoming stack arguments are 3699 // automatically biased by the preserve_stack_slots field above. 3700 calling_convention %{ 3701 // No difference between ingoing/outgoing. Just pass false. 3702 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 3703 %} 3704 3705 // Comment taken from i486.ad: 3706 // Body of function which returns an integer array locating 3707 // arguments either in registers or in stack slots. Passed an array 3708 // of ideal registers called "sig" and a "length" count. Stack-slot 3709 // offsets are based on outgoing arguments, i.e. a CALLER setting up 3710 // arguments for a CALLEE. Incoming stack arguments are 3711 // automatically biased by the preserve_stack_slots field above. 3712 c_calling_convention %{ 3713 // This is obviously always outgoing. 3714 // C argument in register AND stack slot. 3715 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 3716 %} 3717 3718 // Location of native (C/C++) and interpreter return values. This 3719 // is specified to be the same as Java. In the 32-bit VM, long 3720 // values are actually returned from native calls in O0:O1 and 3721 // returned to the interpreter in I0:I1. The copying to and from 3722 // the register pairs is done by the appropriate call and epilog 3723 // opcodes. This simplifies the register allocator. 3724 c_return_value %{ 3725 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 3726 (ideal_reg == Op_RegN && Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0), 3727 "only return normal values"); 3728 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 3729 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 3730 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 3731 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 3732 %} 3733 3734 // Location of compiled Java return values. Same as C 3735 return_value %{ 3736 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 3737 (ideal_reg == Op_RegN && Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0), 3738 "only return normal values"); 3739 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 3740 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 3741 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 3742 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 3743 %} 3744%} 3745 3746 3747//----------ATTRIBUTES--------------------------------------------------------- 3748 3749//----------Operand Attributes------------------------------------------------- 3750op_attrib op_cost(1); // Required cost attribute. 3751 3752//----------Instruction Attributes--------------------------------------------- 3753 3754// Cost attribute. required. 3755ins_attrib ins_cost(DEFAULT_COST); 3756 3757// Is this instruction a non-matching short branch variant of some 3758// long branch? Not required. 3759ins_attrib ins_short_branch(0); 3760 3761ins_attrib ins_is_TrapBasedCheckNode(true); 3762 3763// Number of constants. 3764// This instruction uses the given number of constants 3765// (optional attribute). 3766// This is needed to determine in time whether the constant pool will 3767// exceed 4000 entries. Before postalloc_expand the overall number of constants 3768// is determined. It's also used to compute the constant pool size 3769// in Output(). 3770ins_attrib ins_num_consts(0); 3771 3772// Required alignment attribute (must be a power of 2) specifies the 3773// alignment that some part of the instruction (not necessarily the 3774// start) requires. If > 1, a compute_padding() function must be 3775// provided for the instruction. 3776ins_attrib ins_alignment(1); 3777 3778// Enforce/prohibit rematerializations. 3779// - If an instruction is attributed with 'ins_cannot_rematerialize(true)' 3780// then rematerialization of that instruction is prohibited and the 3781// instruction's value will be spilled if necessary. 3782// Causes that MachNode::rematerialize() returns false. 3783// - If an instruction is attributed with 'ins_should_rematerialize(true)' 3784// then rematerialization should be enforced and a copy of the instruction 3785// should be inserted if possible; rematerialization is not guaranteed. 3786// Note: this may result in rematerializations in front of every use. 3787// Causes that MachNode::rematerialize() can return true. 3788// (optional attribute) 3789ins_attrib ins_cannot_rematerialize(false); 3790ins_attrib ins_should_rematerialize(false); 3791 3792// Instruction has variable size depending on alignment. 3793ins_attrib ins_variable_size_depending_on_alignment(false); 3794 3795// Instruction is a nop. 3796ins_attrib ins_is_nop(false); 3797 3798// Instruction is mapped to a MachIfFastLock node (instead of MachFastLock). 3799ins_attrib ins_use_mach_if_fast_lock_node(false); 3800 3801// Field for the toc offset of a constant. 3802// 3803// This is needed if the toc offset is not encodable as an immediate in 3804// the PPC load instruction. If so, the upper (hi) bits of the offset are 3805// added to the toc, and from this a load with immediate is performed. 3806// With postalloc expand, we get two nodes that require the same offset 3807// but which don't know about each other. The offset is only known 3808// when the constant is added to the constant pool during emitting. 3809// It is generated in the 'hi'-node adding the upper bits, and saved 3810// in this node. The 'lo'-node has a link to the 'hi'-node and reads 3811// the offset from there when it gets encoded. 3812ins_attrib ins_field_const_toc_offset(0); 3813ins_attrib ins_field_const_toc_offset_hi_node(0); 3814 3815// A field that can hold the instructions offset in the code buffer. 3816// Set in the nodes emitter. 3817ins_attrib ins_field_cbuf_insts_offset(-1); 3818 3819// Fields for referencing a call's load-IC-node. 3820// If the toc offset can not be encoded as an immediate in a load, we 3821// use two nodes. 3822ins_attrib ins_field_load_ic_hi_node(0); 3823ins_attrib ins_field_load_ic_node(0); 3824 3825//----------OPERANDS----------------------------------------------------------- 3826// Operand definitions must precede instruction definitions for correct 3827// parsing in the ADLC because operands constitute user defined types 3828// which are used in instruction definitions. 3829// 3830// Formats are generated automatically for constants and base registers. 3831 3832//----------Simple Operands---------------------------------------------------- 3833// Immediate Operands 3834 3835// Integer Immediate: 32-bit 3836operand immI() %{ 3837 match(ConI); 3838 op_cost(40); 3839 format %{ %} 3840 interface(CONST_INTER); 3841%} 3842 3843operand immI8() %{ 3844 predicate(Assembler::is_simm(n->get_int(), 8)); 3845 op_cost(0); 3846 match(ConI); 3847 format %{ %} 3848 interface(CONST_INTER); 3849%} 3850 3851// Integer Immediate: 16-bit 3852operand immI16() %{ 3853 predicate(Assembler::is_simm(n->get_int(), 16)); 3854 op_cost(0); 3855 match(ConI); 3856 format %{ %} 3857 interface(CONST_INTER); 3858%} 3859 3860// Integer Immediate: 32-bit, where lowest 16 bits are 0x0000. 3861operand immIhi16() %{ 3862 predicate(((n->get_int() & 0xffff0000) != 0) && ((n->get_int() & 0xffff) == 0)); 3863 match(ConI); 3864 op_cost(0); 3865 format %{ %} 3866 interface(CONST_INTER); 3867%} 3868 3869operand immInegpow2() %{ 3870 predicate(is_power_of_2_long((jlong) (julong) (juint) (-(n->get_int())))); 3871 match(ConI); 3872 op_cost(0); 3873 format %{ %} 3874 interface(CONST_INTER); 3875%} 3876 3877operand immIpow2minus1() %{ 3878 predicate(is_power_of_2_long((((jlong) (n->get_int()))+1))); 3879 match(ConI); 3880 op_cost(0); 3881 format %{ %} 3882 interface(CONST_INTER); 3883%} 3884 3885operand immIpowerOf2() %{ 3886 predicate(is_power_of_2_long((((jlong) (julong) (juint) (n->get_int()))))); 3887 match(ConI); 3888 op_cost(0); 3889 format %{ %} 3890 interface(CONST_INTER); 3891%} 3892 3893// Unsigned Integer Immediate: the values 0-31 3894operand uimmI5() %{ 3895 predicate(Assembler::is_uimm(n->get_int(), 5)); 3896 match(ConI); 3897 op_cost(0); 3898 format %{ %} 3899 interface(CONST_INTER); 3900%} 3901 3902// Unsigned Integer Immediate: 6-bit 3903operand uimmI6() %{ 3904 predicate(Assembler::is_uimm(n->get_int(), 6)); 3905 match(ConI); 3906 op_cost(0); 3907 format %{ %} 3908 interface(CONST_INTER); 3909%} 3910 3911// Unsigned Integer Immediate: 6-bit int, greater than 32 3912operand uimmI6_ge32() %{ 3913 predicate(Assembler::is_uimm(n->get_int(), 6) && n->get_int() >= 32); 3914 match(ConI); 3915 op_cost(0); 3916 format %{ %} 3917 interface(CONST_INTER); 3918%} 3919 3920// Unsigned Integer Immediate: 15-bit 3921operand uimmI15() %{ 3922 predicate(Assembler::is_uimm(n->get_int(), 15)); 3923 match(ConI); 3924 op_cost(0); 3925 format %{ %} 3926 interface(CONST_INTER); 3927%} 3928 3929// Unsigned Integer Immediate: 16-bit 3930operand uimmI16() %{ 3931 predicate(Assembler::is_uimm(n->get_int(), 16)); 3932 match(ConI); 3933 op_cost(0); 3934 format %{ %} 3935 interface(CONST_INTER); 3936%} 3937 3938// constant 'int 0'. 3939operand immI_0() %{ 3940 predicate(n->get_int() == 0); 3941 match(ConI); 3942 op_cost(0); 3943 format %{ %} 3944 interface(CONST_INTER); 3945%} 3946 3947// constant 'int 1'. 3948operand immI_1() %{ 3949 predicate(n->get_int() == 1); 3950 match(ConI); 3951 op_cost(0); 3952 format %{ %} 3953 interface(CONST_INTER); 3954%} 3955 3956// constant 'int -1'. 3957operand immI_minus1() %{ 3958 predicate(n->get_int() == -1); 3959 match(ConI); 3960 op_cost(0); 3961 format %{ %} 3962 interface(CONST_INTER); 3963%} 3964 3965// int value 16. 3966operand immI_16() %{ 3967 predicate(n->get_int() == 16); 3968 match(ConI); 3969 op_cost(0); 3970 format %{ %} 3971 interface(CONST_INTER); 3972%} 3973 3974// int value 24. 3975operand immI_24() %{ 3976 predicate(n->get_int() == 24); 3977 match(ConI); 3978 op_cost(0); 3979 format %{ %} 3980 interface(CONST_INTER); 3981%} 3982 3983// Compressed oops constants 3984// Pointer Immediate 3985operand immN() %{ 3986 match(ConN); 3987 3988 op_cost(10); 3989 format %{ %} 3990 interface(CONST_INTER); 3991%} 3992 3993// NULL Pointer Immediate 3994operand immN_0() %{ 3995 predicate(n->get_narrowcon() == 0); 3996 match(ConN); 3997 3998 op_cost(0); 3999 format %{ %} 4000 interface(CONST_INTER); 4001%} 4002 4003// Compressed klass constants 4004operand immNKlass() %{ 4005 match(ConNKlass); 4006 4007 op_cost(0); 4008 format %{ %} 4009 interface(CONST_INTER); 4010%} 4011 4012// This operand can be used to avoid matching of an instruct 4013// with chain rule. 4014operand immNKlass_NM() %{ 4015 match(ConNKlass); 4016 predicate(false); 4017 op_cost(0); 4018 format %{ %} 4019 interface(CONST_INTER); 4020%} 4021 4022// Pointer Immediate: 64-bit 4023operand immP() %{ 4024 match(ConP); 4025 op_cost(0); 4026 format %{ %} 4027 interface(CONST_INTER); 4028%} 4029 4030// Operand to avoid match of loadConP. 4031// This operand can be used to avoid matching of an instruct 4032// with chain rule. 4033operand immP_NM() %{ 4034 match(ConP); 4035 predicate(false); 4036 op_cost(0); 4037 format %{ %} 4038 interface(CONST_INTER); 4039%} 4040 4041// costant 'pointer 0'. 4042operand immP_0() %{ 4043 predicate(n->get_ptr() == 0); 4044 match(ConP); 4045 op_cost(0); 4046 format %{ %} 4047 interface(CONST_INTER); 4048%} 4049 4050// pointer 0x0 or 0x1 4051operand immP_0or1() %{ 4052 predicate((n->get_ptr() == 0) || (n->get_ptr() == 1)); 4053 match(ConP); 4054 op_cost(0); 4055 format %{ %} 4056 interface(CONST_INTER); 4057%} 4058 4059operand immL() %{ 4060 match(ConL); 4061 op_cost(40); 4062 format %{ %} 4063 interface(CONST_INTER); 4064%} 4065 4066operand immLmax30() %{ 4067 predicate((n->get_long() <= 30)); 4068 match(ConL); 4069 op_cost(0); 4070 format %{ %} 4071 interface(CONST_INTER); 4072%} 4073 4074// Long Immediate: 16-bit 4075operand immL16() %{ 4076 predicate(Assembler::is_simm(n->get_long(), 16)); 4077 match(ConL); 4078 op_cost(0); 4079 format %{ %} 4080 interface(CONST_INTER); 4081%} 4082 4083// Long Immediate: 16-bit, 4-aligned 4084operand immL16Alg4() %{ 4085 predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0x3) == 0)); 4086 match(ConL); 4087 op_cost(0); 4088 format %{ %} 4089 interface(CONST_INTER); 4090%} 4091 4092// Long Immediate: 32-bit, where lowest 16 bits are 0x0000. 4093operand immL32hi16() %{ 4094 predicate(Assembler::is_simm(n->get_long(), 32) && ((n->get_long() & 0xffffL) == 0L)); 4095 match(ConL); 4096 op_cost(0); 4097 format %{ %} 4098 interface(CONST_INTER); 4099%} 4100 4101// Long Immediate: 32-bit 4102operand immL32() %{ 4103 predicate(Assembler::is_simm(n->get_long(), 32)); 4104 match(ConL); 4105 op_cost(0); 4106 format %{ %} 4107 interface(CONST_INTER); 4108%} 4109 4110// Long Immediate: 64-bit, where highest 16 bits are not 0x0000. 4111operand immLhighest16() %{ 4112 predicate((n->get_long() & 0xffff000000000000L) != 0L && (n->get_long() & 0x0000ffffffffffffL) == 0L); 4113 match(ConL); 4114 op_cost(0); 4115 format %{ %} 4116 interface(CONST_INTER); 4117%} 4118 4119operand immLnegpow2() %{ 4120 predicate(is_power_of_2_long((jlong)-(n->get_long()))); 4121 match(ConL); 4122 op_cost(0); 4123 format %{ %} 4124 interface(CONST_INTER); 4125%} 4126 4127operand immLpow2minus1() %{ 4128 predicate(is_power_of_2_long((((jlong) (n->get_long()))+1)) && 4129 (n->get_long() != (jlong)0xffffffffffffffffL)); 4130 match(ConL); 4131 op_cost(0); 4132 format %{ %} 4133 interface(CONST_INTER); 4134%} 4135 4136// constant 'long 0'. 4137operand immL_0() %{ 4138 predicate(n->get_long() == 0L); 4139 match(ConL); 4140 op_cost(0); 4141 format %{ %} 4142 interface(CONST_INTER); 4143%} 4144 4145// constat ' long -1'. 4146operand immL_minus1() %{ 4147 predicate(n->get_long() == -1L); 4148 match(ConL); 4149 op_cost(0); 4150 format %{ %} 4151 interface(CONST_INTER); 4152%} 4153 4154// Long Immediate: low 32-bit mask 4155operand immL_32bits() %{ 4156 predicate(n->get_long() == 0xFFFFFFFFL); 4157 match(ConL); 4158 op_cost(0); 4159 format %{ %} 4160 interface(CONST_INTER); 4161%} 4162 4163// Unsigned Long Immediate: 16-bit 4164operand uimmL16() %{ 4165 predicate(Assembler::is_uimm(n->get_long(), 16)); 4166 match(ConL); 4167 op_cost(0); 4168 format %{ %} 4169 interface(CONST_INTER); 4170%} 4171 4172// Float Immediate 4173operand immF() %{ 4174 match(ConF); 4175 op_cost(40); 4176 format %{ %} 4177 interface(CONST_INTER); 4178%} 4179 4180// Float Immediate: +0.0f. 4181operand immF_0() %{ 4182 predicate(jint_cast(n->getf()) == 0); 4183 match(ConF); 4184 4185 op_cost(0); 4186 format %{ %} 4187 interface(CONST_INTER); 4188%} 4189 4190// Double Immediate 4191operand immD() %{ 4192 match(ConD); 4193 op_cost(40); 4194 format %{ %} 4195 interface(CONST_INTER); 4196%} 4197 4198// Integer Register Operands 4199// Integer Destination Register 4200// See definition of reg_class bits32_reg_rw. 4201operand iRegIdst() %{ 4202 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4203 match(RegI); 4204 match(rscratch1RegI); 4205 match(rscratch2RegI); 4206 match(rarg1RegI); 4207 match(rarg2RegI); 4208 match(rarg3RegI); 4209 match(rarg4RegI); 4210 format %{ %} 4211 interface(REG_INTER); 4212%} 4213 4214// Integer Source Register 4215// See definition of reg_class bits32_reg_ro. 4216operand iRegIsrc() %{ 4217 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4218 match(RegI); 4219 match(rscratch1RegI); 4220 match(rscratch2RegI); 4221 match(rarg1RegI); 4222 match(rarg2RegI); 4223 match(rarg3RegI); 4224 match(rarg4RegI); 4225 format %{ %} 4226 interface(REG_INTER); 4227%} 4228 4229operand rscratch1RegI() %{ 4230 constraint(ALLOC_IN_RC(rscratch1_bits32_reg)); 4231 match(iRegIdst); 4232 format %{ %} 4233 interface(REG_INTER); 4234%} 4235 4236operand rscratch2RegI() %{ 4237 constraint(ALLOC_IN_RC(rscratch2_bits32_reg)); 4238 match(iRegIdst); 4239 format %{ %} 4240 interface(REG_INTER); 4241%} 4242 4243operand rarg1RegI() %{ 4244 constraint(ALLOC_IN_RC(rarg1_bits32_reg)); 4245 match(iRegIdst); 4246 format %{ %} 4247 interface(REG_INTER); 4248%} 4249 4250operand rarg2RegI() %{ 4251 constraint(ALLOC_IN_RC(rarg2_bits32_reg)); 4252 match(iRegIdst); 4253 format %{ %} 4254 interface(REG_INTER); 4255%} 4256 4257operand rarg3RegI() %{ 4258 constraint(ALLOC_IN_RC(rarg3_bits32_reg)); 4259 match(iRegIdst); 4260 format %{ %} 4261 interface(REG_INTER); 4262%} 4263 4264operand rarg4RegI() %{ 4265 constraint(ALLOC_IN_RC(rarg4_bits32_reg)); 4266 match(iRegIdst); 4267 format %{ %} 4268 interface(REG_INTER); 4269%} 4270 4271operand rarg1RegL() %{ 4272 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4273 match(iRegLdst); 4274 format %{ %} 4275 interface(REG_INTER); 4276%} 4277 4278operand rarg2RegL() %{ 4279 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4280 match(iRegLdst); 4281 format %{ %} 4282 interface(REG_INTER); 4283%} 4284 4285operand rarg3RegL() %{ 4286 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4287 match(iRegLdst); 4288 format %{ %} 4289 interface(REG_INTER); 4290%} 4291 4292operand rarg4RegL() %{ 4293 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4294 match(iRegLdst); 4295 format %{ %} 4296 interface(REG_INTER); 4297%} 4298 4299// Pointer Destination Register 4300// See definition of reg_class bits64_reg_rw. 4301operand iRegPdst() %{ 4302 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4303 match(RegP); 4304 match(rscratch1RegP); 4305 match(rscratch2RegP); 4306 match(rarg1RegP); 4307 match(rarg2RegP); 4308 match(rarg3RegP); 4309 match(rarg4RegP); 4310 format %{ %} 4311 interface(REG_INTER); 4312%} 4313 4314// Pointer Destination Register 4315// Operand not using r11 and r12 (killed in epilog). 4316operand iRegPdstNoScratch() %{ 4317 constraint(ALLOC_IN_RC(bits64_reg_leaf_call)); 4318 match(RegP); 4319 match(rarg1RegP); 4320 match(rarg2RegP); 4321 match(rarg3RegP); 4322 match(rarg4RegP); 4323 format %{ %} 4324 interface(REG_INTER); 4325%} 4326 4327// Pointer Source Register 4328// See definition of reg_class bits64_reg_ro. 4329operand iRegPsrc() %{ 4330 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4331 match(RegP); 4332 match(iRegPdst); 4333 match(rscratch1RegP); 4334 match(rscratch2RegP); 4335 match(rarg1RegP); 4336 match(rarg2RegP); 4337 match(rarg3RegP); 4338 match(rarg4RegP); 4339 match(threadRegP); 4340 format %{ %} 4341 interface(REG_INTER); 4342%} 4343 4344// Thread operand. 4345operand threadRegP() %{ 4346 constraint(ALLOC_IN_RC(thread_bits64_reg)); 4347 match(iRegPdst); 4348 format %{ "R16" %} 4349 interface(REG_INTER); 4350%} 4351 4352operand rscratch1RegP() %{ 4353 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4354 match(iRegPdst); 4355 format %{ "R11" %} 4356 interface(REG_INTER); 4357%} 4358 4359operand rscratch2RegP() %{ 4360 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4361 match(iRegPdst); 4362 format %{ %} 4363 interface(REG_INTER); 4364%} 4365 4366operand rarg1RegP() %{ 4367 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4368 match(iRegPdst); 4369 format %{ %} 4370 interface(REG_INTER); 4371%} 4372 4373operand rarg2RegP() %{ 4374 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4375 match(iRegPdst); 4376 format %{ %} 4377 interface(REG_INTER); 4378%} 4379 4380operand rarg3RegP() %{ 4381 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4382 match(iRegPdst); 4383 format %{ %} 4384 interface(REG_INTER); 4385%} 4386 4387operand rarg4RegP() %{ 4388 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4389 match(iRegPdst); 4390 format %{ %} 4391 interface(REG_INTER); 4392%} 4393 4394operand iRegNsrc() %{ 4395 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4396 match(RegN); 4397 match(iRegNdst); 4398 4399 format %{ %} 4400 interface(REG_INTER); 4401%} 4402 4403operand iRegNdst() %{ 4404 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4405 match(RegN); 4406 4407 format %{ %} 4408 interface(REG_INTER); 4409%} 4410 4411// Long Destination Register 4412// See definition of reg_class bits64_reg_rw. 4413operand iRegLdst() %{ 4414 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4415 match(RegL); 4416 match(rscratch1RegL); 4417 match(rscratch2RegL); 4418 format %{ %} 4419 interface(REG_INTER); 4420%} 4421 4422// Long Source Register 4423// See definition of reg_class bits64_reg_ro. 4424operand iRegLsrc() %{ 4425 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4426 match(RegL); 4427 match(iRegLdst); 4428 match(rscratch1RegL); 4429 match(rscratch2RegL); 4430 format %{ %} 4431 interface(REG_INTER); 4432%} 4433 4434// Special operand for ConvL2I. 4435operand iRegL2Isrc(iRegLsrc reg) %{ 4436 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4437 match(ConvL2I reg); 4438 format %{ "ConvL2I($reg)" %} 4439 interface(REG_INTER) 4440%} 4441 4442operand rscratch1RegL() %{ 4443 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4444 match(RegL); 4445 format %{ %} 4446 interface(REG_INTER); 4447%} 4448 4449operand rscratch2RegL() %{ 4450 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4451 match(RegL); 4452 format %{ %} 4453 interface(REG_INTER); 4454%} 4455 4456// Condition Code Flag Registers 4457operand flagsReg() %{ 4458 constraint(ALLOC_IN_RC(int_flags)); 4459 match(RegFlags); 4460 format %{ %} 4461 interface(REG_INTER); 4462%} 4463 4464operand flagsRegSrc() %{ 4465 constraint(ALLOC_IN_RC(int_flags_ro)); 4466 match(RegFlags); 4467 match(flagsReg); 4468 match(flagsRegCR0); 4469 format %{ %} 4470 interface(REG_INTER); 4471%} 4472 4473// Condition Code Flag Register CR0 4474operand flagsRegCR0() %{ 4475 constraint(ALLOC_IN_RC(int_flags_CR0)); 4476 match(RegFlags); 4477 format %{ "CR0" %} 4478 interface(REG_INTER); 4479%} 4480 4481operand flagsRegCR1() %{ 4482 constraint(ALLOC_IN_RC(int_flags_CR1)); 4483 match(RegFlags); 4484 format %{ "CR1" %} 4485 interface(REG_INTER); 4486%} 4487 4488operand flagsRegCR6() %{ 4489 constraint(ALLOC_IN_RC(int_flags_CR6)); 4490 match(RegFlags); 4491 format %{ "CR6" %} 4492 interface(REG_INTER); 4493%} 4494 4495operand regCTR() %{ 4496 constraint(ALLOC_IN_RC(ctr_reg)); 4497 // RegFlags should work. Introducing a RegSpecial type would cause a 4498 // lot of changes. 4499 match(RegFlags); 4500 format %{"SR_CTR" %} 4501 interface(REG_INTER); 4502%} 4503 4504operand regD() %{ 4505 constraint(ALLOC_IN_RC(dbl_reg)); 4506 match(RegD); 4507 format %{ %} 4508 interface(REG_INTER); 4509%} 4510 4511operand regF() %{ 4512 constraint(ALLOC_IN_RC(flt_reg)); 4513 match(RegF); 4514 format %{ %} 4515 interface(REG_INTER); 4516%} 4517 4518// Special Registers 4519 4520// Method Register 4521operand inline_cache_regP(iRegPdst reg) %{ 4522 constraint(ALLOC_IN_RC(r19_bits64_reg)); // inline_cache_reg 4523 match(reg); 4524 format %{ %} 4525 interface(REG_INTER); 4526%} 4527 4528operand compiler_method_oop_regP(iRegPdst reg) %{ 4529 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); // compiler_method_oop_reg 4530 match(reg); 4531 format %{ %} 4532 interface(REG_INTER); 4533%} 4534 4535operand interpreter_method_oop_regP(iRegPdst reg) %{ 4536 constraint(ALLOC_IN_RC(r19_bits64_reg)); // interpreter_method_oop_reg 4537 match(reg); 4538 format %{ %} 4539 interface(REG_INTER); 4540%} 4541 4542// Operands to remove register moves in unscaled mode. 4543// Match read/write registers with an EncodeP node if neither shift nor add are required. 4544operand iRegP2N(iRegPsrc reg) %{ 4545 predicate(false /* TODO: PPC port MatchDecodeNodes*/&& Universe::narrow_oop_shift() == 0); 4546 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4547 match(EncodeP reg); 4548 format %{ "$reg" %} 4549 interface(REG_INTER) 4550%} 4551 4552operand iRegN2P(iRegNsrc reg) %{ 4553 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4554 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4555 match(DecodeN reg); 4556 format %{ "$reg" %} 4557 interface(REG_INTER) 4558%} 4559 4560operand iRegN2P_klass(iRegNsrc reg) %{ 4561 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 4562 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4563 match(DecodeNKlass reg); 4564 format %{ "$reg" %} 4565 interface(REG_INTER) 4566%} 4567 4568//----------Complex Operands--------------------------------------------------- 4569// Indirect Memory Reference 4570operand indirect(iRegPsrc reg) %{ 4571 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4572 match(reg); 4573 op_cost(100); 4574 format %{ "[$reg]" %} 4575 interface(MEMORY_INTER) %{ 4576 base($reg); 4577 index(0x0); 4578 scale(0x0); 4579 disp(0x0); 4580 %} 4581%} 4582 4583// Indirect with Offset 4584operand indOffset16(iRegPsrc reg, immL16 offset) %{ 4585 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4586 match(AddP reg offset); 4587 op_cost(100); 4588 format %{ "[$reg + $offset]" %} 4589 interface(MEMORY_INTER) %{ 4590 base($reg); 4591 index(0x0); 4592 scale(0x0); 4593 disp($offset); 4594 %} 4595%} 4596 4597// Indirect with 4-aligned Offset 4598operand indOffset16Alg4(iRegPsrc reg, immL16Alg4 offset) %{ 4599 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4600 match(AddP reg offset); 4601 op_cost(100); 4602 format %{ "[$reg + $offset]" %} 4603 interface(MEMORY_INTER) %{ 4604 base($reg); 4605 index(0x0); 4606 scale(0x0); 4607 disp($offset); 4608 %} 4609%} 4610 4611//----------Complex Operands for Compressed OOPs------------------------------- 4612// Compressed OOPs with narrow_oop_shift == 0. 4613 4614// Indirect Memory Reference, compressed OOP 4615operand indirectNarrow(iRegNsrc reg) %{ 4616 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4617 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4618 match(DecodeN reg); 4619 op_cost(100); 4620 format %{ "[$reg]" %} 4621 interface(MEMORY_INTER) %{ 4622 base($reg); 4623 index(0x0); 4624 scale(0x0); 4625 disp(0x0); 4626 %} 4627%} 4628 4629operand indirectNarrow_klass(iRegNsrc reg) %{ 4630 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 4631 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4632 match(DecodeNKlass reg); 4633 op_cost(100); 4634 format %{ "[$reg]" %} 4635 interface(MEMORY_INTER) %{ 4636 base($reg); 4637 index(0x0); 4638 scale(0x0); 4639 disp(0x0); 4640 %} 4641%} 4642 4643// Indirect with Offset, compressed OOP 4644operand indOffset16Narrow(iRegNsrc reg, immL16 offset) %{ 4645 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4646 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4647 match(AddP (DecodeN reg) offset); 4648 op_cost(100); 4649 format %{ "[$reg + $offset]" %} 4650 interface(MEMORY_INTER) %{ 4651 base($reg); 4652 index(0x0); 4653 scale(0x0); 4654 disp($offset); 4655 %} 4656%} 4657 4658operand indOffset16Narrow_klass(iRegNsrc reg, immL16 offset) %{ 4659 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 4660 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4661 match(AddP (DecodeNKlass reg) offset); 4662 op_cost(100); 4663 format %{ "[$reg + $offset]" %} 4664 interface(MEMORY_INTER) %{ 4665 base($reg); 4666 index(0x0); 4667 scale(0x0); 4668 disp($offset); 4669 %} 4670%} 4671 4672// Indirect with 4-aligned Offset, compressed OOP 4673operand indOffset16NarrowAlg4(iRegNsrc reg, immL16Alg4 offset) %{ 4674 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4675 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4676 match(AddP (DecodeN reg) offset); 4677 op_cost(100); 4678 format %{ "[$reg + $offset]" %} 4679 interface(MEMORY_INTER) %{ 4680 base($reg); 4681 index(0x0); 4682 scale(0x0); 4683 disp($offset); 4684 %} 4685%} 4686 4687operand indOffset16NarrowAlg4_klass(iRegNsrc reg, immL16Alg4 offset) %{ 4688 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 4689 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4690 match(AddP (DecodeNKlass reg) offset); 4691 op_cost(100); 4692 format %{ "[$reg + $offset]" %} 4693 interface(MEMORY_INTER) %{ 4694 base($reg); 4695 index(0x0); 4696 scale(0x0); 4697 disp($offset); 4698 %} 4699%} 4700 4701//----------Special Memory Operands-------------------------------------------- 4702// Stack Slot Operand 4703// 4704// This operand is used for loading and storing temporary values on 4705// the stack where a match requires a value to flow through memory. 4706operand stackSlotI(sRegI reg) %{ 4707 constraint(ALLOC_IN_RC(stack_slots)); 4708 op_cost(100); 4709 //match(RegI); 4710 format %{ "[sp+$reg]" %} 4711 interface(MEMORY_INTER) %{ 4712 base(0x1); // R1_SP 4713 index(0x0); 4714 scale(0x0); 4715 disp($reg); // Stack Offset 4716 %} 4717%} 4718 4719operand stackSlotL(sRegL reg) %{ 4720 constraint(ALLOC_IN_RC(stack_slots)); 4721 op_cost(100); 4722 //match(RegL); 4723 format %{ "[sp+$reg]" %} 4724 interface(MEMORY_INTER) %{ 4725 base(0x1); // R1_SP 4726 index(0x0); 4727 scale(0x0); 4728 disp($reg); // Stack Offset 4729 %} 4730%} 4731 4732operand stackSlotP(sRegP reg) %{ 4733 constraint(ALLOC_IN_RC(stack_slots)); 4734 op_cost(100); 4735 //match(RegP); 4736 format %{ "[sp+$reg]" %} 4737 interface(MEMORY_INTER) %{ 4738 base(0x1); // R1_SP 4739 index(0x0); 4740 scale(0x0); 4741 disp($reg); // Stack Offset 4742 %} 4743%} 4744 4745operand stackSlotF(sRegF reg) %{ 4746 constraint(ALLOC_IN_RC(stack_slots)); 4747 op_cost(100); 4748 //match(RegF); 4749 format %{ "[sp+$reg]" %} 4750 interface(MEMORY_INTER) %{ 4751 base(0x1); // R1_SP 4752 index(0x0); 4753 scale(0x0); 4754 disp($reg); // Stack Offset 4755 %} 4756%} 4757 4758operand stackSlotD(sRegD reg) %{ 4759 constraint(ALLOC_IN_RC(stack_slots)); 4760 op_cost(100); 4761 //match(RegD); 4762 format %{ "[sp+$reg]" %} 4763 interface(MEMORY_INTER) %{ 4764 base(0x1); // R1_SP 4765 index(0x0); 4766 scale(0x0); 4767 disp($reg); // Stack Offset 4768 %} 4769%} 4770 4771// Operands for expressing Control Flow 4772// NOTE: Label is a predefined operand which should not be redefined in 4773// the AD file. It is generically handled within the ADLC. 4774 4775//----------Conditional Branch Operands---------------------------------------- 4776// Comparison Op 4777// 4778// This is the operation of the comparison, and is limited to the 4779// following set of codes: L (<), LE (<=), G (>), GE (>=), E (==), NE 4780// (!=). 4781// 4782// Other attributes of the comparison, such as unsignedness, are specified 4783// by the comparison instruction that sets a condition code flags register. 4784// That result is represented by a flags operand whose subtype is appropriate 4785// to the unsignedness (etc.) of the comparison. 4786// 4787// Later, the instruction which matches both the Comparison Op (a Bool) and 4788// the flags (produced by the Cmp) specifies the coding of the comparison op 4789// by matching a specific subtype of Bool operand below. 4790 4791// When used for floating point comparisons: unordered same as less. 4792operand cmpOp() %{ 4793 match(Bool); 4794 format %{ "" %} 4795 interface(COND_INTER) %{ 4796 // BO only encodes bit 4 of bcondCRbiIsX, as bits 1-3 are always '100'. 4797 // BO & BI 4798 equal(0xA); // 10 10: bcondCRbiIs1 & Condition::equal 4799 not_equal(0x2); // 00 10: bcondCRbiIs0 & Condition::equal 4800 less(0x8); // 10 00: bcondCRbiIs1 & Condition::less 4801 greater_equal(0x0); // 00 00: bcondCRbiIs0 & Condition::less 4802 less_equal(0x1); // 00 01: bcondCRbiIs0 & Condition::greater 4803 greater(0x9); // 10 01: bcondCRbiIs1 & Condition::greater 4804 overflow(0xB); // 10 11: bcondCRbiIs1 & Condition::summary_overflow 4805 no_overflow(0x3); // 00 11: bcondCRbiIs0 & Condition::summary_overflow 4806 %} 4807%} 4808 4809//----------OPERAND CLASSES---------------------------------------------------- 4810// Operand Classes are groups of operands that are used to simplify 4811// instruction definitions by not requiring the AD writer to specify 4812// seperate instructions for every form of operand when the 4813// instruction accepts multiple operand types with the same basic 4814// encoding and format. The classic case of this is memory operands. 4815// Indirect is not included since its use is limited to Compare & Swap. 4816 4817opclass memory(indirect, indOffset16 /*, indIndex, tlsReference*/, indirectNarrow, indirectNarrow_klass, indOffset16Narrow, indOffset16Narrow_klass); 4818// Memory operand where offsets are 4-aligned. Required for ld, std. 4819opclass memoryAlg4(indirect, indOffset16Alg4, indirectNarrow, indOffset16NarrowAlg4, indOffset16NarrowAlg4_klass); 4820opclass indirectMemory(indirect, indirectNarrow); 4821 4822// Special opclass for I and ConvL2I. 4823opclass iRegIsrc_iRegL2Isrc(iRegIsrc, iRegL2Isrc); 4824 4825// Operand classes to match encode and decode. iRegN_P2N is only used 4826// for storeN. I have never seen an encode node elsewhere. 4827opclass iRegN_P2N(iRegNsrc, iRegP2N); 4828opclass iRegP_N2P(iRegPsrc, iRegN2P, iRegN2P_klass); 4829 4830//----------PIPELINE----------------------------------------------------------- 4831 4832pipeline %{ 4833 4834// See J.M.Tendler et al. "Power4 system microarchitecture", IBM 4835// J. Res. & Dev., No. 1, Jan. 2002. 4836 4837//----------ATTRIBUTES--------------------------------------------------------- 4838attributes %{ 4839 4840 // Power4 instructions are of fixed length. 4841 fixed_size_instructions; 4842 4843 // TODO: if `bundle' means number of instructions fetched 4844 // per cycle, this is 8. If `bundle' means Power4 `group', that is 4845 // max instructions issued per cycle, this is 5. 4846 max_instructions_per_bundle = 8; 4847 4848 // A Power4 instruction is 4 bytes long. 4849 instruction_unit_size = 4; 4850 4851 // The Power4 processor fetches 64 bytes... 4852 instruction_fetch_unit_size = 64; 4853 4854 // ...in one line 4855 instruction_fetch_units = 1 4856 4857 // Unused, list one so that array generated by adlc is not empty. 4858 // Aix compiler chokes if _nop_count = 0. 4859 nops(fxNop); 4860%} 4861 4862//----------RESOURCES---------------------------------------------------------- 4863// Resources are the functional units available to the machine 4864resources( 4865 PPC_BR, // branch unit 4866 PPC_CR, // condition unit 4867 PPC_FX1, // integer arithmetic unit 1 4868 PPC_FX2, // integer arithmetic unit 2 4869 PPC_LDST1, // load/store unit 1 4870 PPC_LDST2, // load/store unit 2 4871 PPC_FP1, // float arithmetic unit 1 4872 PPC_FP2, // float arithmetic unit 2 4873 PPC_LDST = PPC_LDST1 | PPC_LDST2, 4874 PPC_FX = PPC_FX1 | PPC_FX2, 4875 PPC_FP = PPC_FP1 | PPC_FP2 4876 ); 4877 4878//----------PIPELINE DESCRIPTION----------------------------------------------- 4879// Pipeline Description specifies the stages in the machine's pipeline 4880pipe_desc( 4881 // Power4 longest pipeline path 4882 PPC_IF, // instruction fetch 4883 PPC_IC, 4884 //PPC_BP, // branch prediction 4885 PPC_D0, // decode 4886 PPC_D1, // decode 4887 PPC_D2, // decode 4888 PPC_D3, // decode 4889 PPC_Xfer1, 4890 PPC_GD, // group definition 4891 PPC_MP, // map 4892 PPC_ISS, // issue 4893 PPC_RF, // resource fetch 4894 PPC_EX1, // execute (all units) 4895 PPC_EX2, // execute (FP, LDST) 4896 PPC_EX3, // execute (FP, LDST) 4897 PPC_EX4, // execute (FP) 4898 PPC_EX5, // execute (FP) 4899 PPC_EX6, // execute (FP) 4900 PPC_WB, // write back 4901 PPC_Xfer2, 4902 PPC_CP 4903 ); 4904 4905//----------PIPELINE CLASSES--------------------------------------------------- 4906// Pipeline Classes describe the stages in which input and output are 4907// referenced by the hardware pipeline. 4908 4909// Simple pipeline classes. 4910 4911// Default pipeline class. 4912pipe_class pipe_class_default() %{ 4913 single_instruction; 4914 fixed_latency(2); 4915%} 4916 4917// Pipeline class for empty instructions. 4918pipe_class pipe_class_empty() %{ 4919 single_instruction; 4920 fixed_latency(0); 4921%} 4922 4923// Pipeline class for compares. 4924pipe_class pipe_class_compare() %{ 4925 single_instruction; 4926 fixed_latency(16); 4927%} 4928 4929// Pipeline class for traps. 4930pipe_class pipe_class_trap() %{ 4931 single_instruction; 4932 fixed_latency(100); 4933%} 4934 4935// Pipeline class for memory operations. 4936pipe_class pipe_class_memory() %{ 4937 single_instruction; 4938 fixed_latency(16); 4939%} 4940 4941// Pipeline class for call. 4942pipe_class pipe_class_call() %{ 4943 single_instruction; 4944 fixed_latency(100); 4945%} 4946 4947// Define the class for the Nop node. 4948define %{ 4949 MachNop = pipe_class_default; 4950%} 4951 4952%} 4953 4954//----------INSTRUCTIONS------------------------------------------------------- 4955 4956// Naming of instructions: 4957// opA_operB / opA_operB_operC: 4958// Operation 'op' with one or two source operands 'oper'. Result 4959// type is A, source operand types are B and C. 4960// Iff A == B == C, B and C are left out. 4961// 4962// The instructions are ordered according to the following scheme: 4963// - loads 4964// - load constants 4965// - prefetch 4966// - store 4967// - encode/decode 4968// - membar 4969// - conditional moves 4970// - compare & swap 4971// - arithmetic and logic operations 4972// * int: Add, Sub, Mul, Div, Mod 4973// * int: lShift, arShift, urShift, rot 4974// * float: Add, Sub, Mul, Div 4975// * and, or, xor ... 4976// - register moves: float <-> int, reg <-> stack, repl 4977// - cast (high level type cast, XtoP, castPP, castII, not_null etc. 4978// - conv (low level type cast requiring bit changes (sign extend etc) 4979// - compares, range & zero checks. 4980// - branches 4981// - complex operations, intrinsics, min, max, replicate 4982// - lock 4983// - Calls 4984// 4985// If there are similar instructions with different types they are sorted: 4986// int before float 4987// small before big 4988// signed before unsigned 4989// e.g., loadS before loadUS before loadI before loadF. 4990 4991 4992//----------Load/Store Instructions-------------------------------------------- 4993 4994//----------Load Instructions-------------------------------------------------- 4995 4996// Converts byte to int. 4997// As convB2I_reg, but without match rule. The match rule of convB2I_reg 4998// reuses the 'amount' operand, but adlc expects that operand specification 4999// and operands in match rule are equivalent. 5000instruct convB2I_reg_2(iRegIdst dst, iRegIsrc src) %{ 5001 effect(DEF dst, USE src); 5002 format %{ "EXTSB $dst, $src \t// byte->int" %} 5003 size(4); 5004 ins_encode %{ 5005 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 5006 __ extsb($dst$$Register, $src$$Register); 5007 %} 5008 ins_pipe(pipe_class_default); 5009%} 5010 5011instruct loadUB_indirect(iRegIdst dst, indirectMemory mem) %{ 5012 // match-rule, false predicate 5013 match(Set dst (LoadB mem)); 5014 predicate(false); 5015 5016 format %{ "LBZ $dst, $mem" %} 5017 size(4); 5018 ins_encode( enc_lbz(dst, mem) ); 5019 ins_pipe(pipe_class_memory); 5020%} 5021 5022instruct loadUB_indirect_ac(iRegIdst dst, indirectMemory mem) %{ 5023 // match-rule, false predicate 5024 match(Set dst (LoadB mem)); 5025 predicate(false); 5026 5027 format %{ "LBZ $dst, $mem\n\t" 5028 "TWI $dst\n\t" 5029 "ISYNC" %} 5030 size(12); 5031 ins_encode( enc_lbz_ac(dst, mem) ); 5032 ins_pipe(pipe_class_memory); 5033%} 5034 5035// Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5036instruct loadB_indirect_Ex(iRegIdst dst, indirectMemory mem) %{ 5037 match(Set dst (LoadB mem)); 5038 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5039 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5040 expand %{ 5041 iRegIdst tmp; 5042 loadUB_indirect(tmp, mem); 5043 convB2I_reg_2(dst, tmp); 5044 %} 5045%} 5046 5047instruct loadB_indirect_ac_Ex(iRegIdst dst, indirectMemory mem) %{ 5048 match(Set dst (LoadB mem)); 5049 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5050 expand %{ 5051 iRegIdst tmp; 5052 loadUB_indirect_ac(tmp, mem); 5053 convB2I_reg_2(dst, tmp); 5054 %} 5055%} 5056 5057instruct loadUB_indOffset16(iRegIdst dst, indOffset16 mem) %{ 5058 // match-rule, false predicate 5059 match(Set dst (LoadB mem)); 5060 predicate(false); 5061 5062 format %{ "LBZ $dst, $mem" %} 5063 size(4); 5064 ins_encode( enc_lbz(dst, mem) ); 5065 ins_pipe(pipe_class_memory); 5066%} 5067 5068instruct loadUB_indOffset16_ac(iRegIdst dst, indOffset16 mem) %{ 5069 // match-rule, false predicate 5070 match(Set dst (LoadB mem)); 5071 predicate(false); 5072 5073 format %{ "LBZ $dst, $mem\n\t" 5074 "TWI $dst\n\t" 5075 "ISYNC" %} 5076 size(12); 5077 ins_encode( enc_lbz_ac(dst, mem) ); 5078 ins_pipe(pipe_class_memory); 5079%} 5080 5081// Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5082instruct loadB_indOffset16_Ex(iRegIdst dst, indOffset16 mem) %{ 5083 match(Set dst (LoadB mem)); 5084 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5085 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5086 5087 expand %{ 5088 iRegIdst tmp; 5089 loadUB_indOffset16(tmp, mem); 5090 convB2I_reg_2(dst, tmp); 5091 %} 5092%} 5093 5094instruct loadB_indOffset16_ac_Ex(iRegIdst dst, indOffset16 mem) %{ 5095 match(Set dst (LoadB mem)); 5096 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5097 5098 expand %{ 5099 iRegIdst tmp; 5100 loadUB_indOffset16_ac(tmp, mem); 5101 convB2I_reg_2(dst, tmp); 5102 %} 5103%} 5104 5105// Load Unsigned Byte (8bit UNsigned) into an int reg. 5106instruct loadUB(iRegIdst dst, memory mem) %{ 5107 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5108 match(Set dst (LoadUB mem)); 5109 ins_cost(MEMORY_REF_COST); 5110 5111 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int" %} 5112 size(4); 5113 ins_encode( enc_lbz(dst, mem) ); 5114 ins_pipe(pipe_class_memory); 5115%} 5116 5117// Load Unsigned Byte (8bit UNsigned) acquire. 5118instruct loadUB_ac(iRegIdst dst, memory mem) %{ 5119 match(Set dst (LoadUB mem)); 5120 ins_cost(3*MEMORY_REF_COST); 5121 5122 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int, acquire\n\t" 5123 "TWI $dst\n\t" 5124 "ISYNC" %} 5125 size(12); 5126 ins_encode( enc_lbz_ac(dst, mem) ); 5127 ins_pipe(pipe_class_memory); 5128%} 5129 5130// Load Unsigned Byte (8bit UNsigned) into a Long Register. 5131instruct loadUB2L(iRegLdst dst, memory mem) %{ 5132 match(Set dst (ConvI2L (LoadUB mem))); 5133 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5134 ins_cost(MEMORY_REF_COST); 5135 5136 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long" %} 5137 size(4); 5138 ins_encode( enc_lbz(dst, mem) ); 5139 ins_pipe(pipe_class_memory); 5140%} 5141 5142instruct loadUB2L_ac(iRegLdst dst, memory mem) %{ 5143 match(Set dst (ConvI2L (LoadUB mem))); 5144 ins_cost(3*MEMORY_REF_COST); 5145 5146 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long, acquire\n\t" 5147 "TWI $dst\n\t" 5148 "ISYNC" %} 5149 size(12); 5150 ins_encode( enc_lbz_ac(dst, mem) ); 5151 ins_pipe(pipe_class_memory); 5152%} 5153 5154// Load Short (16bit signed) 5155instruct loadS(iRegIdst dst, memory mem) %{ 5156 match(Set dst (LoadS mem)); 5157 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5158 ins_cost(MEMORY_REF_COST); 5159 5160 format %{ "LHA $dst, $mem" %} 5161 size(4); 5162 ins_encode %{ 5163 // TODO: PPC port $archOpcode(ppc64Opcode_lha); 5164 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5165 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5166 %} 5167 ins_pipe(pipe_class_memory); 5168%} 5169 5170// Load Short (16bit signed) acquire. 5171instruct loadS_ac(iRegIdst dst, memory mem) %{ 5172 match(Set dst (LoadS mem)); 5173 ins_cost(3*MEMORY_REF_COST); 5174 5175 format %{ "LHA $dst, $mem\t acquire\n\t" 5176 "TWI $dst\n\t" 5177 "ISYNC" %} 5178 size(12); 5179 ins_encode %{ 5180 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5181 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5182 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5183 __ twi_0($dst$$Register); 5184 __ isync(); 5185 %} 5186 ins_pipe(pipe_class_memory); 5187%} 5188 5189// Load Char (16bit unsigned) 5190instruct loadUS(iRegIdst dst, memory mem) %{ 5191 match(Set dst (LoadUS mem)); 5192 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5193 ins_cost(MEMORY_REF_COST); 5194 5195 format %{ "LHZ $dst, $mem" %} 5196 size(4); 5197 ins_encode( enc_lhz(dst, mem) ); 5198 ins_pipe(pipe_class_memory); 5199%} 5200 5201// Load Char (16bit unsigned) acquire. 5202instruct loadUS_ac(iRegIdst dst, memory mem) %{ 5203 match(Set dst (LoadUS mem)); 5204 ins_cost(3*MEMORY_REF_COST); 5205 5206 format %{ "LHZ $dst, $mem \t// acquire\n\t" 5207 "TWI $dst\n\t" 5208 "ISYNC" %} 5209 size(12); 5210 ins_encode( enc_lhz_ac(dst, mem) ); 5211 ins_pipe(pipe_class_memory); 5212%} 5213 5214// Load Unsigned Short/Char (16bit UNsigned) into a Long Register. 5215instruct loadUS2L(iRegLdst dst, memory mem) %{ 5216 match(Set dst (ConvI2L (LoadUS mem))); 5217 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5218 ins_cost(MEMORY_REF_COST); 5219 5220 format %{ "LHZ $dst, $mem \t// short, zero-extend to long" %} 5221 size(4); 5222 ins_encode( enc_lhz(dst, mem) ); 5223 ins_pipe(pipe_class_memory); 5224%} 5225 5226// Load Unsigned Short/Char (16bit UNsigned) into a Long Register acquire. 5227instruct loadUS2L_ac(iRegLdst dst, memory mem) %{ 5228 match(Set dst (ConvI2L (LoadUS mem))); 5229 ins_cost(3*MEMORY_REF_COST); 5230 5231 format %{ "LHZ $dst, $mem \t// short, zero-extend to long, acquire\n\t" 5232 "TWI $dst\n\t" 5233 "ISYNC" %} 5234 size(12); 5235 ins_encode( enc_lhz_ac(dst, mem) ); 5236 ins_pipe(pipe_class_memory); 5237%} 5238 5239// Load Integer. 5240instruct loadI(iRegIdst dst, memory mem) %{ 5241 match(Set dst (LoadI mem)); 5242 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5243 ins_cost(MEMORY_REF_COST); 5244 5245 format %{ "LWZ $dst, $mem" %} 5246 size(4); 5247 ins_encode( enc_lwz(dst, mem) ); 5248 ins_pipe(pipe_class_memory); 5249%} 5250 5251// Load Integer acquire. 5252instruct loadI_ac(iRegIdst dst, memory mem) %{ 5253 match(Set dst (LoadI mem)); 5254 ins_cost(3*MEMORY_REF_COST); 5255 5256 format %{ "LWZ $dst, $mem \t// load acquire\n\t" 5257 "TWI $dst\n\t" 5258 "ISYNC" %} 5259 size(12); 5260 ins_encode( enc_lwz_ac(dst, mem) ); 5261 ins_pipe(pipe_class_memory); 5262%} 5263 5264// Match loading integer and casting it to unsigned int in 5265// long register. 5266// LoadI + ConvI2L + AndL 0xffffffff. 5267instruct loadUI2L(iRegLdst dst, memory mem, immL_32bits mask) %{ 5268 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5269 predicate(_kids[0]->_kids[0]->_leaf->as_Load()->is_unordered()); 5270 ins_cost(MEMORY_REF_COST); 5271 5272 format %{ "LWZ $dst, $mem \t// zero-extend to long" %} 5273 size(4); 5274 ins_encode( enc_lwz(dst, mem) ); 5275 ins_pipe(pipe_class_memory); 5276%} 5277 5278// Match loading integer and casting it to long. 5279instruct loadI2L(iRegLdst dst, memoryAlg4 mem) %{ 5280 match(Set dst (ConvI2L (LoadI mem))); 5281 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5282 ins_cost(MEMORY_REF_COST); 5283 5284 format %{ "LWA $dst, $mem \t// loadI2L" %} 5285 size(4); 5286 ins_encode %{ 5287 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5288 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5289 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5290 %} 5291 ins_pipe(pipe_class_memory); 5292%} 5293 5294// Match loading integer and casting it to long - acquire. 5295instruct loadI2L_ac(iRegLdst dst, memoryAlg4 mem) %{ 5296 match(Set dst (ConvI2L (LoadI mem))); 5297 ins_cost(3*MEMORY_REF_COST); 5298 5299 format %{ "LWA $dst, $mem \t// loadI2L acquire" 5300 "TWI $dst\n\t" 5301 "ISYNC" %} 5302 size(12); 5303 ins_encode %{ 5304 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5305 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5306 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5307 __ twi_0($dst$$Register); 5308 __ isync(); 5309 %} 5310 ins_pipe(pipe_class_memory); 5311%} 5312 5313// Load Long - aligned 5314instruct loadL(iRegLdst dst, memoryAlg4 mem) %{ 5315 match(Set dst (LoadL mem)); 5316 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5317 ins_cost(MEMORY_REF_COST); 5318 5319 format %{ "LD $dst, $mem \t// long" %} 5320 size(4); 5321 ins_encode( enc_ld(dst, mem) ); 5322 ins_pipe(pipe_class_memory); 5323%} 5324 5325// Load Long - aligned acquire. 5326instruct loadL_ac(iRegLdst dst, memoryAlg4 mem) %{ 5327 match(Set dst (LoadL mem)); 5328 ins_cost(3*MEMORY_REF_COST); 5329 5330 format %{ "LD $dst, $mem \t// long acquire\n\t" 5331 "TWI $dst\n\t" 5332 "ISYNC" %} 5333 size(12); 5334 ins_encode( enc_ld_ac(dst, mem) ); 5335 ins_pipe(pipe_class_memory); 5336%} 5337 5338// Load Long - UNaligned 5339instruct loadL_unaligned(iRegLdst dst, memoryAlg4 mem) %{ 5340 match(Set dst (LoadL_unaligned mem)); 5341 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 5342 ins_cost(MEMORY_REF_COST); 5343 5344 format %{ "LD $dst, $mem \t// unaligned long" %} 5345 size(4); 5346 ins_encode( enc_ld(dst, mem) ); 5347 ins_pipe(pipe_class_memory); 5348%} 5349 5350// Load nodes for superwords 5351 5352// Load Aligned Packed Byte 5353instruct loadV8(iRegLdst dst, memoryAlg4 mem) %{ 5354 predicate(n->as_LoadVector()->memory_size() == 8); 5355 match(Set dst (LoadVector mem)); 5356 ins_cost(MEMORY_REF_COST); 5357 5358 format %{ "LD $dst, $mem \t// load 8-byte Vector" %} 5359 size(4); 5360 ins_encode( enc_ld(dst, mem) ); 5361 ins_pipe(pipe_class_memory); 5362%} 5363 5364// Load Range, range = array length (=jint) 5365instruct loadRange(iRegIdst dst, memory mem) %{ 5366 match(Set dst (LoadRange mem)); 5367 ins_cost(MEMORY_REF_COST); 5368 5369 format %{ "LWZ $dst, $mem \t// range" %} 5370 size(4); 5371 ins_encode( enc_lwz(dst, mem) ); 5372 ins_pipe(pipe_class_memory); 5373%} 5374 5375// Load Compressed Pointer 5376instruct loadN(iRegNdst dst, memory mem) %{ 5377 match(Set dst (LoadN mem)); 5378 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5379 ins_cost(MEMORY_REF_COST); 5380 5381 format %{ "LWZ $dst, $mem \t// load compressed ptr" %} 5382 size(4); 5383 ins_encode( enc_lwz(dst, mem) ); 5384 ins_pipe(pipe_class_memory); 5385%} 5386 5387// Load Compressed Pointer acquire. 5388instruct loadN_ac(iRegNdst dst, memory mem) %{ 5389 match(Set dst (LoadN mem)); 5390 ins_cost(3*MEMORY_REF_COST); 5391 5392 format %{ "LWZ $dst, $mem \t// load acquire compressed ptr\n\t" 5393 "TWI $dst\n\t" 5394 "ISYNC" %} 5395 size(12); 5396 ins_encode( enc_lwz_ac(dst, mem) ); 5397 ins_pipe(pipe_class_memory); 5398%} 5399 5400// Load Compressed Pointer and decode it if narrow_oop_shift == 0. 5401instruct loadN2P_unscaled(iRegPdst dst, memory mem) %{ 5402 match(Set dst (DecodeN (LoadN mem))); 5403 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && Universe::narrow_oop_shift() == 0); 5404 ins_cost(MEMORY_REF_COST); 5405 5406 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5407 size(4); 5408 ins_encode( enc_lwz(dst, mem) ); 5409 ins_pipe(pipe_class_memory); 5410%} 5411 5412instruct loadN2P_klass_unscaled(iRegPdst dst, memory mem) %{ 5413 match(Set dst (DecodeNKlass (LoadNKlass mem))); 5414 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0 && 5415 _kids[0]->_leaf->as_Load()->is_unordered()); 5416 ins_cost(MEMORY_REF_COST); 5417 5418 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5419 size(4); 5420 ins_encode( enc_lwz(dst, mem) ); 5421 ins_pipe(pipe_class_memory); 5422%} 5423 5424// Load Pointer 5425instruct loadP(iRegPdst dst, memoryAlg4 mem) %{ 5426 match(Set dst (LoadP mem)); 5427 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5428 ins_cost(MEMORY_REF_COST); 5429 5430 format %{ "LD $dst, $mem \t// ptr" %} 5431 size(4); 5432 ins_encode( enc_ld(dst, mem) ); 5433 ins_pipe(pipe_class_memory); 5434%} 5435 5436// Load Pointer acquire. 5437instruct loadP_ac(iRegPdst dst, memoryAlg4 mem) %{ 5438 match(Set dst (LoadP mem)); 5439 ins_cost(3*MEMORY_REF_COST); 5440 5441 format %{ "LD $dst, $mem \t// ptr acquire\n\t" 5442 "TWI $dst\n\t" 5443 "ISYNC" %} 5444 size(12); 5445 ins_encode( enc_ld_ac(dst, mem) ); 5446 ins_pipe(pipe_class_memory); 5447%} 5448 5449// LoadP + CastP2L 5450instruct loadP2X(iRegLdst dst, memoryAlg4 mem) %{ 5451 match(Set dst (CastP2X (LoadP mem))); 5452 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5453 ins_cost(MEMORY_REF_COST); 5454 5455 format %{ "LD $dst, $mem \t// ptr + p2x" %} 5456 size(4); 5457 ins_encode( enc_ld(dst, mem) ); 5458 ins_pipe(pipe_class_memory); 5459%} 5460 5461// Load compressed klass pointer. 5462instruct loadNKlass(iRegNdst dst, memory mem) %{ 5463 match(Set dst (LoadNKlass mem)); 5464 ins_cost(MEMORY_REF_COST); 5465 5466 format %{ "LWZ $dst, $mem \t// compressed klass ptr" %} 5467 size(4); 5468 ins_encode( enc_lwz(dst, mem) ); 5469 ins_pipe(pipe_class_memory); 5470%} 5471 5472// Load Klass Pointer 5473instruct loadKlass(iRegPdst dst, memoryAlg4 mem) %{ 5474 match(Set dst (LoadKlass mem)); 5475 ins_cost(MEMORY_REF_COST); 5476 5477 format %{ "LD $dst, $mem \t// klass ptr" %} 5478 size(4); 5479 ins_encode( enc_ld(dst, mem) ); 5480 ins_pipe(pipe_class_memory); 5481%} 5482 5483// Load Float 5484instruct loadF(regF dst, memory mem) %{ 5485 match(Set dst (LoadF mem)); 5486 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5487 ins_cost(MEMORY_REF_COST); 5488 5489 format %{ "LFS $dst, $mem" %} 5490 size(4); 5491 ins_encode %{ 5492 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 5493 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5494 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5495 %} 5496 ins_pipe(pipe_class_memory); 5497%} 5498 5499// Load Float acquire. 5500instruct loadF_ac(regF dst, memory mem, flagsRegCR0 cr0) %{ 5501 match(Set dst (LoadF mem)); 5502 effect(TEMP cr0); 5503 ins_cost(3*MEMORY_REF_COST); 5504 5505 format %{ "LFS $dst, $mem \t// acquire\n\t" 5506 "FCMPU cr0, $dst, $dst\n\t" 5507 "BNE cr0, next\n" 5508 "next:\n\t" 5509 "ISYNC" %} 5510 size(16); 5511 ins_encode %{ 5512 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5513 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5514 Label next; 5515 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5516 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 5517 __ bne(CCR0, next); 5518 __ bind(next); 5519 __ isync(); 5520 %} 5521 ins_pipe(pipe_class_memory); 5522%} 5523 5524// Load Double - aligned 5525instruct loadD(regD dst, memory mem) %{ 5526 match(Set dst (LoadD mem)); 5527 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5528 ins_cost(MEMORY_REF_COST); 5529 5530 format %{ "LFD $dst, $mem" %} 5531 size(4); 5532 ins_encode( enc_lfd(dst, mem) ); 5533 ins_pipe(pipe_class_memory); 5534%} 5535 5536// Load Double - aligned acquire. 5537instruct loadD_ac(regD dst, memory mem, flagsRegCR0 cr0) %{ 5538 match(Set dst (LoadD mem)); 5539 effect(TEMP cr0); 5540 ins_cost(3*MEMORY_REF_COST); 5541 5542 format %{ "LFD $dst, $mem \t// acquire\n\t" 5543 "FCMPU cr0, $dst, $dst\n\t" 5544 "BNE cr0, next\n" 5545 "next:\n\t" 5546 "ISYNC" %} 5547 size(16); 5548 ins_encode %{ 5549 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5550 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5551 Label next; 5552 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5553 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 5554 __ bne(CCR0, next); 5555 __ bind(next); 5556 __ isync(); 5557 %} 5558 ins_pipe(pipe_class_memory); 5559%} 5560 5561// Load Double - UNaligned 5562instruct loadD_unaligned(regD dst, memory mem) %{ 5563 match(Set dst (LoadD_unaligned mem)); 5564 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 5565 ins_cost(MEMORY_REF_COST); 5566 5567 format %{ "LFD $dst, $mem" %} 5568 size(4); 5569 ins_encode( enc_lfd(dst, mem) ); 5570 ins_pipe(pipe_class_memory); 5571%} 5572 5573//----------Constants-------------------------------------------------------- 5574 5575// Load MachConstantTableBase: add hi offset to global toc. 5576// TODO: Handle hidden register r29 in bundler! 5577instruct loadToc_hi(iRegLdst dst) %{ 5578 effect(DEF dst); 5579 ins_cost(DEFAULT_COST); 5580 5581 format %{ "ADDIS $dst, R29, DISP.hi \t// load TOC hi" %} 5582 size(4); 5583 ins_encode %{ 5584 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 5585 __ calculate_address_from_global_toc_hi16only($dst$$Register, __ method_toc()); 5586 %} 5587 ins_pipe(pipe_class_default); 5588%} 5589 5590// Load MachConstantTableBase: add lo offset to global toc. 5591instruct loadToc_lo(iRegLdst dst, iRegLdst src) %{ 5592 effect(DEF dst, USE src); 5593 ins_cost(DEFAULT_COST); 5594 5595 format %{ "ADDI $dst, $src, DISP.lo \t// load TOC lo" %} 5596 size(4); 5597 ins_encode %{ 5598 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 5599 __ calculate_address_from_global_toc_lo16only($dst$$Register, __ method_toc()); 5600 %} 5601 ins_pipe(pipe_class_default); 5602%} 5603 5604// Load 16-bit integer constant 0xssss???? 5605instruct loadConI16(iRegIdst dst, immI16 src) %{ 5606 match(Set dst src); 5607 5608 format %{ "LI $dst, $src" %} 5609 size(4); 5610 ins_encode %{ 5611 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 5612 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 5613 %} 5614 ins_pipe(pipe_class_default); 5615%} 5616 5617// Load integer constant 0x????0000 5618instruct loadConIhi16(iRegIdst dst, immIhi16 src) %{ 5619 match(Set dst src); 5620 ins_cost(DEFAULT_COST); 5621 5622 format %{ "LIS $dst, $src.hi" %} 5623 size(4); 5624 ins_encode %{ 5625 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 5626 // Lis sign extends 16-bit src then shifts it 16 bit to the left. 5627 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 5628 %} 5629 ins_pipe(pipe_class_default); 5630%} 5631 5632// Part 2 of loading 32 bit constant: hi16 is is src1 (properly shifted 5633// and sign extended), this adds the low 16 bits. 5634instruct loadConI32_lo16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 5635 // no match-rule, false predicate 5636 effect(DEF dst, USE src1, USE src2); 5637 predicate(false); 5638 5639 format %{ "ORI $dst, $src1.hi, $src2.lo" %} 5640 size(4); 5641 ins_encode %{ 5642 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 5643 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 5644 %} 5645 ins_pipe(pipe_class_default); 5646%} 5647 5648instruct loadConI_Ex(iRegIdst dst, immI src) %{ 5649 match(Set dst src); 5650 ins_cost(DEFAULT_COST*2); 5651 5652 expand %{ 5653 // Would like to use $src$$constant. 5654 immI16 srcLo %{ _opnds[1]->constant() %} 5655 // srcHi can be 0000 if srcLo sign-extends to a negative number. 5656 immIhi16 srcHi %{ _opnds[1]->constant() %} 5657 iRegIdst tmpI; 5658 loadConIhi16(tmpI, srcHi); 5659 loadConI32_lo16(dst, tmpI, srcLo); 5660 %} 5661%} 5662 5663// No constant pool entries required. 5664instruct loadConL16(iRegLdst dst, immL16 src) %{ 5665 match(Set dst src); 5666 5667 format %{ "LI $dst, $src \t// long" %} 5668 size(4); 5669 ins_encode %{ 5670 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 5671 __ li($dst$$Register, (int)((short) ($src$$constant & 0xFFFF))); 5672 %} 5673 ins_pipe(pipe_class_default); 5674%} 5675 5676// Load long constant 0xssssssss????0000 5677instruct loadConL32hi16(iRegLdst dst, immL32hi16 src) %{ 5678 match(Set dst src); 5679 ins_cost(DEFAULT_COST); 5680 5681 format %{ "LIS $dst, $src.hi \t// long" %} 5682 size(4); 5683 ins_encode %{ 5684 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 5685 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 5686 %} 5687 ins_pipe(pipe_class_default); 5688%} 5689 5690// To load a 32 bit constant: merge lower 16 bits into already loaded 5691// high 16 bits. 5692instruct loadConL32_lo16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 5693 // no match-rule, false predicate 5694 effect(DEF dst, USE src1, USE src2); 5695 predicate(false); 5696 5697 format %{ "ORI $dst, $src1, $src2.lo" %} 5698 size(4); 5699 ins_encode %{ 5700 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 5701 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 5702 %} 5703 ins_pipe(pipe_class_default); 5704%} 5705 5706// Load 32-bit long constant 5707instruct loadConL32_Ex(iRegLdst dst, immL32 src) %{ 5708 match(Set dst src); 5709 ins_cost(DEFAULT_COST*2); 5710 5711 expand %{ 5712 // Would like to use $src$$constant. 5713 immL16 srcLo %{ _opnds[1]->constant() /*& 0x0000FFFFL */%} 5714 // srcHi can be 0000 if srcLo sign-extends to a negative number. 5715 immL32hi16 srcHi %{ _opnds[1]->constant() /*& 0xFFFF0000L */%} 5716 iRegLdst tmpL; 5717 loadConL32hi16(tmpL, srcHi); 5718 loadConL32_lo16(dst, tmpL, srcLo); 5719 %} 5720%} 5721 5722// Load long constant 0x????000000000000. 5723instruct loadConLhighest16_Ex(iRegLdst dst, immLhighest16 src) %{ 5724 match(Set dst src); 5725 ins_cost(DEFAULT_COST); 5726 5727 expand %{ 5728 immL32hi16 srcHi %{ _opnds[1]->constant() >> 32 /*& 0xFFFF0000L */%} 5729 immI shift32 %{ 32 %} 5730 iRegLdst tmpL; 5731 loadConL32hi16(tmpL, srcHi); 5732 lshiftL_regL_immI(dst, tmpL, shift32); 5733 %} 5734%} 5735 5736// Expand node for constant pool load: small offset. 5737instruct loadConL(iRegLdst dst, immL src, iRegLdst toc) %{ 5738 effect(DEF dst, USE src, USE toc); 5739 ins_cost(MEMORY_REF_COST); 5740 5741 ins_num_consts(1); 5742 // Needed so that CallDynamicJavaDirect can compute the address of this 5743 // instruction for relocation. 5744 ins_field_cbuf_insts_offset(int); 5745 5746 format %{ "LD $dst, offset, $toc \t// load long $src from TOC" %} 5747 size(4); 5748 ins_encode( enc_load_long_constL(dst, src, toc) ); 5749 ins_pipe(pipe_class_memory); 5750%} 5751 5752// Expand node for constant pool load: large offset. 5753instruct loadConL_hi(iRegLdst dst, immL src, iRegLdst toc) %{ 5754 effect(DEF dst, USE src, USE toc); 5755 predicate(false); 5756 5757 ins_num_consts(1); 5758 ins_field_const_toc_offset(int); 5759 // Needed so that CallDynamicJavaDirect can compute the address of this 5760 // instruction for relocation. 5761 ins_field_cbuf_insts_offset(int); 5762 5763 format %{ "ADDIS $dst, $toc, offset \t// load long $src from TOC (hi)" %} 5764 size(4); 5765 ins_encode( enc_load_long_constL_hi(dst, toc, src) ); 5766 ins_pipe(pipe_class_default); 5767%} 5768 5769// Expand node for constant pool load: large offset. 5770// No constant pool entries required. 5771instruct loadConL_lo(iRegLdst dst, immL src, iRegLdst base) %{ 5772 effect(DEF dst, USE src, USE base); 5773 predicate(false); 5774 5775 ins_field_const_toc_offset_hi_node(loadConL_hiNode*); 5776 5777 format %{ "LD $dst, offset, $base \t// load long $src from TOC (lo)" %} 5778 size(4); 5779 ins_encode %{ 5780 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 5781 int offset = ra_->C->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 5782 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 5783 %} 5784 ins_pipe(pipe_class_memory); 5785%} 5786 5787// Load long constant from constant table. Expand in case of 5788// offset > 16 bit is needed. 5789// Adlc adds toc node MachConstantTableBase. 5790instruct loadConL_Ex(iRegLdst dst, immL src) %{ 5791 match(Set dst src); 5792 ins_cost(MEMORY_REF_COST); 5793 5794 format %{ "LD $dst, offset, $constanttablebase\t// load long $src from table, postalloc expanded" %} 5795 // We can not inline the enc_class for the expand as that does not support constanttablebase. 5796 postalloc_expand( postalloc_expand_load_long_constant(dst, src, constanttablebase) ); 5797%} 5798 5799// Load NULL as compressed oop. 5800instruct loadConN0(iRegNdst dst, immN_0 src) %{ 5801 match(Set dst src); 5802 ins_cost(DEFAULT_COST); 5803 5804 format %{ "LI $dst, $src \t// compressed ptr" %} 5805 size(4); 5806 ins_encode %{ 5807 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 5808 __ li($dst$$Register, 0); 5809 %} 5810 ins_pipe(pipe_class_default); 5811%} 5812 5813// Load hi part of compressed oop constant. 5814instruct loadConN_hi(iRegNdst dst, immN src) %{ 5815 effect(DEF dst, USE src); 5816 ins_cost(DEFAULT_COST); 5817 5818 format %{ "LIS $dst, $src \t// narrow oop hi" %} 5819 size(4); 5820 ins_encode %{ 5821 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 5822 __ lis($dst$$Register, (int)(short)(($src$$constant >> 16) & 0xffff)); 5823 %} 5824 ins_pipe(pipe_class_default); 5825%} 5826 5827// Add lo part of compressed oop constant to already loaded hi part. 5828instruct loadConN_lo(iRegNdst dst, iRegNsrc src1, immN src2) %{ 5829 effect(DEF dst, USE src1, USE src2); 5830 ins_cost(DEFAULT_COST); 5831 5832 format %{ "ORI $dst, $src1, $src2 \t// narrow oop lo" %} 5833 size(4); 5834 ins_encode %{ 5835 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 5836 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 5837 int oop_index = __ oop_recorder()->find_index((jobject)$src2$$constant); 5838 RelocationHolder rspec = oop_Relocation::spec(oop_index); 5839 __ relocate(rspec, 1); 5840 __ ori($dst$$Register, $src1$$Register, $src2$$constant & 0xffff); 5841 %} 5842 ins_pipe(pipe_class_default); 5843%} 5844 5845// Needed to postalloc expand loadConN: ConN is loaded as ConI 5846// leaving the upper 32 bits with sign-extension bits. 5847// This clears these bits: dst = src & 0xFFFFFFFF. 5848// TODO: Eventually call this maskN_regN_FFFFFFFF. 5849instruct clearMs32b(iRegNdst dst, iRegNsrc src) %{ 5850 effect(DEF dst, USE src); 5851 predicate(false); 5852 5853 format %{ "MASK $dst, $src, 0xFFFFFFFF" %} // mask 5854 size(4); 5855 ins_encode %{ 5856 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 5857 __ clrldi($dst$$Register, $src$$Register, 0x20); 5858 %} 5859 ins_pipe(pipe_class_default); 5860%} 5861 5862// Optimize DecodeN for disjoint base. 5863// Load base of compressed oops into a register 5864instruct loadBase(iRegLdst dst) %{ 5865 effect(DEF dst); 5866 5867 format %{ "LoadConst $dst, heapbase" %} 5868 ins_encode %{ 5869 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5870 __ load_const_optimized($dst$$Register, Universe::narrow_oop_base(), R0); 5871 %} 5872 ins_pipe(pipe_class_default); 5873%} 5874 5875// Loading ConN must be postalloc expanded so that edges between 5876// the nodes are safe. They may not interfere with a safepoint. 5877// GL TODO: This needs three instructions: better put this into the constant pool. 5878instruct loadConN_Ex(iRegNdst dst, immN src) %{ 5879 match(Set dst src); 5880 ins_cost(DEFAULT_COST*2); 5881 5882 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 5883 postalloc_expand %{ 5884 MachNode *m1 = new loadConN_hiNode(); 5885 MachNode *m2 = new loadConN_loNode(); 5886 MachNode *m3 = new clearMs32bNode(); 5887 m1->add_req(NULL); 5888 m2->add_req(NULL, m1); 5889 m3->add_req(NULL, m2); 5890 m1->_opnds[0] = op_dst; 5891 m1->_opnds[1] = op_src; 5892 m2->_opnds[0] = op_dst; 5893 m2->_opnds[1] = op_dst; 5894 m2->_opnds[2] = op_src; 5895 m3->_opnds[0] = op_dst; 5896 m3->_opnds[1] = op_dst; 5897 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5898 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5899 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5900 nodes->push(m1); 5901 nodes->push(m2); 5902 nodes->push(m3); 5903 %} 5904%} 5905 5906// We have seen a safepoint between the hi and lo parts, and this node was handled 5907// as an oop. Therefore this needs a match rule so that build_oop_map knows this is 5908// not a narrow oop. 5909instruct loadConNKlass_hi(iRegNdst dst, immNKlass_NM src) %{ 5910 match(Set dst src); 5911 effect(DEF dst, USE src); 5912 ins_cost(DEFAULT_COST); 5913 5914 format %{ "LIS $dst, $src \t// narrow klass hi" %} 5915 size(4); 5916 ins_encode %{ 5917 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 5918 intptr_t Csrc = Klass::encode_klass((Klass *)$src$$constant); 5919 __ lis($dst$$Register, (int)(short)((Csrc >> 16) & 0xffff)); 5920 %} 5921 ins_pipe(pipe_class_default); 5922%} 5923 5924// As loadConNKlass_hi this must be recognized as narrow klass, not oop! 5925instruct loadConNKlass_mask(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 5926 match(Set dst src1); 5927 effect(TEMP src2); 5928 ins_cost(DEFAULT_COST); 5929 5930 format %{ "MASK $dst, $src2, 0xFFFFFFFF" %} // mask 5931 size(4); 5932 ins_encode %{ 5933 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 5934 __ clrldi($dst$$Register, $src2$$Register, 0x20); 5935 %} 5936 ins_pipe(pipe_class_default); 5937%} 5938 5939// This needs a match rule so that build_oop_map knows this is 5940// not a narrow oop. 5941instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 5942 match(Set dst src1); 5943 effect(TEMP src2); 5944 ins_cost(DEFAULT_COST); 5945 5946 format %{ "ORI $dst, $src1, $src2 \t// narrow klass lo" %} 5947 size(4); 5948 ins_encode %{ 5949 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 5950 intptr_t Csrc = Klass::encode_klass((Klass *)$src1$$constant); 5951 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 5952 int klass_index = __ oop_recorder()->find_index((Klass *)$src1$$constant); 5953 RelocationHolder rspec = metadata_Relocation::spec(klass_index); 5954 5955 __ relocate(rspec, 1); 5956 __ ori($dst$$Register, $src2$$Register, Csrc & 0xffff); 5957 %} 5958 ins_pipe(pipe_class_default); 5959%} 5960 5961// Loading ConNKlass must be postalloc expanded so that edges between 5962// the nodes are safe. They may not interfere with a safepoint. 5963instruct loadConNKlass_Ex(iRegNdst dst, immNKlass src) %{ 5964 match(Set dst src); 5965 ins_cost(DEFAULT_COST*2); 5966 5967 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 5968 postalloc_expand %{ 5969 // Load high bits into register. Sign extended. 5970 MachNode *m1 = new loadConNKlass_hiNode(); 5971 m1->add_req(NULL); 5972 m1->_opnds[0] = op_dst; 5973 m1->_opnds[1] = op_src; 5974 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5975 nodes->push(m1); 5976 5977 MachNode *m2 = m1; 5978 if (!Assembler::is_uimm((jlong)Klass::encode_klass((Klass *)op_src->constant()), 31)) { 5979 // Value might be 1-extended. Mask out these bits. 5980 m2 = new loadConNKlass_maskNode(); 5981 m2->add_req(NULL, m1); 5982 m2->_opnds[0] = op_dst; 5983 m2->_opnds[1] = op_src; 5984 m2->_opnds[2] = op_dst; 5985 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5986 nodes->push(m2); 5987 } 5988 5989 MachNode *m3 = new loadConNKlass_loNode(); 5990 m3->add_req(NULL, m2); 5991 m3->_opnds[0] = op_dst; 5992 m3->_opnds[1] = op_src; 5993 m3->_opnds[2] = op_dst; 5994 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5995 nodes->push(m3); 5996 %} 5997%} 5998 5999// 0x1 is used in object initialization (initial object header). 6000// No constant pool entries required. 6001instruct loadConP0or1(iRegPdst dst, immP_0or1 src) %{ 6002 match(Set dst src); 6003 6004 format %{ "LI $dst, $src \t// ptr" %} 6005 size(4); 6006 ins_encode %{ 6007 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6008 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 6009 %} 6010 ins_pipe(pipe_class_default); 6011%} 6012 6013// Expand node for constant pool load: small offset. 6014// The match rule is needed to generate the correct bottom_type(), 6015// however this node should never match. The use of predicate is not 6016// possible since ADLC forbids predicates for chain rules. The higher 6017// costs do not prevent matching in this case. For that reason the 6018// operand immP_NM with predicate(false) is used. 6019instruct loadConP(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6020 match(Set dst src); 6021 effect(TEMP toc); 6022 6023 ins_num_consts(1); 6024 6025 format %{ "LD $dst, offset, $toc \t// load ptr $src from TOC" %} 6026 size(4); 6027 ins_encode( enc_load_long_constP(dst, src, toc) ); 6028 ins_pipe(pipe_class_memory); 6029%} 6030 6031// Expand node for constant pool load: large offset. 6032instruct loadConP_hi(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6033 effect(DEF dst, USE src, USE toc); 6034 predicate(false); 6035 6036 ins_num_consts(1); 6037 ins_field_const_toc_offset(int); 6038 6039 format %{ "ADDIS $dst, $toc, offset \t// load ptr $src from TOC (hi)" %} 6040 size(4); 6041 ins_encode( enc_load_long_constP_hi(dst, src, toc) ); 6042 ins_pipe(pipe_class_default); 6043%} 6044 6045// Expand node for constant pool load: large offset. 6046instruct loadConP_lo(iRegPdst dst, immP_NM src, iRegLdst base) %{ 6047 match(Set dst src); 6048 effect(TEMP base); 6049 6050 ins_field_const_toc_offset_hi_node(loadConP_hiNode*); 6051 6052 format %{ "LD $dst, offset, $base \t// load ptr $src from TOC (lo)" %} 6053 size(4); 6054 ins_encode %{ 6055 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 6056 int offset = ra_->C->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 6057 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 6058 %} 6059 ins_pipe(pipe_class_memory); 6060%} 6061 6062// Load pointer constant from constant table. Expand in case an 6063// offset > 16 bit is needed. 6064// Adlc adds toc node MachConstantTableBase. 6065instruct loadConP_Ex(iRegPdst dst, immP src) %{ 6066 match(Set dst src); 6067 ins_cost(MEMORY_REF_COST); 6068 6069 // This rule does not use "expand" because then 6070 // the result type is not known to be an Oop. An ADLC 6071 // enhancement will be needed to make that work - not worth it! 6072 6073 // If this instruction rematerializes, it prolongs the live range 6074 // of the toc node, causing illegal graphs. 6075 // assert(edge_from_to(_reg_node[reg_lo],def)) fails in verify_good_schedule(). 6076 ins_cannot_rematerialize(true); 6077 6078 format %{ "LD $dst, offset, $constanttablebase \t// load ptr $src from table, postalloc expanded" %} 6079 postalloc_expand( postalloc_expand_load_ptr_constant(dst, src, constanttablebase) ); 6080%} 6081 6082// Expand node for constant pool load: small offset. 6083instruct loadConF(regF dst, immF src, iRegLdst toc) %{ 6084 effect(DEF dst, USE src, USE toc); 6085 ins_cost(MEMORY_REF_COST); 6086 6087 ins_num_consts(1); 6088 6089 format %{ "LFS $dst, offset, $toc \t// load float $src from TOC" %} 6090 size(4); 6091 ins_encode %{ 6092 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 6093 address float_address = __ float_constant($src$$constant); 6094 if (float_address == NULL) { 6095 ciEnv::current()->record_out_of_memory_failure(); 6096 return; 6097 } 6098 __ lfs($dst$$FloatRegister, __ offset_to_method_toc(float_address), $toc$$Register); 6099 %} 6100 ins_pipe(pipe_class_memory); 6101%} 6102 6103// Expand node for constant pool load: large offset. 6104instruct loadConFComp(regF dst, immF src, iRegLdst toc) %{ 6105 effect(DEF dst, USE src, USE toc); 6106 ins_cost(MEMORY_REF_COST); 6107 6108 ins_num_consts(1); 6109 6110 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6111 "LFS $dst, offset_lo, $toc \t// load float $src from TOC (hi/lo)\n\t" 6112 "ADDIS $toc, $toc, -offset_hi"%} 6113 size(12); 6114 ins_encode %{ 6115 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6116 FloatRegister Rdst = $dst$$FloatRegister; 6117 Register Rtoc = $toc$$Register; 6118 address float_address = __ float_constant($src$$constant); 6119 if (float_address == NULL) { 6120 ciEnv::current()->record_out_of_memory_failure(); 6121 return; 6122 } 6123 int offset = __ offset_to_method_toc(float_address); 6124 int hi = (offset + (1<<15))>>16; 6125 int lo = offset - hi * (1<<16); 6126 6127 __ addis(Rtoc, Rtoc, hi); 6128 __ lfs(Rdst, lo, Rtoc); 6129 __ addis(Rtoc, Rtoc, -hi); 6130 %} 6131 ins_pipe(pipe_class_memory); 6132%} 6133 6134// Adlc adds toc node MachConstantTableBase. 6135instruct loadConF_Ex(regF dst, immF src) %{ 6136 match(Set dst src); 6137 ins_cost(MEMORY_REF_COST); 6138 6139 // See loadConP. 6140 ins_cannot_rematerialize(true); 6141 6142 format %{ "LFS $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6143 postalloc_expand( postalloc_expand_load_float_constant(dst, src, constanttablebase) ); 6144%} 6145 6146// Expand node for constant pool load: small offset. 6147instruct loadConD(regD dst, immD src, iRegLdst toc) %{ 6148 effect(DEF dst, USE src, USE toc); 6149 ins_cost(MEMORY_REF_COST); 6150 6151 ins_num_consts(1); 6152 6153 format %{ "LFD $dst, offset, $toc \t// load double $src from TOC" %} 6154 size(4); 6155 ins_encode %{ 6156 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 6157 address float_address = __ double_constant($src$$constant); 6158 if (float_address == NULL) { 6159 ciEnv::current()->record_out_of_memory_failure(); 6160 return; 6161 } 6162 int offset = __ offset_to_method_toc(float_address); 6163 __ lfd($dst$$FloatRegister, offset, $toc$$Register); 6164 %} 6165 ins_pipe(pipe_class_memory); 6166%} 6167 6168// Expand node for constant pool load: large offset. 6169instruct loadConDComp(regD dst, immD src, iRegLdst toc) %{ 6170 effect(DEF dst, USE src, USE toc); 6171 ins_cost(MEMORY_REF_COST); 6172 6173 ins_num_consts(1); 6174 6175 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6176 "LFD $dst, offset_lo, $toc \t// load double $src from TOC (hi/lo)\n\t" 6177 "ADDIS $toc, $toc, -offset_hi" %} 6178 size(12); 6179 ins_encode %{ 6180 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6181 FloatRegister Rdst = $dst$$FloatRegister; 6182 Register Rtoc = $toc$$Register; 6183 address float_address = __ double_constant($src$$constant); 6184 if (float_address == NULL) { 6185 ciEnv::current()->record_out_of_memory_failure(); 6186 return; 6187 } 6188 int offset = __ offset_to_method_toc(float_address); 6189 int hi = (offset + (1<<15))>>16; 6190 int lo = offset - hi * (1<<16); 6191 6192 __ addis(Rtoc, Rtoc, hi); 6193 __ lfd(Rdst, lo, Rtoc); 6194 __ addis(Rtoc, Rtoc, -hi); 6195 %} 6196 ins_pipe(pipe_class_memory); 6197%} 6198 6199// Adlc adds toc node MachConstantTableBase. 6200instruct loadConD_Ex(regD dst, immD src) %{ 6201 match(Set dst src); 6202 ins_cost(MEMORY_REF_COST); 6203 6204 // See loadConP. 6205 ins_cannot_rematerialize(true); 6206 6207 format %{ "ConD $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6208 postalloc_expand( postalloc_expand_load_double_constant(dst, src, constanttablebase) ); 6209%} 6210 6211// Prefetch instructions. 6212// Must be safe to execute with invalid address (cannot fault). 6213 6214// Special prefetch versions which use the dcbz instruction. 6215instruct prefetch_alloc_zero(indirectMemory mem, iRegLsrc src) %{ 6216 match(PrefetchAllocation (AddP mem src)); 6217 predicate(AllocatePrefetchStyle == 3); 6218 ins_cost(MEMORY_REF_COST); 6219 6220 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many with zero" %} 6221 size(4); 6222 ins_encode %{ 6223 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6224 __ dcbz($src$$Register, $mem$$base$$Register); 6225 %} 6226 ins_pipe(pipe_class_memory); 6227%} 6228 6229instruct prefetch_alloc_zero_no_offset(indirectMemory mem) %{ 6230 match(PrefetchAllocation mem); 6231 predicate(AllocatePrefetchStyle == 3); 6232 ins_cost(MEMORY_REF_COST); 6233 6234 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many with zero" %} 6235 size(4); 6236 ins_encode %{ 6237 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6238 __ dcbz($mem$$base$$Register); 6239 %} 6240 ins_pipe(pipe_class_memory); 6241%} 6242 6243instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{ 6244 match(PrefetchAllocation (AddP mem src)); 6245 predicate(AllocatePrefetchStyle != 3); 6246 ins_cost(MEMORY_REF_COST); 6247 6248 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many" %} 6249 size(4); 6250 ins_encode %{ 6251 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6252 __ dcbtst($src$$Register, $mem$$base$$Register); 6253 %} 6254 ins_pipe(pipe_class_memory); 6255%} 6256 6257instruct prefetch_alloc_no_offset(indirectMemory mem) %{ 6258 match(PrefetchAllocation mem); 6259 predicate(AllocatePrefetchStyle != 3); 6260 ins_cost(MEMORY_REF_COST); 6261 6262 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many" %} 6263 size(4); 6264 ins_encode %{ 6265 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6266 __ dcbtst($mem$$base$$Register); 6267 %} 6268 ins_pipe(pipe_class_memory); 6269%} 6270 6271//----------Store Instructions------------------------------------------------- 6272 6273// Store Byte 6274instruct storeB(memory mem, iRegIsrc src) %{ 6275 match(Set mem (StoreB mem src)); 6276 ins_cost(MEMORY_REF_COST); 6277 6278 format %{ "STB $src, $mem \t// byte" %} 6279 size(4); 6280 ins_encode %{ 6281 // TODO: PPC port $archOpcode(ppc64Opcode_stb); 6282 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6283 __ stb($src$$Register, Idisp, $mem$$base$$Register); 6284 %} 6285 ins_pipe(pipe_class_memory); 6286%} 6287 6288// Store Char/Short 6289instruct storeC(memory mem, iRegIsrc src) %{ 6290 match(Set mem (StoreC mem src)); 6291 ins_cost(MEMORY_REF_COST); 6292 6293 format %{ "STH $src, $mem \t// short" %} 6294 size(4); 6295 ins_encode %{ 6296 // TODO: PPC port $archOpcode(ppc64Opcode_sth); 6297 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6298 __ sth($src$$Register, Idisp, $mem$$base$$Register); 6299 %} 6300 ins_pipe(pipe_class_memory); 6301%} 6302 6303// Store Integer 6304instruct storeI(memory mem, iRegIsrc src) %{ 6305 match(Set mem (StoreI mem src)); 6306 ins_cost(MEMORY_REF_COST); 6307 6308 format %{ "STW $src, $mem" %} 6309 size(4); 6310 ins_encode( enc_stw(src, mem) ); 6311 ins_pipe(pipe_class_memory); 6312%} 6313 6314// ConvL2I + StoreI. 6315instruct storeI_convL2I(memory mem, iRegLsrc src) %{ 6316 match(Set mem (StoreI mem (ConvL2I src))); 6317 ins_cost(MEMORY_REF_COST); 6318 6319 format %{ "STW l2i($src), $mem" %} 6320 size(4); 6321 ins_encode( enc_stw(src, mem) ); 6322 ins_pipe(pipe_class_memory); 6323%} 6324 6325// Store Long 6326instruct storeL(memoryAlg4 mem, iRegLsrc src) %{ 6327 match(Set mem (StoreL mem src)); 6328 ins_cost(MEMORY_REF_COST); 6329 6330 format %{ "STD $src, $mem \t// long" %} 6331 size(4); 6332 ins_encode( enc_std(src, mem) ); 6333 ins_pipe(pipe_class_memory); 6334%} 6335 6336// Store super word nodes. 6337 6338// Store Aligned Packed Byte long register to memory 6339instruct storeA8B(memoryAlg4 mem, iRegLsrc src) %{ 6340 predicate(n->as_StoreVector()->memory_size() == 8); 6341 match(Set mem (StoreVector mem src)); 6342 ins_cost(MEMORY_REF_COST); 6343 6344 format %{ "STD $mem, $src \t// packed8B" %} 6345 size(4); 6346 ins_encode( enc_std(src, mem) ); 6347 ins_pipe(pipe_class_memory); 6348%} 6349 6350// Store Compressed Oop 6351instruct storeN(memory dst, iRegN_P2N src) %{ 6352 match(Set dst (StoreN dst src)); 6353 ins_cost(MEMORY_REF_COST); 6354 6355 format %{ "STW $src, $dst \t// compressed oop" %} 6356 size(4); 6357 ins_encode( enc_stw(src, dst) ); 6358 ins_pipe(pipe_class_memory); 6359%} 6360 6361// Store Compressed KLass 6362instruct storeNKlass(memory dst, iRegN_P2N src) %{ 6363 match(Set dst (StoreNKlass dst src)); 6364 ins_cost(MEMORY_REF_COST); 6365 6366 format %{ "STW $src, $dst \t// compressed klass" %} 6367 size(4); 6368 ins_encode( enc_stw(src, dst) ); 6369 ins_pipe(pipe_class_memory); 6370%} 6371 6372// Store Pointer 6373instruct storeP(memoryAlg4 dst, iRegPsrc src) %{ 6374 match(Set dst (StoreP dst src)); 6375 ins_cost(MEMORY_REF_COST); 6376 6377 format %{ "STD $src, $dst \t// ptr" %} 6378 size(4); 6379 ins_encode( enc_std(src, dst) ); 6380 ins_pipe(pipe_class_memory); 6381%} 6382 6383// Store Float 6384instruct storeF(memory mem, regF src) %{ 6385 match(Set mem (StoreF mem src)); 6386 ins_cost(MEMORY_REF_COST); 6387 6388 format %{ "STFS $src, $mem" %} 6389 size(4); 6390 ins_encode( enc_stfs(src, mem) ); 6391 ins_pipe(pipe_class_memory); 6392%} 6393 6394// Store Double 6395instruct storeD(memory mem, regD src) %{ 6396 match(Set mem (StoreD mem src)); 6397 ins_cost(MEMORY_REF_COST); 6398 6399 format %{ "STFD $src, $mem" %} 6400 size(4); 6401 ins_encode( enc_stfd(src, mem) ); 6402 ins_pipe(pipe_class_memory); 6403%} 6404 6405//----------Store Instructions With Zeros-------------------------------------- 6406 6407// Card-mark for CMS garbage collection. 6408// This cardmark does an optimization so that it must not always 6409// do a releasing store. For this, it gets the address of 6410// CMSCollectorCardTableModRefBSExt::_requires_release as input. 6411// (Using releaseFieldAddr in the match rule is a hack.) 6412instruct storeCM_CMS(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 6413 match(Set mem (StoreCM mem releaseFieldAddr)); 6414 effect(TEMP crx); 6415 predicate(false); 6416 ins_cost(MEMORY_REF_COST); 6417 6418 // See loadConP. 6419 ins_cannot_rematerialize(true); 6420 6421 format %{ "STB #0, $mem \t// CMS card-mark byte (must be 0!), checking requires_release in [$releaseFieldAddr]" %} 6422 ins_encode( enc_cms_card_mark(mem, releaseFieldAddr, crx) ); 6423 ins_pipe(pipe_class_memory); 6424%} 6425 6426// Card-mark for CMS garbage collection. 6427// This cardmark does an optimization so that it must not always 6428// do a releasing store. For this, it needs the constant address of 6429// CMSCollectorCardTableModRefBSExt::_requires_release. 6430// This constant address is split off here by expand so we can use 6431// adlc / matcher functionality to load it from the constant section. 6432instruct storeCM_CMS_ExEx(memory mem, immI_0 zero) %{ 6433 match(Set mem (StoreCM mem zero)); 6434 predicate(UseConcMarkSweepGC); 6435 6436 expand %{ 6437 immL baseImm %{ 0 /* TODO: PPC port (jlong)CMSCollectorCardTableModRefBSExt::requires_release_address() */ %} 6438 iRegLdst releaseFieldAddress; 6439 flagsReg crx; 6440 loadConL_Ex(releaseFieldAddress, baseImm); 6441 storeCM_CMS(mem, releaseFieldAddress, crx); 6442 %} 6443%} 6444 6445instruct storeCM_G1(memory mem, immI_0 zero) %{ 6446 match(Set mem (StoreCM mem zero)); 6447 predicate(UseG1GC); 6448 ins_cost(MEMORY_REF_COST); 6449 6450 ins_cannot_rematerialize(true); 6451 6452 format %{ "STB #0, $mem \t// CMS card-mark byte store (G1)" %} 6453 size(8); 6454 ins_encode %{ 6455 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6456 __ li(R0, 0); 6457 //__ release(); // G1: oops are allowed to get visible after dirty marking 6458 guarantee($mem$$base$$Register != R1_SP, "use frame_slots_bias"); 6459 __ stb(R0, $mem$$disp, $mem$$base$$Register); 6460 %} 6461 ins_pipe(pipe_class_memory); 6462%} 6463 6464// Convert oop pointer into compressed form. 6465 6466// Nodes for postalloc expand. 6467 6468// Shift node for expand. 6469instruct encodeP_shift(iRegNdst dst, iRegNsrc src) %{ 6470 // The match rule is needed to make it a 'MachTypeNode'! 6471 match(Set dst (EncodeP src)); 6472 predicate(false); 6473 6474 format %{ "SRDI $dst, $src, 3 \t// encode" %} 6475 size(4); 6476 ins_encode %{ 6477 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6478 __ srdi($dst$$Register, $src$$Register, Universe::narrow_oop_shift() & 0x3f); 6479 %} 6480 ins_pipe(pipe_class_default); 6481%} 6482 6483// Add node for expand. 6484instruct encodeP_sub(iRegPdst dst, iRegPdst src) %{ 6485 // The match rule is needed to make it a 'MachTypeNode'! 6486 match(Set dst (EncodeP src)); 6487 predicate(false); 6488 6489 format %{ "SUB $dst, $src, oop_base \t// encode" %} 6490 ins_encode %{ 6491 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6492 __ sub_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 6493 %} 6494 ins_pipe(pipe_class_default); 6495%} 6496 6497// Conditional sub base. 6498instruct cond_sub_base(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6499 // The match rule is needed to make it a 'MachTypeNode'! 6500 match(Set dst (EncodeP (Binary crx src1))); 6501 predicate(false); 6502 6503 format %{ "BEQ $crx, done\n\t" 6504 "SUB $dst, $src1, heapbase \t// encode: subtract base if != NULL\n" 6505 "done:" %} 6506 ins_encode %{ 6507 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6508 Label done; 6509 __ beq($crx$$CondRegister, done); 6510 __ sub_const_optimized($dst$$Register, $src1$$Register, Universe::narrow_oop_base(), R0); 6511 __ bind(done); 6512 %} 6513 ins_pipe(pipe_class_default); 6514%} 6515 6516// Power 7 can use isel instruction 6517instruct cond_set_0_oop(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6518 // The match rule is needed to make it a 'MachTypeNode'! 6519 match(Set dst (EncodeP (Binary crx src1))); 6520 predicate(false); 6521 6522 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// encode: preserve 0" %} 6523 size(4); 6524 ins_encode %{ 6525 // This is a Power7 instruction for which no machine description exists. 6526 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6527 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 6528 %} 6529 ins_pipe(pipe_class_default); 6530%} 6531 6532// Disjoint narrow oop base. 6533instruct encodeP_Disjoint(iRegNdst dst, iRegPsrc src) %{ 6534 match(Set dst (EncodeP src)); 6535 predicate(Universe::narrow_oop_base_disjoint()); 6536 6537 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 6538 size(4); 6539 ins_encode %{ 6540 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6541 __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_oop_shift(), 32); 6542 %} 6543 ins_pipe(pipe_class_default); 6544%} 6545 6546// shift != 0, base != 0 6547instruct encodeP_Ex(iRegNdst dst, flagsReg crx, iRegPsrc src) %{ 6548 match(Set dst (EncodeP src)); 6549 effect(TEMP crx); 6550 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull && 6551 Universe::narrow_oop_shift() != 0 && 6552 Universe::narrow_oop_base_overlaps()); 6553 6554 format %{ "EncodeP $dst, $crx, $src \t// postalloc expanded" %} 6555 postalloc_expand( postalloc_expand_encode_oop(dst, src, crx)); 6556%} 6557 6558// shift != 0, base != 0 6559instruct encodeP_not_null_Ex(iRegNdst dst, iRegPsrc src) %{ 6560 match(Set dst (EncodeP src)); 6561 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull && 6562 Universe::narrow_oop_shift() != 0 && 6563 Universe::narrow_oop_base_overlaps()); 6564 6565 format %{ "EncodeP $dst, $src\t// $src != Null, postalloc expanded" %} 6566 postalloc_expand( postalloc_expand_encode_oop_not_null(dst, src) ); 6567%} 6568 6569// shift != 0, base == 0 6570// TODO: This is the same as encodeP_shift. Merge! 6571instruct encodeP_not_null_base_null(iRegNdst dst, iRegPsrc src) %{ 6572 match(Set dst (EncodeP src)); 6573 predicate(Universe::narrow_oop_shift() != 0 && 6574 Universe::narrow_oop_base() ==0); 6575 6576 format %{ "SRDI $dst, $src, #3 \t// encodeP, $src != NULL" %} 6577 size(4); 6578 ins_encode %{ 6579 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6580 __ srdi($dst$$Register, $src$$Register, Universe::narrow_oop_shift() & 0x3f); 6581 %} 6582 ins_pipe(pipe_class_default); 6583%} 6584 6585// Compressed OOPs with narrow_oop_shift == 0. 6586// shift == 0, base == 0 6587instruct encodeP_narrow_oop_shift_0(iRegNdst dst, iRegPsrc src) %{ 6588 match(Set dst (EncodeP src)); 6589 predicate(Universe::narrow_oop_shift() == 0); 6590 6591 format %{ "MR $dst, $src \t// Ptr->Narrow" %} 6592 // variable size, 0 or 4. 6593 ins_encode %{ 6594 // TODO: PPC port $archOpcode(ppc64Opcode_or); 6595 __ mr_if_needed($dst$$Register, $src$$Register); 6596 %} 6597 ins_pipe(pipe_class_default); 6598%} 6599 6600// Decode nodes. 6601 6602// Shift node for expand. 6603instruct decodeN_shift(iRegPdst dst, iRegPsrc src) %{ 6604 // The match rule is needed to make it a 'MachTypeNode'! 6605 match(Set dst (DecodeN src)); 6606 predicate(false); 6607 6608 format %{ "SLDI $dst, $src, #3 \t// DecodeN" %} 6609 size(4); 6610 ins_encode %{ 6611 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 6612 __ sldi($dst$$Register, $src$$Register, Universe::narrow_oop_shift()); 6613 %} 6614 ins_pipe(pipe_class_default); 6615%} 6616 6617// Add node for expand. 6618instruct decodeN_add(iRegPdst dst, iRegPdst src) %{ 6619 // The match rule is needed to make it a 'MachTypeNode'! 6620 match(Set dst (DecodeN src)); 6621 predicate(false); 6622 6623 format %{ "ADD $dst, $src, heapbase \t// DecodeN, add oop base" %} 6624 ins_encode %{ 6625 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6626 __ add_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 6627 %} 6628 ins_pipe(pipe_class_default); 6629%} 6630 6631// conditianal add base for expand 6632instruct cond_add_base(iRegPdst dst, flagsRegSrc crx, iRegPsrc src) %{ 6633 // The match rule is needed to make it a 'MachTypeNode'! 6634 // NOTICE that the rule is nonsense - we just have to make sure that: 6635 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 6636 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 6637 match(Set dst (DecodeN (Binary crx src))); 6638 predicate(false); 6639 6640 format %{ "BEQ $crx, done\n\t" 6641 "ADD $dst, $src, heapbase \t// DecodeN: add oop base if $src != NULL\n" 6642 "done:" %} 6643 ins_encode %{ 6644 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6645 Label done; 6646 __ beq($crx$$CondRegister, done); 6647 __ add_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 6648 __ bind(done); 6649 %} 6650 ins_pipe(pipe_class_default); 6651%} 6652 6653instruct cond_set_0_ptr(iRegPdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6654 // The match rule is needed to make it a 'MachTypeNode'! 6655 // NOTICE that the rule is nonsense - we just have to make sure that: 6656 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 6657 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 6658 match(Set dst (DecodeN (Binary crx src1))); 6659 predicate(false); 6660 6661 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// decode: preserve 0" %} 6662 size(4); 6663 ins_encode %{ 6664 // This is a Power7 instruction for which no machine description exists. 6665 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6666 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 6667 %} 6668 ins_pipe(pipe_class_default); 6669%} 6670 6671// shift != 0, base != 0 6672instruct decodeN_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 6673 match(Set dst (DecodeN src)); 6674 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 6675 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 6676 Universe::narrow_oop_shift() != 0 && 6677 Universe::narrow_oop_base() != 0); 6678 ins_cost(4 * DEFAULT_COST); // Should be more expensive than decodeN_Disjoint_isel_Ex. 6679 effect(TEMP crx); 6680 6681 format %{ "DecodeN $dst, $src \t// Kills $crx, postalloc expanded" %} 6682 postalloc_expand( postalloc_expand_decode_oop(dst, src, crx) ); 6683%} 6684 6685// shift != 0, base == 0 6686instruct decodeN_nullBase(iRegPdst dst, iRegNsrc src) %{ 6687 match(Set dst (DecodeN src)); 6688 predicate(Universe::narrow_oop_shift() != 0 && 6689 Universe::narrow_oop_base() == 0); 6690 6691 format %{ "SLDI $dst, $src, #3 \t// DecodeN (zerobased)" %} 6692 size(4); 6693 ins_encode %{ 6694 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 6695 __ sldi($dst$$Register, $src$$Register, Universe::narrow_oop_shift()); 6696 %} 6697 ins_pipe(pipe_class_default); 6698%} 6699 6700// Optimize DecodeN for disjoint base. 6701// Shift narrow oop and or it into register that already contains the heap base. 6702// Base == dst must hold, and is assured by construction in postaloc_expand. 6703instruct decodeN_mergeDisjoint(iRegPdst dst, iRegNsrc src, iRegLsrc base) %{ 6704 match(Set dst (DecodeN src)); 6705 effect(TEMP base); 6706 predicate(false); 6707 6708 format %{ "RLDIMI $dst, $src, shift, 32-shift \t// DecodeN (disjoint base)" %} 6709 size(4); 6710 ins_encode %{ 6711 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 6712 __ rldimi($dst$$Register, $src$$Register, Universe::narrow_oop_shift(), 32-Universe::narrow_oop_shift()); 6713 %} 6714 ins_pipe(pipe_class_default); 6715%} 6716 6717// Optimize DecodeN for disjoint base. 6718// This node requires only one cycle on the critical path. 6719// We must postalloc_expand as we can not express use_def effects where 6720// the used register is L and the def'ed register P. 6721instruct decodeN_Disjoint_notNull_Ex(iRegPdst dst, iRegNsrc src) %{ 6722 match(Set dst (DecodeN src)); 6723 effect(TEMP_DEF dst); 6724 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 6725 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 6726 Universe::narrow_oop_base_disjoint()); 6727 ins_cost(DEFAULT_COST); 6728 6729 format %{ "MOV $dst, heapbase \t\n" 6730 "RLDIMI $dst, $src, shift, 32-shift \t// decode with disjoint base" %} 6731 postalloc_expand %{ 6732 loadBaseNode *n1 = new loadBaseNode(); 6733 n1->add_req(NULL); 6734 n1->_opnds[0] = op_dst; 6735 6736 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 6737 n2->add_req(n_region, n_src, n1); 6738 n2->_opnds[0] = op_dst; 6739 n2->_opnds[1] = op_src; 6740 n2->_opnds[2] = op_dst; 6741 n2->_bottom_type = _bottom_type; 6742 6743 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6744 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6745 6746 nodes->push(n1); 6747 nodes->push(n2); 6748 %} 6749%} 6750 6751instruct decodeN_Disjoint_isel_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 6752 match(Set dst (DecodeN src)); 6753 effect(TEMP_DEF dst, TEMP crx); 6754 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 6755 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 6756 Universe::narrow_oop_base_disjoint() && VM_Version::has_isel()); 6757 ins_cost(3 * DEFAULT_COST); 6758 6759 format %{ "DecodeN $dst, $src \t// decode with disjoint base using isel" %} 6760 postalloc_expand %{ 6761 loadBaseNode *n1 = new loadBaseNode(); 6762 n1->add_req(NULL); 6763 n1->_opnds[0] = op_dst; 6764 6765 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 6766 n_compare->add_req(n_region, n_src); 6767 n_compare->_opnds[0] = op_crx; 6768 n_compare->_opnds[1] = op_src; 6769 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 6770 6771 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 6772 n2->add_req(n_region, n_src, n1); 6773 n2->_opnds[0] = op_dst; 6774 n2->_opnds[1] = op_src; 6775 n2->_opnds[2] = op_dst; 6776 n2->_bottom_type = _bottom_type; 6777 6778 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 6779 n_cond_set->add_req(n_region, n_compare, n2); 6780 n_cond_set->_opnds[0] = op_dst; 6781 n_cond_set->_opnds[1] = op_crx; 6782 n_cond_set->_opnds[2] = op_dst; 6783 n_cond_set->_bottom_type = _bottom_type; 6784 6785 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 6786 ra_->set_oop(n_cond_set, true); 6787 6788 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6789 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 6790 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6791 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6792 6793 nodes->push(n1); 6794 nodes->push(n_compare); 6795 nodes->push(n2); 6796 nodes->push(n_cond_set); 6797 %} 6798%} 6799 6800// src != 0, shift != 0, base != 0 6801instruct decodeN_notNull_addBase_Ex(iRegPdst dst, iRegNsrc src) %{ 6802 match(Set dst (DecodeN src)); 6803 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 6804 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 6805 Universe::narrow_oop_shift() != 0 && 6806 Universe::narrow_oop_base() != 0); 6807 ins_cost(2 * DEFAULT_COST); 6808 6809 format %{ "DecodeN $dst, $src \t// $src != NULL, postalloc expanded" %} 6810 postalloc_expand( postalloc_expand_decode_oop_not_null(dst, src)); 6811%} 6812 6813// Compressed OOPs with narrow_oop_shift == 0. 6814instruct decodeN_unscaled(iRegPdst dst, iRegNsrc src) %{ 6815 match(Set dst (DecodeN src)); 6816 predicate(Universe::narrow_oop_shift() == 0); 6817 ins_cost(DEFAULT_COST); 6818 6819 format %{ "MR $dst, $src \t// DecodeN (unscaled)" %} 6820 // variable size, 0 or 4. 6821 ins_encode %{ 6822 // TODO: PPC port $archOpcode(ppc64Opcode_or); 6823 __ mr_if_needed($dst$$Register, $src$$Register); 6824 %} 6825 ins_pipe(pipe_class_default); 6826%} 6827 6828// Convert compressed oop into int for vectors alignment masking. 6829instruct decodeN2I_unscaled(iRegIdst dst, iRegNsrc src) %{ 6830 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6831 predicate(Universe::narrow_oop_shift() == 0); 6832 ins_cost(DEFAULT_COST); 6833 6834 format %{ "MR $dst, $src \t// (int)DecodeN (unscaled)" %} 6835 // variable size, 0 or 4. 6836 ins_encode %{ 6837 // TODO: PPC port $archOpcode(ppc64Opcode_or); 6838 __ mr_if_needed($dst$$Register, $src$$Register); 6839 %} 6840 ins_pipe(pipe_class_default); 6841%} 6842 6843// Convert klass pointer into compressed form. 6844 6845// Nodes for postalloc expand. 6846 6847// Shift node for expand. 6848instruct encodePKlass_shift(iRegNdst dst, iRegNsrc src) %{ 6849 // The match rule is needed to make it a 'MachTypeNode'! 6850 match(Set dst (EncodePKlass src)); 6851 predicate(false); 6852 6853 format %{ "SRDI $dst, $src, 3 \t// encode" %} 6854 size(4); 6855 ins_encode %{ 6856 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6857 __ srdi($dst$$Register, $src$$Register, Universe::narrow_klass_shift()); 6858 %} 6859 ins_pipe(pipe_class_default); 6860%} 6861 6862// Add node for expand. 6863instruct encodePKlass_sub_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 6864 // The match rule is needed to make it a 'MachTypeNode'! 6865 match(Set dst (EncodePKlass (Binary base src))); 6866 predicate(false); 6867 6868 format %{ "SUB $dst, $base, $src \t// encode" %} 6869 size(4); 6870 ins_encode %{ 6871 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 6872 __ subf($dst$$Register, $base$$Register, $src$$Register); 6873 %} 6874 ins_pipe(pipe_class_default); 6875%} 6876 6877// Disjoint narrow oop base. 6878instruct encodePKlass_Disjoint(iRegNdst dst, iRegPsrc src) %{ 6879 match(Set dst (EncodePKlass src)); 6880 predicate(false /* TODO: PPC port Universe::narrow_klass_base_disjoint()*/); 6881 6882 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 6883 size(4); 6884 ins_encode %{ 6885 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6886 __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_klass_shift(), 32); 6887 %} 6888 ins_pipe(pipe_class_default); 6889%} 6890 6891// shift != 0, base != 0 6892instruct encodePKlass_not_null_Ex(iRegNdst dst, iRegLsrc base, iRegPsrc src) %{ 6893 match(Set dst (EncodePKlass (Binary base src))); 6894 predicate(false); 6895 6896 format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 6897 postalloc_expand %{ 6898 encodePKlass_sub_baseNode *n1 = new encodePKlass_sub_baseNode(); 6899 n1->add_req(n_region, n_base, n_src); 6900 n1->_opnds[0] = op_dst; 6901 n1->_opnds[1] = op_base; 6902 n1->_opnds[2] = op_src; 6903 n1->_bottom_type = _bottom_type; 6904 6905 encodePKlass_shiftNode *n2 = new encodePKlass_shiftNode(); 6906 n2->add_req(n_region, n1); 6907 n2->_opnds[0] = op_dst; 6908 n2->_opnds[1] = op_dst; 6909 n2->_bottom_type = _bottom_type; 6910 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6911 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6912 6913 nodes->push(n1); 6914 nodes->push(n2); 6915 %} 6916%} 6917 6918// shift != 0, base != 0 6919instruct encodePKlass_not_null_ExEx(iRegNdst dst, iRegPsrc src) %{ 6920 match(Set dst (EncodePKlass src)); 6921 //predicate(Universe::narrow_klass_shift() != 0 && 6922 // true /* TODO: PPC port Universe::narrow_klass_base_overlaps()*/); 6923 6924 //format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 6925 ins_cost(DEFAULT_COST*2); // Don't count constant. 6926 expand %{ 6927 immL baseImm %{ (jlong)(intptr_t)Universe::narrow_klass_base() %} 6928 iRegLdst base; 6929 loadConL_Ex(base, baseImm); 6930 encodePKlass_not_null_Ex(dst, base, src); 6931 %} 6932%} 6933 6934// Decode nodes. 6935 6936// Shift node for expand. 6937instruct decodeNKlass_shift(iRegPdst dst, iRegPsrc src) %{ 6938 // The match rule is needed to make it a 'MachTypeNode'! 6939 match(Set dst (DecodeNKlass src)); 6940 predicate(false); 6941 6942 format %{ "SLDI $dst, $src, #3 \t// DecodeNKlass" %} 6943 size(4); 6944 ins_encode %{ 6945 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 6946 __ sldi($dst$$Register, $src$$Register, Universe::narrow_klass_shift()); 6947 %} 6948 ins_pipe(pipe_class_default); 6949%} 6950 6951// Add node for expand. 6952 6953instruct decodeNKlass_add_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 6954 // The match rule is needed to make it a 'MachTypeNode'! 6955 match(Set dst (DecodeNKlass (Binary base src))); 6956 predicate(false); 6957 6958 format %{ "ADD $dst, $base, $src \t// DecodeNKlass, add klass base" %} 6959 size(4); 6960 ins_encode %{ 6961 // TODO: PPC port $archOpcode(ppc64Opcode_add); 6962 __ add($dst$$Register, $base$$Register, $src$$Register); 6963 %} 6964 ins_pipe(pipe_class_default); 6965%} 6966 6967// src != 0, shift != 0, base != 0 6968instruct decodeNKlass_notNull_addBase_Ex(iRegPdst dst, iRegLsrc base, iRegNsrc src) %{ 6969 match(Set dst (DecodeNKlass (Binary base src))); 6970 //effect(kill src); // We need a register for the immediate result after shifting. 6971 predicate(false); 6972 6973 format %{ "DecodeNKlass $dst = $base + ($src << 3) \t// $src != NULL, postalloc expanded" %} 6974 postalloc_expand %{ 6975 decodeNKlass_add_baseNode *n1 = new decodeNKlass_add_baseNode(); 6976 n1->add_req(n_region, n_base, n_src); 6977 n1->_opnds[0] = op_dst; 6978 n1->_opnds[1] = op_base; 6979 n1->_opnds[2] = op_src; 6980 n1->_bottom_type = _bottom_type; 6981 6982 decodeNKlass_shiftNode *n2 = new decodeNKlass_shiftNode(); 6983 n2->add_req(n_region, n1); 6984 n2->_opnds[0] = op_dst; 6985 n2->_opnds[1] = op_dst; 6986 n2->_bottom_type = _bottom_type; 6987 6988 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6989 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6990 6991 nodes->push(n1); 6992 nodes->push(n2); 6993 %} 6994%} 6995 6996// src != 0, shift != 0, base != 0 6997instruct decodeNKlass_notNull_addBase_ExEx(iRegPdst dst, iRegNsrc src) %{ 6998 match(Set dst (DecodeNKlass src)); 6999 // predicate(Universe::narrow_klass_shift() != 0 && 7000 // Universe::narrow_klass_base() != 0); 7001 7002 //format %{ "DecodeNKlass $dst, $src \t// $src != NULL, expanded" %} 7003 7004 ins_cost(DEFAULT_COST*2); // Don't count constant. 7005 expand %{ 7006 // We add first, then we shift. Like this, we can get along with one register less. 7007 // But we have to load the base pre-shifted. 7008 immL baseImm %{ (jlong)((intptr_t)Universe::narrow_klass_base() >> Universe::narrow_klass_shift()) %} 7009 iRegLdst base; 7010 loadConL_Ex(base, baseImm); 7011 decodeNKlass_notNull_addBase_Ex(dst, base, src); 7012 %} 7013%} 7014 7015//----------MemBar Instructions----------------------------------------------- 7016// Memory barrier flavors 7017 7018instruct membar_acquire() %{ 7019 match(LoadFence); 7020 ins_cost(4*MEMORY_REF_COST); 7021 7022 format %{ "MEMBAR-acquire" %} 7023 size(4); 7024 ins_encode %{ 7025 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7026 __ acquire(); 7027 %} 7028 ins_pipe(pipe_class_default); 7029%} 7030 7031instruct unnecessary_membar_acquire() %{ 7032 match(MemBarAcquire); 7033 ins_cost(0); 7034 7035 format %{ " -- \t// redundant MEMBAR-acquire - empty" %} 7036 size(0); 7037 ins_encode( /*empty*/ ); 7038 ins_pipe(pipe_class_default); 7039%} 7040 7041instruct membar_acquire_lock() %{ 7042 match(MemBarAcquireLock); 7043 ins_cost(0); 7044 7045 format %{ " -- \t// redundant MEMBAR-acquire - empty (acquire as part of CAS in prior FastLock)" %} 7046 size(0); 7047 ins_encode( /*empty*/ ); 7048 ins_pipe(pipe_class_default); 7049%} 7050 7051instruct membar_release() %{ 7052 match(MemBarRelease); 7053 match(StoreFence); 7054 ins_cost(4*MEMORY_REF_COST); 7055 7056 format %{ "MEMBAR-release" %} 7057 size(4); 7058 ins_encode %{ 7059 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7060 __ release(); 7061 %} 7062 ins_pipe(pipe_class_default); 7063%} 7064 7065instruct membar_storestore() %{ 7066 match(MemBarStoreStore); 7067 ins_cost(4*MEMORY_REF_COST); 7068 7069 format %{ "MEMBAR-store-store" %} 7070 size(4); 7071 ins_encode %{ 7072 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7073 __ membar(Assembler::StoreStore); 7074 %} 7075 ins_pipe(pipe_class_default); 7076%} 7077 7078instruct membar_release_lock() %{ 7079 match(MemBarReleaseLock); 7080 ins_cost(0); 7081 7082 format %{ " -- \t// redundant MEMBAR-release - empty (release in FastUnlock)" %} 7083 size(0); 7084 ins_encode( /*empty*/ ); 7085 ins_pipe(pipe_class_default); 7086%} 7087 7088instruct membar_volatile() %{ 7089 match(MemBarVolatile); 7090 ins_cost(4*MEMORY_REF_COST); 7091 7092 format %{ "MEMBAR-volatile" %} 7093 size(4); 7094 ins_encode %{ 7095 // TODO: PPC port $archOpcode(ppc64Opcode_sync); 7096 __ fence(); 7097 %} 7098 ins_pipe(pipe_class_default); 7099%} 7100 7101// This optimization is wrong on PPC. The following pattern is not supported: 7102// MemBarVolatile 7103// ^ ^ 7104// | | 7105// CtrlProj MemProj 7106// ^ ^ 7107// | | 7108// | Load 7109// | 7110// MemBarVolatile 7111// 7112// The first MemBarVolatile could get optimized out! According to 7113// Vladimir, this pattern can not occur on Oracle platforms. 7114// However, it does occur on PPC64 (because of membars in 7115// inline_unsafe_load_store). 7116// 7117// Add this node again if we found a good solution for inline_unsafe_load_store(). 7118// Don't forget to look at the implementation of post_store_load_barrier again, 7119// we did other fixes in that method. 7120//instruct unnecessary_membar_volatile() %{ 7121// match(MemBarVolatile); 7122// predicate(Matcher::post_store_load_barrier(n)); 7123// ins_cost(0); 7124// 7125// format %{ " -- \t// redundant MEMBAR-volatile - empty" %} 7126// size(0); 7127// ins_encode( /*empty*/ ); 7128// ins_pipe(pipe_class_default); 7129//%} 7130 7131instruct membar_CPUOrder() %{ 7132 match(MemBarCPUOrder); 7133 ins_cost(0); 7134 7135 format %{ " -- \t// MEMBAR-CPUOrder - empty: PPC64 processors are self-consistent." %} 7136 size(0); 7137 ins_encode( /*empty*/ ); 7138 ins_pipe(pipe_class_default); 7139%} 7140 7141//----------Conditional Move--------------------------------------------------- 7142 7143// Cmove using isel. 7144instruct cmovI_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7145 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7146 predicate(VM_Version::has_isel()); 7147 ins_cost(DEFAULT_COST); 7148 7149 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7150 size(4); 7151 ins_encode %{ 7152 // This is a Power7 instruction for which no machine description 7153 // exists. Anyways, the scheduler should be off on Power7. 7154 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7155 int cc = $cmp$$cmpcode; 7156 __ isel($dst$$Register, $crx$$CondRegister, 7157 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7158 %} 7159 ins_pipe(pipe_class_default); 7160%} 7161 7162instruct cmovI_reg(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7163 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7164 predicate(!VM_Version::has_isel()); 7165 ins_cost(DEFAULT_COST+BRANCH_COST); 7166 7167 ins_variable_size_depending_on_alignment(true); 7168 7169 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7170 // Worst case is branch + move + stop, no stop without scheduler 7171 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7172 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7173 ins_pipe(pipe_class_default); 7174%} 7175 7176instruct cmovI_imm(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, immI16 src) %{ 7177 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7178 ins_cost(DEFAULT_COST+BRANCH_COST); 7179 7180 ins_variable_size_depending_on_alignment(true); 7181 7182 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7183 // Worst case is branch + move + stop, no stop without scheduler 7184 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7185 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7186 ins_pipe(pipe_class_default); 7187%} 7188 7189// Cmove using isel. 7190instruct cmovL_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7191 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7192 predicate(VM_Version::has_isel()); 7193 ins_cost(DEFAULT_COST); 7194 7195 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7196 size(4); 7197 ins_encode %{ 7198 // This is a Power7 instruction for which no machine description 7199 // exists. Anyways, the scheduler should be off on Power7. 7200 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7201 int cc = $cmp$$cmpcode; 7202 __ isel($dst$$Register, $crx$$CondRegister, 7203 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7204 %} 7205 ins_pipe(pipe_class_default); 7206%} 7207 7208instruct cmovL_reg(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7209 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7210 predicate(!VM_Version::has_isel()); 7211 ins_cost(DEFAULT_COST+BRANCH_COST); 7212 7213 ins_variable_size_depending_on_alignment(true); 7214 7215 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7216 // Worst case is branch + move + stop, no stop without scheduler. 7217 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7218 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7219 ins_pipe(pipe_class_default); 7220%} 7221 7222instruct cmovL_imm(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, immL16 src) %{ 7223 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7224 ins_cost(DEFAULT_COST+BRANCH_COST); 7225 7226 ins_variable_size_depending_on_alignment(true); 7227 7228 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7229 // Worst case is branch + move + stop, no stop without scheduler. 7230 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7231 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7232 ins_pipe(pipe_class_default); 7233%} 7234 7235// Cmove using isel. 7236instruct cmovN_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7237 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7238 predicate(VM_Version::has_isel()); 7239 ins_cost(DEFAULT_COST); 7240 7241 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7242 size(4); 7243 ins_encode %{ 7244 // This is a Power7 instruction for which no machine description 7245 // exists. Anyways, the scheduler should be off on Power7. 7246 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7247 int cc = $cmp$$cmpcode; 7248 __ isel($dst$$Register, $crx$$CondRegister, 7249 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7250 %} 7251 ins_pipe(pipe_class_default); 7252%} 7253 7254// Conditional move for RegN. Only cmov(reg, reg). 7255instruct cmovN_reg(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7256 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7257 predicate(!VM_Version::has_isel()); 7258 ins_cost(DEFAULT_COST+BRANCH_COST); 7259 7260 ins_variable_size_depending_on_alignment(true); 7261 7262 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7263 // Worst case is branch + move + stop, no stop without scheduler. 7264 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7265 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7266 ins_pipe(pipe_class_default); 7267%} 7268 7269instruct cmovN_imm(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, immN_0 src) %{ 7270 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7271 ins_cost(DEFAULT_COST+BRANCH_COST); 7272 7273 ins_variable_size_depending_on_alignment(true); 7274 7275 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7276 // Worst case is branch + move + stop, no stop without scheduler. 7277 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7278 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7279 ins_pipe(pipe_class_default); 7280%} 7281 7282// Cmove using isel. 7283instruct cmovP_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegPsrc src) %{ 7284 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7285 predicate(VM_Version::has_isel()); 7286 ins_cost(DEFAULT_COST); 7287 7288 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7289 size(4); 7290 ins_encode %{ 7291 // This is a Power7 instruction for which no machine description 7292 // exists. Anyways, the scheduler should be off on Power7. 7293 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7294 int cc = $cmp$$cmpcode; 7295 __ isel($dst$$Register, $crx$$CondRegister, 7296 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7297 %} 7298 ins_pipe(pipe_class_default); 7299%} 7300 7301instruct cmovP_reg(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegP_N2P src) %{ 7302 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7303 predicate(!VM_Version::has_isel()); 7304 ins_cost(DEFAULT_COST+BRANCH_COST); 7305 7306 ins_variable_size_depending_on_alignment(true); 7307 7308 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7309 // Worst case is branch + move + stop, no stop without scheduler. 7310 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7311 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7312 ins_pipe(pipe_class_default); 7313%} 7314 7315instruct cmovP_imm(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, immP_0 src) %{ 7316 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7317 ins_cost(DEFAULT_COST+BRANCH_COST); 7318 7319 ins_variable_size_depending_on_alignment(true); 7320 7321 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7322 // Worst case is branch + move + stop, no stop without scheduler. 7323 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7324 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7325 ins_pipe(pipe_class_default); 7326%} 7327 7328instruct cmovF_reg(cmpOp cmp, flagsRegSrc crx, regF dst, regF src) %{ 7329 match(Set dst (CMoveF (Binary cmp crx) (Binary dst src))); 7330 ins_cost(DEFAULT_COST+BRANCH_COST); 7331 7332 ins_variable_size_depending_on_alignment(true); 7333 7334 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7335 // Worst case is branch + move + stop, no stop without scheduler. 7336 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 7337 ins_encode %{ 7338 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7339 Label done; 7340 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7341 // Branch if not (cmp crx). 7342 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7343 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7344 // TODO PPC port __ endgroup_if_needed(_size == 12); 7345 __ bind(done); 7346 %} 7347 ins_pipe(pipe_class_default); 7348%} 7349 7350instruct cmovD_reg(cmpOp cmp, flagsRegSrc crx, regD dst, regD src) %{ 7351 match(Set dst (CMoveD (Binary cmp crx) (Binary dst src))); 7352 ins_cost(DEFAULT_COST+BRANCH_COST); 7353 7354 ins_variable_size_depending_on_alignment(true); 7355 7356 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7357 // Worst case is branch + move + stop, no stop without scheduler. 7358 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 7359 ins_encode %{ 7360 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7361 Label done; 7362 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7363 // Branch if not (cmp crx). 7364 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7365 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7366 // TODO PPC port __ endgroup_if_needed(_size == 12); 7367 __ bind(done); 7368 %} 7369 ins_pipe(pipe_class_default); 7370%} 7371 7372//----------Conditional_store-------------------------------------------------- 7373// Conditional-store of the updated heap-top. 7374// Used during allocation of the shared heap. 7375// Sets flags (EQ) on success. Implemented with a CASA on Sparc. 7376 7377// As compareAndSwapL, but return flag register instead of boolean value in 7378// int register. 7379// Used by sun/misc/AtomicLongCSImpl.java. 7380// Mem_ptr must be a memory operand, else this node does not get 7381// Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7382// can be rematerialized which leads to errors. 7383instruct storeLConditional_regP_regL_regL(flagsReg crx, indirect mem_ptr, iRegLsrc oldVal, iRegLsrc newVal, flagsRegCR0 cr0) %{ 7384 match(Set crx (StoreLConditional mem_ptr (Binary oldVal newVal))); 7385 effect(TEMP cr0); 7386 format %{ "CMPXCHGD if ($crx = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7387 ins_encode %{ 7388 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7389 __ cmpxchgd($crx$$CondRegister, R0, $oldVal$$Register, $newVal$$Register, $mem_ptr$$Register, 7390 MacroAssembler::MemBarAcq, MacroAssembler::cmpxchgx_hint_atomic_update(), 7391 noreg, NULL, true); 7392 %} 7393 ins_pipe(pipe_class_default); 7394%} 7395 7396// As compareAndSwapP, but return flag register instead of boolean value in 7397// int register. 7398// This instruction is matched if UseTLAB is off. 7399// Mem_ptr must be a memory operand, else this node does not get 7400// Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7401// can be rematerialized which leads to errors. 7402instruct storePConditional_regP_regP_regP(flagsRegCR0 cr0, indirect mem_ptr, iRegPsrc oldVal, iRegPsrc newVal) %{ 7403 match(Set cr0 (StorePConditional mem_ptr (Binary oldVal newVal))); 7404 ins_cost(2*MEMORY_REF_COST); 7405 7406 format %{ "STDCX_ if ($cr0 = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7407 ins_encode %{ 7408 // TODO: PPC port $archOpcode(ppc64Opcode_stdcx_); 7409 __ stdcx_($newVal$$Register, $mem_ptr$$Register); 7410 %} 7411 ins_pipe(pipe_class_memory); 7412%} 7413 7414// Implement LoadPLocked. Must be ordered against changes of the memory location 7415// by storePConditional. 7416// Don't know whether this is ever used. 7417instruct loadPLocked(iRegPdst dst, memory mem) %{ 7418 match(Set dst (LoadPLocked mem)); 7419 ins_cost(2*MEMORY_REF_COST); 7420 7421 format %{ "LDARX $dst, $mem \t// loadPLocked\n\t" %} 7422 size(4); 7423 ins_encode %{ 7424 // TODO: PPC port $archOpcode(ppc64Opcode_ldarx); 7425 __ ldarx($dst$$Register, $mem$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 7426 %} 7427 ins_pipe(pipe_class_memory); 7428%} 7429 7430//----------Compare-And-Swap--------------------------------------------------- 7431 7432// CompareAndSwap{P,I,L} have more than one output, therefore "CmpI 7433// (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be 7434// matched. 7435 7436// Strong versions: 7437 7438instruct compareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7439 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7440 predicate(VM_Version::has_lqarx()); 7441 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7442 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7443 ins_encode %{ 7444 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7445 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7446 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7447 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7448 $res$$Register, true); 7449 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7450 __ isync(); 7451 } else { 7452 __ sync(); 7453 } 7454 %} 7455 ins_pipe(pipe_class_default); 7456%} 7457 7458instruct compareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7459 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7460 predicate(!VM_Version::has_lqarx()); 7461 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7462 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7463 ins_encode %{ 7464 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7465 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7466 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7467 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7468 $res$$Register, true); 7469 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7470 __ isync(); 7471 } else { 7472 __ sync(); 7473 } 7474 %} 7475 ins_pipe(pipe_class_default); 7476%} 7477 7478instruct compareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7479 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7480 predicate(VM_Version::has_lqarx()); 7481 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7482 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7483 ins_encode %{ 7484 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7485 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7486 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7487 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7488 $res$$Register, true); 7489 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7490 __ isync(); 7491 } else { 7492 __ sync(); 7493 } 7494 %} 7495 ins_pipe(pipe_class_default); 7496%} 7497 7498instruct compareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7499 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7500 predicate(!VM_Version::has_lqarx()); 7501 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7502 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7503 ins_encode %{ 7504 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7505 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7506 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7507 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7508 $res$$Register, true); 7509 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7510 __ isync(); 7511 } else { 7512 __ sync(); 7513 } 7514 %} 7515 ins_pipe(pipe_class_default); 7516%} 7517 7518instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7519 match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2))); 7520 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7521 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7522 ins_encode %{ 7523 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7524 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7525 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7526 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7527 $res$$Register, true); 7528 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7529 __ isync(); 7530 } else { 7531 __ sync(); 7532 } 7533 %} 7534 ins_pipe(pipe_class_default); 7535%} 7536 7537instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 7538 match(Set res (CompareAndSwapN mem_ptr (Binary src1 src2))); 7539 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7540 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7541 ins_encode %{ 7542 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7543 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7544 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7545 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7546 $res$$Register, true); 7547 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7548 __ isync(); 7549 } else { 7550 __ sync(); 7551 } 7552 %} 7553 ins_pipe(pipe_class_default); 7554%} 7555 7556instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 7557 match(Set res (CompareAndSwapL mem_ptr (Binary src1 src2))); 7558 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7559 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 7560 ins_encode %{ 7561 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7562 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7563 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7564 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7565 $res$$Register, NULL, true); 7566 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7567 __ isync(); 7568 } else { 7569 __ sync(); 7570 } 7571 %} 7572 ins_pipe(pipe_class_default); 7573%} 7574 7575instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 7576 match(Set res (CompareAndSwapP mem_ptr (Binary src1 src2))); 7577 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7578 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 7579 ins_encode %{ 7580 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7581 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7582 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7583 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7584 $res$$Register, NULL, true); 7585 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7586 __ isync(); 7587 } else { 7588 __ sync(); 7589 } 7590 %} 7591 ins_pipe(pipe_class_default); 7592%} 7593 7594// Weak versions: 7595 7596instruct weakCompareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7597 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7598 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7599 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7600 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7601 ins_encode %{ 7602 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7603 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7604 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7605 MacroAssembler::MemBarNone, 7606 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7607 %} 7608 ins_pipe(pipe_class_default); 7609%} 7610 7611instruct weakCompareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7612 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7613 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 7614 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7615 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7616 ins_encode %{ 7617 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7618 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7619 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7620 MacroAssembler::MemBarNone, 7621 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7622 %} 7623 ins_pipe(pipe_class_default); 7624%} 7625 7626instruct weakCompareAndSwapB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7627 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7628 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 7629 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7630 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 7631 ins_encode %{ 7632 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7633 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7634 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7635 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7636 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7637 %} 7638 ins_pipe(pipe_class_default); 7639%} 7640 7641instruct weakCompareAndSwapB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7642 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7643 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 7644 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7645 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 7646 ins_encode %{ 7647 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7648 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7649 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7650 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7651 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7652 %} 7653 ins_pipe(pipe_class_default); 7654%} 7655 7656instruct weakCompareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7657 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 7658 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7659 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7660 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7661 ins_encode %{ 7662 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7663 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7664 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7665 MacroAssembler::MemBarNone, 7666 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7667 %} 7668 ins_pipe(pipe_class_default); 7669%} 7670 7671instruct weakCompareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7672 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 7673 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 7674 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7675 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7676 ins_encode %{ 7677 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7678 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7679 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7680 MacroAssembler::MemBarNone, 7681 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7682 %} 7683 ins_pipe(pipe_class_default); 7684%} 7685 7686instruct weakCompareAndSwapS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7687 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 7688 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 7689 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7690 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 7691 ins_encode %{ 7692 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7693 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7694 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7695 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7696 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7697 %} 7698 ins_pipe(pipe_class_default); 7699%} 7700 7701instruct weakCompareAndSwapS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7702 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 7703 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 7704 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7705 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 7706 ins_encode %{ 7707 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7708 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7709 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7710 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7711 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7712 %} 7713 ins_pipe(pipe_class_default); 7714%} 7715 7716instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7717 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 7718 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7719 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7720 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7721 ins_encode %{ 7722 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7723 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7724 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7725 MacroAssembler::MemBarNone, 7726 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7727 %} 7728 ins_pipe(pipe_class_default); 7729%} 7730 7731instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7732 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 7733 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 7734 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7735 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 7736 ins_encode %{ 7737 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7738 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7739 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 7740 // value is never passed to caller. 7741 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7742 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7743 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7744 %} 7745 ins_pipe(pipe_class_default); 7746%} 7747 7748instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 7749 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 7750 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7751 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7752 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7753 ins_encode %{ 7754 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7755 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7756 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7757 MacroAssembler::MemBarNone, 7758 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7759 %} 7760 ins_pipe(pipe_class_default); 7761%} 7762 7763instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 7764 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 7765 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 7766 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7767 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 7768 ins_encode %{ 7769 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7770 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7771 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 7772 // value is never passed to caller. 7773 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7774 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7775 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7776 %} 7777 ins_pipe(pipe_class_default); 7778%} 7779 7780instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 7781 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 7782 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7783 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7784 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 7785 ins_encode %{ 7786 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7787 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7788 // value is never passed to caller. 7789 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7790 MacroAssembler::MemBarNone, 7791 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 7792 %} 7793 ins_pipe(pipe_class_default); 7794%} 7795 7796instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 7797 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 7798 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 7799 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7800 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %} 7801 ins_encode %{ 7802 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7803 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7804 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 7805 // value is never passed to caller. 7806 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7807 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7808 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 7809 %} 7810 ins_pipe(pipe_class_default); 7811%} 7812 7813instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 7814 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 7815 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7816 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7817 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 7818 ins_encode %{ 7819 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7820 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7821 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7822 MacroAssembler::MemBarNone, 7823 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 7824 %} 7825 ins_pipe(pipe_class_default); 7826%} 7827 7828instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 7829 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 7830 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 7831 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7832 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 7833 ins_encode %{ 7834 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7835 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7836 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 7837 // value is never passed to caller. 7838 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7839 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7840 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 7841 %} 7842 ins_pipe(pipe_class_default); 7843%} 7844 7845// CompareAndExchange 7846 7847instruct compareAndExchangeB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7848 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 7849 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7850 effect(TEMP_DEF res, TEMP cr0); 7851 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 7852 ins_encode %{ 7853 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7854 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7855 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7856 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7857 noreg, true); 7858 %} 7859 ins_pipe(pipe_class_default); 7860%} 7861 7862instruct compareAndExchangeB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 7863 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 7864 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 7865 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 7866 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 7867 ins_encode %{ 7868 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7869 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7870 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 7871 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7872 noreg, true); 7873 %} 7874 ins_pipe(pipe_class_default); 7875%} 7876 7877instruct compareAndExchangeB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7878 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 7879 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 7880 effect(TEMP_DEF res, TEMP cr0); 7881 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 7882 ins_encode %{ 7883 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7884 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7885 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7886 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7887 noreg, true); 7888 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7889 __ isync(); 7890 } else { 7891 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 7892 __ sync(); 7893 } 7894 %} 7895 ins_pipe(pipe_class_default); 7896%} 7897 7898instruct compareAndExchangeB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 7899 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 7900 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 7901 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 7902 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 7903 ins_encode %{ 7904 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7905 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7906 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 7907 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7908 noreg, true); 7909 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7910 __ isync(); 7911 } else { 7912 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 7913 __ sync(); 7914 } 7915 %} 7916 ins_pipe(pipe_class_default); 7917%} 7918 7919instruct compareAndExchangeS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7920 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 7921 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7922 effect(TEMP_DEF res, TEMP cr0); 7923 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 7924 ins_encode %{ 7925 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7926 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7927 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7928 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7929 noreg, true); 7930 %} 7931 ins_pipe(pipe_class_default); 7932%} 7933 7934instruct compareAndExchangeS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 7935 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 7936 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 7937 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 7938 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 7939 ins_encode %{ 7940 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7941 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7942 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 7943 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7944 noreg, true); 7945 %} 7946 ins_pipe(pipe_class_default); 7947%} 7948 7949instruct compareAndExchangeS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7950 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 7951 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 7952 effect(TEMP_DEF res, TEMP cr0); 7953 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 7954 ins_encode %{ 7955 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7956 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7957 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7958 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7959 noreg, true); 7960 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7961 __ isync(); 7962 } else { 7963 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 7964 __ sync(); 7965 } 7966 %} 7967 ins_pipe(pipe_class_default); 7968%} 7969 7970instruct compareAndExchangeS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 7971 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 7972 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 7973 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 7974 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 7975 ins_encode %{ 7976 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7977 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7978 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 7979 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7980 noreg, true); 7981 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7982 __ isync(); 7983 } else { 7984 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 7985 __ sync(); 7986 } 7987 %} 7988 ins_pipe(pipe_class_default); 7989%} 7990 7991instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7992 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 7993 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7994 effect(TEMP_DEF res, TEMP cr0); 7995 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %} 7996 ins_encode %{ 7997 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7998 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7999 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8000 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8001 noreg, true); 8002 %} 8003 ins_pipe(pipe_class_default); 8004%} 8005 8006instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8007 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8008 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8009 effect(TEMP_DEF res, TEMP cr0); 8010 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %} 8011 ins_encode %{ 8012 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8013 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8014 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8015 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8016 noreg, true); 8017 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8018 __ isync(); 8019 } else { 8020 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8021 __ sync(); 8022 } 8023 %} 8024 ins_pipe(pipe_class_default); 8025%} 8026 8027instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8028 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8029 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8030 effect(TEMP_DEF res, TEMP cr0); 8031 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8032 ins_encode %{ 8033 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8034 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8035 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8036 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8037 noreg, true); 8038 %} 8039 ins_pipe(pipe_class_default); 8040%} 8041 8042instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8043 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8044 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8045 effect(TEMP_DEF res, TEMP cr0); 8046 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8047 ins_encode %{ 8048 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8049 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8050 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8051 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8052 noreg, true); 8053 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8054 __ isync(); 8055 } else { 8056 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8057 __ sync(); 8058 } 8059 %} 8060 ins_pipe(pipe_class_default); 8061%} 8062 8063instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8064 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8065 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8066 effect(TEMP_DEF res, TEMP cr0); 8067 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %} 8068 ins_encode %{ 8069 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8070 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8071 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8072 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8073 noreg, NULL, true); 8074 %} 8075 ins_pipe(pipe_class_default); 8076%} 8077 8078instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8079 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8080 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8081 effect(TEMP_DEF res, TEMP cr0); 8082 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %} 8083 ins_encode %{ 8084 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8085 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8086 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8087 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8088 noreg, NULL, true); 8089 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8090 __ isync(); 8091 } else { 8092 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8093 __ sync(); 8094 } 8095 %} 8096 ins_pipe(pipe_class_default); 8097%} 8098 8099instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8100 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8101 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8102 effect(TEMP_DEF res, TEMP cr0); 8103 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8104 ins_encode %{ 8105 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8106 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8107 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8108 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8109 noreg, NULL, true); 8110 %} 8111 ins_pipe(pipe_class_default); 8112%} 8113 8114instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8115 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8116 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8117 effect(TEMP_DEF res, TEMP cr0); 8118 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8119 ins_encode %{ 8120 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8121 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8122 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8123 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8124 noreg, NULL, true); 8125 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8126 __ isync(); 8127 } else { 8128 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8129 __ sync(); 8130 } 8131 %} 8132 ins_pipe(pipe_class_default); 8133%} 8134 8135// Special RMW 8136 8137instruct getAndAddB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8138 match(Set res (GetAndAddB mem_ptr src)); 8139 predicate(VM_Version::has_lqarx()); 8140 effect(TEMP_DEF res, TEMP cr0); 8141 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8142 ins_encode %{ 8143 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8144 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8145 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8146 __ isync(); 8147 } else { 8148 __ sync(); 8149 } 8150 %} 8151 ins_pipe(pipe_class_default); 8152%} 8153 8154instruct getAndAddB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8155 match(Set res (GetAndAddB mem_ptr src)); 8156 predicate(!VM_Version::has_lqarx()); 8157 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8158 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8159 ins_encode %{ 8160 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8161 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8162 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8163 __ isync(); 8164 } else { 8165 __ sync(); 8166 } 8167 %} 8168 ins_pipe(pipe_class_default); 8169%} 8170 8171instruct getAndAddS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8172 match(Set res (GetAndAddS mem_ptr src)); 8173 predicate(VM_Version::has_lqarx()); 8174 effect(TEMP_DEF res, TEMP cr0); 8175 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8176 ins_encode %{ 8177 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8178 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8179 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8180 __ isync(); 8181 } else { 8182 __ sync(); 8183 } 8184 %} 8185 ins_pipe(pipe_class_default); 8186%} 8187 8188instruct getAndAddS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8189 match(Set res (GetAndAddS mem_ptr src)); 8190 predicate(!VM_Version::has_lqarx()); 8191 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8192 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8193 ins_encode %{ 8194 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8195 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8196 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8197 __ isync(); 8198 } else { 8199 __ sync(); 8200 } 8201 %} 8202 ins_pipe(pipe_class_default); 8203%} 8204 8205instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8206 match(Set res (GetAndAddI mem_ptr src)); 8207 effect(TEMP_DEF res, TEMP cr0); 8208 format %{ "GetAndAddI $res, $mem_ptr, $src" %} 8209 ins_encode %{ 8210 __ getandaddw($res$$Register, $src$$Register, $mem_ptr$$Register, 8211 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8212 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8213 __ isync(); 8214 } else { 8215 __ sync(); 8216 } 8217 %} 8218 ins_pipe(pipe_class_default); 8219%} 8220 8221instruct getAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8222 match(Set res (GetAndAddL mem_ptr src)); 8223 effect(TEMP_DEF res, TEMP cr0); 8224 format %{ "GetAndAddL $res, $mem_ptr, $src" %} 8225 ins_encode %{ 8226 __ getandaddd($res$$Register, $src$$Register, $mem_ptr$$Register, 8227 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8228 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8229 __ isync(); 8230 } else { 8231 __ sync(); 8232 } 8233 %} 8234 ins_pipe(pipe_class_default); 8235%} 8236 8237instruct getAndSetB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8238 match(Set res (GetAndSetB mem_ptr src)); 8239 predicate(VM_Version::has_lqarx()); 8240 effect(TEMP_DEF res, TEMP cr0); 8241 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8242 ins_encode %{ 8243 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8244 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8245 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8246 __ isync(); 8247 } else { 8248 __ sync(); 8249 } 8250 %} 8251 ins_pipe(pipe_class_default); 8252%} 8253 8254instruct getAndSetB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8255 match(Set res (GetAndSetB mem_ptr src)); 8256 predicate(!VM_Version::has_lqarx()); 8257 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8258 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8259 ins_encode %{ 8260 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8261 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8262 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8263 __ isync(); 8264 } else { 8265 __ sync(); 8266 } 8267 %} 8268 ins_pipe(pipe_class_default); 8269%} 8270 8271instruct getAndSetS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8272 match(Set res (GetAndSetS mem_ptr src)); 8273 predicate(VM_Version::has_lqarx()); 8274 effect(TEMP_DEF res, TEMP cr0); 8275 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8276 ins_encode %{ 8277 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8278 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8279 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8280 __ isync(); 8281 } else { 8282 __ sync(); 8283 } 8284 %} 8285 ins_pipe(pipe_class_default); 8286%} 8287 8288instruct getAndSetS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8289 match(Set res (GetAndSetS mem_ptr src)); 8290 predicate(!VM_Version::has_lqarx()); 8291 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8292 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8293 ins_encode %{ 8294 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8295 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8296 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8297 __ isync(); 8298 } else { 8299 __ sync(); 8300 } 8301 %} 8302 ins_pipe(pipe_class_default); 8303%} 8304 8305instruct getAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8306 match(Set res (GetAndSetI mem_ptr src)); 8307 effect(TEMP_DEF res, TEMP cr0); 8308 format %{ "GetAndSetI $res, $mem_ptr, $src" %} 8309 ins_encode %{ 8310 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8311 MacroAssembler::cmpxchgx_hint_atomic_update()); 8312 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8313 __ isync(); 8314 } else { 8315 __ sync(); 8316 } 8317 %} 8318 ins_pipe(pipe_class_default); 8319%} 8320 8321instruct getAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8322 match(Set res (GetAndSetL mem_ptr src)); 8323 effect(TEMP_DEF res, TEMP cr0); 8324 format %{ "GetAndSetL $res, $mem_ptr, $src" %} 8325 ins_encode %{ 8326 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8327 MacroAssembler::cmpxchgx_hint_atomic_update()); 8328 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8329 __ isync(); 8330 } else { 8331 __ sync(); 8332 } 8333 %} 8334 ins_pipe(pipe_class_default); 8335%} 8336 8337instruct getAndSetP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src, flagsRegCR0 cr0) %{ 8338 match(Set res (GetAndSetP mem_ptr src)); 8339 effect(TEMP_DEF res, TEMP cr0); 8340 format %{ "GetAndSetP $res, $mem_ptr, $src" %} 8341 ins_encode %{ 8342 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8343 MacroAssembler::cmpxchgx_hint_atomic_update()); 8344 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8345 __ isync(); 8346 } else { 8347 __ sync(); 8348 } 8349 %} 8350 ins_pipe(pipe_class_default); 8351%} 8352 8353instruct getAndSetN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src, flagsRegCR0 cr0) %{ 8354 match(Set res (GetAndSetN mem_ptr src)); 8355 effect(TEMP_DEF res, TEMP cr0); 8356 format %{ "GetAndSetN $res, $mem_ptr, $src" %} 8357 ins_encode %{ 8358 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8359 MacroAssembler::cmpxchgx_hint_atomic_update()); 8360 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8361 __ isync(); 8362 } else { 8363 __ sync(); 8364 } 8365 %} 8366 ins_pipe(pipe_class_default); 8367%} 8368 8369//----------Arithmetic Instructions-------------------------------------------- 8370// Addition Instructions 8371 8372// Register Addition 8373instruct addI_reg_reg(iRegIdst dst, iRegIsrc_iRegL2Isrc src1, iRegIsrc_iRegL2Isrc src2) %{ 8374 match(Set dst (AddI src1 src2)); 8375 format %{ "ADD $dst, $src1, $src2" %} 8376 size(4); 8377 ins_encode %{ 8378 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8379 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8380 %} 8381 ins_pipe(pipe_class_default); 8382%} 8383 8384// Expand does not work with above instruct. (??) 8385instruct addI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8386 // no match-rule 8387 effect(DEF dst, USE src1, USE src2); 8388 format %{ "ADD $dst, $src1, $src2" %} 8389 size(4); 8390 ins_encode %{ 8391 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8392 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8393 %} 8394 ins_pipe(pipe_class_default); 8395%} 8396 8397instruct tree_addI_addI_addI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 8398 match(Set dst (AddI (AddI (AddI src1 src2) src3) src4)); 8399 ins_cost(DEFAULT_COST*3); 8400 8401 expand %{ 8402 // FIXME: we should do this in the ideal world. 8403 iRegIdst tmp1; 8404 iRegIdst tmp2; 8405 addI_reg_reg(tmp1, src1, src2); 8406 addI_reg_reg_2(tmp2, src3, src4); // Adlc complains about addI_reg_reg. 8407 addI_reg_reg(dst, tmp1, tmp2); 8408 %} 8409%} 8410 8411// Immediate Addition 8412instruct addI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 8413 match(Set dst (AddI src1 src2)); 8414 format %{ "ADDI $dst, $src1, $src2" %} 8415 size(4); 8416 ins_encode %{ 8417 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8418 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8419 %} 8420 ins_pipe(pipe_class_default); 8421%} 8422 8423// Immediate Addition with 16-bit shifted operand 8424instruct addI_reg_immhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2) %{ 8425 match(Set dst (AddI src1 src2)); 8426 format %{ "ADDIS $dst, $src1, $src2" %} 8427 size(4); 8428 ins_encode %{ 8429 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8430 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8431 %} 8432 ins_pipe(pipe_class_default); 8433%} 8434 8435// Long Addition 8436instruct addL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8437 match(Set dst (AddL src1 src2)); 8438 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8439 size(4); 8440 ins_encode %{ 8441 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8442 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8443 %} 8444 ins_pipe(pipe_class_default); 8445%} 8446 8447// Expand does not work with above instruct. (??) 8448instruct addL_reg_reg_2(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8449 // no match-rule 8450 effect(DEF dst, USE src1, USE src2); 8451 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8452 size(4); 8453 ins_encode %{ 8454 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8455 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8456 %} 8457 ins_pipe(pipe_class_default); 8458%} 8459 8460instruct tree_addL_addL_addL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2, iRegLsrc src3, iRegLsrc src4) %{ 8461 match(Set dst (AddL (AddL (AddL src1 src2) src3) src4)); 8462 ins_cost(DEFAULT_COST*3); 8463 8464 expand %{ 8465 // FIXME: we should do this in the ideal world. 8466 iRegLdst tmp1; 8467 iRegLdst tmp2; 8468 addL_reg_reg(tmp1, src1, src2); 8469 addL_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 8470 addL_reg_reg(dst, tmp1, tmp2); 8471 %} 8472%} 8473 8474// AddL + ConvL2I. 8475instruct addI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8476 match(Set dst (ConvL2I (AddL src1 src2))); 8477 8478 format %{ "ADD $dst, $src1, $src2 \t// long + l2i" %} 8479 size(4); 8480 ins_encode %{ 8481 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8482 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8483 %} 8484 ins_pipe(pipe_class_default); 8485%} 8486 8487// No constant pool entries required. 8488instruct addL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 8489 match(Set dst (AddL src1 src2)); 8490 8491 format %{ "ADDI $dst, $src1, $src2" %} 8492 size(4); 8493 ins_encode %{ 8494 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8495 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8496 %} 8497 ins_pipe(pipe_class_default); 8498%} 8499 8500// Long Immediate Addition with 16-bit shifted operand. 8501// No constant pool entries required. 8502instruct addL_reg_immhi16(iRegLdst dst, iRegLsrc src1, immL32hi16 src2) %{ 8503 match(Set dst (AddL src1 src2)); 8504 8505 format %{ "ADDIS $dst, $src1, $src2" %} 8506 size(4); 8507 ins_encode %{ 8508 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8509 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8510 %} 8511 ins_pipe(pipe_class_default); 8512%} 8513 8514// Pointer Register Addition 8515instruct addP_reg_reg(iRegPdst dst, iRegP_N2P src1, iRegLsrc src2) %{ 8516 match(Set dst (AddP src1 src2)); 8517 format %{ "ADD $dst, $src1, $src2" %} 8518 size(4); 8519 ins_encode %{ 8520 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8521 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8522 %} 8523 ins_pipe(pipe_class_default); 8524%} 8525 8526// Pointer Immediate Addition 8527// No constant pool entries required. 8528instruct addP_reg_imm16(iRegPdst dst, iRegP_N2P src1, immL16 src2) %{ 8529 match(Set dst (AddP src1 src2)); 8530 8531 format %{ "ADDI $dst, $src1, $src2" %} 8532 size(4); 8533 ins_encode %{ 8534 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8535 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8536 %} 8537 ins_pipe(pipe_class_default); 8538%} 8539 8540// Pointer Immediate Addition with 16-bit shifted operand. 8541// No constant pool entries required. 8542instruct addP_reg_immhi16(iRegPdst dst, iRegP_N2P src1, immL32hi16 src2) %{ 8543 match(Set dst (AddP src1 src2)); 8544 8545 format %{ "ADDIS $dst, $src1, $src2" %} 8546 size(4); 8547 ins_encode %{ 8548 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8549 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8550 %} 8551 ins_pipe(pipe_class_default); 8552%} 8553 8554//--------------------- 8555// Subtraction Instructions 8556 8557// Register Subtraction 8558instruct subI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8559 match(Set dst (SubI src1 src2)); 8560 format %{ "SUBF $dst, $src2, $src1" %} 8561 size(4); 8562 ins_encode %{ 8563 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 8564 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 8565 %} 8566 ins_pipe(pipe_class_default); 8567%} 8568 8569// Immediate Subtraction 8570// Immediate Subtraction: The compiler converts "x-c0" into "x+ -c0" (see SubLNode::Ideal), 8571// Don't try to use addi with - $src2$$constant since it can overflow when $src2$$constant == minI16. 8572 8573// SubI from constant (using subfic). 8574instruct subI_imm16_reg(iRegIdst dst, immI16 src1, iRegIsrc src2) %{ 8575 match(Set dst (SubI src1 src2)); 8576 format %{ "SUBI $dst, $src1, $src2" %} 8577 8578 size(4); 8579 ins_encode %{ 8580 // TODO: PPC port $archOpcode(ppc64Opcode_subfic); 8581 __ subfic($dst$$Register, $src2$$Register, $src1$$constant); 8582 %} 8583 ins_pipe(pipe_class_default); 8584%} 8585 8586// Turn the sign-bit of an integer into a 32-bit mask, 0x0...0 for 8587// positive integers and 0xF...F for negative ones. 8588instruct signmask32I_regI(iRegIdst dst, iRegIsrc src) %{ 8589 // no match-rule, false predicate 8590 effect(DEF dst, USE src); 8591 predicate(false); 8592 8593 format %{ "SRAWI $dst, $src, #31" %} 8594 size(4); 8595 ins_encode %{ 8596 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 8597 __ srawi($dst$$Register, $src$$Register, 0x1f); 8598 %} 8599 ins_pipe(pipe_class_default); 8600%} 8601 8602instruct absI_reg_Ex(iRegIdst dst, iRegIsrc src) %{ 8603 match(Set dst (AbsI src)); 8604 ins_cost(DEFAULT_COST*3); 8605 8606 expand %{ 8607 iRegIdst tmp1; 8608 iRegIdst tmp2; 8609 signmask32I_regI(tmp1, src); 8610 xorI_reg_reg(tmp2, tmp1, src); 8611 subI_reg_reg(dst, tmp2, tmp1); 8612 %} 8613%} 8614 8615instruct negI_regI(iRegIdst dst, immI_0 zero, iRegIsrc src2) %{ 8616 match(Set dst (SubI zero src2)); 8617 format %{ "NEG $dst, $src2" %} 8618 size(4); 8619 ins_encode %{ 8620 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 8621 __ neg($dst$$Register, $src2$$Register); 8622 %} 8623 ins_pipe(pipe_class_default); 8624%} 8625 8626// Long subtraction 8627instruct subL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8628 match(Set dst (SubL src1 src2)); 8629 format %{ "SUBF $dst, $src2, $src1 \t// long" %} 8630 size(4); 8631 ins_encode %{ 8632 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 8633 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 8634 %} 8635 ins_pipe(pipe_class_default); 8636%} 8637 8638// SubL + convL2I. 8639instruct subI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8640 match(Set dst (ConvL2I (SubL src1 src2))); 8641 8642 format %{ "SUBF $dst, $src2, $src1 \t// long + l2i" %} 8643 size(4); 8644 ins_encode %{ 8645 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 8646 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 8647 %} 8648 ins_pipe(pipe_class_default); 8649%} 8650 8651// Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 8652// positive longs and 0xF...F for negative ones. 8653instruct signmask64I_regL(iRegIdst dst, iRegLsrc src) %{ 8654 // no match-rule, false predicate 8655 effect(DEF dst, USE src); 8656 predicate(false); 8657 8658 format %{ "SRADI $dst, $src, #63" %} 8659 size(4); 8660 ins_encode %{ 8661 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 8662 __ sradi($dst$$Register, $src$$Register, 0x3f); 8663 %} 8664 ins_pipe(pipe_class_default); 8665%} 8666 8667// Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 8668// positive longs and 0xF...F for negative ones. 8669instruct signmask64L_regL(iRegLdst dst, iRegLsrc src) %{ 8670 // no match-rule, false predicate 8671 effect(DEF dst, USE src); 8672 predicate(false); 8673 8674 format %{ "SRADI $dst, $src, #63" %} 8675 size(4); 8676 ins_encode %{ 8677 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 8678 __ sradi($dst$$Register, $src$$Register, 0x3f); 8679 %} 8680 ins_pipe(pipe_class_default); 8681%} 8682 8683// Long negation 8684instruct negL_reg_reg(iRegLdst dst, immL_0 zero, iRegLsrc src2) %{ 8685 match(Set dst (SubL zero src2)); 8686 format %{ "NEG $dst, $src2 \t// long" %} 8687 size(4); 8688 ins_encode %{ 8689 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 8690 __ neg($dst$$Register, $src2$$Register); 8691 %} 8692 ins_pipe(pipe_class_default); 8693%} 8694 8695// NegL + ConvL2I. 8696instruct negI_con0_regL(iRegIdst dst, immL_0 zero, iRegLsrc src2) %{ 8697 match(Set dst (ConvL2I (SubL zero src2))); 8698 8699 format %{ "NEG $dst, $src2 \t// long + l2i" %} 8700 size(4); 8701 ins_encode %{ 8702 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 8703 __ neg($dst$$Register, $src2$$Register); 8704 %} 8705 ins_pipe(pipe_class_default); 8706%} 8707 8708// Multiplication Instructions 8709// Integer Multiplication 8710 8711// Register Multiplication 8712instruct mulI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8713 match(Set dst (MulI src1 src2)); 8714 ins_cost(DEFAULT_COST); 8715 8716 format %{ "MULLW $dst, $src1, $src2" %} 8717 size(4); 8718 ins_encode %{ 8719 // TODO: PPC port $archOpcode(ppc64Opcode_mullw); 8720 __ mullw($dst$$Register, $src1$$Register, $src2$$Register); 8721 %} 8722 ins_pipe(pipe_class_default); 8723%} 8724 8725// Immediate Multiplication 8726instruct mulI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 8727 match(Set dst (MulI src1 src2)); 8728 ins_cost(DEFAULT_COST); 8729 8730 format %{ "MULLI $dst, $src1, $src2" %} 8731 size(4); 8732 ins_encode %{ 8733 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 8734 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 8735 %} 8736 ins_pipe(pipe_class_default); 8737%} 8738 8739instruct mulL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8740 match(Set dst (MulL src1 src2)); 8741 ins_cost(DEFAULT_COST); 8742 8743 format %{ "MULLD $dst $src1, $src2 \t// long" %} 8744 size(4); 8745 ins_encode %{ 8746 // TODO: PPC port $archOpcode(ppc64Opcode_mulld); 8747 __ mulld($dst$$Register, $src1$$Register, $src2$$Register); 8748 %} 8749 ins_pipe(pipe_class_default); 8750%} 8751 8752// Multiply high for optimized long division by constant. 8753instruct mulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8754 match(Set dst (MulHiL src1 src2)); 8755 ins_cost(DEFAULT_COST); 8756 8757 format %{ "MULHD $dst $src1, $src2 \t// long" %} 8758 size(4); 8759 ins_encode %{ 8760 // TODO: PPC port $archOpcode(ppc64Opcode_mulhd); 8761 __ mulhd($dst$$Register, $src1$$Register, $src2$$Register); 8762 %} 8763 ins_pipe(pipe_class_default); 8764%} 8765 8766// Immediate Multiplication 8767instruct mulL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 8768 match(Set dst (MulL src1 src2)); 8769 ins_cost(DEFAULT_COST); 8770 8771 format %{ "MULLI $dst, $src1, $src2" %} 8772 size(4); 8773 ins_encode %{ 8774 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 8775 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 8776 %} 8777 ins_pipe(pipe_class_default); 8778%} 8779 8780// Integer Division with Immediate -1: Negate. 8781instruct divI_reg_immIvalueMinus1(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 8782 match(Set dst (DivI src1 src2)); 8783 ins_cost(DEFAULT_COST); 8784 8785 format %{ "NEG $dst, $src1 \t// /-1" %} 8786 size(4); 8787 ins_encode %{ 8788 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 8789 __ neg($dst$$Register, $src1$$Register); 8790 %} 8791 ins_pipe(pipe_class_default); 8792%} 8793 8794// Integer Division with constant, but not -1. 8795// We should be able to improve this by checking the type of src2. 8796// It might well be that src2 is known to be positive. 8797instruct divI_reg_regnotMinus1(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8798 match(Set dst (DivI src1 src2)); 8799 predicate(n->in(2)->find_int_con(-1) != -1); // src2 is a constant, but not -1 8800 ins_cost(2*DEFAULT_COST); 8801 8802 format %{ "DIVW $dst, $src1, $src2 \t// /not-1" %} 8803 size(4); 8804 ins_encode %{ 8805 // TODO: PPC port $archOpcode(ppc64Opcode_divw); 8806 __ divw($dst$$Register, $src1$$Register, $src2$$Register); 8807 %} 8808 ins_pipe(pipe_class_default); 8809%} 8810 8811instruct cmovI_bne_negI_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src1) %{ 8812 effect(USE_DEF dst, USE src1, USE crx); 8813 predicate(false); 8814 8815 ins_variable_size_depending_on_alignment(true); 8816 8817 format %{ "CMOVE $dst, neg($src1), $crx" %} 8818 // Worst case is branch + move + stop, no stop without scheduler. 8819 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 8820 ins_encode %{ 8821 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 8822 Label done; 8823 __ bne($crx$$CondRegister, done); 8824 __ neg($dst$$Register, $src1$$Register); 8825 // TODO PPC port __ endgroup_if_needed(_size == 12); 8826 __ bind(done); 8827 %} 8828 ins_pipe(pipe_class_default); 8829%} 8830 8831// Integer Division with Registers not containing constants. 8832instruct divI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8833 match(Set dst (DivI src1 src2)); 8834 ins_cost(10*DEFAULT_COST); 8835 8836 expand %{ 8837 immI16 imm %{ (int)-1 %} 8838 flagsReg tmp1; 8839 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 8840 divI_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 8841 cmovI_bne_negI_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 8842 %} 8843%} 8844 8845// Long Division with Immediate -1: Negate. 8846instruct divL_reg_immLvalueMinus1(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 8847 match(Set dst (DivL src1 src2)); 8848 ins_cost(DEFAULT_COST); 8849 8850 format %{ "NEG $dst, $src1 \t// /-1, long" %} 8851 size(4); 8852 ins_encode %{ 8853 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 8854 __ neg($dst$$Register, $src1$$Register); 8855 %} 8856 ins_pipe(pipe_class_default); 8857%} 8858 8859// Long Division with constant, but not -1. 8860instruct divL_reg_regnotMinus1(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8861 match(Set dst (DivL src1 src2)); 8862 predicate(n->in(2)->find_long_con(-1L) != -1L); // Src2 is a constant, but not -1. 8863 ins_cost(2*DEFAULT_COST); 8864 8865 format %{ "DIVD $dst, $src1, $src2 \t// /not-1, long" %} 8866 size(4); 8867 ins_encode %{ 8868 // TODO: PPC port $archOpcode(ppc64Opcode_divd); 8869 __ divd($dst$$Register, $src1$$Register, $src2$$Register); 8870 %} 8871 ins_pipe(pipe_class_default); 8872%} 8873 8874instruct cmovL_bne_negL_reg(iRegLdst dst, flagsRegSrc crx, iRegLsrc src1) %{ 8875 effect(USE_DEF dst, USE src1, USE crx); 8876 predicate(false); 8877 8878 ins_variable_size_depending_on_alignment(true); 8879 8880 format %{ "CMOVE $dst, neg($src1), $crx" %} 8881 // Worst case is branch + move + stop, no stop without scheduler. 8882 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 8883 ins_encode %{ 8884 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 8885 Label done; 8886 __ bne($crx$$CondRegister, done); 8887 __ neg($dst$$Register, $src1$$Register); 8888 // TODO PPC port __ endgroup_if_needed(_size == 12); 8889 __ bind(done); 8890 %} 8891 ins_pipe(pipe_class_default); 8892%} 8893 8894// Long Division with Registers not containing constants. 8895instruct divL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8896 match(Set dst (DivL src1 src2)); 8897 ins_cost(10*DEFAULT_COST); 8898 8899 expand %{ 8900 immL16 imm %{ (int)-1 %} 8901 flagsReg tmp1; 8902 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 8903 divL_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 8904 cmovL_bne_negL_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 8905 %} 8906%} 8907 8908// Integer Remainder with registers. 8909instruct modI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8910 match(Set dst (ModI src1 src2)); 8911 ins_cost(10*DEFAULT_COST); 8912 8913 expand %{ 8914 immI16 imm %{ (int)-1 %} 8915 flagsReg tmp1; 8916 iRegIdst tmp2; 8917 iRegIdst tmp3; 8918 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 8919 divI_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 8920 cmovI_bne_negI_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 8921 mulI_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 8922 subI_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 8923 %} 8924%} 8925 8926// Long Remainder with registers 8927instruct modL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8928 match(Set dst (ModL src1 src2)); 8929 ins_cost(10*DEFAULT_COST); 8930 8931 expand %{ 8932 immL16 imm %{ (int)-1 %} 8933 flagsReg tmp1; 8934 iRegLdst tmp2; 8935 iRegLdst tmp3; 8936 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 8937 divL_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 8938 cmovL_bne_negL_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 8939 mulL_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 8940 subL_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 8941 %} 8942%} 8943 8944// Integer Shift Instructions 8945 8946// Register Shift Left 8947 8948// Clear all but the lowest #mask bits. 8949// Used to normalize shift amounts in registers. 8950instruct maskI_reg_imm(iRegIdst dst, iRegIsrc src, uimmI6 mask) %{ 8951 // no match-rule, false predicate 8952 effect(DEF dst, USE src, USE mask); 8953 predicate(false); 8954 8955 format %{ "MASK $dst, $src, $mask \t// clear $mask upper bits" %} 8956 size(4); 8957 ins_encode %{ 8958 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 8959 __ clrldi($dst$$Register, $src$$Register, $mask$$constant); 8960 %} 8961 ins_pipe(pipe_class_default); 8962%} 8963 8964instruct lShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8965 // no match-rule, false predicate 8966 effect(DEF dst, USE src1, USE src2); 8967 predicate(false); 8968 8969 format %{ "SLW $dst, $src1, $src2" %} 8970 size(4); 8971 ins_encode %{ 8972 // TODO: PPC port $archOpcode(ppc64Opcode_slw); 8973 __ slw($dst$$Register, $src1$$Register, $src2$$Register); 8974 %} 8975 ins_pipe(pipe_class_default); 8976%} 8977 8978instruct lShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8979 match(Set dst (LShiftI src1 src2)); 8980 ins_cost(DEFAULT_COST*2); 8981 expand %{ 8982 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 8983 iRegIdst tmpI; 8984 maskI_reg_imm(tmpI, src2, mask); 8985 lShiftI_reg_reg(dst, src1, tmpI); 8986 %} 8987%} 8988 8989// Register Shift Left Immediate 8990instruct lShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 8991 match(Set dst (LShiftI src1 src2)); 8992 8993 format %{ "SLWI $dst, $src1, ($src2 & 0x1f)" %} 8994 size(4); 8995 ins_encode %{ 8996 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 8997 __ slwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 8998 %} 8999 ins_pipe(pipe_class_default); 9000%} 9001 9002// AndI with negpow2-constant + LShiftI 9003instruct lShiftI_andI_immInegpow2_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9004 match(Set dst (LShiftI (AndI src1 src2) src3)); 9005 predicate(UseRotateAndMaskInstructionsPPC64); 9006 9007 format %{ "RLWINM $dst, lShiftI(AndI($src1, $src2), $src3)" %} 9008 size(4); 9009 ins_encode %{ 9010 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9011 long src2 = $src2$$constant; 9012 long src3 = $src3$$constant; 9013 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9014 if (maskbits >= 32) { 9015 __ li($dst$$Register, 0); // addi 9016 } else { 9017 __ rlwinm($dst$$Register, $src1$$Register, src3 & 0x1f, 0, (31-maskbits) & 0x1f); 9018 } 9019 %} 9020 ins_pipe(pipe_class_default); 9021%} 9022 9023// RShiftI + AndI with negpow2-constant + LShiftI 9024instruct lShiftI_andI_immInegpow2_rShiftI_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9025 match(Set dst (LShiftI (AndI (RShiftI src1 src3) src2) src3)); 9026 predicate(UseRotateAndMaskInstructionsPPC64); 9027 9028 format %{ "RLWINM $dst, lShiftI(AndI(RShiftI($src1, $src3), $src2), $src3)" %} 9029 size(4); 9030 ins_encode %{ 9031 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9032 long src2 = $src2$$constant; 9033 long src3 = $src3$$constant; 9034 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9035 if (maskbits >= 32) { 9036 __ li($dst$$Register, 0); // addi 9037 } else { 9038 __ rlwinm($dst$$Register, $src1$$Register, 0, 0, (31-maskbits) & 0x1f); 9039 } 9040 %} 9041 ins_pipe(pipe_class_default); 9042%} 9043 9044instruct lShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9045 // no match-rule, false predicate 9046 effect(DEF dst, USE src1, USE src2); 9047 predicate(false); 9048 9049 format %{ "SLD $dst, $src1, $src2" %} 9050 size(4); 9051 ins_encode %{ 9052 // TODO: PPC port $archOpcode(ppc64Opcode_sld); 9053 __ sld($dst$$Register, $src1$$Register, $src2$$Register); 9054 %} 9055 ins_pipe(pipe_class_default); 9056%} 9057 9058// Register Shift Left 9059instruct lShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9060 match(Set dst (LShiftL src1 src2)); 9061 ins_cost(DEFAULT_COST*2); 9062 expand %{ 9063 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9064 iRegIdst tmpI; 9065 maskI_reg_imm(tmpI, src2, mask); 9066 lShiftL_regL_regI(dst, src1, tmpI); 9067 %} 9068%} 9069 9070// Register Shift Left Immediate 9071instruct lshiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9072 match(Set dst (LShiftL src1 src2)); 9073 format %{ "SLDI $dst, $src1, ($src2 & 0x3f)" %} 9074 size(4); 9075 ins_encode %{ 9076 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9077 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9078 %} 9079 ins_pipe(pipe_class_default); 9080%} 9081 9082// If we shift more than 32 bits, we need not convert I2L. 9083instruct lShiftL_regI_immGE32(iRegLdst dst, iRegIsrc src1, uimmI6_ge32 src2) %{ 9084 match(Set dst (LShiftL (ConvI2L src1) src2)); 9085 ins_cost(DEFAULT_COST); 9086 9087 size(4); 9088 format %{ "SLDI $dst, i2l($src1), $src2" %} 9089 ins_encode %{ 9090 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9091 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9092 %} 9093 ins_pipe(pipe_class_default); 9094%} 9095 9096// Shift a postivie int to the left. 9097// Clrlsldi clears the upper 32 bits and shifts. 9098instruct scaledPositiveI2L_lShiftL_convI2L_reg_imm6(iRegLdst dst, iRegIsrc src1, uimmI6 src2) %{ 9099 match(Set dst (LShiftL (ConvI2L src1) src2)); 9100 predicate(((ConvI2LNode*)(_kids[0]->_leaf))->type()->is_long()->is_positive_int()); 9101 9102 format %{ "SLDI $dst, i2l(positive_int($src1)), $src2" %} 9103 size(4); 9104 ins_encode %{ 9105 // TODO: PPC port $archOpcode(ppc64Opcode_rldic); 9106 __ clrlsldi($dst$$Register, $src1$$Register, 0x20, $src2$$constant); 9107 %} 9108 ins_pipe(pipe_class_default); 9109%} 9110 9111instruct arShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9112 // no match-rule, false predicate 9113 effect(DEF dst, USE src1, USE src2); 9114 predicate(false); 9115 9116 format %{ "SRAW $dst, $src1, $src2" %} 9117 size(4); 9118 ins_encode %{ 9119 // TODO: PPC port $archOpcode(ppc64Opcode_sraw); 9120 __ sraw($dst$$Register, $src1$$Register, $src2$$Register); 9121 %} 9122 ins_pipe(pipe_class_default); 9123%} 9124 9125// Register Arithmetic Shift Right 9126instruct arShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9127 match(Set dst (RShiftI src1 src2)); 9128 ins_cost(DEFAULT_COST*2); 9129 expand %{ 9130 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9131 iRegIdst tmpI; 9132 maskI_reg_imm(tmpI, src2, mask); 9133 arShiftI_reg_reg(dst, src1, tmpI); 9134 %} 9135%} 9136 9137// Register Arithmetic Shift Right Immediate 9138instruct arShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9139 match(Set dst (RShiftI src1 src2)); 9140 9141 format %{ "SRAWI $dst, $src1, ($src2 & 0x1f)" %} 9142 size(4); 9143 ins_encode %{ 9144 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 9145 __ srawi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9146 %} 9147 ins_pipe(pipe_class_default); 9148%} 9149 9150instruct arShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9151 // no match-rule, false predicate 9152 effect(DEF dst, USE src1, USE src2); 9153 predicate(false); 9154 9155 format %{ "SRAD $dst, $src1, $src2" %} 9156 size(4); 9157 ins_encode %{ 9158 // TODO: PPC port $archOpcode(ppc64Opcode_srad); 9159 __ srad($dst$$Register, $src1$$Register, $src2$$Register); 9160 %} 9161 ins_pipe(pipe_class_default); 9162%} 9163 9164// Register Shift Right Arithmetic Long 9165instruct arShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9166 match(Set dst (RShiftL src1 src2)); 9167 ins_cost(DEFAULT_COST*2); 9168 9169 expand %{ 9170 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9171 iRegIdst tmpI; 9172 maskI_reg_imm(tmpI, src2, mask); 9173 arShiftL_regL_regI(dst, src1, tmpI); 9174 %} 9175%} 9176 9177// Register Shift Right Immediate 9178instruct arShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9179 match(Set dst (RShiftL src1 src2)); 9180 9181 format %{ "SRADI $dst, $src1, ($src2 & 0x3f)" %} 9182 size(4); 9183 ins_encode %{ 9184 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9185 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9186 %} 9187 ins_pipe(pipe_class_default); 9188%} 9189 9190// RShiftL + ConvL2I 9191instruct convL2I_arShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9192 match(Set dst (ConvL2I (RShiftL src1 src2))); 9193 9194 format %{ "SRADI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9195 size(4); 9196 ins_encode %{ 9197 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9198 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9199 %} 9200 ins_pipe(pipe_class_default); 9201%} 9202 9203instruct urShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9204 // no match-rule, false predicate 9205 effect(DEF dst, USE src1, USE src2); 9206 predicate(false); 9207 9208 format %{ "SRW $dst, $src1, $src2" %} 9209 size(4); 9210 ins_encode %{ 9211 // TODO: PPC port $archOpcode(ppc64Opcode_srw); 9212 __ srw($dst$$Register, $src1$$Register, $src2$$Register); 9213 %} 9214 ins_pipe(pipe_class_default); 9215%} 9216 9217// Register Shift Right 9218instruct urShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9219 match(Set dst (URShiftI src1 src2)); 9220 ins_cost(DEFAULT_COST*2); 9221 9222 expand %{ 9223 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9224 iRegIdst tmpI; 9225 maskI_reg_imm(tmpI, src2, mask); 9226 urShiftI_reg_reg(dst, src1, tmpI); 9227 %} 9228%} 9229 9230// Register Shift Right Immediate 9231instruct urShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9232 match(Set dst (URShiftI src1 src2)); 9233 9234 format %{ "SRWI $dst, $src1, ($src2 & 0x1f)" %} 9235 size(4); 9236 ins_encode %{ 9237 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9238 __ srwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9239 %} 9240 ins_pipe(pipe_class_default); 9241%} 9242 9243instruct urShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9244 // no match-rule, false predicate 9245 effect(DEF dst, USE src1, USE src2); 9246 predicate(false); 9247 9248 format %{ "SRD $dst, $src1, $src2" %} 9249 size(4); 9250 ins_encode %{ 9251 // TODO: PPC port $archOpcode(ppc64Opcode_srd); 9252 __ srd($dst$$Register, $src1$$Register, $src2$$Register); 9253 %} 9254 ins_pipe(pipe_class_default); 9255%} 9256 9257// Register Shift Right 9258instruct urShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9259 match(Set dst (URShiftL src1 src2)); 9260 ins_cost(DEFAULT_COST*2); 9261 9262 expand %{ 9263 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9264 iRegIdst tmpI; 9265 maskI_reg_imm(tmpI, src2, mask); 9266 urShiftL_regL_regI(dst, src1, tmpI); 9267 %} 9268%} 9269 9270// Register Shift Right Immediate 9271instruct urShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9272 match(Set dst (URShiftL src1 src2)); 9273 9274 format %{ "SRDI $dst, $src1, ($src2 & 0x3f)" %} 9275 size(4); 9276 ins_encode %{ 9277 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9278 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9279 %} 9280 ins_pipe(pipe_class_default); 9281%} 9282 9283// URShiftL + ConvL2I. 9284instruct convL2I_urShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9285 match(Set dst (ConvL2I (URShiftL src1 src2))); 9286 9287 format %{ "SRDI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9288 size(4); 9289 ins_encode %{ 9290 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9291 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9292 %} 9293 ins_pipe(pipe_class_default); 9294%} 9295 9296// Register Shift Right Immediate with a CastP2X 9297instruct shrP_convP2X_reg_imm6(iRegLdst dst, iRegP_N2P src1, uimmI6 src2) %{ 9298 match(Set dst (URShiftL (CastP2X src1) src2)); 9299 9300 format %{ "SRDI $dst, $src1, $src2 \t// Cast ptr $src1 to long and shift" %} 9301 size(4); 9302 ins_encode %{ 9303 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9304 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9305 %} 9306 ins_pipe(pipe_class_default); 9307%} 9308 9309instruct sxtI_reg(iRegIdst dst, iRegIsrc src) %{ 9310 match(Set dst (ConvL2I (ConvI2L src))); 9311 9312 format %{ "EXTSW $dst, $src \t// int->int" %} 9313 size(4); 9314 ins_encode %{ 9315 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 9316 __ extsw($dst$$Register, $src$$Register); 9317 %} 9318 ins_pipe(pipe_class_default); 9319%} 9320 9321//----------Rotate Instructions------------------------------------------------ 9322 9323// Rotate Left by 8-bit immediate 9324instruct rotlI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 lshift, immI8 rshift) %{ 9325 match(Set dst (OrI (LShiftI src lshift) (URShiftI src rshift))); 9326 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9327 9328 format %{ "ROTLWI $dst, $src, $lshift" %} 9329 size(4); 9330 ins_encode %{ 9331 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9332 __ rotlwi($dst$$Register, $src$$Register, $lshift$$constant); 9333 %} 9334 ins_pipe(pipe_class_default); 9335%} 9336 9337// Rotate Right by 8-bit immediate 9338instruct rotrI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 rshift, immI8 lshift) %{ 9339 match(Set dst (OrI (URShiftI src rshift) (LShiftI src lshift))); 9340 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9341 9342 format %{ "ROTRWI $dst, $rshift" %} 9343 size(4); 9344 ins_encode %{ 9345 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9346 __ rotrwi($dst$$Register, $src$$Register, $rshift$$constant); 9347 %} 9348 ins_pipe(pipe_class_default); 9349%} 9350 9351//----------Floating Point Arithmetic Instructions----------------------------- 9352 9353// Add float single precision 9354instruct addF_reg_reg(regF dst, regF src1, regF src2) %{ 9355 match(Set dst (AddF src1 src2)); 9356 9357 format %{ "FADDS $dst, $src1, $src2" %} 9358 size(4); 9359 ins_encode %{ 9360 // TODO: PPC port $archOpcode(ppc64Opcode_fadds); 9361 __ fadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9362 %} 9363 ins_pipe(pipe_class_default); 9364%} 9365 9366// Add float double precision 9367instruct addD_reg_reg(regD dst, regD src1, regD src2) %{ 9368 match(Set dst (AddD src1 src2)); 9369 9370 format %{ "FADD $dst, $src1, $src2" %} 9371 size(4); 9372 ins_encode %{ 9373 // TODO: PPC port $archOpcode(ppc64Opcode_fadd); 9374 __ fadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9375 %} 9376 ins_pipe(pipe_class_default); 9377%} 9378 9379// Sub float single precision 9380instruct subF_reg_reg(regF dst, regF src1, regF src2) %{ 9381 match(Set dst (SubF src1 src2)); 9382 9383 format %{ "FSUBS $dst, $src1, $src2" %} 9384 size(4); 9385 ins_encode %{ 9386 // TODO: PPC port $archOpcode(ppc64Opcode_fsubs); 9387 __ fsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9388 %} 9389 ins_pipe(pipe_class_default); 9390%} 9391 9392// Sub float double precision 9393instruct subD_reg_reg(regD dst, regD src1, regD src2) %{ 9394 match(Set dst (SubD src1 src2)); 9395 format %{ "FSUB $dst, $src1, $src2" %} 9396 size(4); 9397 ins_encode %{ 9398 // TODO: PPC port $archOpcode(ppc64Opcode_fsub); 9399 __ fsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9400 %} 9401 ins_pipe(pipe_class_default); 9402%} 9403 9404// Mul float single precision 9405instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{ 9406 match(Set dst (MulF src1 src2)); 9407 format %{ "FMULS $dst, $src1, $src2" %} 9408 size(4); 9409 ins_encode %{ 9410 // TODO: PPC port $archOpcode(ppc64Opcode_fmuls); 9411 __ fmuls($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9412 %} 9413 ins_pipe(pipe_class_default); 9414%} 9415 9416// Mul float double precision 9417instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{ 9418 match(Set dst (MulD src1 src2)); 9419 format %{ "FMUL $dst, $src1, $src2" %} 9420 size(4); 9421 ins_encode %{ 9422 // TODO: PPC port $archOpcode(ppc64Opcode_fmul); 9423 __ fmul($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9424 %} 9425 ins_pipe(pipe_class_default); 9426%} 9427 9428// Div float single precision 9429instruct divF_reg_reg(regF dst, regF src1, regF src2) %{ 9430 match(Set dst (DivF src1 src2)); 9431 format %{ "FDIVS $dst, $src1, $src2" %} 9432 size(4); 9433 ins_encode %{ 9434 // TODO: PPC port $archOpcode(ppc64Opcode_fdivs); 9435 __ fdivs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9436 %} 9437 ins_pipe(pipe_class_default); 9438%} 9439 9440// Div float double precision 9441instruct divD_reg_reg(regD dst, regD src1, regD src2) %{ 9442 match(Set dst (DivD src1 src2)); 9443 format %{ "FDIV $dst, $src1, $src2" %} 9444 size(4); 9445 ins_encode %{ 9446 // TODO: PPC port $archOpcode(ppc64Opcode_fdiv); 9447 __ fdiv($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9448 %} 9449 ins_pipe(pipe_class_default); 9450%} 9451 9452// Absolute float single precision 9453instruct absF_reg(regF dst, regF src) %{ 9454 match(Set dst (AbsF src)); 9455 format %{ "FABS $dst, $src \t// float" %} 9456 size(4); 9457 ins_encode %{ 9458 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 9459 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9460 %} 9461 ins_pipe(pipe_class_default); 9462%} 9463 9464// Absolute float double precision 9465instruct absD_reg(regD dst, regD src) %{ 9466 match(Set dst (AbsD src)); 9467 format %{ "FABS $dst, $src \t// double" %} 9468 size(4); 9469 ins_encode %{ 9470 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 9471 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9472 %} 9473 ins_pipe(pipe_class_default); 9474%} 9475 9476instruct negF_reg(regF dst, regF src) %{ 9477 match(Set dst (NegF src)); 9478 format %{ "FNEG $dst, $src \t// float" %} 9479 size(4); 9480 ins_encode %{ 9481 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 9482 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 9483 %} 9484 ins_pipe(pipe_class_default); 9485%} 9486 9487instruct negD_reg(regD dst, regD src) %{ 9488 match(Set dst (NegD src)); 9489 format %{ "FNEG $dst, $src \t// double" %} 9490 size(4); 9491 ins_encode %{ 9492 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 9493 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 9494 %} 9495 ins_pipe(pipe_class_default); 9496%} 9497 9498// AbsF + NegF. 9499instruct negF_absF_reg(regF dst, regF src) %{ 9500 match(Set dst (NegF (AbsF src))); 9501 format %{ "FNABS $dst, $src \t// float" %} 9502 size(4); 9503 ins_encode %{ 9504 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 9505 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 9506 %} 9507 ins_pipe(pipe_class_default); 9508%} 9509 9510// AbsD + NegD. 9511instruct negD_absD_reg(regD dst, regD src) %{ 9512 match(Set dst (NegD (AbsD src))); 9513 format %{ "FNABS $dst, $src \t// double" %} 9514 size(4); 9515 ins_encode %{ 9516 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 9517 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 9518 %} 9519 ins_pipe(pipe_class_default); 9520%} 9521 9522// VM_Version::has_fsqrt() decides if this node will be used. 9523// Sqrt float double precision 9524instruct sqrtD_reg(regD dst, regD src) %{ 9525 match(Set dst (SqrtD src)); 9526 format %{ "FSQRT $dst, $src" %} 9527 size(4); 9528 ins_encode %{ 9529 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrt); 9530 __ fsqrt($dst$$FloatRegister, $src$$FloatRegister); 9531 %} 9532 ins_pipe(pipe_class_default); 9533%} 9534 9535// Single-precision sqrt. 9536instruct sqrtF_reg(regF dst, regF src) %{ 9537 match(Set dst (ConvD2F (SqrtD (ConvF2D src)))); 9538 predicate(VM_Version::has_fsqrts()); 9539 ins_cost(DEFAULT_COST); 9540 9541 format %{ "FSQRTS $dst, $src" %} 9542 size(4); 9543 ins_encode %{ 9544 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrts); 9545 __ fsqrts($dst$$FloatRegister, $src$$FloatRegister); 9546 %} 9547 ins_pipe(pipe_class_default); 9548%} 9549 9550instruct roundDouble_nop(regD dst) %{ 9551 match(Set dst (RoundDouble dst)); 9552 ins_cost(0); 9553 9554 format %{ " -- \t// RoundDouble not needed - empty" %} 9555 size(0); 9556 // PPC results are already "rounded" (i.e., normal-format IEEE). 9557 ins_encode( /*empty*/ ); 9558 ins_pipe(pipe_class_default); 9559%} 9560 9561instruct roundFloat_nop(regF dst) %{ 9562 match(Set dst (RoundFloat dst)); 9563 ins_cost(0); 9564 9565 format %{ " -- \t// RoundFloat not needed - empty" %} 9566 size(0); 9567 // PPC results are already "rounded" (i.e., normal-format IEEE). 9568 ins_encode( /*empty*/ ); 9569 ins_pipe(pipe_class_default); 9570%} 9571 9572 9573// Multiply-Accumulate 9574// src1 * src2 + src3 9575instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 9576 match(Set dst (FmaF src3 (Binary src1 src2))); 9577 9578 format %{ "FMADDS $dst, $src1, $src2, $src3" %} 9579 size(4); 9580 ins_encode %{ 9581 // TODO: PPC port $archOpcode(ppc64Opcode_fmadds); 9582 __ fmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 9583 %} 9584 ins_pipe(pipe_class_default); 9585%} 9586 9587// src1 * src2 + src3 9588instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 9589 match(Set dst (FmaD src3 (Binary src1 src2))); 9590 9591 format %{ "FMADD $dst, $src1, $src2, $src3" %} 9592 size(4); 9593 ins_encode %{ 9594 // TODO: PPC port $archOpcode(ppc64Opcode_fmadd); 9595 __ fmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 9596 %} 9597 ins_pipe(pipe_class_default); 9598%} 9599 9600// -src1 * src2 + src3 = -(src1*src2-src3) 9601instruct mnsubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 9602 match(Set dst (FmaF src3 (Binary (NegF src1) src2))); 9603 match(Set dst (FmaF src3 (Binary src1 (NegF src2)))); 9604 9605 format %{ "FNMSUBS $dst, $src1, $src2, $src3" %} 9606 size(4); 9607 ins_encode %{ 9608 // TODO: PPC port $archOpcode(ppc64Opcode_fnmsubs); 9609 __ fnmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 9610 %} 9611 ins_pipe(pipe_class_default); 9612%} 9613 9614// -src1 * src2 + src3 = -(src1*src2-src3) 9615instruct mnsubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 9616 match(Set dst (FmaD src3 (Binary (NegD src1) src2))); 9617 match(Set dst (FmaD src3 (Binary src1 (NegD src2)))); 9618 9619 format %{ "FNMSUB $dst, $src1, $src2, $src3" %} 9620 size(4); 9621 ins_encode %{ 9622 // TODO: PPC port $archOpcode(ppc64Opcode_fnmsub); 9623 __ fnmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 9624 %} 9625 ins_pipe(pipe_class_default); 9626%} 9627 9628// -src1 * src2 - src3 = -(src1*src2+src3) 9629instruct mnaddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 9630 match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2))); 9631 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2)))); 9632 9633 format %{ "FNMADDS $dst, $src1, $src2, $src3" %} 9634 size(4); 9635 ins_encode %{ 9636 // TODO: PPC port $archOpcode(ppc64Opcode_fnmadds); 9637 __ fnmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 9638 %} 9639 ins_pipe(pipe_class_default); 9640%} 9641 9642// -src1 * src2 - src3 = -(src1*src2+src3) 9643instruct mnaddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 9644 match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2))); 9645 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2)))); 9646 9647 format %{ "FNMADD $dst, $src1, $src2, $src3" %} 9648 size(4); 9649 ins_encode %{ 9650 // TODO: PPC port $archOpcode(ppc64Opcode_fnmadd); 9651 __ fnmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 9652 %} 9653 ins_pipe(pipe_class_default); 9654%} 9655 9656// src1 * src2 - src3 9657instruct msubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 9658 match(Set dst (FmaF (NegF src3) (Binary src1 src2))); 9659 9660 format %{ "FMSUBS $dst, $src1, $src2, $src3" %} 9661 size(4); 9662 ins_encode %{ 9663 // TODO: PPC port $archOpcode(ppc64Opcode_fmsubs); 9664 __ fmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 9665 %} 9666 ins_pipe(pipe_class_default); 9667%} 9668 9669// src1 * src2 - src3 9670instruct msubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 9671 match(Set dst (FmaD (NegD src3) (Binary src1 src2))); 9672 9673 format %{ "FMSUB $dst, $src1, $src2, $src3" %} 9674 size(4); 9675 ins_encode %{ 9676 // TODO: PPC port $archOpcode(ppc64Opcode_fmsub); 9677 __ fmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 9678 %} 9679 ins_pipe(pipe_class_default); 9680%} 9681 9682 9683//----------Logical Instructions----------------------------------------------- 9684 9685// And Instructions 9686 9687// Register And 9688instruct andI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9689 match(Set dst (AndI src1 src2)); 9690 format %{ "AND $dst, $src1, $src2" %} 9691 size(4); 9692 ins_encode %{ 9693 // TODO: PPC port $archOpcode(ppc64Opcode_and); 9694 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 9695 %} 9696 ins_pipe(pipe_class_default); 9697%} 9698 9699// Left shifted Immediate And 9700instruct andI_reg_immIhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2, flagsRegCR0 cr0) %{ 9701 match(Set dst (AndI src1 src2)); 9702 effect(KILL cr0); 9703 format %{ "ANDIS $dst, $src1, $src2.hi" %} 9704 size(4); 9705 ins_encode %{ 9706 // TODO: PPC port $archOpcode(ppc64Opcode_andis_); 9707 __ andis_($dst$$Register, $src1$$Register, (int)((unsigned short)(($src2$$constant & 0xFFFF0000) >> 16))); 9708 %} 9709 ins_pipe(pipe_class_default); 9710%} 9711 9712// Immediate And 9713instruct andI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2, flagsRegCR0 cr0) %{ 9714 match(Set dst (AndI src1 src2)); 9715 effect(KILL cr0); 9716 9717 format %{ "ANDI $dst, $src1, $src2" %} 9718 size(4); 9719 ins_encode %{ 9720 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 9721 // FIXME: avoid andi_ ? 9722 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 9723 %} 9724 ins_pipe(pipe_class_default); 9725%} 9726 9727// Immediate And where the immediate is a negative power of 2. 9728instruct andI_reg_immInegpow2(iRegIdst dst, iRegIsrc src1, immInegpow2 src2) %{ 9729 match(Set dst (AndI src1 src2)); 9730 format %{ "ANDWI $dst, $src1, $src2" %} 9731 size(4); 9732 ins_encode %{ 9733 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9734 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)(julong)(juint)-($src2$$constant))); 9735 %} 9736 ins_pipe(pipe_class_default); 9737%} 9738 9739instruct andI_reg_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immIpow2minus1 src2) %{ 9740 match(Set dst (AndI src1 src2)); 9741 format %{ "ANDWI $dst, $src1, $src2" %} 9742 size(4); 9743 ins_encode %{ 9744 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9745 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 9746 %} 9747 ins_pipe(pipe_class_default); 9748%} 9749 9750instruct andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src1, immIpowerOf2 src2) %{ 9751 match(Set dst (AndI src1 src2)); 9752 predicate(UseRotateAndMaskInstructionsPPC64); 9753 format %{ "ANDWI $dst, $src1, $src2" %} 9754 size(4); 9755 ins_encode %{ 9756 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9757 __ rlwinm($dst$$Register, $src1$$Register, 0, 9758 (31-log2_long((jlong) $src2$$constant)) & 0x1f, (31-log2_long((jlong) $src2$$constant)) & 0x1f); 9759 %} 9760 ins_pipe(pipe_class_default); 9761%} 9762 9763// Register And Long 9764instruct andL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9765 match(Set dst (AndL src1 src2)); 9766 ins_cost(DEFAULT_COST); 9767 9768 format %{ "AND $dst, $src1, $src2 \t// long" %} 9769 size(4); 9770 ins_encode %{ 9771 // TODO: PPC port $archOpcode(ppc64Opcode_and); 9772 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 9773 %} 9774 ins_pipe(pipe_class_default); 9775%} 9776 9777// Immediate And long 9778instruct andL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2, flagsRegCR0 cr0) %{ 9779 match(Set dst (AndL src1 src2)); 9780 effect(KILL cr0); 9781 9782 format %{ "ANDI $dst, $src1, $src2 \t// long" %} 9783 size(4); 9784 ins_encode %{ 9785 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 9786 // FIXME: avoid andi_ ? 9787 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 9788 %} 9789 ins_pipe(pipe_class_default); 9790%} 9791 9792// Immediate And Long where the immediate is a negative power of 2. 9793instruct andL_reg_immLnegpow2(iRegLdst dst, iRegLsrc src1, immLnegpow2 src2) %{ 9794 match(Set dst (AndL src1 src2)); 9795 format %{ "ANDDI $dst, $src1, $src2" %} 9796 size(4); 9797 ins_encode %{ 9798 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9799 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)-$src2$$constant)); 9800 %} 9801 ins_pipe(pipe_class_default); 9802%} 9803 9804instruct andL_reg_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 9805 match(Set dst (AndL src1 src2)); 9806 format %{ "ANDDI $dst, $src1, $src2" %} 9807 size(4); 9808 ins_encode %{ 9809 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9810 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 9811 %} 9812 ins_pipe(pipe_class_default); 9813%} 9814 9815// AndL + ConvL2I. 9816instruct convL2I_andL_reg_immLpow2minus1(iRegIdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 9817 match(Set dst (ConvL2I (AndL src1 src2))); 9818 ins_cost(DEFAULT_COST); 9819 9820 format %{ "ANDDI $dst, $src1, $src2 \t// long + l2i" %} 9821 size(4); 9822 ins_encode %{ 9823 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9824 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 9825 %} 9826 ins_pipe(pipe_class_default); 9827%} 9828 9829// Or Instructions 9830 9831// Register Or 9832instruct orI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9833 match(Set dst (OrI src1 src2)); 9834 format %{ "OR $dst, $src1, $src2" %} 9835 size(4); 9836 ins_encode %{ 9837 // TODO: PPC port $archOpcode(ppc64Opcode_or); 9838 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 9839 %} 9840 ins_pipe(pipe_class_default); 9841%} 9842 9843// Expand does not work with above instruct. (??) 9844instruct orI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9845 // no match-rule 9846 effect(DEF dst, USE src1, USE src2); 9847 format %{ "OR $dst, $src1, $src2" %} 9848 size(4); 9849 ins_encode %{ 9850 // TODO: PPC port $archOpcode(ppc64Opcode_or); 9851 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 9852 %} 9853 ins_pipe(pipe_class_default); 9854%} 9855 9856instruct tree_orI_orI_orI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 9857 match(Set dst (OrI (OrI (OrI src1 src2) src3) src4)); 9858 ins_cost(DEFAULT_COST*3); 9859 9860 expand %{ 9861 // FIXME: we should do this in the ideal world. 9862 iRegIdst tmp1; 9863 iRegIdst tmp2; 9864 orI_reg_reg(tmp1, src1, src2); 9865 orI_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 9866 orI_reg_reg(dst, tmp1, tmp2); 9867 %} 9868%} 9869 9870// Immediate Or 9871instruct orI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 9872 match(Set dst (OrI src1 src2)); 9873 format %{ "ORI $dst, $src1, $src2" %} 9874 size(4); 9875 ins_encode %{ 9876 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 9877 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 9878 %} 9879 ins_pipe(pipe_class_default); 9880%} 9881 9882// Register Or Long 9883instruct orL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9884 match(Set dst (OrL src1 src2)); 9885 ins_cost(DEFAULT_COST); 9886 9887 size(4); 9888 format %{ "OR $dst, $src1, $src2 \t// long" %} 9889 ins_encode %{ 9890 // TODO: PPC port $archOpcode(ppc64Opcode_or); 9891 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 9892 %} 9893 ins_pipe(pipe_class_default); 9894%} 9895 9896// OrL + ConvL2I. 9897instruct orI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9898 match(Set dst (ConvL2I (OrL src1 src2))); 9899 ins_cost(DEFAULT_COST); 9900 9901 format %{ "OR $dst, $src1, $src2 \t// long + l2i" %} 9902 size(4); 9903 ins_encode %{ 9904 // TODO: PPC port $archOpcode(ppc64Opcode_or); 9905 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 9906 %} 9907 ins_pipe(pipe_class_default); 9908%} 9909 9910// Immediate Or long 9911instruct orL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 con) %{ 9912 match(Set dst (OrL src1 con)); 9913 ins_cost(DEFAULT_COST); 9914 9915 format %{ "ORI $dst, $src1, $con \t// long" %} 9916 size(4); 9917 ins_encode %{ 9918 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 9919 __ ori($dst$$Register, $src1$$Register, ($con$$constant) & 0xFFFF); 9920 %} 9921 ins_pipe(pipe_class_default); 9922%} 9923 9924// Xor Instructions 9925 9926// Register Xor 9927instruct xorI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9928 match(Set dst (XorI src1 src2)); 9929 format %{ "XOR $dst, $src1, $src2" %} 9930 size(4); 9931 ins_encode %{ 9932 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 9933 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 9934 %} 9935 ins_pipe(pipe_class_default); 9936%} 9937 9938// Expand does not work with above instruct. (??) 9939instruct xorI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9940 // no match-rule 9941 effect(DEF dst, USE src1, USE src2); 9942 format %{ "XOR $dst, $src1, $src2" %} 9943 size(4); 9944 ins_encode %{ 9945 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 9946 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 9947 %} 9948 ins_pipe(pipe_class_default); 9949%} 9950 9951instruct tree_xorI_xorI_xorI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 9952 match(Set dst (XorI (XorI (XorI src1 src2) src3) src4)); 9953 ins_cost(DEFAULT_COST*3); 9954 9955 expand %{ 9956 // FIXME: we should do this in the ideal world. 9957 iRegIdst tmp1; 9958 iRegIdst tmp2; 9959 xorI_reg_reg(tmp1, src1, src2); 9960 xorI_reg_reg_2(tmp2, src3, src4); // Adlc complains about xorI_reg_reg. 9961 xorI_reg_reg(dst, tmp1, tmp2); 9962 %} 9963%} 9964 9965// Immediate Xor 9966instruct xorI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 9967 match(Set dst (XorI src1 src2)); 9968 format %{ "XORI $dst, $src1, $src2" %} 9969 size(4); 9970 ins_encode %{ 9971 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 9972 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 9973 %} 9974 ins_pipe(pipe_class_default); 9975%} 9976 9977// Register Xor Long 9978instruct xorL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9979 match(Set dst (XorL src1 src2)); 9980 ins_cost(DEFAULT_COST); 9981 9982 format %{ "XOR $dst, $src1, $src2 \t// long" %} 9983 size(4); 9984 ins_encode %{ 9985 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 9986 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 9987 %} 9988 ins_pipe(pipe_class_default); 9989%} 9990 9991// XorL + ConvL2I. 9992instruct xorI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9993 match(Set dst (ConvL2I (XorL src1 src2))); 9994 ins_cost(DEFAULT_COST); 9995 9996 format %{ "XOR $dst, $src1, $src2 \t// long + l2i" %} 9997 size(4); 9998 ins_encode %{ 9999 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10000 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10001 %} 10002 ins_pipe(pipe_class_default); 10003%} 10004 10005// Immediate Xor Long 10006instruct xorL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2) %{ 10007 match(Set dst (XorL src1 src2)); 10008 ins_cost(DEFAULT_COST); 10009 10010 format %{ "XORI $dst, $src1, $src2 \t// long" %} 10011 size(4); 10012 ins_encode %{ 10013 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 10014 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 10015 %} 10016 ins_pipe(pipe_class_default); 10017%} 10018 10019instruct notI_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 10020 match(Set dst (XorI src1 src2)); 10021 ins_cost(DEFAULT_COST); 10022 10023 format %{ "NOT $dst, $src1 ($src2)" %} 10024 size(4); 10025 ins_encode %{ 10026 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 10027 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 10028 %} 10029 ins_pipe(pipe_class_default); 10030%} 10031 10032instruct notL_reg(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 10033 match(Set dst (XorL src1 src2)); 10034 ins_cost(DEFAULT_COST); 10035 10036 format %{ "NOT $dst, $src1 ($src2) \t// long" %} 10037 size(4); 10038 ins_encode %{ 10039 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 10040 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 10041 %} 10042 ins_pipe(pipe_class_default); 10043%} 10044 10045// And-complement 10046instruct andcI_reg_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2, iRegIsrc src3) %{ 10047 match(Set dst (AndI (XorI src1 src2) src3)); 10048 ins_cost(DEFAULT_COST); 10049 10050 format %{ "ANDW $dst, xori($src1, $src2), $src3" %} 10051 size(4); 10052 ins_encode( enc_andc(dst, src3, src1) ); 10053 ins_pipe(pipe_class_default); 10054%} 10055 10056// And-complement 10057instruct andcL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10058 // no match-rule, false predicate 10059 effect(DEF dst, USE src1, USE src2); 10060 predicate(false); 10061 10062 format %{ "ANDC $dst, $src1, $src2" %} 10063 size(4); 10064 ins_encode %{ 10065 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 10066 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 10067 %} 10068 ins_pipe(pipe_class_default); 10069%} 10070 10071//----------Moves between int/long and float/double---------------------------- 10072// 10073// The following rules move values from int/long registers/stack-locations 10074// to float/double registers/stack-locations and vice versa, without doing any 10075// conversions. These rules are used to implement the bit-conversion methods 10076// of java.lang.Float etc., e.g. 10077// int floatToIntBits(float value) 10078// float intBitsToFloat(int bits) 10079// 10080// Notes on the implementation on ppc64: 10081// We only provide rules which move between a register and a stack-location, 10082// because we always have to go through memory when moving between a float 10083// register and an integer register. 10084 10085//---------- Chain stack slots between similar types -------- 10086 10087// These are needed so that the rules below can match. 10088 10089// Load integer from stack slot 10090instruct stkI_to_regI(iRegIdst dst, stackSlotI src) %{ 10091 match(Set dst src); 10092 ins_cost(MEMORY_REF_COST); 10093 10094 format %{ "LWZ $dst, $src" %} 10095 size(4); 10096 ins_encode( enc_lwz(dst, src) ); 10097 ins_pipe(pipe_class_memory); 10098%} 10099 10100// Store integer to stack slot 10101instruct regI_to_stkI(stackSlotI dst, iRegIsrc src) %{ 10102 match(Set dst src); 10103 ins_cost(MEMORY_REF_COST); 10104 10105 format %{ "STW $src, $dst \t// stk" %} 10106 size(4); 10107 ins_encode( enc_stw(src, dst) ); // rs=rt 10108 ins_pipe(pipe_class_memory); 10109%} 10110 10111// Load long from stack slot 10112instruct stkL_to_regL(iRegLdst dst, stackSlotL src) %{ 10113 match(Set dst src); 10114 ins_cost(MEMORY_REF_COST); 10115 10116 format %{ "LD $dst, $src \t// long" %} 10117 size(4); 10118 ins_encode( enc_ld(dst, src) ); 10119 ins_pipe(pipe_class_memory); 10120%} 10121 10122// Store long to stack slot 10123instruct regL_to_stkL(stackSlotL dst, iRegLsrc src) %{ 10124 match(Set dst src); 10125 ins_cost(MEMORY_REF_COST); 10126 10127 format %{ "STD $src, $dst \t// long" %} 10128 size(4); 10129 ins_encode( enc_std(src, dst) ); // rs=rt 10130 ins_pipe(pipe_class_memory); 10131%} 10132 10133//----------Moves between int and float 10134 10135// Move float value from float stack-location to integer register. 10136instruct moveF2I_stack_reg(iRegIdst dst, stackSlotF src) %{ 10137 match(Set dst (MoveF2I src)); 10138 ins_cost(MEMORY_REF_COST); 10139 10140 format %{ "LWZ $dst, $src \t// MoveF2I" %} 10141 size(4); 10142 ins_encode( enc_lwz(dst, src) ); 10143 ins_pipe(pipe_class_memory); 10144%} 10145 10146// Move float value from float register to integer stack-location. 10147instruct moveF2I_reg_stack(stackSlotI dst, regF src) %{ 10148 match(Set dst (MoveF2I src)); 10149 ins_cost(MEMORY_REF_COST); 10150 10151 format %{ "STFS $src, $dst \t// MoveF2I" %} 10152 size(4); 10153 ins_encode( enc_stfs(src, dst) ); 10154 ins_pipe(pipe_class_memory); 10155%} 10156 10157// Move integer value from integer stack-location to float register. 10158instruct moveI2F_stack_reg(regF dst, stackSlotI src) %{ 10159 match(Set dst (MoveI2F src)); 10160 ins_cost(MEMORY_REF_COST); 10161 10162 format %{ "LFS $dst, $src \t// MoveI2F" %} 10163 size(4); 10164 ins_encode %{ 10165 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 10166 int Idisp = $src$$disp + frame_slots_bias($src$$base, ra_); 10167 __ lfs($dst$$FloatRegister, Idisp, $src$$base$$Register); 10168 %} 10169 ins_pipe(pipe_class_memory); 10170%} 10171 10172// Move integer value from integer register to float stack-location. 10173instruct moveI2F_reg_stack(stackSlotF dst, iRegIsrc src) %{ 10174 match(Set dst (MoveI2F src)); 10175 ins_cost(MEMORY_REF_COST); 10176 10177 format %{ "STW $src, $dst \t// MoveI2F" %} 10178 size(4); 10179 ins_encode( enc_stw(src, dst) ); 10180 ins_pipe(pipe_class_memory); 10181%} 10182 10183//----------Moves between long and float 10184 10185instruct moveF2L_reg_stack(stackSlotL dst, regF src) %{ 10186 // no match-rule, false predicate 10187 effect(DEF dst, USE src); 10188 predicate(false); 10189 10190 format %{ "storeD $src, $dst \t// STACK" %} 10191 size(4); 10192 ins_encode( enc_stfd(src, dst) ); 10193 ins_pipe(pipe_class_default); 10194%} 10195 10196//----------Moves between long and double 10197 10198// Move double value from double stack-location to long register. 10199instruct moveD2L_stack_reg(iRegLdst dst, stackSlotD src) %{ 10200 match(Set dst (MoveD2L src)); 10201 ins_cost(MEMORY_REF_COST); 10202 size(4); 10203 format %{ "LD $dst, $src \t// MoveD2L" %} 10204 ins_encode( enc_ld(dst, src) ); 10205 ins_pipe(pipe_class_memory); 10206%} 10207 10208// Move double value from double register to long stack-location. 10209instruct moveD2L_reg_stack(stackSlotL dst, regD src) %{ 10210 match(Set dst (MoveD2L src)); 10211 effect(DEF dst, USE src); 10212 ins_cost(MEMORY_REF_COST); 10213 10214 format %{ "STFD $src, $dst \t// MoveD2L" %} 10215 size(4); 10216 ins_encode( enc_stfd(src, dst) ); 10217 ins_pipe(pipe_class_memory); 10218%} 10219 10220// Move long value from long stack-location to double register. 10221instruct moveL2D_stack_reg(regD dst, stackSlotL src) %{ 10222 match(Set dst (MoveL2D src)); 10223 ins_cost(MEMORY_REF_COST); 10224 10225 format %{ "LFD $dst, $src \t// MoveL2D" %} 10226 size(4); 10227 ins_encode( enc_lfd(dst, src) ); 10228 ins_pipe(pipe_class_memory); 10229%} 10230 10231// Move long value from long register to double stack-location. 10232instruct moveL2D_reg_stack(stackSlotD dst, iRegLsrc src) %{ 10233 match(Set dst (MoveL2D src)); 10234 ins_cost(MEMORY_REF_COST); 10235 10236 format %{ "STD $src, $dst \t// MoveL2D" %} 10237 size(4); 10238 ins_encode( enc_std(src, dst) ); 10239 ins_pipe(pipe_class_memory); 10240%} 10241 10242//----------Register Move Instructions----------------------------------------- 10243 10244// Replicate for Superword 10245 10246instruct moveReg(iRegLdst dst, iRegIsrc src) %{ 10247 predicate(false); 10248 effect(DEF dst, USE src); 10249 10250 format %{ "MR $dst, $src \t// replicate " %} 10251 // variable size, 0 or 4. 10252 ins_encode %{ 10253 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10254 __ mr_if_needed($dst$$Register, $src$$Register); 10255 %} 10256 ins_pipe(pipe_class_default); 10257%} 10258 10259//----------Cast instructions (Java-level type cast)--------------------------- 10260 10261// Cast Long to Pointer for unsafe natives. 10262instruct castX2P(iRegPdst dst, iRegLsrc src) %{ 10263 match(Set dst (CastX2P src)); 10264 10265 format %{ "MR $dst, $src \t// Long->Ptr" %} 10266 // variable size, 0 or 4. 10267 ins_encode %{ 10268 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10269 __ mr_if_needed($dst$$Register, $src$$Register); 10270 %} 10271 ins_pipe(pipe_class_default); 10272%} 10273 10274// Cast Pointer to Long for unsafe natives. 10275instruct castP2X(iRegLdst dst, iRegP_N2P src) %{ 10276 match(Set dst (CastP2X src)); 10277 10278 format %{ "MR $dst, $src \t// Ptr->Long" %} 10279 // variable size, 0 or 4. 10280 ins_encode %{ 10281 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10282 __ mr_if_needed($dst$$Register, $src$$Register); 10283 %} 10284 ins_pipe(pipe_class_default); 10285%} 10286 10287instruct castPP(iRegPdst dst) %{ 10288 match(Set dst (CastPP dst)); 10289 format %{ " -- \t// castPP of $dst" %} 10290 size(0); 10291 ins_encode( /*empty*/ ); 10292 ins_pipe(pipe_class_default); 10293%} 10294 10295instruct castII(iRegIdst dst) %{ 10296 match(Set dst (CastII dst)); 10297 format %{ " -- \t// castII of $dst" %} 10298 size(0); 10299 ins_encode( /*empty*/ ); 10300 ins_pipe(pipe_class_default); 10301%} 10302 10303instruct checkCastPP(iRegPdst dst) %{ 10304 match(Set dst (CheckCastPP dst)); 10305 format %{ " -- \t// checkcastPP of $dst" %} 10306 size(0); 10307 ins_encode( /*empty*/ ); 10308 ins_pipe(pipe_class_default); 10309%} 10310 10311//----------Convert instructions----------------------------------------------- 10312 10313// Convert to boolean. 10314 10315// int_to_bool(src) : { 1 if src != 0 10316// { 0 else 10317// 10318// strategy: 10319// 1) Count leading zeros of 32 bit-value src, 10320// this returns 32 (0b10.0000) iff src == 0 and <32 otherwise. 10321// 2) Shift 5 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10322// 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10323 10324// convI2Bool 10325instruct convI2Bool_reg__cntlz_Ex(iRegIdst dst, iRegIsrc src) %{ 10326 match(Set dst (Conv2B src)); 10327 predicate(UseCountLeadingZerosInstructionsPPC64); 10328 ins_cost(DEFAULT_COST); 10329 10330 expand %{ 10331 immI shiftAmount %{ 0x5 %} 10332 uimmI16 mask %{ 0x1 %} 10333 iRegIdst tmp1; 10334 iRegIdst tmp2; 10335 countLeadingZerosI(tmp1, src); 10336 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10337 xorI_reg_uimm16(dst, tmp2, mask); 10338 %} 10339%} 10340 10341instruct convI2Bool_reg__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx) %{ 10342 match(Set dst (Conv2B src)); 10343 effect(TEMP crx); 10344 predicate(!UseCountLeadingZerosInstructionsPPC64); 10345 ins_cost(DEFAULT_COST); 10346 10347 format %{ "CMPWI $crx, $src, #0 \t// convI2B" 10348 "LI $dst, #0\n\t" 10349 "BEQ $crx, done\n\t" 10350 "LI $dst, #1\n" 10351 "done:" %} 10352 size(16); 10353 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x0, 0x1) ); 10354 ins_pipe(pipe_class_compare); 10355%} 10356 10357// ConvI2B + XorI 10358instruct xorI_convI2Bool_reg_immIvalue1__cntlz_Ex(iRegIdst dst, iRegIsrc src, immI_1 mask) %{ 10359 match(Set dst (XorI (Conv2B src) mask)); 10360 predicate(UseCountLeadingZerosInstructionsPPC64); 10361 ins_cost(DEFAULT_COST); 10362 10363 expand %{ 10364 immI shiftAmount %{ 0x5 %} 10365 iRegIdst tmp1; 10366 countLeadingZerosI(tmp1, src); 10367 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10368 %} 10369%} 10370 10371instruct xorI_convI2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI_1 mask) %{ 10372 match(Set dst (XorI (Conv2B src) mask)); 10373 effect(TEMP crx); 10374 predicate(!UseCountLeadingZerosInstructionsPPC64); 10375 ins_cost(DEFAULT_COST); 10376 10377 format %{ "CMPWI $crx, $src, #0 \t// Xor(convI2B($src), $mask)" 10378 "LI $dst, #1\n\t" 10379 "BEQ $crx, done\n\t" 10380 "LI $dst, #0\n" 10381 "done:" %} 10382 size(16); 10383 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x1, 0x0) ); 10384 ins_pipe(pipe_class_compare); 10385%} 10386 10387// AndI 0b0..010..0 + ConvI2B 10388instruct convI2Bool_andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src, immIpowerOf2 mask) %{ 10389 match(Set dst (Conv2B (AndI src mask))); 10390 predicate(UseRotateAndMaskInstructionsPPC64); 10391 ins_cost(DEFAULT_COST); 10392 10393 format %{ "RLWINM $dst, $src, $mask \t// convI2B(AndI($src, $mask))" %} 10394 size(4); 10395 ins_encode %{ 10396 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 10397 __ rlwinm($dst$$Register, $src$$Register, (32-log2_long((jlong)$mask$$constant)) & 0x1f, 31, 31); 10398 %} 10399 ins_pipe(pipe_class_default); 10400%} 10401 10402// Convert pointer to boolean. 10403// 10404// ptr_to_bool(src) : { 1 if src != 0 10405// { 0 else 10406// 10407// strategy: 10408// 1) Count leading zeros of 64 bit-value src, 10409// this returns 64 (0b100.0000) iff src == 0 and <64 otherwise. 10410// 2) Shift 6 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10411// 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10412 10413// ConvP2B 10414instruct convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src) %{ 10415 match(Set dst (Conv2B src)); 10416 predicate(UseCountLeadingZerosInstructionsPPC64); 10417 ins_cost(DEFAULT_COST); 10418 10419 expand %{ 10420 immI shiftAmount %{ 0x6 %} 10421 uimmI16 mask %{ 0x1 %} 10422 iRegIdst tmp1; 10423 iRegIdst tmp2; 10424 countLeadingZerosP(tmp1, src); 10425 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10426 xorI_reg_uimm16(dst, tmp2, mask); 10427 %} 10428%} 10429 10430instruct convP2Bool_reg__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx) %{ 10431 match(Set dst (Conv2B src)); 10432 effect(TEMP crx); 10433 predicate(!UseCountLeadingZerosInstructionsPPC64); 10434 ins_cost(DEFAULT_COST); 10435 10436 format %{ "CMPDI $crx, $src, #0 \t// convP2B" 10437 "LI $dst, #0\n\t" 10438 "BEQ $crx, done\n\t" 10439 "LI $dst, #1\n" 10440 "done:" %} 10441 size(16); 10442 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x0, 0x1) ); 10443 ins_pipe(pipe_class_compare); 10444%} 10445 10446// ConvP2B + XorI 10447instruct xorI_convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src, immI_1 mask) %{ 10448 match(Set dst (XorI (Conv2B src) mask)); 10449 predicate(UseCountLeadingZerosInstructionsPPC64); 10450 ins_cost(DEFAULT_COST); 10451 10452 expand %{ 10453 immI shiftAmount %{ 0x6 %} 10454 iRegIdst tmp1; 10455 countLeadingZerosP(tmp1, src); 10456 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10457 %} 10458%} 10459 10460instruct xorI_convP2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx, immI_1 mask) %{ 10461 match(Set dst (XorI (Conv2B src) mask)); 10462 effect(TEMP crx); 10463 predicate(!UseCountLeadingZerosInstructionsPPC64); 10464 ins_cost(DEFAULT_COST); 10465 10466 format %{ "CMPDI $crx, $src, #0 \t// XorI(convP2B($src), $mask)" 10467 "LI $dst, #1\n\t" 10468 "BEQ $crx, done\n\t" 10469 "LI $dst, #0\n" 10470 "done:" %} 10471 size(16); 10472 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x1, 0x0) ); 10473 ins_pipe(pipe_class_compare); 10474%} 10475 10476// if src1 < src2, return -1 else return 0 10477instruct cmpLTMask_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10478 match(Set dst (CmpLTMask src1 src2)); 10479 ins_cost(DEFAULT_COST*4); 10480 10481 expand %{ 10482 iRegLdst src1s; 10483 iRegLdst src2s; 10484 iRegLdst diff; 10485 convI2L_reg(src1s, src1); // Ensure proper sign extension. 10486 convI2L_reg(src2s, src2); // Ensure proper sign extension. 10487 subL_reg_reg(diff, src1s, src2s); 10488 // Need to consider >=33 bit result, therefore we need signmaskL. 10489 signmask64I_regL(dst, diff); 10490 %} 10491%} 10492 10493instruct cmpLTMask_reg_immI0(iRegIdst dst, iRegIsrc src1, immI_0 src2) %{ 10494 match(Set dst (CmpLTMask src1 src2)); // if src1 < src2, return -1 else return 0 10495 format %{ "SRAWI $dst, $src1, $src2 \t// CmpLTMask" %} 10496 size(4); 10497 ins_encode %{ 10498 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 10499 __ srawi($dst$$Register, $src1$$Register, 0x1f); 10500 %} 10501 ins_pipe(pipe_class_default); 10502%} 10503 10504//----------Arithmetic Conversion Instructions--------------------------------- 10505 10506// Convert to Byte -- nop 10507// Convert to Short -- nop 10508 10509// Convert to Int 10510 10511instruct convB2I_reg(iRegIdst dst, iRegIsrc src, immI_24 amount) %{ 10512 match(Set dst (RShiftI (LShiftI src amount) amount)); 10513 format %{ "EXTSB $dst, $src \t// byte->int" %} 10514 size(4); 10515 ins_encode %{ 10516 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 10517 __ extsb($dst$$Register, $src$$Register); 10518 %} 10519 ins_pipe(pipe_class_default); 10520%} 10521 10522// LShiftI 16 + RShiftI 16 converts short to int. 10523instruct convS2I_reg(iRegIdst dst, iRegIsrc src, immI_16 amount) %{ 10524 match(Set dst (RShiftI (LShiftI src amount) amount)); 10525 format %{ "EXTSH $dst, $src \t// short->int" %} 10526 size(4); 10527 ins_encode %{ 10528 // TODO: PPC port $archOpcode(ppc64Opcode_extsh); 10529 __ extsh($dst$$Register, $src$$Register); 10530 %} 10531 ins_pipe(pipe_class_default); 10532%} 10533 10534// ConvL2I + ConvI2L: Sign extend int in long register. 10535instruct sxtI_L2L_reg(iRegLdst dst, iRegLsrc src) %{ 10536 match(Set dst (ConvI2L (ConvL2I src))); 10537 10538 format %{ "EXTSW $dst, $src \t// long->long" %} 10539 size(4); 10540 ins_encode %{ 10541 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 10542 __ extsw($dst$$Register, $src$$Register); 10543 %} 10544 ins_pipe(pipe_class_default); 10545%} 10546 10547instruct convL2I_reg(iRegIdst dst, iRegLsrc src) %{ 10548 match(Set dst (ConvL2I src)); 10549 format %{ "MR $dst, $src \t// long->int" %} 10550 // variable size, 0 or 4 10551 ins_encode %{ 10552 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10553 __ mr_if_needed($dst$$Register, $src$$Register); 10554 %} 10555 ins_pipe(pipe_class_default); 10556%} 10557 10558instruct convD2IRaw_regD(regD dst, regD src) %{ 10559 // no match-rule, false predicate 10560 effect(DEF dst, USE src); 10561 predicate(false); 10562 10563 format %{ "FCTIWZ $dst, $src \t// convD2I, $src != NaN" %} 10564 size(4); 10565 ins_encode %{ 10566 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz);; 10567 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 10568 %} 10569 ins_pipe(pipe_class_default); 10570%} 10571 10572instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL src) %{ 10573 // no match-rule, false predicate 10574 effect(DEF dst, USE crx, USE src); 10575 predicate(false); 10576 10577 ins_variable_size_depending_on_alignment(true); 10578 10579 format %{ "cmovI $crx, $dst, $src" %} 10580 // Worst case is branch + move + stop, no stop without scheduler. 10581 size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 10582 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 10583 ins_pipe(pipe_class_default); 10584%} 10585 10586instruct cmovI_bso_stackSlotL_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, stackSlotL mem) %{ 10587 // no match-rule, false predicate 10588 effect(DEF dst, USE crx, USE mem); 10589 predicate(false); 10590 10591 format %{ "CmovI $dst, $crx, $mem \t// postalloc expanded" %} 10592 postalloc_expand %{ 10593 // 10594 // replaces 10595 // 10596 // region dst crx mem 10597 // \ | | / 10598 // dst=cmovI_bso_stackSlotL_conLvalue0 10599 // 10600 // with 10601 // 10602 // region dst 10603 // \ / 10604 // dst=loadConI16(0) 10605 // | 10606 // ^ region dst crx mem 10607 // | \ | | / 10608 // dst=cmovI_bso_stackSlotL 10609 // 10610 10611 // Create new nodes. 10612 MachNode *m1 = new loadConI16Node(); 10613 MachNode *m2 = new cmovI_bso_stackSlotLNode(); 10614 10615 // inputs for new nodes 10616 m1->add_req(n_region); 10617 m2->add_req(n_region, n_crx, n_mem); 10618 10619 // precedences for new nodes 10620 m2->add_prec(m1); 10621 10622 // operands for new nodes 10623 m1->_opnds[0] = op_dst; 10624 m1->_opnds[1] = new immI16Oper(0); 10625 10626 m2->_opnds[0] = op_dst; 10627 m2->_opnds[1] = op_crx; 10628 m2->_opnds[2] = op_mem; 10629 10630 // registers for new nodes 10631 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10632 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10633 10634 // Insert new nodes. 10635 nodes->push(m1); 10636 nodes->push(m2); 10637 %} 10638%} 10639 10640// Double to Int conversion, NaN is mapped to 0. 10641instruct convD2I_reg_ExEx(iRegIdst dst, regD src) %{ 10642 match(Set dst (ConvD2I src)); 10643 ins_cost(DEFAULT_COST); 10644 10645 expand %{ 10646 regD tmpD; 10647 stackSlotL tmpS; 10648 flagsReg crx; 10649 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10650 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 10651 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 10652 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 10653 %} 10654%} 10655 10656instruct convF2IRaw_regF(regF dst, regF src) %{ 10657 // no match-rule, false predicate 10658 effect(DEF dst, USE src); 10659 predicate(false); 10660 10661 format %{ "FCTIWZ $dst, $src \t// convF2I, $src != NaN" %} 10662 size(4); 10663 ins_encode %{ 10664 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 10665 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 10666 %} 10667 ins_pipe(pipe_class_default); 10668%} 10669 10670// Float to Int conversion, NaN is mapped to 0. 10671instruct convF2I_regF_ExEx(iRegIdst dst, regF src) %{ 10672 match(Set dst (ConvF2I src)); 10673 ins_cost(DEFAULT_COST); 10674 10675 expand %{ 10676 regF tmpF; 10677 stackSlotL tmpS; 10678 flagsReg crx; 10679 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10680 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 10681 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 10682 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 10683 %} 10684%} 10685 10686// Convert to Long 10687 10688instruct convI2L_reg(iRegLdst dst, iRegIsrc src) %{ 10689 match(Set dst (ConvI2L src)); 10690 format %{ "EXTSW $dst, $src \t// int->long" %} 10691 size(4); 10692 ins_encode %{ 10693 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 10694 __ extsw($dst$$Register, $src$$Register); 10695 %} 10696 ins_pipe(pipe_class_default); 10697%} 10698 10699// Zero-extend: convert unsigned int to long (convUI2L). 10700instruct zeroExtendL_regI(iRegLdst dst, iRegIsrc src, immL_32bits mask) %{ 10701 match(Set dst (AndL (ConvI2L src) mask)); 10702 ins_cost(DEFAULT_COST); 10703 10704 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 10705 size(4); 10706 ins_encode %{ 10707 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10708 __ clrldi($dst$$Register, $src$$Register, 32); 10709 %} 10710 ins_pipe(pipe_class_default); 10711%} 10712 10713// Zero-extend: convert unsigned int to long in long register. 10714instruct zeroExtendL_regL(iRegLdst dst, iRegLsrc src, immL_32bits mask) %{ 10715 match(Set dst (AndL src mask)); 10716 ins_cost(DEFAULT_COST); 10717 10718 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 10719 size(4); 10720 ins_encode %{ 10721 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10722 __ clrldi($dst$$Register, $src$$Register, 32); 10723 %} 10724 ins_pipe(pipe_class_default); 10725%} 10726 10727instruct convF2LRaw_regF(regF dst, regF src) %{ 10728 // no match-rule, false predicate 10729 effect(DEF dst, USE src); 10730 predicate(false); 10731 10732 format %{ "FCTIDZ $dst, $src \t// convF2L, $src != NaN" %} 10733 size(4); 10734 ins_encode %{ 10735 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 10736 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 10737 %} 10738 ins_pipe(pipe_class_default); 10739%} 10740 10741instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL src) %{ 10742 // no match-rule, false predicate 10743 effect(DEF dst, USE crx, USE src); 10744 predicate(false); 10745 10746 ins_variable_size_depending_on_alignment(true); 10747 10748 format %{ "cmovL $crx, $dst, $src" %} 10749 // Worst case is branch + move + stop, no stop without scheduler. 10750 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 10751 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 10752 ins_pipe(pipe_class_default); 10753%} 10754 10755instruct cmovL_bso_stackSlotL_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, stackSlotL mem) %{ 10756 // no match-rule, false predicate 10757 effect(DEF dst, USE crx, USE mem); 10758 predicate(false); 10759 10760 format %{ "CmovL $dst, $crx, $mem \t// postalloc expanded" %} 10761 postalloc_expand %{ 10762 // 10763 // replaces 10764 // 10765 // region dst crx mem 10766 // \ | | / 10767 // dst=cmovL_bso_stackSlotL_conLvalue0 10768 // 10769 // with 10770 // 10771 // region dst 10772 // \ / 10773 // dst=loadConL16(0) 10774 // | 10775 // ^ region dst crx mem 10776 // | \ | | / 10777 // dst=cmovL_bso_stackSlotL 10778 // 10779 10780 // Create new nodes. 10781 MachNode *m1 = new loadConL16Node(); 10782 MachNode *m2 = new cmovL_bso_stackSlotLNode(); 10783 10784 // inputs for new nodes 10785 m1->add_req(n_region); 10786 m2->add_req(n_region, n_crx, n_mem); 10787 m2->add_prec(m1); 10788 10789 // operands for new nodes 10790 m1->_opnds[0] = op_dst; 10791 m1->_opnds[1] = new immL16Oper(0); 10792 m2->_opnds[0] = op_dst; 10793 m2->_opnds[1] = op_crx; 10794 m2->_opnds[2] = op_mem; 10795 10796 // registers for new nodes 10797 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10798 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10799 10800 // Insert new nodes. 10801 nodes->push(m1); 10802 nodes->push(m2); 10803 %} 10804%} 10805 10806// Float to Long conversion, NaN is mapped to 0. 10807instruct convF2L_reg_ExEx(iRegLdst dst, regF src) %{ 10808 match(Set dst (ConvF2L src)); 10809 ins_cost(DEFAULT_COST); 10810 10811 expand %{ 10812 regF tmpF; 10813 stackSlotL tmpS; 10814 flagsReg crx; 10815 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10816 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 10817 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 10818 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 10819 %} 10820%} 10821 10822instruct convD2LRaw_regD(regD dst, regD src) %{ 10823 // no match-rule, false predicate 10824 effect(DEF dst, USE src); 10825 predicate(false); 10826 10827 format %{ "FCTIDZ $dst, $src \t// convD2L $src != NaN" %} 10828 size(4); 10829 ins_encode %{ 10830 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 10831 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 10832 %} 10833 ins_pipe(pipe_class_default); 10834%} 10835 10836// Double to Long conversion, NaN is mapped to 0. 10837instruct convD2L_reg_ExEx(iRegLdst dst, regD src) %{ 10838 match(Set dst (ConvD2L src)); 10839 ins_cost(DEFAULT_COST); 10840 10841 expand %{ 10842 regD tmpD; 10843 stackSlotL tmpS; 10844 flagsReg crx; 10845 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10846 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 10847 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 10848 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 10849 %} 10850%} 10851 10852// Convert to Float 10853 10854// Placed here as needed in expand. 10855instruct convL2DRaw_regD(regD dst, regD src) %{ 10856 // no match-rule, false predicate 10857 effect(DEF dst, USE src); 10858 predicate(false); 10859 10860 format %{ "FCFID $dst, $src \t// convL2D" %} 10861 size(4); 10862 ins_encode %{ 10863 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 10864 __ fcfid($dst$$FloatRegister, $src$$FloatRegister); 10865 %} 10866 ins_pipe(pipe_class_default); 10867%} 10868 10869// Placed here as needed in expand. 10870instruct convD2F_reg(regF dst, regD src) %{ 10871 match(Set dst (ConvD2F src)); 10872 format %{ "FRSP $dst, $src \t// convD2F" %} 10873 size(4); 10874 ins_encode %{ 10875 // TODO: PPC port $archOpcode(ppc64Opcode_frsp); 10876 __ frsp($dst$$FloatRegister, $src$$FloatRegister); 10877 %} 10878 ins_pipe(pipe_class_default); 10879%} 10880 10881// Integer to Float conversion. 10882instruct convI2F_ireg_Ex(regF dst, iRegIsrc src) %{ 10883 match(Set dst (ConvI2F src)); 10884 predicate(!VM_Version::has_fcfids()); 10885 ins_cost(DEFAULT_COST); 10886 10887 expand %{ 10888 iRegLdst tmpL; 10889 stackSlotL tmpS; 10890 regD tmpD; 10891 regD tmpD2; 10892 convI2L_reg(tmpL, src); // Sign-extension int to long. 10893 regL_to_stkL(tmpS, tmpL); // Store long to stack. 10894 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 10895 convL2DRaw_regD(tmpD2, tmpD); // Convert to double. 10896 convD2F_reg(dst, tmpD2); // Convert double to float. 10897 %} 10898%} 10899 10900instruct convL2FRaw_regF(regF dst, regD src) %{ 10901 // no match-rule, false predicate 10902 effect(DEF dst, USE src); 10903 predicate(false); 10904 10905 format %{ "FCFIDS $dst, $src \t// convL2F" %} 10906 size(4); 10907 ins_encode %{ 10908 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 10909 __ fcfids($dst$$FloatRegister, $src$$FloatRegister); 10910 %} 10911 ins_pipe(pipe_class_default); 10912%} 10913 10914// Integer to Float conversion. Special version for Power7. 10915instruct convI2F_ireg_fcfids_Ex(regF dst, iRegIsrc src) %{ 10916 match(Set dst (ConvI2F src)); 10917 predicate(VM_Version::has_fcfids()); 10918 ins_cost(DEFAULT_COST); 10919 10920 expand %{ 10921 iRegLdst tmpL; 10922 stackSlotL tmpS; 10923 regD tmpD; 10924 convI2L_reg(tmpL, src); // Sign-extension int to long. 10925 regL_to_stkL(tmpS, tmpL); // Store long to stack. 10926 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 10927 convL2FRaw_regF(dst, tmpD); // Convert to float. 10928 %} 10929%} 10930 10931// L2F to avoid runtime call. 10932instruct convL2F_ireg_fcfids_Ex(regF dst, iRegLsrc src) %{ 10933 match(Set dst (ConvL2F src)); 10934 predicate(VM_Version::has_fcfids()); 10935 ins_cost(DEFAULT_COST); 10936 10937 expand %{ 10938 stackSlotL tmpS; 10939 regD tmpD; 10940 regL_to_stkL(tmpS, src); // Store long to stack. 10941 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 10942 convL2FRaw_regF(dst, tmpD); // Convert to float. 10943 %} 10944%} 10945 10946// Moved up as used in expand. 10947//instruct convD2F_reg(regF dst, regD src) %{%} 10948 10949// Convert to Double 10950 10951// Integer to Double conversion. 10952instruct convI2D_reg_Ex(regD dst, iRegIsrc src) %{ 10953 match(Set dst (ConvI2D src)); 10954 ins_cost(DEFAULT_COST); 10955 10956 expand %{ 10957 iRegLdst tmpL; 10958 stackSlotL tmpS; 10959 regD tmpD; 10960 convI2L_reg(tmpL, src); // Sign-extension int to long. 10961 regL_to_stkL(tmpS, tmpL); // Store long to stack. 10962 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 10963 convL2DRaw_regD(dst, tmpD); // Convert to double. 10964 %} 10965%} 10966 10967// Long to Double conversion 10968instruct convL2D_reg_Ex(regD dst, stackSlotL src) %{ 10969 match(Set dst (ConvL2D src)); 10970 ins_cost(DEFAULT_COST + MEMORY_REF_COST); 10971 10972 expand %{ 10973 regD tmpD; 10974 moveL2D_stack_reg(tmpD, src); 10975 convL2DRaw_regD(dst, tmpD); 10976 %} 10977%} 10978 10979instruct convF2D_reg(regD dst, regF src) %{ 10980 match(Set dst (ConvF2D src)); 10981 format %{ "FMR $dst, $src \t// float->double" %} 10982 // variable size, 0 or 4 10983 ins_encode %{ 10984 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 10985 __ fmr_if_needed($dst$$FloatRegister, $src$$FloatRegister); 10986 %} 10987 ins_pipe(pipe_class_default); 10988%} 10989 10990//----------Control Flow Instructions------------------------------------------ 10991// Compare Instructions 10992 10993// Compare Integers 10994instruct cmpI_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 10995 match(Set crx (CmpI src1 src2)); 10996 size(4); 10997 format %{ "CMPW $crx, $src1, $src2" %} 10998 ins_encode %{ 10999 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 11000 __ cmpw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11001 %} 11002 ins_pipe(pipe_class_compare); 11003%} 11004 11005instruct cmpI_reg_imm16(flagsReg crx, iRegIsrc src1, immI16 src2) %{ 11006 match(Set crx (CmpI src1 src2)); 11007 format %{ "CMPWI $crx, $src1, $src2" %} 11008 size(4); 11009 ins_encode %{ 11010 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11011 __ cmpwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11012 %} 11013 ins_pipe(pipe_class_compare); 11014%} 11015 11016// (src1 & src2) == 0? 11017instruct testI_reg_imm(flagsRegCR0 cr0, iRegIsrc src1, uimmI16 src2, immI_0 zero) %{ 11018 match(Set cr0 (CmpI (AndI src1 src2) zero)); 11019 // r0 is killed 11020 format %{ "ANDI R0, $src1, $src2 \t// BTST int" %} 11021 size(4); 11022 ins_encode %{ 11023 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 11024 __ andi_(R0, $src1$$Register, $src2$$constant); 11025 %} 11026 ins_pipe(pipe_class_compare); 11027%} 11028 11029instruct cmpL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 11030 match(Set crx (CmpL src1 src2)); 11031 format %{ "CMPD $crx, $src1, $src2" %} 11032 size(4); 11033 ins_encode %{ 11034 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 11035 __ cmpd($crx$$CondRegister, $src1$$Register, $src2$$Register); 11036 %} 11037 ins_pipe(pipe_class_compare); 11038%} 11039 11040instruct cmpL_reg_imm16(flagsReg crx, iRegLsrc src1, immL16 src2) %{ 11041 match(Set crx (CmpL src1 src2)); 11042 format %{ "CMPDI $crx, $src1, $src2" %} 11043 size(4); 11044 ins_encode %{ 11045 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11046 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11047 %} 11048 ins_pipe(pipe_class_compare); 11049%} 11050 11051// Added CmpUL for LoopPredicate. 11052instruct cmpUL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 11053 match(Set crx (CmpUL src1 src2)); 11054 format %{ "CMPLD $crx, $src1, $src2" %} 11055 size(4); 11056 ins_encode %{ 11057 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11058 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 11059 %} 11060 ins_pipe(pipe_class_compare); 11061%} 11062 11063instruct cmpUL_reg_imm16(flagsReg crx, iRegLsrc src1, uimmL16 src2) %{ 11064 match(Set crx (CmpUL src1 src2)); 11065 format %{ "CMPLDI $crx, $src1, $src2" %} 11066 size(4); 11067 ins_encode %{ 11068 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 11069 __ cmpldi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11070 %} 11071 ins_pipe(pipe_class_compare); 11072%} 11073 11074instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zero) %{ 11075 match(Set cr0 (CmpL (AndL src1 src2) zero)); 11076 // r0 is killed 11077 format %{ "AND R0, $src1, $src2 \t// BTST long" %} 11078 size(4); 11079 ins_encode %{ 11080 // TODO: PPC port $archOpcode(ppc64Opcode_and_); 11081 __ and_(R0, $src1$$Register, $src2$$Register); 11082 %} 11083 ins_pipe(pipe_class_compare); 11084%} 11085 11086instruct testL_reg_imm(flagsRegCR0 cr0, iRegLsrc src1, uimmL16 src2, immL_0 zero) %{ 11087 match(Set cr0 (CmpL (AndL src1 src2) zero)); 11088 // r0 is killed 11089 format %{ "ANDI R0, $src1, $src2 \t// BTST long" %} 11090 size(4); 11091 ins_encode %{ 11092 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 11093 __ andi_(R0, $src1$$Register, $src2$$constant); 11094 %} 11095 ins_pipe(pipe_class_compare); 11096%} 11097 11098instruct cmovI_conIvalueMinus1_conIvalue1(iRegIdst dst, flagsRegSrc crx) %{ 11099 // no match-rule, false predicate 11100 effect(DEF dst, USE crx); 11101 predicate(false); 11102 11103 ins_variable_size_depending_on_alignment(true); 11104 11105 format %{ "cmovI $crx, $dst, -1, 0, +1" %} 11106 // Worst case is branch + move + branch + move + stop, no stop without scheduler. 11107 size(false /* TODO: PPC PORTInsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 20 : 16); 11108 ins_encode %{ 11109 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 11110 Label done; 11111 // li(Rdst, 0); // equal -> 0 11112 __ beq($crx$$CondRegister, done); 11113 __ li($dst$$Register, 1); // greater -> +1 11114 __ bgt($crx$$CondRegister, done); 11115 __ li($dst$$Register, -1); // unordered or less -> -1 11116 // TODO: PPC port__ endgroup_if_needed(_size == 20); 11117 __ bind(done); 11118 %} 11119 ins_pipe(pipe_class_compare); 11120%} 11121 11122instruct cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(iRegIdst dst, flagsRegSrc crx) %{ 11123 // no match-rule, false predicate 11124 effect(DEF dst, USE crx); 11125 predicate(false); 11126 11127 format %{ "CmovI $crx, $dst, -1, 0, +1 \t// postalloc expanded" %} 11128 postalloc_expand %{ 11129 // 11130 // replaces 11131 // 11132 // region crx 11133 // \ | 11134 // dst=cmovI_conIvalueMinus1_conIvalue0_conIvalue1 11135 // 11136 // with 11137 // 11138 // region 11139 // \ 11140 // dst=loadConI16(0) 11141 // | 11142 // ^ region crx 11143 // | \ | 11144 // dst=cmovI_conIvalueMinus1_conIvalue1 11145 // 11146 11147 // Create new nodes. 11148 MachNode *m1 = new loadConI16Node(); 11149 MachNode *m2 = new cmovI_conIvalueMinus1_conIvalue1Node(); 11150 11151 // inputs for new nodes 11152 m1->add_req(n_region); 11153 m2->add_req(n_region, n_crx); 11154 m2->add_prec(m1); 11155 11156 // operands for new nodes 11157 m1->_opnds[0] = op_dst; 11158 m1->_opnds[1] = new immI16Oper(0); 11159 m2->_opnds[0] = op_dst; 11160 m2->_opnds[1] = op_crx; 11161 11162 // registers for new nodes 11163 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11164 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11165 11166 // Insert new nodes. 11167 nodes->push(m1); 11168 nodes->push(m2); 11169 %} 11170%} 11171 11172// Manifest a CmpL3 result in an integer register. Very painful. 11173// This is the test to avoid. 11174// (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 11175instruct cmpL3_reg_reg_ExEx(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 11176 match(Set dst (CmpL3 src1 src2)); 11177 ins_cost(DEFAULT_COST*5+BRANCH_COST); 11178 11179 expand %{ 11180 flagsReg tmp1; 11181 cmpL_reg_reg(tmp1, src1, src2); 11182 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 11183 %} 11184%} 11185 11186// Implicit range checks. 11187// A range check in the ideal world has one of the following shapes: 11188// - (If le (CmpU length index)), (IfTrue throw exception) 11189// - (If lt (CmpU index length)), (IfFalse throw exception) 11190// 11191// Match range check 'If le (CmpU length index)'. 11192instruct rangeCheck_iReg_uimm15(cmpOp cmp, iRegIsrc src_length, uimmI15 index, label labl) %{ 11193 match(If cmp (CmpU src_length index)); 11194 effect(USE labl); 11195 predicate(TrapBasedRangeChecks && 11196 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le && 11197 PROB_UNLIKELY(_leaf->as_If()->_prob) >= PROB_ALWAYS && 11198 (Matcher::branches_to_uncommon_trap(_leaf))); 11199 11200 ins_is_TrapBasedCheckNode(true); 11201 11202 format %{ "TWI $index $cmp $src_length \t// RangeCheck => trap $labl" %} 11203 size(4); 11204 ins_encode %{ 11205 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 11206 if ($cmp$$cmpcode == 0x1 /* less_equal */) { 11207 __ trap_range_check_le($src_length$$Register, $index$$constant); 11208 } else { 11209 // Both successors are uncommon traps, probability is 0. 11210 // Node got flipped during fixup flow. 11211 assert($cmp$$cmpcode == 0x9, "must be greater"); 11212 __ trap_range_check_g($src_length$$Register, $index$$constant); 11213 } 11214 %} 11215 ins_pipe(pipe_class_trap); 11216%} 11217 11218// Match range check 'If lt (CmpU index length)'. 11219instruct rangeCheck_iReg_iReg(cmpOp cmp, iRegIsrc src_index, iRegIsrc src_length, label labl) %{ 11220 match(If cmp (CmpU src_index src_length)); 11221 effect(USE labl); 11222 predicate(TrapBasedRangeChecks && 11223 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 11224 _leaf->as_If()->_prob >= PROB_ALWAYS && 11225 (Matcher::branches_to_uncommon_trap(_leaf))); 11226 11227 ins_is_TrapBasedCheckNode(true); 11228 11229 format %{ "TW $src_index $cmp $src_length \t// RangeCheck => trap $labl" %} 11230 size(4); 11231 ins_encode %{ 11232 // TODO: PPC port $archOpcode(ppc64Opcode_tw); 11233 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 11234 __ trap_range_check_ge($src_index$$Register, $src_length$$Register); 11235 } else { 11236 // Both successors are uncommon traps, probability is 0. 11237 // Node got flipped during fixup flow. 11238 assert($cmp$$cmpcode == 0x8, "must be less"); 11239 __ trap_range_check_l($src_index$$Register, $src_length$$Register); 11240 } 11241 %} 11242 ins_pipe(pipe_class_trap); 11243%} 11244 11245// Match range check 'If lt (CmpU index length)'. 11246instruct rangeCheck_uimm15_iReg(cmpOp cmp, iRegIsrc src_index, uimmI15 length, label labl) %{ 11247 match(If cmp (CmpU src_index length)); 11248 effect(USE labl); 11249 predicate(TrapBasedRangeChecks && 11250 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 11251 _leaf->as_If()->_prob >= PROB_ALWAYS && 11252 (Matcher::branches_to_uncommon_trap(_leaf))); 11253 11254 ins_is_TrapBasedCheckNode(true); 11255 11256 format %{ "TWI $src_index $cmp $length \t// RangeCheck => trap $labl" %} 11257 size(4); 11258 ins_encode %{ 11259 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 11260 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 11261 __ trap_range_check_ge($src_index$$Register, $length$$constant); 11262 } else { 11263 // Both successors are uncommon traps, probability is 0. 11264 // Node got flipped during fixup flow. 11265 assert($cmp$$cmpcode == 0x8, "must be less"); 11266 __ trap_range_check_l($src_index$$Register, $length$$constant); 11267 } 11268 %} 11269 ins_pipe(pipe_class_trap); 11270%} 11271 11272instruct compU_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 11273 match(Set crx (CmpU src1 src2)); 11274 format %{ "CMPLW $crx, $src1, $src2 \t// unsigned" %} 11275 size(4); 11276 ins_encode %{ 11277 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11278 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11279 %} 11280 ins_pipe(pipe_class_compare); 11281%} 11282 11283instruct compU_reg_uimm16(flagsReg crx, iRegIsrc src1, uimmI16 src2) %{ 11284 match(Set crx (CmpU src1 src2)); 11285 size(4); 11286 format %{ "CMPLWI $crx, $src1, $src2" %} 11287 ins_encode %{ 11288 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 11289 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11290 %} 11291 ins_pipe(pipe_class_compare); 11292%} 11293 11294// Implicit zero checks (more implicit null checks). 11295// No constant pool entries required. 11296instruct zeroCheckN_iReg_imm0(cmpOp cmp, iRegNsrc value, immN_0 zero, label labl) %{ 11297 match(If cmp (CmpN value zero)); 11298 effect(USE labl); 11299 predicate(TrapBasedNullChecks && 11300 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 11301 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 11302 Matcher::branches_to_uncommon_trap(_leaf)); 11303 ins_cost(1); 11304 11305 ins_is_TrapBasedCheckNode(true); 11306 11307 format %{ "TDI $value $cmp $zero \t// ZeroCheckN => trap $labl" %} 11308 size(4); 11309 ins_encode %{ 11310 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 11311 if ($cmp$$cmpcode == 0xA) { 11312 __ trap_null_check($value$$Register); 11313 } else { 11314 // Both successors are uncommon traps, probability is 0. 11315 // Node got flipped during fixup flow. 11316 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 11317 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 11318 } 11319 %} 11320 ins_pipe(pipe_class_trap); 11321%} 11322 11323// Compare narrow oops. 11324instruct cmpN_reg_reg(flagsReg crx, iRegNsrc src1, iRegNsrc src2) %{ 11325 match(Set crx (CmpN src1 src2)); 11326 11327 size(4); 11328 ins_cost(2); 11329 format %{ "CMPLW $crx, $src1, $src2 \t// compressed ptr" %} 11330 ins_encode %{ 11331 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11332 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11333 %} 11334 ins_pipe(pipe_class_compare); 11335%} 11336 11337instruct cmpN_reg_imm0(flagsReg crx, iRegNsrc src1, immN_0 src2) %{ 11338 match(Set crx (CmpN src1 src2)); 11339 // Make this more expensive than zeroCheckN_iReg_imm0. 11340 ins_cost(2); 11341 11342 format %{ "CMPLWI $crx, $src1, $src2 \t// compressed ptr" %} 11343 size(4); 11344 ins_encode %{ 11345 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 11346 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11347 %} 11348 ins_pipe(pipe_class_compare); 11349%} 11350 11351// Implicit zero checks (more implicit null checks). 11352// No constant pool entries required. 11353instruct zeroCheckP_reg_imm0(cmpOp cmp, iRegP_N2P value, immP_0 zero, label labl) %{ 11354 match(If cmp (CmpP value zero)); 11355 effect(USE labl); 11356 predicate(TrapBasedNullChecks && 11357 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 11358 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 11359 Matcher::branches_to_uncommon_trap(_leaf)); 11360 ins_cost(1); // Should not be cheaper than zeroCheckN. 11361 11362 ins_is_TrapBasedCheckNode(true); 11363 11364 format %{ "TDI $value $cmp $zero \t// ZeroCheckP => trap $labl" %} 11365 size(4); 11366 ins_encode %{ 11367 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 11368 if ($cmp$$cmpcode == 0xA) { 11369 __ trap_null_check($value$$Register); 11370 } else { 11371 // Both successors are uncommon traps, probability is 0. 11372 // Node got flipped during fixup flow. 11373 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 11374 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 11375 } 11376 %} 11377 ins_pipe(pipe_class_trap); 11378%} 11379 11380// Compare Pointers 11381instruct cmpP_reg_reg(flagsReg crx, iRegP_N2P src1, iRegP_N2P src2) %{ 11382 match(Set crx (CmpP src1 src2)); 11383 format %{ "CMPLD $crx, $src1, $src2 \t// ptr" %} 11384 size(4); 11385 ins_encode %{ 11386 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11387 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 11388 %} 11389 ins_pipe(pipe_class_compare); 11390%} 11391 11392instruct cmpP_reg_null(flagsReg crx, iRegP_N2P src1, immP_0or1 src2) %{ 11393 match(Set crx (CmpP src1 src2)); 11394 format %{ "CMPLDI $crx, $src1, $src2 \t// ptr" %} 11395 size(4); 11396 ins_encode %{ 11397 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11398 __ cmpldi($crx$$CondRegister, $src1$$Register, (int)((short)($src2$$constant & 0xFFFF))); 11399 %} 11400 ins_pipe(pipe_class_compare); 11401%} 11402 11403// Used in postalloc expand. 11404instruct cmpP_reg_imm16(flagsReg crx, iRegPsrc src1, immL16 src2) %{ 11405 // This match rule prevents reordering of node before a safepoint. 11406 // This only makes sense if this instructions is used exclusively 11407 // for the expansion of EncodeP! 11408 match(Set crx (CmpP src1 src2)); 11409 predicate(false); 11410 11411 format %{ "CMPDI $crx, $src1, $src2" %} 11412 size(4); 11413 ins_encode %{ 11414 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11415 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11416 %} 11417 ins_pipe(pipe_class_compare); 11418%} 11419 11420//----------Float Compares---------------------------------------------------- 11421 11422instruct cmpFUnordered_reg_reg(flagsReg crx, regF src1, regF src2) %{ 11423 // Needs matchrule, see cmpDUnordered. 11424 match(Set crx (CmpF src1 src2)); 11425 // no match-rule, false predicate 11426 predicate(false); 11427 11428 format %{ "cmpFUrd $crx, $src1, $src2" %} 11429 size(4); 11430 ins_encode %{ 11431 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 11432 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 11433 %} 11434 ins_pipe(pipe_class_default); 11435%} 11436 11437instruct cmov_bns_less(flagsReg crx) %{ 11438 // no match-rule, false predicate 11439 effect(DEF crx); 11440 predicate(false); 11441 11442 ins_variable_size_depending_on_alignment(true); 11443 11444 format %{ "cmov $crx" %} 11445 // Worst case is branch + move + stop, no stop without scheduler. 11446 size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 16 : 12); 11447 ins_encode %{ 11448 // TODO: PPC port $archOpcode(ppc64Opcode_cmovecr); 11449 Label done; 11450 __ bns($crx$$CondRegister, done); // not unordered -> keep crx 11451 __ li(R0, 0); 11452 __ cmpwi($crx$$CondRegister, R0, 1); // unordered -> set crx to 'less' 11453 // TODO PPC port __ endgroup_if_needed(_size == 16); 11454 __ bind(done); 11455 %} 11456 ins_pipe(pipe_class_default); 11457%} 11458 11459// Compare floating, generate condition code. 11460instruct cmpF_reg_reg_Ex(flagsReg crx, regF src1, regF src2) %{ 11461 // FIXME: should we match 'If cmp (CmpF src1 src2))' ?? 11462 // 11463 // The following code sequence occurs a lot in mpegaudio: 11464 // 11465 // block BXX: 11466 // 0: instruct cmpFUnordered_reg_reg (cmpF_reg_reg-0): 11467 // cmpFUrd CCR6, F11, F9 11468 // 4: instruct cmov_bns_less (cmpF_reg_reg-1): 11469 // cmov CCR6 11470 // 8: instruct branchConSched: 11471 // B_FARle CCR6, B56 P=0.500000 C=-1.000000 11472 match(Set crx (CmpF src1 src2)); 11473 ins_cost(DEFAULT_COST+BRANCH_COST); 11474 11475 format %{ "CmpF $crx, $src1, $src2 \t// postalloc expanded" %} 11476 postalloc_expand %{ 11477 // 11478 // replaces 11479 // 11480 // region src1 src2 11481 // \ | | 11482 // crx=cmpF_reg_reg 11483 // 11484 // with 11485 // 11486 // region src1 src2 11487 // \ | | 11488 // crx=cmpFUnordered_reg_reg 11489 // | 11490 // ^ region 11491 // | \ 11492 // crx=cmov_bns_less 11493 // 11494 11495 // Create new nodes. 11496 MachNode *m1 = new cmpFUnordered_reg_regNode(); 11497 MachNode *m2 = new cmov_bns_lessNode(); 11498 11499 // inputs for new nodes 11500 m1->add_req(n_region, n_src1, n_src2); 11501 m2->add_req(n_region); 11502 m2->add_prec(m1); 11503 11504 // operands for new nodes 11505 m1->_opnds[0] = op_crx; 11506 m1->_opnds[1] = op_src1; 11507 m1->_opnds[2] = op_src2; 11508 m2->_opnds[0] = op_crx; 11509 11510 // registers for new nodes 11511 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 11512 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 11513 11514 // Insert new nodes. 11515 nodes->push(m1); 11516 nodes->push(m2); 11517 %} 11518%} 11519 11520// Compare float, generate -1,0,1 11521instruct cmpF3_reg_reg_ExEx(iRegIdst dst, regF src1, regF src2) %{ 11522 match(Set dst (CmpF3 src1 src2)); 11523 ins_cost(DEFAULT_COST*5+BRANCH_COST); 11524 11525 expand %{ 11526 flagsReg tmp1; 11527 cmpFUnordered_reg_reg(tmp1, src1, src2); 11528 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 11529 %} 11530%} 11531 11532instruct cmpDUnordered_reg_reg(flagsReg crx, regD src1, regD src2) %{ 11533 // Needs matchrule so that ideal opcode is Cmp. This causes that gcm places the 11534 // node right before the conditional move using it. 11535 // In jck test api/java_awt/geom/QuadCurve2DFloat/index.html#SetCurveTesttestCase7, 11536 // compilation of java.awt.geom.RectangularShape::getBounds()Ljava/awt/Rectangle 11537 // crashed in register allocation where the flags Reg between cmpDUnoredered and a 11538 // conditional move was supposed to be spilled. 11539 match(Set crx (CmpD src1 src2)); 11540 // False predicate, shall not be matched. 11541 predicate(false); 11542 11543 format %{ "cmpFUrd $crx, $src1, $src2" %} 11544 size(4); 11545 ins_encode %{ 11546 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 11547 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 11548 %} 11549 ins_pipe(pipe_class_default); 11550%} 11551 11552instruct cmpD_reg_reg_Ex(flagsReg crx, regD src1, regD src2) %{ 11553 match(Set crx (CmpD src1 src2)); 11554 ins_cost(DEFAULT_COST+BRANCH_COST); 11555 11556 format %{ "CmpD $crx, $src1, $src2 \t// postalloc expanded" %} 11557 postalloc_expand %{ 11558 // 11559 // replaces 11560 // 11561 // region src1 src2 11562 // \ | | 11563 // crx=cmpD_reg_reg 11564 // 11565 // with 11566 // 11567 // region src1 src2 11568 // \ | | 11569 // crx=cmpDUnordered_reg_reg 11570 // | 11571 // ^ region 11572 // | \ 11573 // crx=cmov_bns_less 11574 // 11575 11576 // create new nodes 11577 MachNode *m1 = new cmpDUnordered_reg_regNode(); 11578 MachNode *m2 = new cmov_bns_lessNode(); 11579 11580 // inputs for new nodes 11581 m1->add_req(n_region, n_src1, n_src2); 11582 m2->add_req(n_region); 11583 m2->add_prec(m1); 11584 11585 // operands for new nodes 11586 m1->_opnds[0] = op_crx; 11587 m1->_opnds[1] = op_src1; 11588 m1->_opnds[2] = op_src2; 11589 m2->_opnds[0] = op_crx; 11590 11591 // registers for new nodes 11592 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 11593 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 11594 11595 // Insert new nodes. 11596 nodes->push(m1); 11597 nodes->push(m2); 11598 %} 11599%} 11600 11601// Compare double, generate -1,0,1 11602instruct cmpD3_reg_reg_ExEx(iRegIdst dst, regD src1, regD src2) %{ 11603 match(Set dst (CmpD3 src1 src2)); 11604 ins_cost(DEFAULT_COST*5+BRANCH_COST); 11605 11606 expand %{ 11607 flagsReg tmp1; 11608 cmpDUnordered_reg_reg(tmp1, src1, src2); 11609 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 11610 %} 11611%} 11612 11613//----------Branches--------------------------------------------------------- 11614// Jump 11615 11616// Direct Branch. 11617instruct branch(label labl) %{ 11618 match(Goto); 11619 effect(USE labl); 11620 ins_cost(BRANCH_COST); 11621 11622 format %{ "B $labl" %} 11623 size(4); 11624 ins_encode %{ 11625 // TODO: PPC port $archOpcode(ppc64Opcode_b); 11626 Label d; // dummy 11627 __ bind(d); 11628 Label* p = $labl$$label; 11629 // `p' is `NULL' when this encoding class is used only to 11630 // determine the size of the encoded instruction. 11631 Label& l = (NULL == p)? d : *(p); 11632 __ b(l); 11633 %} 11634 ins_pipe(pipe_class_default); 11635%} 11636 11637// Conditional Near Branch 11638instruct branchCon(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 11639 // Same match rule as `branchConFar'. 11640 match(If cmp crx); 11641 effect(USE lbl); 11642 ins_cost(BRANCH_COST); 11643 11644 // If set to 1 this indicates that the current instruction is a 11645 // short variant of a long branch. This avoids using this 11646 // instruction in first-pass matching. It will then only be used in 11647 // the `Shorten_branches' pass. 11648 ins_short_branch(1); 11649 11650 format %{ "B$cmp $crx, $lbl" %} 11651 size(4); 11652 ins_encode( enc_bc(crx, cmp, lbl) ); 11653 ins_pipe(pipe_class_default); 11654%} 11655 11656// This is for cases when the ppc64 `bc' instruction does not 11657// reach far enough. So we emit a far branch here, which is more 11658// expensive. 11659// 11660// Conditional Far Branch 11661instruct branchConFar(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 11662 // Same match rule as `branchCon'. 11663 match(If cmp crx); 11664 effect(USE crx, USE lbl); 11665 predicate(!false /* TODO: PPC port HB_Schedule*/); 11666 // Higher cost than `branchCon'. 11667 ins_cost(5*BRANCH_COST); 11668 11669 // This is not a short variant of a branch, but the long variant. 11670 ins_short_branch(0); 11671 11672 format %{ "B_FAR$cmp $crx, $lbl" %} 11673 size(8); 11674 ins_encode( enc_bc_far(crx, cmp, lbl) ); 11675 ins_pipe(pipe_class_default); 11676%} 11677 11678// Conditional Branch used with Power6 scheduler (can be far or short). 11679instruct branchConSched(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 11680 // Same match rule as `branchCon'. 11681 match(If cmp crx); 11682 effect(USE crx, USE lbl); 11683 predicate(false /* TODO: PPC port HB_Schedule*/); 11684 // Higher cost than `branchCon'. 11685 ins_cost(5*BRANCH_COST); 11686 11687 // Actually size doesn't depend on alignment but on shortening. 11688 ins_variable_size_depending_on_alignment(true); 11689 // long variant. 11690 ins_short_branch(0); 11691 11692 format %{ "B_FAR$cmp $crx, $lbl" %} 11693 size(8); // worst case 11694 ins_encode( enc_bc_short_far(crx, cmp, lbl) ); 11695 ins_pipe(pipe_class_default); 11696%} 11697 11698instruct branchLoopEnd(cmpOp cmp, flagsRegSrc crx, label labl) %{ 11699 match(CountedLoopEnd cmp crx); 11700 effect(USE labl); 11701 ins_cost(BRANCH_COST); 11702 11703 // short variant. 11704 ins_short_branch(1); 11705 11706 format %{ "B$cmp $crx, $labl \t// counted loop end" %} 11707 size(4); 11708 ins_encode( enc_bc(crx, cmp, labl) ); 11709 ins_pipe(pipe_class_default); 11710%} 11711 11712instruct branchLoopEndFar(cmpOp cmp, flagsRegSrc crx, label labl) %{ 11713 match(CountedLoopEnd cmp crx); 11714 effect(USE labl); 11715 predicate(!false /* TODO: PPC port HB_Schedule */); 11716 ins_cost(BRANCH_COST); 11717 11718 // Long variant. 11719 ins_short_branch(0); 11720 11721 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 11722 size(8); 11723 ins_encode( enc_bc_far(crx, cmp, labl) ); 11724 ins_pipe(pipe_class_default); 11725%} 11726 11727// Conditional Branch used with Power6 scheduler (can be far or short). 11728instruct branchLoopEndSched(cmpOp cmp, flagsRegSrc crx, label labl) %{ 11729 match(CountedLoopEnd cmp crx); 11730 effect(USE labl); 11731 predicate(false /* TODO: PPC port HB_Schedule */); 11732 // Higher cost than `branchCon'. 11733 ins_cost(5*BRANCH_COST); 11734 11735 // Actually size doesn't depend on alignment but on shortening. 11736 ins_variable_size_depending_on_alignment(true); 11737 // Long variant. 11738 ins_short_branch(0); 11739 11740 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 11741 size(8); // worst case 11742 ins_encode( enc_bc_short_far(crx, cmp, labl) ); 11743 ins_pipe(pipe_class_default); 11744%} 11745 11746// ============================================================================ 11747// Java runtime operations, intrinsics and other complex operations. 11748 11749// The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass 11750// array for an instance of the superklass. Set a hidden internal cache on a 11751// hit (cache is checked with exposed code in gen_subtype_check()). Return 11752// not zero for a miss or zero for a hit. The encoding ALSO sets flags. 11753// 11754// GL TODO: Improve this. 11755// - result should not be a TEMP 11756// - Add match rule as on sparc avoiding additional Cmp. 11757instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass, 11758 iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{ 11759 match(Set result (PartialSubtypeCheck subklass superklass)); 11760 effect(TEMP_DEF result, TEMP tmp_klass, TEMP tmp_arrayptr); 11761 ins_cost(DEFAULT_COST*10); 11762 11763 format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %} 11764 ins_encode %{ 11765 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11766 __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register, 11767 $tmp_klass$$Register, NULL, $result$$Register); 11768 %} 11769 ins_pipe(pipe_class_default); 11770%} 11771 11772// inlined locking and unlocking 11773 11774instruct cmpFastLock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2) %{ 11775 match(Set crx (FastLock oop box)); 11776 effect(TEMP tmp1, TEMP tmp2); 11777 predicate(!Compile::current()->use_rtm()); 11778 11779 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2" %} 11780 ins_encode %{ 11781 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11782 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 11783 $tmp1$$Register, $tmp2$$Register, /*tmp3*/ R0, 11784 UseBiasedLocking && !UseOptoBiasInlining); 11785 // If locking was successfull, crx should indicate 'EQ'. 11786 // The compiler generates a branch to the runtime call to 11787 // _complete_monitor_locking_Java for the case where crx is 'NE'. 11788 %} 11789 ins_pipe(pipe_class_compare); 11790%} 11791 11792// Separate version for TM. Use bound register for box to enable USE_KILL. 11793instruct cmpFastLock_tm(flagsReg crx, iRegPdst oop, rarg2RegP box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 11794 match(Set crx (FastLock oop box)); 11795 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL box); 11796 predicate(Compile::current()->use_rtm()); 11797 11798 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2, $tmp3 (TM)" %} 11799 ins_encode %{ 11800 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11801 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 11802 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 11803 /*Biased Locking*/ false, 11804 _rtm_counters, _stack_rtm_counters, 11805 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 11806 /*TM*/ true, ra_->C->profile_rtm()); 11807 // If locking was successfull, crx should indicate 'EQ'. 11808 // The compiler generates a branch to the runtime call to 11809 // _complete_monitor_locking_Java for the case where crx is 'NE'. 11810 %} 11811 ins_pipe(pipe_class_compare); 11812%} 11813 11814instruct cmpFastUnlock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 11815 match(Set crx (FastUnlock oop box)); 11816 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 11817 predicate(!Compile::current()->use_rtm()); 11818 11819 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2" %} 11820 ins_encode %{ 11821 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11822 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 11823 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 11824 UseBiasedLocking && !UseOptoBiasInlining, 11825 false); 11826 // If unlocking was successfull, crx should indicate 'EQ'. 11827 // The compiler generates a branch to the runtime call to 11828 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 11829 %} 11830 ins_pipe(pipe_class_compare); 11831%} 11832 11833instruct cmpFastUnlock_tm(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 11834 match(Set crx (FastUnlock oop box)); 11835 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 11836 predicate(Compile::current()->use_rtm()); 11837 11838 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2 (TM)" %} 11839 ins_encode %{ 11840 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11841 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 11842 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 11843 /*Biased Locking*/ false, /*TM*/ true); 11844 // If unlocking was successfull, crx should indicate 'EQ'. 11845 // The compiler generates a branch to the runtime call to 11846 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 11847 %} 11848 ins_pipe(pipe_class_compare); 11849%} 11850 11851// Align address. 11852instruct align_addr(iRegPdst dst, iRegPsrc src, immLnegpow2 mask) %{ 11853 match(Set dst (CastX2P (AndL (CastP2X src) mask))); 11854 11855 format %{ "ANDDI $dst, $src, $mask \t// next aligned address" %} 11856 size(4); 11857 ins_encode %{ 11858 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 11859 __ clrrdi($dst$$Register, $src$$Register, log2_long((jlong)-$mask$$constant)); 11860 %} 11861 ins_pipe(pipe_class_default); 11862%} 11863 11864// Array size computation. 11865instruct array_size(iRegLdst dst, iRegPsrc end, iRegPsrc start) %{ 11866 match(Set dst (SubL (CastP2X end) (CastP2X start))); 11867 11868 format %{ "SUB $dst, $end, $start \t// array size in bytes" %} 11869 size(4); 11870 ins_encode %{ 11871 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 11872 __ subf($dst$$Register, $start$$Register, $end$$Register); 11873 %} 11874 ins_pipe(pipe_class_default); 11875%} 11876 11877// Clear-array with constant short array length. The versions below can use dcbz with cnt > 30. 11878instruct inlineCallClearArrayShort(immLmax30 cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 11879 match(Set dummy (ClearArray cnt base)); 11880 effect(USE_KILL base, KILL ctr); 11881 ins_cost(2 * MEMORY_REF_COST); 11882 11883 format %{ "ClearArray $cnt, $base" %} 11884 ins_encode %{ 11885 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11886 __ clear_memory_constlen($base$$Register, $cnt$$constant, R0); // kills base, R0 11887 %} 11888 ins_pipe(pipe_class_default); 11889%} 11890 11891// Clear-array with constant large array length. 11892instruct inlineCallClearArrayLarge(immL cnt, rarg2RegP base, Universe dummy, iRegLdst tmp, regCTR ctr) %{ 11893 match(Set dummy (ClearArray cnt base)); 11894 effect(USE_KILL base, TEMP tmp, KILL ctr); 11895 ins_cost(3 * MEMORY_REF_COST); 11896 11897 format %{ "ClearArray $cnt, $base \t// KILL $tmp" %} 11898 ins_encode %{ 11899 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11900 __ clear_memory_doubleword($base$$Register, $tmp$$Register, R0, $cnt$$constant); // kills base, R0 11901 %} 11902 ins_pipe(pipe_class_default); 11903%} 11904 11905// Clear-array with dynamic array length. 11906instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 11907 match(Set dummy (ClearArray cnt base)); 11908 effect(USE_KILL cnt, USE_KILL base, KILL ctr); 11909 ins_cost(4 * MEMORY_REF_COST); 11910 11911 format %{ "ClearArray $cnt, $base" %} 11912 ins_encode %{ 11913 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11914 __ clear_memory_doubleword($base$$Register, $cnt$$Register, R0); // kills cnt, base, R0 11915 %} 11916 ins_pipe(pipe_class_default); 11917%} 11918 11919instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 11920 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 11921 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 11922 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11923 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 11924 ins_cost(300); 11925 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 11926 ins_encode %{ 11927 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11928 __ string_compare($str1$$Register, $str2$$Register, 11929 $cnt1$$Register, $cnt2$$Register, 11930 $tmp$$Register, 11931 $result$$Register, StrIntrinsicNode::LL); 11932 %} 11933 ins_pipe(pipe_class_default); 11934%} 11935 11936instruct string_compareU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 11937 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 11938 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 11939 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11940 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 11941 ins_cost(300); 11942 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 11943 ins_encode %{ 11944 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11945 __ string_compare($str1$$Register, $str2$$Register, 11946 $cnt1$$Register, $cnt2$$Register, 11947 $tmp$$Register, 11948 $result$$Register, StrIntrinsicNode::UU); 11949 %} 11950 ins_pipe(pipe_class_default); 11951%} 11952 11953instruct string_compareLU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 11954 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 11955 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 11956 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11957 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 11958 ins_cost(300); 11959 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 11960 ins_encode %{ 11961 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11962 __ string_compare($str1$$Register, $str2$$Register, 11963 $cnt1$$Register, $cnt2$$Register, 11964 $tmp$$Register, 11965 $result$$Register, StrIntrinsicNode::LU); 11966 %} 11967 ins_pipe(pipe_class_default); 11968%} 11969 11970instruct string_compareUL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 11971 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 11972 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 11973 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11974 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 11975 ins_cost(300); 11976 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 11977 ins_encode %{ 11978 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11979 __ string_compare($str2$$Register, $str1$$Register, 11980 $cnt2$$Register, $cnt1$$Register, 11981 $tmp$$Register, 11982 $result$$Register, StrIntrinsicNode::UL); 11983 %} 11984 ins_pipe(pipe_class_default); 11985%} 11986 11987instruct string_equalsL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 11988 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 11989 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 11990 match(Set result (StrEquals (Binary str1 str2) cnt)); 11991 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 11992 ins_cost(300); 11993 format %{ "String Equals byte[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 11994 ins_encode %{ 11995 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11996 __ array_equals(false, $str1$$Register, $str2$$Register, 11997 $cnt$$Register, $tmp$$Register, 11998 $result$$Register, true /* byte */); 11999 %} 12000 ins_pipe(pipe_class_default); 12001%} 12002 12003instruct string_equalsU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 12004 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12005 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 12006 match(Set result (StrEquals (Binary str1 str2) cnt)); 12007 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 12008 ins_cost(300); 12009 format %{ "String Equals char[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 12010 ins_encode %{ 12011 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12012 __ array_equals(false, $str1$$Register, $str2$$Register, 12013 $cnt$$Register, $tmp$$Register, 12014 $result$$Register, false /* byte */); 12015 %} 12016 ins_pipe(pipe_class_default); 12017%} 12018 12019instruct array_equalsB(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 12020 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 12021 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 12022 match(Set result (AryEq ary1 ary2)); 12023 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 12024 ins_cost(300); 12025 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 12026 ins_encode %{ 12027 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12028 __ array_equals(true, $ary1$$Register, $ary2$$Register, 12029 $tmp1$$Register, $tmp2$$Register, 12030 $result$$Register, true /* byte */); 12031 %} 12032 ins_pipe(pipe_class_default); 12033%} 12034 12035instruct array_equalsC(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 12036 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 12037 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 12038 match(Set result (AryEq ary1 ary2)); 12039 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 12040 ins_cost(300); 12041 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 12042 ins_encode %{ 12043 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12044 __ array_equals(true, $ary1$$Register, $ary2$$Register, 12045 $tmp1$$Register, $tmp2$$Register, 12046 $result$$Register, false /* byte */); 12047 %} 12048 ins_pipe(pipe_class_default); 12049%} 12050 12051instruct indexOf_imm1_char_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12052 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12053 iRegIdst tmp1, iRegIdst tmp2, 12054 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12055 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12056 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12057 // Required for EA: check if it is still a type_array. 12058 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 12059 ins_cost(150); 12060 12061 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12062 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12063 12064 ins_encode %{ 12065 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12066 immPOper *needleOper = (immPOper *)$needleImm; 12067 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12068 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12069 jchar chr; 12070#ifdef VM_LITTLE_ENDIAN 12071 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 12072 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 12073#else 12074 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 12075 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 12076#endif 12077 __ string_indexof_char($result$$Register, 12078 $haystack$$Register, $haycnt$$Register, 12079 R0, chr, 12080 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12081 %} 12082 ins_pipe(pipe_class_compare); 12083%} 12084 12085instruct indexOf_imm1_char_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12086 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12087 iRegIdst tmp1, iRegIdst tmp2, 12088 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12089 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12090 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12091 // Required for EA: check if it is still a type_array. 12092 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 12093 ins_cost(150); 12094 12095 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12096 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12097 12098 ins_encode %{ 12099 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12100 immPOper *needleOper = (immPOper *)$needleImm; 12101 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12102 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12103 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12104 __ string_indexof_char($result$$Register, 12105 $haystack$$Register, $haycnt$$Register, 12106 R0, chr, 12107 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 12108 %} 12109 ins_pipe(pipe_class_compare); 12110%} 12111 12112instruct indexOf_imm1_char_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12113 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12114 iRegIdst tmp1, iRegIdst tmp2, 12115 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12116 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12117 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12118 // Required for EA: check if it is still a type_array. 12119 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 12120 ins_cost(150); 12121 12122 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12123 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12124 12125 ins_encode %{ 12126 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12127 immPOper *needleOper = (immPOper *)$needleImm; 12128 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12129 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12130 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12131 __ string_indexof_char($result$$Register, 12132 $haystack$$Register, $haycnt$$Register, 12133 R0, chr, 12134 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12135 %} 12136 ins_pipe(pipe_class_compare); 12137%} 12138 12139instruct indexOf_imm1_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12140 rscratch2RegP needle, immI_1 needlecntImm, 12141 iRegIdst tmp1, iRegIdst tmp2, 12142 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12143 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12144 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12145 // Required for EA: check if it is still a type_array. 12146 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 12147 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12148 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12149 ins_cost(180); 12150 12151 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12152 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12153 ins_encode %{ 12154 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12155 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12156 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12157 guarantee(needle_values, "sanity"); 12158 jchar chr; 12159#ifdef VM_LITTLE_ENDIAN 12160 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 12161 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 12162#else 12163 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 12164 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 12165#endif 12166 __ string_indexof_char($result$$Register, 12167 $haystack$$Register, $haycnt$$Register, 12168 R0, chr, 12169 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12170 %} 12171 ins_pipe(pipe_class_compare); 12172%} 12173 12174instruct indexOf_imm1_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12175 rscratch2RegP needle, immI_1 needlecntImm, 12176 iRegIdst tmp1, iRegIdst tmp2, 12177 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12178 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12179 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12180 // Required for EA: check if it is still a type_array. 12181 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 12182 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12183 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12184 ins_cost(180); 12185 12186 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12187 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12188 ins_encode %{ 12189 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12190 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12191 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12192 guarantee(needle_values, "sanity"); 12193 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12194 __ string_indexof_char($result$$Register, 12195 $haystack$$Register, $haycnt$$Register, 12196 R0, chr, 12197 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 12198 %} 12199 ins_pipe(pipe_class_compare); 12200%} 12201 12202instruct indexOf_imm1_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12203 rscratch2RegP needle, immI_1 needlecntImm, 12204 iRegIdst tmp1, iRegIdst tmp2, 12205 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12206 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12207 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12208 // Required for EA: check if it is still a type_array. 12209 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 12210 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12211 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12212 ins_cost(180); 12213 12214 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12215 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12216 ins_encode %{ 12217 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12218 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12219 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12220 guarantee(needle_values, "sanity"); 12221 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12222 __ string_indexof_char($result$$Register, 12223 $haystack$$Register, $haycnt$$Register, 12224 R0, chr, 12225 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12226 %} 12227 ins_pipe(pipe_class_compare); 12228%} 12229 12230instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12231 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2, 12232 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12233 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch)); 12234 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12235 ins_cost(180); 12236 12237 format %{ "String IndexOfChar $haystack[0..$haycnt], $ch" 12238 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12239 ins_encode %{ 12240 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12241 __ string_indexof_char($result$$Register, 12242 $haystack$$Register, $haycnt$$Register, 12243 $ch$$Register, 0 /* this is not used if the character is already in a register */, 12244 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12245 %} 12246 ins_pipe(pipe_class_compare); 12247%} 12248 12249instruct indexOf_imm_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 12250 iRegPsrc needle, uimmI15 needlecntImm, 12251 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 12252 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12253 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12254 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 12255 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12256 // Required for EA: check if it is still a type_array. 12257 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 12258 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12259 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12260 ins_cost(250); 12261 12262 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12263 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 12264 ins_encode %{ 12265 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12266 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12267 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12268 12269 __ string_indexof($result$$Register, 12270 $haystack$$Register, $haycnt$$Register, 12271 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 12272 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 12273 %} 12274 ins_pipe(pipe_class_compare); 12275%} 12276 12277instruct indexOf_imm_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 12278 iRegPsrc needle, uimmI15 needlecntImm, 12279 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 12280 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12281 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12282 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 12283 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12284 // Required for EA: check if it is still a type_array. 12285 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 12286 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12287 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12288 ins_cost(250); 12289 12290 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12291 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 12292 ins_encode %{ 12293 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12294 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12295 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12296 12297 __ string_indexof($result$$Register, 12298 $haystack$$Register, $haycnt$$Register, 12299 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 12300 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 12301 %} 12302 ins_pipe(pipe_class_compare); 12303%} 12304 12305instruct indexOf_imm_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 12306 iRegPsrc needle, uimmI15 needlecntImm, 12307 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 12308 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12309 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12310 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 12311 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12312 // Required for EA: check if it is still a type_array. 12313 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 12314 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12315 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12316 ins_cost(250); 12317 12318 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12319 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 12320 ins_encode %{ 12321 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12322 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12323 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12324 12325 __ string_indexof($result$$Register, 12326 $haystack$$Register, $haycnt$$Register, 12327 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 12328 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 12329 %} 12330 ins_pipe(pipe_class_compare); 12331%} 12332 12333instruct indexOf_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 12334 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 12335 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12336 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 12337 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 12338 TEMP_DEF result, 12339 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12340 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 12341 ins_cost(300); 12342 12343 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 12344 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 12345 ins_encode %{ 12346 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12347 __ string_indexof($result$$Register, 12348 $haystack$$Register, $haycnt$$Register, 12349 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 12350 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 12351 %} 12352 ins_pipe(pipe_class_compare); 12353%} 12354 12355instruct indexOf_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 12356 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 12357 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12358 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 12359 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 12360 TEMP_DEF result, 12361 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12362 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 12363 ins_cost(300); 12364 12365 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 12366 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 12367 ins_encode %{ 12368 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12369 __ string_indexof($result$$Register, 12370 $haystack$$Register, $haycnt$$Register, 12371 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 12372 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 12373 %} 12374 ins_pipe(pipe_class_compare); 12375%} 12376 12377instruct indexOf_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 12378 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 12379 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12380 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 12381 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 12382 TEMP_DEF result, 12383 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12384 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 12385 ins_cost(300); 12386 12387 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 12388 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 12389 ins_encode %{ 12390 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12391 __ string_indexof($result$$Register, 12392 $haystack$$Register, $haycnt$$Register, 12393 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 12394 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 12395 %} 12396 ins_pipe(pipe_class_compare); 12397%} 12398 12399// char[] to byte[] compression 12400instruct string_compress(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 12401 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 12402 match(Set result (StrCompressedCopy src (Binary dst len))); 12403 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 12404 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 12405 ins_cost(300); 12406 format %{ "String Compress $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 12407 ins_encode %{ 12408 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12409 Label Lskip, Ldone; 12410 __ li($result$$Register, 0); 12411 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 12412 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Ldone); 12413 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 12414 __ beq(CCR0, Lskip); 12415 __ string_compress($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register, Ldone); 12416 __ bind(Lskip); 12417 __ mr($result$$Register, $len$$Register); 12418 __ bind(Ldone); 12419 %} 12420 ins_pipe(pipe_class_default); 12421%} 12422 12423// byte[] to char[] inflation 12424instruct string_inflate(Universe dummy, rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegLdst tmp1, 12425 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 12426 match(Set dummy (StrInflatedCopy src (Binary dst len))); 12427 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 12428 ins_cost(300); 12429 format %{ "String Inflate $src,$dst,$len \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 12430 ins_encode %{ 12431 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12432 Label Ldone; 12433 __ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 12434 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register); 12435 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 12436 __ beq(CCR0, Ldone); 12437 __ string_inflate($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register); 12438 __ bind(Ldone); 12439 %} 12440 ins_pipe(pipe_class_default); 12441%} 12442 12443// StringCoding.java intrinsics 12444instruct has_negatives(rarg1RegP ary1, iRegIsrc len, iRegIdst result, iRegLdst tmp1, iRegLdst tmp2, 12445 regCTR ctr, flagsRegCR0 cr0) 12446%{ 12447 match(Set result (HasNegatives ary1 len)); 12448 effect(TEMP_DEF result, USE_KILL ary1, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0); 12449 ins_cost(300); 12450 format %{ "has negatives byte[] $ary1,$len -> $result \t// KILL $tmp1, $tmp2" %} 12451 ins_encode %{ 12452 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12453 __ has_negatives($ary1$$Register, $len$$Register, $result$$Register, 12454 $tmp1$$Register, $tmp2$$Register); 12455 %} 12456 ins_pipe(pipe_class_default); 12457%} 12458 12459// encode char[] to byte[] in ISO_8859_1 12460instruct encode_iso_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 12461 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 12462 match(Set result (EncodeISOArray src (Binary dst len))); 12463 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 12464 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 12465 ins_cost(300); 12466 format %{ "Encode array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 12467 ins_encode %{ 12468 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12469 Label Lslow, Lfailure1, Lfailure2, Ldone; 12470 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 12471 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Lfailure1); 12472 __ rldicl_($result$$Register, $len$$Register, 0, 64-3); // Remaining characters. 12473 __ beq(CCR0, Ldone); 12474 __ bind(Lslow); 12475 __ string_compress($src$$Register, $dst$$Register, $result$$Register, $tmp2$$Register, Lfailure2); 12476 __ li($result$$Register, 0); 12477 __ b(Ldone); 12478 12479 __ bind(Lfailure1); 12480 __ mr($result$$Register, $len$$Register); 12481 __ mfctr($tmp1$$Register); 12482 __ rldimi_($result$$Register, $tmp1$$Register, 3, 0); // Remaining characters. 12483 __ beq(CCR0, Ldone); 12484 __ b(Lslow); 12485 12486 __ bind(Lfailure2); 12487 __ mfctr($result$$Register); // Remaining characters. 12488 12489 __ bind(Ldone); 12490 __ subf($result$$Register, $result$$Register, $len$$Register); 12491 %} 12492 ins_pipe(pipe_class_default); 12493%} 12494 12495 12496//---------- Min/Max Instructions --------------------------------------------- 12497 12498instruct minI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 12499 match(Set dst (MinI src1 src2)); 12500 ins_cost(DEFAULT_COST*6); 12501 12502 expand %{ 12503 iRegLdst src1s; 12504 iRegLdst src2s; 12505 iRegLdst diff; 12506 iRegLdst sm; 12507 iRegLdst doz; // difference or zero 12508 convI2L_reg(src1s, src1); // Ensure proper sign extension. 12509 convI2L_reg(src2s, src2); // Ensure proper sign extension. 12510 subL_reg_reg(diff, src2s, src1s); 12511 // Need to consider >=33 bit result, therefore we need signmaskL. 12512 signmask64L_regL(sm, diff); 12513 andL_reg_reg(doz, diff, sm); // <=0 12514 addI_regL_regL(dst, doz, src1s); 12515 %} 12516%} 12517 12518instruct minI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 12519 match(Set dst (MinI src1 src2)); 12520 effect(KILL cr0); 12521 predicate(VM_Version::has_isel()); 12522 ins_cost(DEFAULT_COST*2); 12523 12524 ins_encode %{ 12525 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12526 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 12527 __ isel($dst$$Register, CCR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register); 12528 %} 12529 ins_pipe(pipe_class_default); 12530%} 12531 12532instruct maxI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 12533 match(Set dst (MaxI src1 src2)); 12534 ins_cost(DEFAULT_COST*6); 12535 12536 expand %{ 12537 iRegLdst src1s; 12538 iRegLdst src2s; 12539 iRegLdst diff; 12540 iRegLdst sm; 12541 iRegLdst doz; // difference or zero 12542 convI2L_reg(src1s, src1); // Ensure proper sign extension. 12543 convI2L_reg(src2s, src2); // Ensure proper sign extension. 12544 subL_reg_reg(diff, src2s, src1s); 12545 // Need to consider >=33 bit result, therefore we need signmaskL. 12546 signmask64L_regL(sm, diff); 12547 andcL_reg_reg(doz, diff, sm); // >=0 12548 addI_regL_regL(dst, doz, src1s); 12549 %} 12550%} 12551 12552instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 12553 match(Set dst (MaxI src1 src2)); 12554 effect(KILL cr0); 12555 predicate(VM_Version::has_isel()); 12556 ins_cost(DEFAULT_COST*2); 12557 12558 ins_encode %{ 12559 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12560 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 12561 __ isel($dst$$Register, CCR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register); 12562 %} 12563 ins_pipe(pipe_class_default); 12564%} 12565 12566//---------- Population Count Instructions ------------------------------------ 12567 12568// Popcnt for Power7. 12569instruct popCountI(iRegIdst dst, iRegIsrc src) %{ 12570 match(Set dst (PopCountI src)); 12571 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 12572 ins_cost(DEFAULT_COST); 12573 12574 format %{ "POPCNTW $dst, $src" %} 12575 size(4); 12576 ins_encode %{ 12577 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 12578 __ popcntw($dst$$Register, $src$$Register); 12579 %} 12580 ins_pipe(pipe_class_default); 12581%} 12582 12583// Popcnt for Power7. 12584instruct popCountL(iRegIdst dst, iRegLsrc src) %{ 12585 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 12586 match(Set dst (PopCountL src)); 12587 ins_cost(DEFAULT_COST); 12588 12589 format %{ "POPCNTD $dst, $src" %} 12590 size(4); 12591 ins_encode %{ 12592 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 12593 __ popcntd($dst$$Register, $src$$Register); 12594 %} 12595 ins_pipe(pipe_class_default); 12596%} 12597 12598instruct countLeadingZerosI(iRegIdst dst, iRegIsrc src) %{ 12599 match(Set dst (CountLeadingZerosI src)); 12600 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 12601 ins_cost(DEFAULT_COST); 12602 12603 format %{ "CNTLZW $dst, $src" %} 12604 size(4); 12605 ins_encode %{ 12606 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzw); 12607 __ cntlzw($dst$$Register, $src$$Register); 12608 %} 12609 ins_pipe(pipe_class_default); 12610%} 12611 12612instruct countLeadingZerosL(iRegIdst dst, iRegLsrc src) %{ 12613 match(Set dst (CountLeadingZerosL src)); 12614 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 12615 ins_cost(DEFAULT_COST); 12616 12617 format %{ "CNTLZD $dst, $src" %} 12618 size(4); 12619 ins_encode %{ 12620 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 12621 __ cntlzd($dst$$Register, $src$$Register); 12622 %} 12623 ins_pipe(pipe_class_default); 12624%} 12625 12626instruct countLeadingZerosP(iRegIdst dst, iRegPsrc src) %{ 12627 // no match-rule, false predicate 12628 effect(DEF dst, USE src); 12629 predicate(false); 12630 12631 format %{ "CNTLZD $dst, $src" %} 12632 size(4); 12633 ins_encode %{ 12634 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 12635 __ cntlzd($dst$$Register, $src$$Register); 12636 %} 12637 ins_pipe(pipe_class_default); 12638%} 12639 12640instruct countTrailingZerosI_Ex(iRegIdst dst, iRegIsrc src) %{ 12641 match(Set dst (CountTrailingZerosI src)); 12642 predicate(UseCountLeadingZerosInstructionsPPC64); 12643 ins_cost(DEFAULT_COST); 12644 12645 expand %{ 12646 immI16 imm1 %{ (int)-1 %} 12647 immI16 imm2 %{ (int)32 %} 12648 immI_minus1 m1 %{ -1 %} 12649 iRegIdst tmpI1; 12650 iRegIdst tmpI2; 12651 iRegIdst tmpI3; 12652 addI_reg_imm16(tmpI1, src, imm1); 12653 andcI_reg_reg(tmpI2, src, m1, tmpI1); 12654 countLeadingZerosI(tmpI3, tmpI2); 12655 subI_imm16_reg(dst, imm2, tmpI3); 12656 %} 12657%} 12658 12659instruct countTrailingZerosL_Ex(iRegIdst dst, iRegLsrc src) %{ 12660 match(Set dst (CountTrailingZerosL src)); 12661 predicate(UseCountLeadingZerosInstructionsPPC64); 12662 ins_cost(DEFAULT_COST); 12663 12664 expand %{ 12665 immL16 imm1 %{ (long)-1 %} 12666 immI16 imm2 %{ (int)64 %} 12667 iRegLdst tmpL1; 12668 iRegLdst tmpL2; 12669 iRegIdst tmpL3; 12670 addL_reg_imm16(tmpL1, src, imm1); 12671 andcL_reg_reg(tmpL2, tmpL1, src); 12672 countLeadingZerosL(tmpL3, tmpL2); 12673 subI_imm16_reg(dst, imm2, tmpL3); 12674 %} 12675%} 12676 12677// Expand nodes for byte_reverse_int. 12678instruct insrwi_a(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 12679 effect(DEF dst, USE src, USE pos, USE shift); 12680 predicate(false); 12681 12682 format %{ "INSRWI $dst, $src, $pos, $shift" %} 12683 size(4); 12684 ins_encode %{ 12685 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 12686 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 12687 %} 12688 ins_pipe(pipe_class_default); 12689%} 12690 12691// As insrwi_a, but with USE_DEF. 12692instruct insrwi(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 12693 effect(USE_DEF dst, USE src, USE pos, USE shift); 12694 predicate(false); 12695 12696 format %{ "INSRWI $dst, $src, $pos, $shift" %} 12697 size(4); 12698 ins_encode %{ 12699 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 12700 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 12701 %} 12702 ins_pipe(pipe_class_default); 12703%} 12704 12705// Just slightly faster than java implementation. 12706instruct bytes_reverse_int_Ex(iRegIdst dst, iRegIsrc src) %{ 12707 match(Set dst (ReverseBytesI src)); 12708 predicate(UseCountLeadingZerosInstructionsPPC64); 12709 ins_cost(DEFAULT_COST); 12710 12711 expand %{ 12712 immI16 imm24 %{ (int) 24 %} 12713 immI16 imm16 %{ (int) 16 %} 12714 immI16 imm8 %{ (int) 8 %} 12715 immI16 imm4 %{ (int) 4 %} 12716 immI16 imm0 %{ (int) 0 %} 12717 iRegLdst tmpI1; 12718 iRegLdst tmpI2; 12719 iRegLdst tmpI3; 12720 12721 urShiftI_reg_imm(tmpI1, src, imm24); 12722 insrwi_a(dst, tmpI1, imm24, imm8); 12723 urShiftI_reg_imm(tmpI2, src, imm16); 12724 insrwi(dst, tmpI2, imm8, imm16); 12725 urShiftI_reg_imm(tmpI3, src, imm8); 12726 insrwi(dst, tmpI3, imm8, imm8); 12727 insrwi(dst, src, imm0, imm8); 12728 %} 12729%} 12730 12731//---------- Replicate Vector Instructions ------------------------------------ 12732 12733// Insrdi does replicate if src == dst. 12734instruct repl32(iRegLdst dst) %{ 12735 predicate(false); 12736 effect(USE_DEF dst); 12737 12738 format %{ "INSRDI $dst, #0, $dst, #32 \t// replicate" %} 12739 size(4); 12740 ins_encode %{ 12741 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 12742 __ insrdi($dst$$Register, $dst$$Register, 32, 0); 12743 %} 12744 ins_pipe(pipe_class_default); 12745%} 12746 12747// Insrdi does replicate if src == dst. 12748instruct repl48(iRegLdst dst) %{ 12749 predicate(false); 12750 effect(USE_DEF dst); 12751 12752 format %{ "INSRDI $dst, #0, $dst, #48 \t// replicate" %} 12753 size(4); 12754 ins_encode %{ 12755 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 12756 __ insrdi($dst$$Register, $dst$$Register, 48, 0); 12757 %} 12758 ins_pipe(pipe_class_default); 12759%} 12760 12761// Insrdi does replicate if src == dst. 12762instruct repl56(iRegLdst dst) %{ 12763 predicate(false); 12764 effect(USE_DEF dst); 12765 12766 format %{ "INSRDI $dst, #0, $dst, #56 \t// replicate" %} 12767 size(4); 12768 ins_encode %{ 12769 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 12770 __ insrdi($dst$$Register, $dst$$Register, 56, 0); 12771 %} 12772 ins_pipe(pipe_class_default); 12773%} 12774 12775instruct repl8B_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 12776 match(Set dst (ReplicateB src)); 12777 predicate(n->as_Vector()->length() == 8); 12778 expand %{ 12779 moveReg(dst, src); 12780 repl56(dst); 12781 repl48(dst); 12782 repl32(dst); 12783 %} 12784%} 12785 12786instruct repl8B_immI0(iRegLdst dst, immI_0 zero) %{ 12787 match(Set dst (ReplicateB zero)); 12788 predicate(n->as_Vector()->length() == 8); 12789 format %{ "LI $dst, #0 \t// replicate8B" %} 12790 size(4); 12791 ins_encode %{ 12792 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12793 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 12794 %} 12795 ins_pipe(pipe_class_default); 12796%} 12797 12798instruct repl8B_immIminus1(iRegLdst dst, immI_minus1 src) %{ 12799 match(Set dst (ReplicateB src)); 12800 predicate(n->as_Vector()->length() == 8); 12801 format %{ "LI $dst, #-1 \t// replicate8B" %} 12802 size(4); 12803 ins_encode %{ 12804 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12805 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 12806 %} 12807 ins_pipe(pipe_class_default); 12808%} 12809 12810instruct repl4S_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 12811 match(Set dst (ReplicateS src)); 12812 predicate(n->as_Vector()->length() == 4); 12813 expand %{ 12814 moveReg(dst, src); 12815 repl48(dst); 12816 repl32(dst); 12817 %} 12818%} 12819 12820instruct repl4S_immI0(iRegLdst dst, immI_0 zero) %{ 12821 match(Set dst (ReplicateS zero)); 12822 predicate(n->as_Vector()->length() == 4); 12823 format %{ "LI $dst, #0 \t// replicate4C" %} 12824 size(4); 12825 ins_encode %{ 12826 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12827 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 12828 %} 12829 ins_pipe(pipe_class_default); 12830%} 12831 12832instruct repl4S_immIminus1(iRegLdst dst, immI_minus1 src) %{ 12833 match(Set dst (ReplicateS src)); 12834 predicate(n->as_Vector()->length() == 4); 12835 format %{ "LI $dst, -1 \t// replicate4C" %} 12836 size(4); 12837 ins_encode %{ 12838 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12839 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 12840 %} 12841 ins_pipe(pipe_class_default); 12842%} 12843 12844instruct repl2I_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 12845 match(Set dst (ReplicateI src)); 12846 predicate(n->as_Vector()->length() == 2); 12847 ins_cost(2 * DEFAULT_COST); 12848 expand %{ 12849 moveReg(dst, src); 12850 repl32(dst); 12851 %} 12852%} 12853 12854instruct repl2I_immI0(iRegLdst dst, immI_0 zero) %{ 12855 match(Set dst (ReplicateI zero)); 12856 predicate(n->as_Vector()->length() == 2); 12857 format %{ "LI $dst, #0 \t// replicate4C" %} 12858 size(4); 12859 ins_encode %{ 12860 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12861 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 12862 %} 12863 ins_pipe(pipe_class_default); 12864%} 12865 12866instruct repl2I_immIminus1(iRegLdst dst, immI_minus1 src) %{ 12867 match(Set dst (ReplicateI src)); 12868 predicate(n->as_Vector()->length() == 2); 12869 format %{ "LI $dst, -1 \t// replicate4C" %} 12870 size(4); 12871 ins_encode %{ 12872 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12873 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 12874 %} 12875 ins_pipe(pipe_class_default); 12876%} 12877 12878// Move float to int register via stack, replicate. 12879instruct repl2F_reg_Ex(iRegLdst dst, regF src) %{ 12880 match(Set dst (ReplicateF src)); 12881 predicate(n->as_Vector()->length() == 2); 12882 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST); 12883 expand %{ 12884 stackSlotL tmpS; 12885 iRegIdst tmpI; 12886 moveF2I_reg_stack(tmpS, src); // Move float to stack. 12887 moveF2I_stack_reg(tmpI, tmpS); // Move stack to int reg. 12888 moveReg(dst, tmpI); // Move int to long reg. 12889 repl32(dst); // Replicate bitpattern. 12890 %} 12891%} 12892 12893// Replicate scalar constant to packed float values in Double register 12894instruct repl2F_immF_Ex(iRegLdst dst, immF src) %{ 12895 match(Set dst (ReplicateF src)); 12896 predicate(n->as_Vector()->length() == 2); 12897 ins_cost(5 * DEFAULT_COST); 12898 12899 format %{ "LD $dst, offset, $constanttablebase\t// load replicated float $src $src from table, postalloc expanded" %} 12900 postalloc_expand( postalloc_expand_load_replF_constant(dst, src, constanttablebase) ); 12901%} 12902 12903// Replicate scalar zero constant to packed float values in Double register 12904instruct repl2F_immF0(iRegLdst dst, immF_0 zero) %{ 12905 match(Set dst (ReplicateF zero)); 12906 predicate(n->as_Vector()->length() == 2); 12907 12908 format %{ "LI $dst, #0 \t// replicate2F" %} 12909 ins_encode %{ 12910 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12911 __ li($dst$$Register, 0x0); 12912 %} 12913 ins_pipe(pipe_class_default); 12914%} 12915 12916 12917//----------Overflow Math Instructions----------------------------------------- 12918 12919// Note that we have to make sure that XER.SO is reset before using overflow instructions. 12920// Simple Overflow operations can be matched by very few instructions (e.g. addExact: xor, and_, bc). 12921// Seems like only Long intrinsincs have an advantage. (The only expensive one is OverflowMulL.) 12922 12923instruct overflowAddL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 12924 match(Set cr0 (OverflowAddL op1 op2)); 12925 12926 format %{ "add_ $op1, $op2\t# overflow check long" %} 12927 ins_encode %{ 12928 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12929 __ li(R0, 0); 12930 __ mtxer(R0); // clear XER.SO 12931 __ addo_(R0, $op1$$Register, $op2$$Register); 12932 %} 12933 ins_pipe(pipe_class_default); 12934%} 12935 12936instruct overflowSubL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 12937 match(Set cr0 (OverflowSubL op1 op2)); 12938 12939 format %{ "subfo_ R0, $op2, $op1\t# overflow check long" %} 12940 ins_encode %{ 12941 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12942 __ li(R0, 0); 12943 __ mtxer(R0); // clear XER.SO 12944 __ subfo_(R0, $op2$$Register, $op1$$Register); 12945 %} 12946 ins_pipe(pipe_class_default); 12947%} 12948 12949instruct overflowNegL_reg(flagsRegCR0 cr0, immL_0 zero, iRegLsrc op2) %{ 12950 match(Set cr0 (OverflowSubL zero op2)); 12951 12952 format %{ "nego_ R0, $op2\t# overflow check long" %} 12953 ins_encode %{ 12954 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12955 __ li(R0, 0); 12956 __ mtxer(R0); // clear XER.SO 12957 __ nego_(R0, $op2$$Register); 12958 %} 12959 ins_pipe(pipe_class_default); 12960%} 12961 12962instruct overflowMulL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 12963 match(Set cr0 (OverflowMulL op1 op2)); 12964 12965 format %{ "mulldo_ R0, $op1, $op2\t# overflow check long" %} 12966 ins_encode %{ 12967 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12968 __ li(R0, 0); 12969 __ mtxer(R0); // clear XER.SO 12970 __ mulldo_(R0, $op1$$Register, $op2$$Register); 12971 %} 12972 ins_pipe(pipe_class_default); 12973%} 12974 12975 12976// ============================================================================ 12977// Safepoint Instruction 12978 12979instruct safePoint_poll(iRegPdst poll) %{ 12980 match(SafePoint poll); 12981 predicate(LoadPollAddressFromThread); 12982 12983 // It caused problems to add the effect that r0 is killed, but this 12984 // effect no longer needs to be mentioned, since r0 is not contained 12985 // in a reg_class. 12986 12987 format %{ "LD R0, #0, $poll \t// Safepoint poll for GC" %} 12988 size(4); 12989 ins_encode( enc_poll(0x0, poll) ); 12990 ins_pipe(pipe_class_default); 12991%} 12992 12993// Safepoint without per-thread support. Load address of page to poll 12994// as constant. 12995// Rscratch2RegP is R12. 12996// LoadConPollAddr node is added in pd_post_matching_hook(). It must be 12997// a seperate node so that the oop map is at the right location. 12998instruct safePoint_poll_conPollAddr(rscratch2RegP poll) %{ 12999 match(SafePoint poll); 13000 predicate(!LoadPollAddressFromThread); 13001 13002 // It caused problems to add the effect that r0 is killed, but this 13003 // effect no longer needs to be mentioned, since r0 is not contained 13004 // in a reg_class. 13005 13006 format %{ "LD R0, #0, R12 \t// Safepoint poll for GC" %} 13007 ins_encode( enc_poll(0x0, poll) ); 13008 ins_pipe(pipe_class_default); 13009%} 13010 13011// ============================================================================ 13012// Call Instructions 13013 13014// Call Java Static Instruction 13015 13016// Schedulable version of call static node. 13017instruct CallStaticJavaDirect(method meth) %{ 13018 match(CallStaticJava); 13019 effect(USE meth); 13020 ins_cost(CALL_COST); 13021 13022 ins_num_consts(3 /* up to 3 patchable constants: inline cache, 2 call targets. */); 13023 13024 format %{ "CALL,static $meth \t// ==> " %} 13025 size(4); 13026 ins_encode( enc_java_static_call(meth) ); 13027 ins_pipe(pipe_class_call); 13028%} 13029 13030// Call Java Dynamic Instruction 13031 13032// Used by postalloc expand of CallDynamicJavaDirectSchedEx (actual call). 13033// Loading of IC was postalloc expanded. The nodes loading the IC are reachable 13034// via fields ins_field_load_ic_hi_node and ins_field_load_ic_node. 13035// The call destination must still be placed in the constant pool. 13036instruct CallDynamicJavaDirectSched(method meth) %{ 13037 match(CallDynamicJava); // To get all the data fields we need ... 13038 effect(USE meth); 13039 predicate(false); // ... but never match. 13040 13041 ins_field_load_ic_hi_node(loadConL_hiNode*); 13042 ins_field_load_ic_node(loadConLNode*); 13043 ins_num_consts(1 /* 1 patchable constant: call destination */); 13044 13045 format %{ "BL \t// dynamic $meth ==> " %} 13046 size(4); 13047 ins_encode( enc_java_dynamic_call_sched(meth) ); 13048 ins_pipe(pipe_class_call); 13049%} 13050 13051// Schedulable (i.e. postalloc expanded) version of call dynamic java. 13052// We use postalloc expanded calls if we use inline caches 13053// and do not update method data. 13054// 13055// This instruction has two constants: inline cache (IC) and call destination. 13056// Loading the inline cache will be postalloc expanded, thus leaving a call with 13057// one constant. 13058instruct CallDynamicJavaDirectSched_Ex(method meth) %{ 13059 match(CallDynamicJava); 13060 effect(USE meth); 13061 predicate(UseInlineCaches); 13062 ins_cost(CALL_COST); 13063 13064 ins_num_consts(2 /* 2 patchable constants: inline cache, call destination. */); 13065 13066 format %{ "CALL,dynamic $meth \t// postalloc expanded" %} 13067 postalloc_expand( postalloc_expand_java_dynamic_call_sched(meth, constanttablebase) ); 13068%} 13069 13070// Compound version of call dynamic java 13071// We use postalloc expanded calls if we use inline caches 13072// and do not update method data. 13073instruct CallDynamicJavaDirect(method meth) %{ 13074 match(CallDynamicJava); 13075 effect(USE meth); 13076 predicate(!UseInlineCaches); 13077 ins_cost(CALL_COST); 13078 13079 // Enc_java_to_runtime_call needs up to 4 constants (method data oop). 13080 ins_num_consts(4); 13081 13082 format %{ "CALL,dynamic $meth \t// ==> " %} 13083 ins_encode( enc_java_dynamic_call(meth, constanttablebase) ); 13084 ins_pipe(pipe_class_call); 13085%} 13086 13087// Call Runtime Instruction 13088 13089instruct CallRuntimeDirect(method meth) %{ 13090 match(CallRuntime); 13091 effect(USE meth); 13092 ins_cost(CALL_COST); 13093 13094 // Enc_java_to_runtime_call needs up to 3 constants: call target, 13095 // env for callee, C-toc. 13096 ins_num_consts(3); 13097 13098 format %{ "CALL,runtime" %} 13099 ins_encode( enc_java_to_runtime_call(meth) ); 13100 ins_pipe(pipe_class_call); 13101%} 13102 13103// Call Leaf 13104 13105// Used by postalloc expand of CallLeafDirect_Ex (mtctr). 13106instruct CallLeafDirect_mtctr(iRegLdst dst, iRegLsrc src) %{ 13107 effect(DEF dst, USE src); 13108 13109 ins_num_consts(1); 13110 13111 format %{ "MTCTR $src" %} 13112 size(4); 13113 ins_encode( enc_leaf_call_mtctr(src) ); 13114 ins_pipe(pipe_class_default); 13115%} 13116 13117// Used by postalloc expand of CallLeafDirect_Ex (actual call). 13118instruct CallLeafDirect(method meth) %{ 13119 match(CallLeaf); // To get the data all the data fields we need ... 13120 effect(USE meth); 13121 predicate(false); // but never match. 13122 13123 format %{ "BCTRL \t// leaf call $meth ==> " %} 13124 size(4); 13125 ins_encode %{ 13126 // TODO: PPC port $archOpcode(ppc64Opcode_bctrl); 13127 __ bctrl(); 13128 %} 13129 ins_pipe(pipe_class_call); 13130%} 13131 13132// postalloc expand of CallLeafDirect. 13133// Load adress to call from TOC, then bl to it. 13134instruct CallLeafDirect_Ex(method meth) %{ 13135 match(CallLeaf); 13136 effect(USE meth); 13137 ins_cost(CALL_COST); 13138 13139 // Postalloc_expand_java_to_runtime_call needs up to 3 constants: call target, 13140 // env for callee, C-toc. 13141 ins_num_consts(3); 13142 13143 format %{ "CALL,runtime leaf $meth \t// postalloc expanded" %} 13144 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 13145%} 13146 13147// Call runtime without safepoint - same as CallLeaf. 13148// postalloc expand of CallLeafNoFPDirect. 13149// Load adress to call from TOC, then bl to it. 13150instruct CallLeafNoFPDirect_Ex(method meth) %{ 13151 match(CallLeafNoFP); 13152 effect(USE meth); 13153 ins_cost(CALL_COST); 13154 13155 // Enc_java_to_runtime_call needs up to 3 constants: call target, 13156 // env for callee, C-toc. 13157 ins_num_consts(3); 13158 13159 format %{ "CALL,runtime leaf nofp $meth \t// postalloc expanded" %} 13160 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 13161%} 13162 13163// Tail Call; Jump from runtime stub to Java code. 13164// Also known as an 'interprocedural jump'. 13165// Target of jump will eventually return to caller. 13166// TailJump below removes the return address. 13167instruct TailCalljmpInd(iRegPdstNoScratch jump_target, inline_cache_regP method_oop) %{ 13168 match(TailCall jump_target method_oop); 13169 ins_cost(CALL_COST); 13170 13171 format %{ "MTCTR $jump_target \t// $method_oop holds method oop\n\t" 13172 "BCTR \t// tail call" %} 13173 size(8); 13174 ins_encode %{ 13175 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13176 __ mtctr($jump_target$$Register); 13177 __ bctr(); 13178 %} 13179 ins_pipe(pipe_class_call); 13180%} 13181 13182// Return Instruction 13183instruct Ret() %{ 13184 match(Return); 13185 format %{ "BLR \t// branch to link register" %} 13186 size(4); 13187 ins_encode %{ 13188 // TODO: PPC port $archOpcode(ppc64Opcode_blr); 13189 // LR is restored in MachEpilogNode. Just do the RET here. 13190 __ blr(); 13191 %} 13192 ins_pipe(pipe_class_default); 13193%} 13194 13195// Tail Jump; remove the return address; jump to target. 13196// TailCall above leaves the return address around. 13197// TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2). 13198// ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a 13199// "restore" before this instruction (in Epilogue), we need to materialize it 13200// in %i0. 13201instruct tailjmpInd(iRegPdstNoScratch jump_target, rarg1RegP ex_oop) %{ 13202 match(TailJump jump_target ex_oop); 13203 ins_cost(CALL_COST); 13204 13205 format %{ "LD R4_ARG2 = LR\n\t" 13206 "MTCTR $jump_target\n\t" 13207 "BCTR \t// TailJump, exception oop: $ex_oop" %} 13208 size(12); 13209 ins_encode %{ 13210 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13211 __ ld(R4_ARG2/* issuing pc */, _abi(lr), R1_SP); 13212 __ mtctr($jump_target$$Register); 13213 __ bctr(); 13214 %} 13215 ins_pipe(pipe_class_call); 13216%} 13217 13218// Create exception oop: created by stack-crawling runtime code. 13219// Created exception is now available to this handler, and is setup 13220// just prior to jumping to this handler. No code emitted. 13221instruct CreateException(rarg1RegP ex_oop) %{ 13222 match(Set ex_oop (CreateEx)); 13223 ins_cost(0); 13224 13225 format %{ " -- \t// exception oop; no code emitted" %} 13226 size(0); 13227 ins_encode( /*empty*/ ); 13228 ins_pipe(pipe_class_default); 13229%} 13230 13231// Rethrow exception: The exception oop will come in the first 13232// argument position. Then JUMP (not call) to the rethrow stub code. 13233instruct RethrowException() %{ 13234 match(Rethrow); 13235 ins_cost(CALL_COST); 13236 13237 format %{ "Jmp rethrow_stub" %} 13238 ins_encode %{ 13239 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13240 cbuf.set_insts_mark(); 13241 __ b64_patchable((address)OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type); 13242 %} 13243 ins_pipe(pipe_class_call); 13244%} 13245 13246// Die now. 13247instruct ShouldNotReachHere() %{ 13248 match(Halt); 13249 ins_cost(CALL_COST); 13250 13251 format %{ "ShouldNotReachHere" %} 13252 size(4); 13253 ins_encode %{ 13254 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 13255 __ trap_should_not_reach_here(); 13256 %} 13257 ins_pipe(pipe_class_default); 13258%} 13259 13260// This name is KNOWN by the ADLC and cannot be changed. The ADLC 13261// forces a 'TypeRawPtr::BOTTOM' output type for this guy. 13262// Get a DEF on threadRegP, no costs, no encoding, use 13263// 'ins_should_rematerialize(true)' to avoid spilling. 13264instruct tlsLoadP(threadRegP dst) %{ 13265 match(Set dst (ThreadLocal)); 13266 ins_cost(0); 13267 13268 ins_should_rematerialize(true); 13269 13270 format %{ " -- \t// $dst=Thread::current(), empty" %} 13271 size(0); 13272 ins_encode( /*empty*/ ); 13273 ins_pipe(pipe_class_empty); 13274%} 13275 13276//---Some PPC specific nodes--------------------------------------------------- 13277 13278// Stop a group. 13279instruct endGroup() %{ 13280 ins_cost(0); 13281 13282 ins_is_nop(true); 13283 13284 format %{ "End Bundle (ori r1, r1, 0)" %} 13285 size(4); 13286 ins_encode %{ 13287 // TODO: PPC port $archOpcode(ppc64Opcode_endgroup); 13288 __ endgroup(); 13289 %} 13290 ins_pipe(pipe_class_default); 13291%} 13292 13293// Nop instructions 13294 13295instruct fxNop() %{ 13296 ins_cost(0); 13297 13298 ins_is_nop(true); 13299 13300 format %{ "fxNop" %} 13301 size(4); 13302 ins_encode %{ 13303 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 13304 __ nop(); 13305 %} 13306 ins_pipe(pipe_class_default); 13307%} 13308 13309instruct fpNop0() %{ 13310 ins_cost(0); 13311 13312 ins_is_nop(true); 13313 13314 format %{ "fpNop0" %} 13315 size(4); 13316 ins_encode %{ 13317 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 13318 __ fpnop0(); 13319 %} 13320 ins_pipe(pipe_class_default); 13321%} 13322 13323instruct fpNop1() %{ 13324 ins_cost(0); 13325 13326 ins_is_nop(true); 13327 13328 format %{ "fpNop1" %} 13329 size(4); 13330 ins_encode %{ 13331 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 13332 __ fpnop1(); 13333 %} 13334 ins_pipe(pipe_class_default); 13335%} 13336 13337instruct brNop0() %{ 13338 ins_cost(0); 13339 size(4); 13340 format %{ "brNop0" %} 13341 ins_encode %{ 13342 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 13343 __ brnop0(); 13344 %} 13345 ins_is_nop(true); 13346 ins_pipe(pipe_class_default); 13347%} 13348 13349instruct brNop1() %{ 13350 ins_cost(0); 13351 13352 ins_is_nop(true); 13353 13354 format %{ "brNop1" %} 13355 size(4); 13356 ins_encode %{ 13357 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 13358 __ brnop1(); 13359 %} 13360 ins_pipe(pipe_class_default); 13361%} 13362 13363instruct brNop2() %{ 13364 ins_cost(0); 13365 13366 ins_is_nop(true); 13367 13368 format %{ "brNop2" %} 13369 size(4); 13370 ins_encode %{ 13371 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 13372 __ brnop2(); 13373 %} 13374 ins_pipe(pipe_class_default); 13375%} 13376 13377//----------PEEPHOLE RULES----------------------------------------------------- 13378// These must follow all instruction definitions as they use the names 13379// defined in the instructions definitions. 13380// 13381// peepmatch ( root_instr_name [preceeding_instruction]* ); 13382// 13383// peepconstraint %{ 13384// (instruction_number.operand_name relational_op instruction_number.operand_name 13385// [, ...] ); 13386// // instruction numbers are zero-based using left to right order in peepmatch 13387// 13388// peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 13389// // provide an instruction_number.operand_name for each operand that appears 13390// // in the replacement instruction's match rule 13391// 13392// ---------VM FLAGS--------------------------------------------------------- 13393// 13394// All peephole optimizations can be turned off using -XX:-OptoPeephole 13395// 13396// Each peephole rule is given an identifying number starting with zero and 13397// increasing by one in the order seen by the parser. An individual peephole 13398// can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 13399// on the command-line. 13400// 13401// ---------CURRENT LIMITATIONS---------------------------------------------- 13402// 13403// Only match adjacent instructions in same basic block 13404// Only equality constraints 13405// Only constraints between operands, not (0.dest_reg == EAX_enc) 13406// Only one replacement instruction 13407// 13408// ---------EXAMPLE---------------------------------------------------------- 13409// 13410// // pertinent parts of existing instructions in architecture description 13411// instruct movI(eRegI dst, eRegI src) %{ 13412// match(Set dst (CopyI src)); 13413// %} 13414// 13415// instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{ 13416// match(Set dst (AddI dst src)); 13417// effect(KILL cr); 13418// %} 13419// 13420// // Change (inc mov) to lea 13421// peephole %{ 13422// // increment preceeded by register-register move 13423// peepmatch ( incI_eReg movI ); 13424// // require that the destination register of the increment 13425// // match the destination register of the move 13426// peepconstraint ( 0.dst == 1.dst ); 13427// // construct a replacement instruction that sets 13428// // the destination to ( move's source register + one ) 13429// peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 13430// %} 13431// 13432// Implementation no longer uses movX instructions since 13433// machine-independent system no longer uses CopyX nodes. 13434// 13435// peephole %{ 13436// peepmatch ( incI_eReg movI ); 13437// peepconstraint ( 0.dst == 1.dst ); 13438// peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 13439// %} 13440// 13441// peephole %{ 13442// peepmatch ( decI_eReg movI ); 13443// peepconstraint ( 0.dst == 1.dst ); 13444// peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 13445// %} 13446// 13447// peephole %{ 13448// peepmatch ( addI_eReg_imm movI ); 13449// peepconstraint ( 0.dst == 1.dst ); 13450// peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 13451// %} 13452// 13453// peephole %{ 13454// peepmatch ( addP_eReg_imm movP ); 13455// peepconstraint ( 0.dst == 1.dst ); 13456// peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) ); 13457// %} 13458 13459// // Change load of spilled value to only a spill 13460// instruct storeI(memory mem, eRegI src) %{ 13461// match(Set mem (StoreI mem src)); 13462// %} 13463// 13464// instruct loadI(eRegI dst, memory mem) %{ 13465// match(Set dst (LoadI mem)); 13466// %} 13467// 13468peephole %{ 13469 peepmatch ( loadI storeI ); 13470 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 13471 peepreplace ( storeI( 1.mem 1.mem 1.src ) ); 13472%} 13473 13474peephole %{ 13475 peepmatch ( loadL storeL ); 13476 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 13477 peepreplace ( storeL( 1.mem 1.mem 1.src ) ); 13478%} 13479 13480peephole %{ 13481 peepmatch ( loadP storeP ); 13482 peepconstraint ( 1.src == 0.dst, 1.dst == 0.mem ); 13483 peepreplace ( storeP( 1.dst 1.dst 1.src ) ); 13484%} 13485 13486//----------SMARTSPILL RULES--------------------------------------------------- 13487// These must follow all instruction definitions as they use the names 13488// defined in the instructions definitions. 13489