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. 34 register %{ 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 284 alloc_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 332 alloc_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 374 alloc_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 387 alloc_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. 420 reg_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. 457 reg_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 492 reg_class rscratch1_bits32_reg(R11); 493 reg_class rscratch2_bits32_reg(R12); 494 reg_class rarg1_bits32_reg(R3); 495 reg_class rarg2_bits32_reg(R4); 496 reg_class rarg3_bits32_reg(R5); 497 reg_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 504 reg_class rscratch1_bits64_reg(R11_H, R11); 505 reg_class rscratch2_bits64_reg(R12_H, R12); 506 reg_class rarg1_bits64_reg(R3_H, R3); 507 reg_class rarg2_bits64_reg(R4_H, R4); 508 reg_class rarg3_bits64_reg(R5_H, R5); 509 reg_class rarg4_bits64_reg(R6_H, R6); 510 // Thread register, 'written' by tlsLoadP, see there. 511 reg_class thread_bits64_reg(R16_H, R16); 512 513 reg_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. 517 reg_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. 555 reg_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. 593 reg_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. 630 reg_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 669 reg_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 680 reg_class int_flags_ro( 681 CCR0, 682 CCR1, 683 CCR2, 684 CCR3, 685 CCR4, 686 CCR5, 687 CCR6, 688 CCR7 689 ); 690 691 reg_class int_flags_CR0(CCR0); 692 reg_class int_flags_CR1(CCR1); 693 reg_class int_flags_CR6(CCR6); 694 reg_class ctr_reg(SR_CTR); 695 696 // ---------------------------- 697 // Float Register Classes 698 // ---------------------------- 699 700 reg_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. 737 reg_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 // 785 definitions %{ 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. 804 source_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 818 source %{ 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? 823 bool 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 827 void 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 // 844 bool 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 916 int MachCallStaticJavaNode::ret_addr_offset() { 917 // It's only a single branch-and-link instruction. 918 return 4; 919 } 920 921 int 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 938 int 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 950 static int cc_to_boint(int cc) { 951 return Assembler::bcondCRbiIs0 | (cc & 8); 952 } 953 954 static int cc_to_inverse_boint(int cc) { 955 return Assembler::bcondCRbiIs0 | (8-(cc & 8)); 956 } 957 958 static 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 int inlineCallClearArrayNode::compute_padding(int current_offset) const { 969 int desired_padding = (2*4-current_offset)&31; // see MacroAssembler::clear_memory_doubleword 970 return (desired_padding <= 3*4) ? desired_padding : 0; 971 } 972 973 //============================================================================= 974 975 // Indicate if the safepoint node needs the polling page as an input. 976 bool SafePointNode::needs_polling_address_input() { 977 // The address is loaded from thread by a seperate node. 978 return true; 979 } 980 981 //============================================================================= 982 983 // Emit an interrupt that is caught by the debugger (for debugging compiler). 984 void emit_break(CodeBuffer &cbuf) { 985 MacroAssembler _masm(&cbuf); 986 __ illtrap(); 987 } 988 989 #ifndef PRODUCT 990 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 991 st->print("BREAKPOINT"); 992 } 993 #endif 994 995 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 996 emit_break(cbuf); 997 } 998 999 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 1000 return MachNode::size(ra_); 1001 } 1002 1003 //============================================================================= 1004 1005 void emit_nop(CodeBuffer &cbuf) { 1006 MacroAssembler _masm(&cbuf); 1007 __ nop(); 1008 } 1009 1010 static inline void emit_long(CodeBuffer &cbuf, int value) { 1011 *((int*)(cbuf.insts_end())) = value; 1012 cbuf.set_insts_end(cbuf.insts_end() + BytesPerInstWord); 1013 } 1014 1015 //============================================================================= 1016 1017 %} // interrupt source 1018 1019 source_hpp %{ // Header information of the source block. 1020 1021 //-------------------------------------------------------------- 1022 //---< Used for optimization in Compile::Shorten_branches >--- 1023 //-------------------------------------------------------------- 1024 1025 class CallStubImpl { 1026 1027 public: 1028 1029 // Emit call stub, compiled java to interpreter. 1030 static void emit_trampoline_stub(MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset); 1031 1032 // Size of call trampoline stub. 1033 // This doesn't need to be accurate to the byte, but it 1034 // must be larger than or equal to the real size of the stub. 1035 static uint size_call_trampoline() { 1036 return MacroAssembler::trampoline_stub_size; 1037 } 1038 1039 // number of relocations needed by a call trampoline stub 1040 static uint reloc_call_trampoline() { 1041 return 5; 1042 } 1043 1044 }; 1045 1046 %} // end source_hpp 1047 1048 source %{ 1049 1050 // Emit a trampoline stub for a call to a target which is too far away. 1051 // 1052 // code sequences: 1053 // 1054 // call-site: 1055 // branch-and-link to <destination> or <trampoline stub> 1056 // 1057 // Related trampoline stub for this call-site in the stub section: 1058 // load the call target from the constant pool 1059 // branch via CTR (LR/link still points to the call-site above) 1060 1061 void CallStubImpl::emit_trampoline_stub(MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset) { 1062 address stub = __ emit_trampoline_stub(destination_toc_offset, insts_call_instruction_offset); 1063 if (stub == NULL) { 1064 ciEnv::current()->record_out_of_memory_failure(); 1065 } 1066 } 1067 1068 //============================================================================= 1069 1070 // Emit an inline branch-and-link call and a related trampoline stub. 1071 // 1072 // code sequences: 1073 // 1074 // call-site: 1075 // branch-and-link to <destination> or <trampoline stub> 1076 // 1077 // Related trampoline stub for this call-site in the stub section: 1078 // load the call target from the constant pool 1079 // branch via CTR (LR/link still points to the call-site above) 1080 // 1081 1082 typedef struct { 1083 int insts_call_instruction_offset; 1084 int ret_addr_offset; 1085 } EmitCallOffsets; 1086 1087 // Emit a branch-and-link instruction that branches to a trampoline. 1088 // - Remember the offset of the branch-and-link instruction. 1089 // - Add a relocation at the branch-and-link instruction. 1090 // - Emit a branch-and-link. 1091 // - Remember the return pc offset. 1092 EmitCallOffsets emit_call_with_trampoline_stub(MacroAssembler &_masm, address entry_point, relocInfo::relocType rtype) { 1093 EmitCallOffsets offsets = { -1, -1 }; 1094 const int start_offset = __ offset(); 1095 offsets.insts_call_instruction_offset = __ offset(); 1096 1097 // No entry point given, use the current pc. 1098 if (entry_point == NULL) entry_point = __ pc(); 1099 1100 if (!Compile::current()->in_scratch_emit_size()) { 1101 // Put the entry point as a constant into the constant pool. 1102 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 1103 if (entry_point_toc_addr == NULL) { 1104 ciEnv::current()->record_out_of_memory_failure(); 1105 return offsets; 1106 } 1107 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 1108 1109 // Emit the trampoline stub which will be related to the branch-and-link below. 1110 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, offsets.insts_call_instruction_offset); 1111 if (ciEnv::current()->failing()) { return offsets; } // Code cache may be full. 1112 __ relocate(rtype); 1113 } 1114 1115 // Note: At this point we do not have the address of the trampoline 1116 // stub, and the entry point might be too far away for bl, so __ pc() 1117 // serves as dummy and the bl will be patched later. 1118 __ bl((address) __ pc()); 1119 1120 offsets.ret_addr_offset = __ offset() - start_offset; 1121 1122 return offsets; 1123 } 1124 1125 //============================================================================= 1126 1127 // Factory for creating loadConL* nodes for large/small constant pool. 1128 1129 static inline jlong replicate_immF(float con) { 1130 // Replicate float con 2 times and pack into vector. 1131 int val = *((int*)&con); 1132 jlong lval = val; 1133 lval = (lval << 32) | (lval & 0xFFFFFFFFl); 1134 return lval; 1135 } 1136 1137 //============================================================================= 1138 1139 const RegMask& MachConstantBaseNode::_out_RegMask = BITS64_CONSTANT_TABLE_BASE_mask(); 1140 int Compile::ConstantTable::calculate_table_base_offset() const { 1141 return 0; // absolute addressing, no offset 1142 } 1143 1144 bool MachConstantBaseNode::requires_postalloc_expand() const { return true; } 1145 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 1146 iRegPdstOper *op_dst = new iRegPdstOper(); 1147 MachNode *m1 = new loadToc_hiNode(); 1148 MachNode *m2 = new loadToc_loNode(); 1149 1150 m1->add_req(NULL); 1151 m2->add_req(NULL, m1); 1152 m1->_opnds[0] = op_dst; 1153 m2->_opnds[0] = op_dst; 1154 m2->_opnds[1] = op_dst; 1155 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 1156 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 1157 nodes->push(m1); 1158 nodes->push(m2); 1159 } 1160 1161 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1162 // Is postalloc expanded. 1163 ShouldNotReachHere(); 1164 } 1165 1166 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 1167 return 0; 1168 } 1169 1170 #ifndef PRODUCT 1171 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1172 st->print("-- \t// MachConstantBaseNode (empty encoding)"); 1173 } 1174 #endif 1175 1176 //============================================================================= 1177 1178 #ifndef PRODUCT 1179 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1180 Compile* C = ra_->C; 1181 const long framesize = C->frame_slots() << LogBytesPerInt; 1182 1183 st->print("PROLOG\n\t"); 1184 if (C->need_stack_bang(framesize)) { 1185 st->print("stack_overflow_check\n\t"); 1186 } 1187 1188 if (!false /* TODO: PPC port C->is_frameless_method()*/) { 1189 st->print("save return pc\n\t"); 1190 st->print("push frame %ld\n\t", -framesize); 1191 } 1192 } 1193 #endif 1194 1195 // Macro used instead of the common __ to emulate the pipes of PPC. 1196 // Instead of e.g. __ ld(...) one hase to write ___(ld) ld(...) This enables the 1197 // micro scheduler to cope with "hand written" assembler like in the prolog. Though 1198 // still no scheduling of this code is possible, the micro scheduler is aware of the 1199 // code and can update its internal data. The following mechanism is used to achieve this: 1200 // The micro scheduler calls size() of each compound node during scheduling. size() does a 1201 // dummy emit and only during this dummy emit C->hb_scheduling() is not NULL. 1202 #if 0 // TODO: PPC port 1203 #define ___(op) if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1204 C->hb_scheduling()->_pdScheduling->PdEmulatePipe(ppc64Opcode_##op); \ 1205 _masm. 1206 #define ___stop if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1207 C->hb_scheduling()->_pdScheduling->PdEmulatePipe(archOpcode_none) 1208 #define ___advance if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1209 C->hb_scheduling()->_pdScheduling->advance_offset 1210 #else 1211 #define ___(op) if (UsePower6SchedulerPPC64) \ 1212 Unimplemented(); \ 1213 _masm. 1214 #define ___stop if (UsePower6SchedulerPPC64) \ 1215 Unimplemented() 1216 #define ___advance if (UsePower6SchedulerPPC64) \ 1217 Unimplemented() 1218 #endif 1219 1220 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1221 Compile* C = ra_->C; 1222 MacroAssembler _masm(&cbuf); 1223 1224 const long framesize = C->frame_size_in_bytes(); 1225 assert(framesize % (2 * wordSize) == 0, "must preserve 2*wordSize alignment"); 1226 1227 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; 1228 1229 const Register return_pc = R20; // Must match return_addr() in frame section. 1230 const Register callers_sp = R21; 1231 const Register push_frame_temp = R22; 1232 const Register toc_temp = R23; 1233 assert_different_registers(R11, return_pc, callers_sp, push_frame_temp, toc_temp); 1234 1235 if (method_is_frameless) { 1236 // Add nop at beginning of all frameless methods to prevent any 1237 // oop instructions from getting overwritten by make_not_entrant 1238 // (patching attempt would fail). 1239 ___(nop) nop(); 1240 } else { 1241 // Get return pc. 1242 ___(mflr) mflr(return_pc); 1243 } 1244 1245 // Calls to C2R adapters often do not accept exceptional returns. 1246 // We require that their callers must bang for them. But be 1247 // careful, because some VM calls (such as call site linkage) can 1248 // use several kilobytes of stack. But the stack safety zone should 1249 // account for that. See bugs 4446381, 4468289, 4497237. 1250 1251 int bangsize = C->bang_size_in_bytes(); 1252 assert(bangsize >= framesize || bangsize <= 0, "stack bang size incorrect"); 1253 if (C->need_stack_bang(bangsize) && UseStackBanging) { 1254 // Unfortunately we cannot use the function provided in 1255 // assembler.cpp as we have to emulate the pipes. So I had to 1256 // insert the code of generate_stack_overflow_check(), see 1257 // assembler.cpp for some illuminative comments. 1258 const int page_size = os::vm_page_size(); 1259 int bang_end = JavaThread::stack_shadow_zone_size(); 1260 1261 // This is how far the previous frame's stack banging extended. 1262 const int bang_end_safe = bang_end; 1263 1264 if (bangsize > page_size) { 1265 bang_end += bangsize; 1266 } 1267 1268 int bang_offset = bang_end_safe; 1269 1270 while (bang_offset <= bang_end) { 1271 // Need at least one stack bang at end of shadow zone. 1272 1273 // Again I had to copy code, this time from assembler_ppc.cpp, 1274 // bang_stack_with_offset - see there for comments. 1275 1276 // Stack grows down, caller passes positive offset. 1277 assert(bang_offset > 0, "must bang with positive offset"); 1278 1279 long stdoffset = -bang_offset; 1280 1281 if (Assembler::is_simm(stdoffset, 16)) { 1282 // Signed 16 bit offset, a simple std is ok. 1283 if (UseLoadInstructionsForStackBangingPPC64) { 1284 ___(ld) ld(R0, (int)(signed short)stdoffset, R1_SP); 1285 } else { 1286 ___(std) std(R0, (int)(signed short)stdoffset, R1_SP); 1287 } 1288 } else if (Assembler::is_simm(stdoffset, 31)) { 1289 // Use largeoffset calculations for addis & ld/std. 1290 const int hi = MacroAssembler::largeoffset_si16_si16_hi(stdoffset); 1291 const int lo = MacroAssembler::largeoffset_si16_si16_lo(stdoffset); 1292 1293 Register tmp = R11; 1294 ___(addis) addis(tmp, R1_SP, hi); 1295 if (UseLoadInstructionsForStackBangingPPC64) { 1296 ___(ld) ld(R0, lo, tmp); 1297 } else { 1298 ___(std) std(R0, lo, tmp); 1299 } 1300 } else { 1301 ShouldNotReachHere(); 1302 } 1303 1304 bang_offset += page_size; 1305 } 1306 // R11 trashed 1307 } // C->need_stack_bang(framesize) && UseStackBanging 1308 1309 unsigned int bytes = (unsigned int)framesize; 1310 long offset = Assembler::align_addr(bytes, frame::alignment_in_bytes); 1311 ciMethod *currMethod = C->method(); 1312 1313 // Optimized version for most common case. 1314 if (UsePower6SchedulerPPC64 && 1315 !method_is_frameless && Assembler::is_simm((int)(-offset), 16) && 1316 !(false /* ConstantsALot TODO: PPC port*/)) { 1317 ___(or) mr(callers_sp, R1_SP); 1318 ___(std) std(return_pc, _abi(lr), R1_SP); 1319 ___(stdu) stdu(R1_SP, -offset, R1_SP); 1320 return; 1321 } 1322 1323 if (!method_is_frameless) { 1324 // Get callers sp. 1325 ___(or) mr(callers_sp, R1_SP); 1326 1327 // Push method's frame, modifies SP. 1328 assert(Assembler::is_uimm(framesize, 32U), "wrong type"); 1329 // The ABI is already accounted for in 'framesize' via the 1330 // 'out_preserve' area. 1331 Register tmp = push_frame_temp; 1332 // Had to insert code of push_frame((unsigned int)framesize, push_frame_temp). 1333 if (Assembler::is_simm(-offset, 16)) { 1334 ___(stdu) stdu(R1_SP, -offset, R1_SP); 1335 } else { 1336 long x = -offset; 1337 // Had to insert load_const(tmp, -offset). 1338 ___(addis) lis( tmp, (int)((signed short)(((x >> 32) & 0xffff0000) >> 16))); 1339 ___(ori) ori( tmp, tmp, ((x >> 32) & 0x0000ffff)); 1340 ___(rldicr) sldi(tmp, tmp, 32); 1341 ___(oris) oris(tmp, tmp, (x & 0xffff0000) >> 16); 1342 ___(ori) ori( tmp, tmp, (x & 0x0000ffff)); 1343 1344 ___(stdux) stdux(R1_SP, R1_SP, tmp); 1345 } 1346 } 1347 #if 0 // TODO: PPC port 1348 // For testing large constant pools, emit a lot of constants to constant pool. 1349 // "Randomize" const_size. 1350 if (ConstantsALot) { 1351 const int num_consts = const_size(); 1352 for (int i = 0; i < num_consts; i++) { 1353 __ long_constant(0xB0B5B00BBABE); 1354 } 1355 } 1356 #endif 1357 if (!method_is_frameless) { 1358 // Save return pc. 1359 ___(std) std(return_pc, _abi(lr), callers_sp); 1360 } 1361 1362 C->set_frame_complete(cbuf.insts_size()); 1363 } 1364 #undef ___ 1365 #undef ___stop 1366 #undef ___advance 1367 1368 uint MachPrologNode::size(PhaseRegAlloc *ra_) const { 1369 // Variable size. determine dynamically. 1370 return MachNode::size(ra_); 1371 } 1372 1373 int MachPrologNode::reloc() const { 1374 // Return number of relocatable values contained in this instruction. 1375 return 1; // 1 reloc entry for load_const(toc). 1376 } 1377 1378 //============================================================================= 1379 1380 #ifndef PRODUCT 1381 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1382 Compile* C = ra_->C; 1383 1384 st->print("EPILOG\n\t"); 1385 st->print("restore return pc\n\t"); 1386 st->print("pop frame\n\t"); 1387 1388 if (do_polling() && C->is_method_compilation()) { 1389 st->print("touch polling page\n\t"); 1390 } 1391 } 1392 #endif 1393 1394 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1395 Compile* C = ra_->C; 1396 MacroAssembler _masm(&cbuf); 1397 1398 const long framesize = ((long)C->frame_slots()) << LogBytesPerInt; 1399 assert(framesize >= 0, "negative frame-size?"); 1400 1401 const bool method_needs_polling = do_polling() && C->is_method_compilation(); 1402 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; 1403 const Register return_pc = R31; // Must survive C-call to enable_stack_reserved_zone(). 1404 const Register polling_page = R12; 1405 1406 if (!method_is_frameless) { 1407 // Restore return pc relative to callers' sp. 1408 __ ld(return_pc, ((int)framesize) + _abi(lr), R1_SP); 1409 } 1410 1411 if (method_needs_polling) { 1412 if (LoadPollAddressFromThread) { 1413 // TODO: PPC port __ ld(polling_page, in_bytes(JavaThread::poll_address_offset()), R16_thread); 1414 Unimplemented(); 1415 } else { 1416 __ load_const_optimized(polling_page, (long)(address) os::get_polling_page()); // TODO: PPC port: get_standard_polling_page() 1417 } 1418 } 1419 1420 if (!method_is_frameless) { 1421 // Move return pc to LR. 1422 __ mtlr(return_pc); 1423 // Pop frame (fixed frame-size). 1424 __ addi(R1_SP, R1_SP, (int)framesize); 1425 } 1426 1427 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1428 __ reserved_stack_check(return_pc); 1429 } 1430 1431 if (method_needs_polling) { 1432 // We need to mark the code position where the load from the safepoint 1433 // polling page was emitted as relocInfo::poll_return_type here. 1434 __ relocate(relocInfo::poll_return_type); 1435 __ load_from_polling_page(polling_page); 1436 } 1437 } 1438 1439 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 1440 // Variable size. Determine dynamically. 1441 return MachNode::size(ra_); 1442 } 1443 1444 int MachEpilogNode::reloc() const { 1445 // Return number of relocatable values contained in this instruction. 1446 return 1; // 1 for load_from_polling_page. 1447 } 1448 1449 const Pipeline * MachEpilogNode::pipeline() const { 1450 return MachNode::pipeline_class(); 1451 } 1452 1453 // This method seems to be obsolete. It is declared in machnode.hpp 1454 // and defined in all *.ad files, but it is never called. Should we 1455 // get rid of it? 1456 int MachEpilogNode::safepoint_offset() const { 1457 assert(do_polling(), "no return for this epilog node"); 1458 return 0; 1459 } 1460 1461 #if 0 // TODO: PPC port 1462 void MachLoadPollAddrLateNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1463 MacroAssembler _masm(&cbuf); 1464 if (LoadPollAddressFromThread) { 1465 _masm.ld(R11, in_bytes(JavaThread::poll_address_offset()), R16_thread); 1466 } else { 1467 _masm.nop(); 1468 } 1469 } 1470 1471 uint MachLoadPollAddrLateNode::size(PhaseRegAlloc* ra_) const { 1472 if (LoadPollAddressFromThread) { 1473 return 4; 1474 } else { 1475 return 4; 1476 } 1477 } 1478 1479 #ifndef PRODUCT 1480 void MachLoadPollAddrLateNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1481 st->print_cr(" LD R11, PollAddressOffset, R16_thread \t// LoadPollAddressFromThread"); 1482 } 1483 #endif 1484 1485 const RegMask &MachLoadPollAddrLateNode::out_RegMask() const { 1486 return RSCRATCH1_BITS64_REG_mask(); 1487 } 1488 #endif // PPC port 1489 1490 // ============================================================================= 1491 1492 // Figure out which register class each belongs in: rc_int, rc_float or 1493 // rc_stack. 1494 enum RC { rc_bad, rc_int, rc_float, rc_stack }; 1495 1496 static enum RC rc_class(OptoReg::Name reg) { 1497 // Return the register class for the given register. The given register 1498 // reg is a <register>_num value, which is an index into the MachRegisterNumbers 1499 // enumeration in adGlobals_ppc.hpp. 1500 1501 if (reg == OptoReg::Bad) return rc_bad; 1502 1503 // We have 64 integer register halves, starting at index 0. 1504 if (reg < 64) return rc_int; 1505 1506 // We have 64 floating-point register halves, starting at index 64. 1507 if (reg < 64+64) return rc_float; 1508 1509 // Between float regs & stack are the flags regs. 1510 assert(OptoReg::is_stack(reg), "blow up if spilling flags"); 1511 1512 return rc_stack; 1513 } 1514 1515 static int ld_st_helper(CodeBuffer *cbuf, const char *op_str, uint opcode, int reg, int offset, 1516 bool do_print, Compile* C, outputStream *st) { 1517 1518 assert(opcode == Assembler::LD_OPCODE || 1519 opcode == Assembler::STD_OPCODE || 1520 opcode == Assembler::LWZ_OPCODE || 1521 opcode == Assembler::STW_OPCODE || 1522 opcode == Assembler::LFD_OPCODE || 1523 opcode == Assembler::STFD_OPCODE || 1524 opcode == Assembler::LFS_OPCODE || 1525 opcode == Assembler::STFS_OPCODE, 1526 "opcode not supported"); 1527 1528 if (cbuf) { 1529 int d = 1530 (Assembler::LD_OPCODE == opcode || Assembler::STD_OPCODE == opcode) ? 1531 Assembler::ds(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/) 1532 : Assembler::d1(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); // Makes no difference in opt build. 1533 emit_long(*cbuf, opcode | Assembler::rt(Matcher::_regEncode[reg]) | d | Assembler::ra(R1_SP)); 1534 } 1535 #ifndef PRODUCT 1536 else if (do_print) { 1537 st->print("%-7s %s, [R1_SP + #%d+%d] \t// spill copy", 1538 op_str, 1539 Matcher::regName[reg], 1540 offset, 0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); 1541 } 1542 #endif 1543 return 4; // size 1544 } 1545 1546 uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 1547 Compile* C = ra_->C; 1548 1549 // Get registers to move. 1550 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 1551 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 1552 OptoReg::Name dst_hi = ra_->get_reg_second(this); 1553 OptoReg::Name dst_lo = ra_->get_reg_first(this); 1554 1555 enum RC src_hi_rc = rc_class(src_hi); 1556 enum RC src_lo_rc = rc_class(src_lo); 1557 enum RC dst_hi_rc = rc_class(dst_hi); 1558 enum RC dst_lo_rc = rc_class(dst_lo); 1559 1560 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 1561 if (src_hi != OptoReg::Bad) 1562 assert((src_lo&1)==0 && src_lo+1==src_hi && 1563 (dst_lo&1)==0 && dst_lo+1==dst_hi, 1564 "expected aligned-adjacent pairs"); 1565 // Generate spill code! 1566 int size = 0; 1567 1568 if (src_lo == dst_lo && src_hi == dst_hi) 1569 return size; // Self copy, no move. 1570 1571 // -------------------------------------- 1572 // Memory->Memory Spill. Use R0 to hold the value. 1573 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1574 int src_offset = ra_->reg2offset(src_lo); 1575 int dst_offset = ra_->reg2offset(dst_lo); 1576 if (src_hi != OptoReg::Bad) { 1577 assert(src_hi_rc==rc_stack && dst_hi_rc==rc_stack, 1578 "expected same type of move for high parts"); 1579 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, R0_num, src_offset, !do_size, C, st); 1580 if (!cbuf && !do_size) st->print("\n\t"); 1581 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, R0_num, dst_offset, !do_size, C, st); 1582 } else { 1583 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, R0_num, src_offset, !do_size, C, st); 1584 if (!cbuf && !do_size) st->print("\n\t"); 1585 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, R0_num, dst_offset, !do_size, C, st); 1586 } 1587 return size; 1588 } 1589 1590 // -------------------------------------- 1591 // Check for float->int copy; requires a trip through memory. 1592 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) { 1593 Unimplemented(); 1594 } 1595 1596 // -------------------------------------- 1597 // Check for integer reg-reg copy. 1598 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) { 1599 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]); 1600 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]); 1601 size = (Rsrc != Rdst) ? 4 : 0; 1602 1603 if (cbuf) { 1604 MacroAssembler _masm(cbuf); 1605 if (size) { 1606 __ mr(Rdst, Rsrc); 1607 } 1608 } 1609 #ifndef PRODUCT 1610 else if (!do_size) { 1611 if (size) { 1612 st->print("%-7s %s, %s \t// spill copy", "MR", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1613 } else { 1614 st->print("%-7s %s, %s \t// spill copy", "MR-NOP", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1615 } 1616 } 1617 #endif 1618 return size; 1619 } 1620 1621 // Check for integer store. 1622 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) { 1623 int dst_offset = ra_->reg2offset(dst_lo); 1624 if (src_hi != OptoReg::Bad) { 1625 assert(src_hi_rc==rc_int && dst_hi_rc==rc_stack, 1626 "expected same type of move for high parts"); 1627 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, src_lo, dst_offset, !do_size, C, st); 1628 } else { 1629 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, src_lo, dst_offset, !do_size, C, st); 1630 } 1631 return size; 1632 } 1633 1634 // Check for integer load. 1635 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) { 1636 int src_offset = ra_->reg2offset(src_lo); 1637 if (src_hi != OptoReg::Bad) { 1638 assert(dst_hi_rc==rc_int && src_hi_rc==rc_stack, 1639 "expected same type of move for high parts"); 1640 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, dst_lo, src_offset, !do_size, C, st); 1641 } else { 1642 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, dst_lo, src_offset, !do_size, C, st); 1643 } 1644 return size; 1645 } 1646 1647 // Check for float reg-reg copy. 1648 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1649 if (cbuf) { 1650 MacroAssembler _masm(cbuf); 1651 FloatRegister Rsrc = as_FloatRegister(Matcher::_regEncode[src_lo]); 1652 FloatRegister Rdst = as_FloatRegister(Matcher::_regEncode[dst_lo]); 1653 __ fmr(Rdst, Rsrc); 1654 } 1655 #ifndef PRODUCT 1656 else if (!do_size) { 1657 st->print("%-7s %s, %s \t// spill copy", "FMR", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1658 } 1659 #endif 1660 return 4; 1661 } 1662 1663 // Check for float store. 1664 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1665 int dst_offset = ra_->reg2offset(dst_lo); 1666 if (src_hi != OptoReg::Bad) { 1667 assert(src_hi_rc==rc_float && dst_hi_rc==rc_stack, 1668 "expected same type of move for high parts"); 1669 size += ld_st_helper(cbuf, "STFD", Assembler::STFD_OPCODE, src_lo, dst_offset, !do_size, C, st); 1670 } else { 1671 size += ld_st_helper(cbuf, "STFS", Assembler::STFS_OPCODE, src_lo, dst_offset, !do_size, C, st); 1672 } 1673 return size; 1674 } 1675 1676 // Check for float load. 1677 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) { 1678 int src_offset = ra_->reg2offset(src_lo); 1679 if (src_hi != OptoReg::Bad) { 1680 assert(dst_hi_rc==rc_float && src_hi_rc==rc_stack, 1681 "expected same type of move for high parts"); 1682 size += ld_st_helper(cbuf, "LFD ", Assembler::LFD_OPCODE, dst_lo, src_offset, !do_size, C, st); 1683 } else { 1684 size += ld_st_helper(cbuf, "LFS ", Assembler::LFS_OPCODE, dst_lo, src_offset, !do_size, C, st); 1685 } 1686 return size; 1687 } 1688 1689 // -------------------------------------------------------------------- 1690 // Check for hi bits still needing moving. Only happens for misaligned 1691 // arguments to native calls. 1692 if (src_hi == dst_hi) 1693 return size; // Self copy; no move. 1694 1695 assert(src_hi_rc != rc_bad && dst_hi_rc != rc_bad, "src_hi & dst_hi cannot be Bad"); 1696 ShouldNotReachHere(); // Unimplemented 1697 return 0; 1698 } 1699 1700 #ifndef PRODUCT 1701 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1702 if (!ra_) 1703 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 1704 else 1705 implementation(NULL, ra_, false, st); 1706 } 1707 #endif 1708 1709 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1710 implementation(&cbuf, ra_, false, NULL); 1711 } 1712 1713 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1714 return implementation(NULL, ra_, true, NULL); 1715 } 1716 1717 #if 0 // TODO: PPC port 1718 ArchOpcode MachSpillCopyNode_archOpcode(MachSpillCopyNode *n, PhaseRegAlloc *ra_) { 1719 #ifndef PRODUCT 1720 if (ra_->node_regs_max_index() == 0) return archOpcode_undefined; 1721 #endif 1722 assert(ra_->node_regs_max_index() != 0, ""); 1723 1724 // Get registers to move. 1725 OptoReg::Name src_hi = ra_->get_reg_second(n->in(1)); 1726 OptoReg::Name src_lo = ra_->get_reg_first(n->in(1)); 1727 OptoReg::Name dst_hi = ra_->get_reg_second(n); 1728 OptoReg::Name dst_lo = ra_->get_reg_first(n); 1729 1730 enum RC src_lo_rc = rc_class(src_lo); 1731 enum RC dst_lo_rc = rc_class(dst_lo); 1732 1733 if (src_lo == dst_lo && src_hi == dst_hi) 1734 return ppc64Opcode_none; // Self copy, no move. 1735 1736 // -------------------------------------- 1737 // Memory->Memory Spill. Use R0 to hold the value. 1738 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1739 return ppc64Opcode_compound; 1740 } 1741 1742 // -------------------------------------- 1743 // Check for float->int copy; requires a trip through memory. 1744 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) { 1745 Unimplemented(); 1746 } 1747 1748 // -------------------------------------- 1749 // Check for integer reg-reg copy. 1750 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) { 1751 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]); 1752 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]); 1753 if (Rsrc == Rdst) { 1754 return ppc64Opcode_none; 1755 } else { 1756 return ppc64Opcode_or; 1757 } 1758 } 1759 1760 // Check for integer store. 1761 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) { 1762 if (src_hi != OptoReg::Bad) { 1763 return ppc64Opcode_std; 1764 } else { 1765 return ppc64Opcode_stw; 1766 } 1767 } 1768 1769 // Check for integer load. 1770 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) { 1771 if (src_hi != OptoReg::Bad) { 1772 return ppc64Opcode_ld; 1773 } else { 1774 return ppc64Opcode_lwz; 1775 } 1776 } 1777 1778 // Check for float reg-reg copy. 1779 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1780 return ppc64Opcode_fmr; 1781 } 1782 1783 // Check for float store. 1784 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1785 if (src_hi != OptoReg::Bad) { 1786 return ppc64Opcode_stfd; 1787 } else { 1788 return ppc64Opcode_stfs; 1789 } 1790 } 1791 1792 // Check for float load. 1793 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) { 1794 if (src_hi != OptoReg::Bad) { 1795 return ppc64Opcode_lfd; 1796 } else { 1797 return ppc64Opcode_lfs; 1798 } 1799 } 1800 1801 // -------------------------------------------------------------------- 1802 // Check for hi bits still needing moving. Only happens for misaligned 1803 // arguments to native calls. 1804 if (src_hi == dst_hi) { 1805 return ppc64Opcode_none; // Self copy; no move. 1806 } 1807 1808 ShouldNotReachHere(); 1809 return ppc64Opcode_undefined; 1810 } 1811 #endif // PPC port 1812 1813 #ifndef PRODUCT 1814 void MachNopNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1815 st->print("NOP \t// %d nops to pad for loops.", _count); 1816 } 1817 #endif 1818 1819 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *) const { 1820 MacroAssembler _masm(&cbuf); 1821 // _count contains the number of nops needed for padding. 1822 for (int i = 0; i < _count; i++) { 1823 __ nop(); 1824 } 1825 } 1826 1827 uint MachNopNode::size(PhaseRegAlloc *ra_) const { 1828 return _count * 4; 1829 } 1830 1831 #ifndef PRODUCT 1832 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1833 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1834 char reg_str[128]; 1835 ra_->dump_register(this, reg_str); 1836 st->print("ADDI %s, SP, %d \t// box node", reg_str, offset); 1837 } 1838 #endif 1839 1840 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1841 MacroAssembler _masm(&cbuf); 1842 1843 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1844 int reg = ra_->get_encode(this); 1845 1846 if (Assembler::is_simm(offset, 16)) { 1847 __ addi(as_Register(reg), R1, offset); 1848 } else { 1849 ShouldNotReachHere(); 1850 } 1851 } 1852 1853 uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 1854 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 1855 return 4; 1856 } 1857 1858 #ifndef PRODUCT 1859 void MachUEPNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1860 st->print_cr("---- MachUEPNode ----"); 1861 st->print_cr("..."); 1862 } 1863 #endif 1864 1865 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1866 // This is the unverified entry point. 1867 MacroAssembler _masm(&cbuf); 1868 1869 // Inline_cache contains a klass. 1870 Register ic_klass = as_Register(Matcher::inline_cache_reg_encode()); 1871 Register receiver_klass = R12_scratch2; // tmp 1872 1873 assert_different_registers(ic_klass, receiver_klass, R11_scratch1, R3_ARG1); 1874 assert(R11_scratch1 == R11, "need prologue scratch register"); 1875 1876 // Check for NULL argument if we don't have implicit null checks. 1877 if (!ImplicitNullChecks || !os::zero_page_read_protected()) { 1878 if (TrapBasedNullChecks) { 1879 __ trap_null_check(R3_ARG1); 1880 } else { 1881 Label valid; 1882 __ cmpdi(CCR0, R3_ARG1, 0); 1883 __ bne_predict_taken(CCR0, valid); 1884 // We have a null argument, branch to ic_miss_stub. 1885 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), 1886 relocInfo::runtime_call_type); 1887 __ bind(valid); 1888 } 1889 } 1890 // Assume argument is not NULL, load klass from receiver. 1891 __ load_klass(receiver_klass, R3_ARG1); 1892 1893 if (TrapBasedICMissChecks) { 1894 __ trap_ic_miss_check(receiver_klass, ic_klass); 1895 } else { 1896 Label valid; 1897 __ cmpd(CCR0, receiver_klass, ic_klass); 1898 __ beq_predict_taken(CCR0, valid); 1899 // We have an unexpected klass, branch to ic_miss_stub. 1900 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), 1901 relocInfo::runtime_call_type); 1902 __ bind(valid); 1903 } 1904 1905 // Argument is valid and klass is as expected, continue. 1906 } 1907 1908 #if 0 // TODO: PPC port 1909 // Optimize UEP code on z (save a load_const() call in main path). 1910 int MachUEPNode::ep_offset() { 1911 return 0; 1912 } 1913 #endif 1914 1915 uint MachUEPNode::size(PhaseRegAlloc *ra_) const { 1916 // Variable size. Determine dynamically. 1917 return MachNode::size(ra_); 1918 } 1919 1920 //============================================================================= 1921 1922 %} // interrupt source 1923 1924 source_hpp %{ // Header information of the source block. 1925 1926 class HandlerImpl { 1927 1928 public: 1929 1930 static int emit_exception_handler(CodeBuffer &cbuf); 1931 static int emit_deopt_handler(CodeBuffer& cbuf); 1932 1933 static uint size_exception_handler() { 1934 // The exception_handler is a b64_patchable. 1935 return MacroAssembler::b64_patchable_size; 1936 } 1937 1938 static uint size_deopt_handler() { 1939 // The deopt_handler is a bl64_patchable. 1940 return MacroAssembler::bl64_patchable_size; 1941 } 1942 1943 }; 1944 1945 %} // end source_hpp 1946 1947 source %{ 1948 1949 int HandlerImpl::emit_exception_handler(CodeBuffer &cbuf) { 1950 MacroAssembler _masm(&cbuf); 1951 1952 address base = __ start_a_stub(size_exception_handler()); 1953 if (base == NULL) return 0; // CodeBuffer::expand failed 1954 1955 int offset = __ offset(); 1956 __ b64_patchable((address)OptoRuntime::exception_blob()->content_begin(), 1957 relocInfo::runtime_call_type); 1958 assert(__ offset() - offset == (int)size_exception_handler(), "must be fixed size"); 1959 __ end_a_stub(); 1960 1961 return offset; 1962 } 1963 1964 // The deopt_handler is like the exception handler, but it calls to 1965 // the deoptimization blob instead of jumping to the exception blob. 1966 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) { 1967 MacroAssembler _masm(&cbuf); 1968 1969 address base = __ start_a_stub(size_deopt_handler()); 1970 if (base == NULL) return 0; // CodeBuffer::expand failed 1971 1972 int offset = __ offset(); 1973 __ bl64_patchable((address)SharedRuntime::deopt_blob()->unpack(), 1974 relocInfo::runtime_call_type); 1975 assert(__ offset() - offset == (int) size_deopt_handler(), "must be fixed size"); 1976 __ end_a_stub(); 1977 1978 return offset; 1979 } 1980 1981 //============================================================================= 1982 1983 // Use a frame slots bias for frameless methods if accessing the stack. 1984 static int frame_slots_bias(int reg_enc, PhaseRegAlloc* ra_) { 1985 if (as_Register(reg_enc) == R1_SP) { 1986 return 0; // TODO: PPC port ra_->C->frame_slots_sp_bias_in_bytes(); 1987 } 1988 return 0; 1989 } 1990 1991 const bool Matcher::match_rule_supported(int opcode) { 1992 if (!has_match_rule(opcode)) 1993 return false; 1994 1995 switch (opcode) { 1996 case Op_SqrtD: 1997 return VM_Version::has_fsqrt(); 1998 case Op_CountLeadingZerosI: 1999 case Op_CountLeadingZerosL: 2000 case Op_CountTrailingZerosI: 2001 case Op_CountTrailingZerosL: 2002 if (!UseCountLeadingZerosInstructionsPPC64) 2003 return false; 2004 break; 2005 2006 case Op_PopCountI: 2007 case Op_PopCountL: 2008 return (UsePopCountInstruction && VM_Version::has_popcntw()); 2009 2010 case Op_StrComp: 2011 return SpecialStringCompareTo; 2012 case Op_StrEquals: 2013 return SpecialStringEquals; 2014 case Op_StrIndexOf: 2015 return SpecialStringIndexOf; 2016 case Op_StrIndexOfChar: 2017 return SpecialStringIndexOf; 2018 } 2019 2020 return true; // Per default match rules are supported. 2021 } 2022 2023 const bool Matcher::match_rule_supported_vector(int opcode, int vlen) { 2024 2025 // TODO 2026 // identify extra cases that we might want to provide match rules for 2027 // e.g. Op_ vector nodes and other intrinsics while guarding with vlen 2028 bool ret_value = match_rule_supported(opcode); 2029 // Add rules here. 2030 2031 return ret_value; // Per default match rules are supported. 2032 } 2033 2034 const bool Matcher::has_predicated_vectors(void) { 2035 return false; 2036 } 2037 2038 const int Matcher::float_pressure(int default_pressure_threshold) { 2039 return default_pressure_threshold; 2040 } 2041 2042 int Matcher::regnum_to_fpu_offset(int regnum) { 2043 // No user for this method? 2044 Unimplemented(); 2045 return 999; 2046 } 2047 2048 const bool Matcher::convL2FSupported(void) { 2049 // fcfids can do the conversion (>= Power7). 2050 // fcfid + frsp showed rounding problem when result should be 0x3f800001. 2051 return VM_Version::has_fcfids(); // False means that conversion is done by runtime call. 2052 } 2053 2054 // Vector width in bytes. 2055 const int Matcher::vector_width_in_bytes(BasicType bt) { 2056 assert(MaxVectorSize == 8, ""); 2057 return 8; 2058 } 2059 2060 // Vector ideal reg. 2061 const int Matcher::vector_ideal_reg(int size) { 2062 assert(MaxVectorSize == 8 && size == 8, ""); 2063 return Op_RegL; 2064 } 2065 2066 const int Matcher::vector_shift_count_ideal_reg(int size) { 2067 fatal("vector shift is not supported"); 2068 return Node::NotAMachineReg; 2069 } 2070 2071 // Limits on vector size (number of elements) loaded into vector. 2072 const int Matcher::max_vector_size(const BasicType bt) { 2073 assert(is_java_primitive(bt), "only primitive type vectors"); 2074 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2075 } 2076 2077 const int Matcher::min_vector_size(const BasicType bt) { 2078 return max_vector_size(bt); // Same as max. 2079 } 2080 2081 // PPC doesn't support misaligned vectors store/load. 2082 const bool Matcher::misaligned_vectors_ok() { 2083 return false; 2084 } 2085 2086 // PPC AES support not yet implemented 2087 const bool Matcher::pass_original_key_for_aes() { 2088 return false; 2089 } 2090 2091 // RETURNS: whether this branch offset is short enough that a short 2092 // branch can be used. 2093 // 2094 // If the platform does not provide any short branch variants, then 2095 // this method should return `false' for offset 0. 2096 // 2097 // `Compile::Fill_buffer' will decide on basis of this information 2098 // whether to do the pass `Compile::Shorten_branches' at all. 2099 // 2100 // And `Compile::Shorten_branches' will decide on basis of this 2101 // information whether to replace particular branch sites by short 2102 // ones. 2103 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 2104 // Is the offset within the range of a ppc64 pc relative branch? 2105 bool b; 2106 2107 const int safety_zone = 3 * BytesPerInstWord; 2108 b = Assembler::is_simm((offset<0 ? offset-safety_zone : offset+safety_zone), 2109 29 - 16 + 1 + 2); 2110 return b; 2111 } 2112 2113 const bool Matcher::isSimpleConstant64(jlong value) { 2114 // Probably always true, even if a temp register is required. 2115 return true; 2116 } 2117 /* TODO: PPC port 2118 // Make a new machine dependent decode node (with its operands). 2119 MachTypeNode *Matcher::make_decode_node() { 2120 assert(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0, 2121 "This method is only implemented for unscaled cOops mode so far"); 2122 MachTypeNode *decode = new decodeN_unscaledNode(); 2123 decode->set_opnd_array(0, new iRegPdstOper()); 2124 decode->set_opnd_array(1, new iRegNsrcOper()); 2125 return decode; 2126 } 2127 */ 2128 2129 // false => size gets scaled to BytesPerLong, ok. 2130 const bool Matcher::init_array_count_is_in_bytes = false; 2131 2132 // Use conditional move (CMOVL) on Power7. 2133 const int Matcher::long_cmove_cost() { return 0; } // this only makes long cmoves more expensive than int cmoves 2134 2135 // Suppress CMOVF. Conditional move available (sort of) on PPC64 only from P7 onwards. Not exploited yet. 2136 // fsel doesn't accept a condition register as input, so this would be slightly different. 2137 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 2138 2139 // Power6 requires postalloc expand (see block.cpp for description of postalloc expand). 2140 const bool Matcher::require_postalloc_expand = true; 2141 2142 // Do we need to mask the count passed to shift instructions or does 2143 // the cpu only look at the lower 5/6 bits anyway? 2144 // PowerPC requires masked shift counts. 2145 const bool Matcher::need_masked_shift_count = true; 2146 2147 // This affects two different things: 2148 // - how Decode nodes are matched 2149 // - how ImplicitNullCheck opportunities are recognized 2150 // If true, the matcher will try to remove all Decodes and match them 2151 // (as operands) into nodes. NullChecks are not prepared to deal with 2152 // Decodes by final_graph_reshaping(). 2153 // If false, final_graph_reshaping() forces the decode behind the Cmp 2154 // for a NullCheck. The matcher matches the Decode node into a register. 2155 // Implicit_null_check optimization moves the Decode along with the 2156 // memory operation back up before the NullCheck. 2157 bool Matcher::narrow_oop_use_complex_address() { 2158 // TODO: PPC port if (MatchDecodeNodes) return true; 2159 return false; 2160 } 2161 2162 bool Matcher::narrow_klass_use_complex_address() { 2163 NOT_LP64(ShouldNotCallThis()); 2164 assert(UseCompressedClassPointers, "only for compressed klass code"); 2165 // TODO: PPC port if (MatchDecodeNodes) return true; 2166 return false; 2167 } 2168 2169 // Is it better to copy float constants, or load them directly from memory? 2170 // Intel can load a float constant from a direct address, requiring no 2171 // extra registers. Most RISCs will have to materialize an address into a 2172 // register first, so they would do better to copy the constant from stack. 2173 const bool Matcher::rematerialize_float_constants = false; 2174 2175 // If CPU can load and store mis-aligned doubles directly then no fixup is 2176 // needed. Else we split the double into 2 integer pieces and move it 2177 // piece-by-piece. Only happens when passing doubles into C code as the 2178 // Java calling convention forces doubles to be aligned. 2179 const bool Matcher::misaligned_doubles_ok = true; 2180 2181 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) { 2182 Unimplemented(); 2183 } 2184 2185 // Advertise here if the CPU requires explicit rounding operations 2186 // to implement the UseStrictFP mode. 2187 const bool Matcher::strict_fp_requires_explicit_rounding = false; 2188 2189 // Do floats take an entire double register or just half? 2190 // 2191 // A float occupies a ppc64 double register. For the allocator, a 2192 // ppc64 double register appears as a pair of float registers. 2193 bool Matcher::float_in_double() { return true; } 2194 2195 // Do ints take an entire long register or just half? 2196 // The relevant question is how the int is callee-saved: 2197 // the whole long is written but de-opt'ing will have to extract 2198 // the relevant 32 bits. 2199 const bool Matcher::int_in_long = true; 2200 2201 // Constants for c2c and c calling conventions. 2202 2203 const MachRegisterNumbers iarg_reg[8] = { 2204 R3_num, R4_num, R5_num, R6_num, 2205 R7_num, R8_num, R9_num, R10_num 2206 }; 2207 2208 const MachRegisterNumbers farg_reg[13] = { 2209 F1_num, F2_num, F3_num, F4_num, 2210 F5_num, F6_num, F7_num, F8_num, 2211 F9_num, F10_num, F11_num, F12_num, 2212 F13_num 2213 }; 2214 2215 const int num_iarg_registers = sizeof(iarg_reg) / sizeof(iarg_reg[0]); 2216 2217 const int num_farg_registers = sizeof(farg_reg) / sizeof(farg_reg[0]); 2218 2219 // Return whether or not this register is ever used as an argument. This 2220 // function is used on startup to build the trampoline stubs in generateOptoStub. 2221 // Registers not mentioned will be killed by the VM call in the trampoline, and 2222 // arguments in those registers not be available to the callee. 2223 bool Matcher::can_be_java_arg(int reg) { 2224 // We return true for all registers contained in iarg_reg[] and 2225 // farg_reg[] and their virtual halves. 2226 // We must include the virtual halves in order to get STDs and LDs 2227 // instead of STWs and LWs in the trampoline stubs. 2228 2229 if ( reg == R3_num || reg == R3_H_num 2230 || reg == R4_num || reg == R4_H_num 2231 || reg == R5_num || reg == R5_H_num 2232 || reg == R6_num || reg == R6_H_num 2233 || reg == R7_num || reg == R7_H_num 2234 || reg == R8_num || reg == R8_H_num 2235 || reg == R9_num || reg == R9_H_num 2236 || reg == R10_num || reg == R10_H_num) 2237 return true; 2238 2239 if ( reg == F1_num || reg == F1_H_num 2240 || reg == F2_num || reg == F2_H_num 2241 || reg == F3_num || reg == F3_H_num 2242 || reg == F4_num || reg == F4_H_num 2243 || reg == F5_num || reg == F5_H_num 2244 || reg == F6_num || reg == F6_H_num 2245 || reg == F7_num || reg == F7_H_num 2246 || reg == F8_num || reg == F8_H_num 2247 || reg == F9_num || reg == F9_H_num 2248 || reg == F10_num || reg == F10_H_num 2249 || reg == F11_num || reg == F11_H_num 2250 || reg == F12_num || reg == F12_H_num 2251 || reg == F13_num || reg == F13_H_num) 2252 return true; 2253 2254 return false; 2255 } 2256 2257 bool Matcher::is_spillable_arg(int reg) { 2258 return can_be_java_arg(reg); 2259 } 2260 2261 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2262 return false; 2263 } 2264 2265 // Register for DIVI projection of divmodI. 2266 RegMask Matcher::divI_proj_mask() { 2267 ShouldNotReachHere(); 2268 return RegMask(); 2269 } 2270 2271 // Register for MODI projection of divmodI. 2272 RegMask Matcher::modI_proj_mask() { 2273 ShouldNotReachHere(); 2274 return RegMask(); 2275 } 2276 2277 // Register for DIVL projection of divmodL. 2278 RegMask Matcher::divL_proj_mask() { 2279 ShouldNotReachHere(); 2280 return RegMask(); 2281 } 2282 2283 // Register for MODL projection of divmodL. 2284 RegMask Matcher::modL_proj_mask() { 2285 ShouldNotReachHere(); 2286 return RegMask(); 2287 } 2288 2289 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2290 return RegMask(); 2291 } 2292 2293 const bool Matcher::convi2l_type_required = true; 2294 2295 %} 2296 2297 //----------ENCODING BLOCK----------------------------------------------------- 2298 // This block specifies the encoding classes used by the compiler to output 2299 // byte streams. Encoding classes are parameterized macros used by 2300 // Machine Instruction Nodes in order to generate the bit encoding of the 2301 // instruction. Operands specify their base encoding interface with the 2302 // interface keyword. There are currently supported four interfaces, 2303 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an 2304 // operand to generate a function which returns its register number when 2305 // queried. CONST_INTER causes an operand to generate a function which 2306 // returns the value of the constant when queried. MEMORY_INTER causes an 2307 // operand to generate four functions which return the Base Register, the 2308 // Index Register, the Scale Value, and the Offset Value of the operand when 2309 // queried. COND_INTER causes an operand to generate six functions which 2310 // return the encoding code (ie - encoding bits for the instruction) 2311 // associated with each basic boolean condition for a conditional instruction. 2312 // 2313 // Instructions specify two basic values for encoding. Again, a function 2314 // is available to check if the constant displacement is an oop. They use the 2315 // ins_encode keyword to specify their encoding classes (which must be 2316 // a sequence of enc_class names, and their parameters, specified in 2317 // the encoding block), and they use the 2318 // opcode keyword to specify, in order, their primary, secondary, and 2319 // tertiary opcode. Only the opcode sections which a particular instruction 2320 // needs for encoding need to be specified. 2321 encode %{ 2322 enc_class enc_unimplemented %{ 2323 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2324 MacroAssembler _masm(&cbuf); 2325 __ unimplemented("Unimplemented mach node encoding in AD file.", 13); 2326 %} 2327 2328 enc_class enc_untested %{ 2329 #ifdef ASSERT 2330 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2331 MacroAssembler _masm(&cbuf); 2332 __ untested("Untested mach node encoding in AD file."); 2333 #else 2334 // TODO: PPC port $archOpcode(ppc64Opcode_none); 2335 #endif 2336 %} 2337 2338 enc_class enc_lbz(iRegIdst dst, memory mem) %{ 2339 // TODO: PPC port $archOpcode(ppc64Opcode_lbz); 2340 MacroAssembler _masm(&cbuf); 2341 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2342 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2343 %} 2344 2345 // Load acquire. 2346 enc_class enc_lbz_ac(iRegIdst dst, memory mem) %{ 2347 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2348 MacroAssembler _masm(&cbuf); 2349 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2350 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2351 __ twi_0($dst$$Register); 2352 __ isync(); 2353 %} 2354 2355 enc_class enc_lhz(iRegIdst dst, memory mem) %{ 2356 // TODO: PPC port $archOpcode(ppc64Opcode_lhz); 2357 2358 MacroAssembler _masm(&cbuf); 2359 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2360 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2361 %} 2362 2363 // Load acquire. 2364 enc_class enc_lhz_ac(iRegIdst dst, memory mem) %{ 2365 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2366 2367 MacroAssembler _masm(&cbuf); 2368 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2369 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2370 __ twi_0($dst$$Register); 2371 __ isync(); 2372 %} 2373 2374 enc_class enc_lwz(iRegIdst dst, memory mem) %{ 2375 // TODO: PPC port $archOpcode(ppc64Opcode_lwz); 2376 2377 MacroAssembler _masm(&cbuf); 2378 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2379 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2380 %} 2381 2382 // Load acquire. 2383 enc_class enc_lwz_ac(iRegIdst dst, memory mem) %{ 2384 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2385 2386 MacroAssembler _masm(&cbuf); 2387 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2388 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2389 __ twi_0($dst$$Register); 2390 __ isync(); 2391 %} 2392 2393 enc_class enc_ld(iRegLdst dst, memoryAlg4 mem) %{ 2394 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2395 MacroAssembler _masm(&cbuf); 2396 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2397 // Operand 'ds' requires 4-alignment. 2398 assert((Idisp & 0x3) == 0, "unaligned offset"); 2399 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2400 %} 2401 2402 // Load acquire. 2403 enc_class enc_ld_ac(iRegLdst dst, memoryAlg4 mem) %{ 2404 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2405 MacroAssembler _masm(&cbuf); 2406 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2407 // Operand 'ds' requires 4-alignment. 2408 assert((Idisp & 0x3) == 0, "unaligned offset"); 2409 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2410 __ twi_0($dst$$Register); 2411 __ isync(); 2412 %} 2413 2414 enc_class enc_lfd(RegF dst, memory mem) %{ 2415 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 2416 MacroAssembler _masm(&cbuf); 2417 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2418 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 2419 %} 2420 2421 enc_class enc_load_long_constL(iRegLdst dst, immL src, iRegLdst toc) %{ 2422 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2423 2424 MacroAssembler _masm(&cbuf); 2425 int toc_offset = 0; 2426 2427 if (!ra_->C->in_scratch_emit_size()) { 2428 address const_toc_addr; 2429 // Create a non-oop constant, no relocation needed. 2430 // If it is an IC, it has a virtual_call_Relocation. 2431 const_toc_addr = __ long_constant((jlong)$src$$constant); 2432 if (const_toc_addr == NULL) { 2433 ciEnv::current()->record_out_of_memory_failure(); 2434 return; 2435 } 2436 2437 // Get the constant's TOC offset. 2438 toc_offset = __ offset_to_method_toc(const_toc_addr); 2439 2440 // Keep the current instruction offset in mind. 2441 ((loadConLNode*)this)->_cbuf_insts_offset = __ offset(); 2442 } 2443 2444 __ ld($dst$$Register, toc_offset, $toc$$Register); 2445 %} 2446 2447 enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{ 2448 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 2449 2450 MacroAssembler _masm(&cbuf); 2451 2452 if (!ra_->C->in_scratch_emit_size()) { 2453 address const_toc_addr; 2454 // Create a non-oop constant, no relocation needed. 2455 // If it is an IC, it has a virtual_call_Relocation. 2456 const_toc_addr = __ long_constant((jlong)$src$$constant); 2457 if (const_toc_addr == NULL) { 2458 ciEnv::current()->record_out_of_memory_failure(); 2459 return; 2460 } 2461 2462 // Get the constant's TOC offset. 2463 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 2464 // Store the toc offset of the constant. 2465 ((loadConL_hiNode*)this)->_const_toc_offset = toc_offset; 2466 2467 // Also keep the current instruction offset in mind. 2468 ((loadConL_hiNode*)this)->_cbuf_insts_offset = __ offset(); 2469 } 2470 2471 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 2472 %} 2473 2474 %} // encode 2475 2476 source %{ 2477 2478 typedef struct { 2479 loadConL_hiNode *_large_hi; 2480 loadConL_loNode *_large_lo; 2481 loadConLNode *_small; 2482 MachNode *_last; 2483 } loadConLNodesTuple; 2484 2485 loadConLNodesTuple loadConLNodesTuple_create(PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2486 OptoReg::Name reg_second, OptoReg::Name reg_first) { 2487 loadConLNodesTuple nodes; 2488 2489 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2490 if (large_constant_pool) { 2491 // Create new nodes. 2492 loadConL_hiNode *m1 = new loadConL_hiNode(); 2493 loadConL_loNode *m2 = new loadConL_loNode(); 2494 2495 // inputs for new nodes 2496 m1->add_req(NULL, toc); 2497 m2->add_req(NULL, m1); 2498 2499 // operands for new nodes 2500 m1->_opnds[0] = new iRegLdstOper(); // dst 2501 m1->_opnds[1] = immSrc; // src 2502 m1->_opnds[2] = new iRegPdstOper(); // toc 2503 m2->_opnds[0] = new iRegLdstOper(); // dst 2504 m2->_opnds[1] = immSrc; // src 2505 m2->_opnds[2] = new iRegLdstOper(); // base 2506 2507 // Initialize ins_attrib TOC fields. 2508 m1->_const_toc_offset = -1; 2509 m2->_const_toc_offset_hi_node = m1; 2510 2511 // Initialize ins_attrib instruction offset. 2512 m1->_cbuf_insts_offset = -1; 2513 2514 // register allocation for new nodes 2515 ra_->set_pair(m1->_idx, reg_second, reg_first); 2516 ra_->set_pair(m2->_idx, reg_second, reg_first); 2517 2518 // Create result. 2519 nodes._large_hi = m1; 2520 nodes._large_lo = m2; 2521 nodes._small = NULL; 2522 nodes._last = nodes._large_lo; 2523 assert(m2->bottom_type()->isa_long(), "must be long"); 2524 } else { 2525 loadConLNode *m2 = new loadConLNode(); 2526 2527 // inputs for new nodes 2528 m2->add_req(NULL, toc); 2529 2530 // operands for new nodes 2531 m2->_opnds[0] = new iRegLdstOper(); // dst 2532 m2->_opnds[1] = immSrc; // src 2533 m2->_opnds[2] = new iRegPdstOper(); // toc 2534 2535 // Initialize ins_attrib instruction offset. 2536 m2->_cbuf_insts_offset = -1; 2537 2538 // register allocation for new nodes 2539 ra_->set_pair(m2->_idx, reg_second, reg_first); 2540 2541 // Create result. 2542 nodes._large_hi = NULL; 2543 nodes._large_lo = NULL; 2544 nodes._small = m2; 2545 nodes._last = nodes._small; 2546 assert(m2->bottom_type()->isa_long(), "must be long"); 2547 } 2548 2549 return nodes; 2550 } 2551 2552 %} // source 2553 2554 encode %{ 2555 // Postalloc expand emitter for loading a long constant from the method's TOC. 2556 // Enc_class needed as consttanttablebase is not supported by postalloc 2557 // expand. 2558 enc_class postalloc_expand_load_long_constant(iRegLdst dst, immL src, iRegLdst toc) %{ 2559 // Create new nodes. 2560 loadConLNodesTuple loadConLNodes = 2561 loadConLNodesTuple_create(ra_, n_toc, op_src, 2562 ra_->get_reg_second(this), ra_->get_reg_first(this)); 2563 2564 // Push new nodes. 2565 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 2566 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 2567 2568 // some asserts 2569 assert(nodes->length() >= 1, "must have created at least 1 node"); 2570 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 2571 %} 2572 2573 enc_class enc_load_long_constP(iRegLdst dst, immP src, iRegLdst toc) %{ 2574 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2575 2576 MacroAssembler _masm(&cbuf); 2577 int toc_offset = 0; 2578 2579 if (!ra_->C->in_scratch_emit_size()) { 2580 intptr_t val = $src$$constant; 2581 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 2582 address const_toc_addr; 2583 if (constant_reloc == relocInfo::oop_type) { 2584 // Create an oop constant and a corresponding relocation. 2585 AddressLiteral a = __ allocate_oop_address((jobject)val); 2586 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2587 __ relocate(a.rspec()); 2588 } else if (constant_reloc == relocInfo::metadata_type) { 2589 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 2590 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2591 __ relocate(a.rspec()); 2592 } else { 2593 // Create a non-oop constant, no relocation needed. 2594 const_toc_addr = __ long_constant((jlong)$src$$constant); 2595 } 2596 2597 if (const_toc_addr == NULL) { 2598 ciEnv::current()->record_out_of_memory_failure(); 2599 return; 2600 } 2601 // Get the constant's TOC offset. 2602 toc_offset = __ offset_to_method_toc(const_toc_addr); 2603 } 2604 2605 __ ld($dst$$Register, toc_offset, $toc$$Register); 2606 %} 2607 2608 enc_class enc_load_long_constP_hi(iRegLdst dst, immP src, iRegLdst toc) %{ 2609 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 2610 2611 MacroAssembler _masm(&cbuf); 2612 if (!ra_->C->in_scratch_emit_size()) { 2613 intptr_t val = $src$$constant; 2614 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 2615 address const_toc_addr; 2616 if (constant_reloc == relocInfo::oop_type) { 2617 // Create an oop constant and a corresponding relocation. 2618 AddressLiteral a = __ allocate_oop_address((jobject)val); 2619 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2620 __ relocate(a.rspec()); 2621 } else if (constant_reloc == relocInfo::metadata_type) { 2622 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 2623 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2624 __ relocate(a.rspec()); 2625 } else { // non-oop pointers, e.g. card mark base, heap top 2626 // Create a non-oop constant, no relocation needed. 2627 const_toc_addr = __ long_constant((jlong)$src$$constant); 2628 } 2629 2630 if (const_toc_addr == NULL) { 2631 ciEnv::current()->record_out_of_memory_failure(); 2632 return; 2633 } 2634 // Get the constant's TOC offset. 2635 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 2636 // Store the toc offset of the constant. 2637 ((loadConP_hiNode*)this)->_const_toc_offset = toc_offset; 2638 } 2639 2640 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 2641 %} 2642 2643 // Postalloc expand emitter for loading a ptr constant from the method's TOC. 2644 // Enc_class needed as consttanttablebase is not supported by postalloc 2645 // expand. 2646 enc_class postalloc_expand_load_ptr_constant(iRegPdst dst, immP src, iRegLdst toc) %{ 2647 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2648 if (large_constant_pool) { 2649 // Create new nodes. 2650 loadConP_hiNode *m1 = new loadConP_hiNode(); 2651 loadConP_loNode *m2 = new loadConP_loNode(); 2652 2653 // inputs for new nodes 2654 m1->add_req(NULL, n_toc); 2655 m2->add_req(NULL, m1); 2656 2657 // operands for new nodes 2658 m1->_opnds[0] = new iRegPdstOper(); // dst 2659 m1->_opnds[1] = op_src; // src 2660 m1->_opnds[2] = new iRegPdstOper(); // toc 2661 m2->_opnds[0] = new iRegPdstOper(); // dst 2662 m2->_opnds[1] = op_src; // src 2663 m2->_opnds[2] = new iRegLdstOper(); // base 2664 2665 // Initialize ins_attrib TOC fields. 2666 m1->_const_toc_offset = -1; 2667 m2->_const_toc_offset_hi_node = m1; 2668 2669 // Register allocation for new nodes. 2670 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2671 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2672 2673 nodes->push(m1); 2674 nodes->push(m2); 2675 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 2676 } else { 2677 loadConPNode *m2 = new loadConPNode(); 2678 2679 // inputs for new nodes 2680 m2->add_req(NULL, n_toc); 2681 2682 // operands for new nodes 2683 m2->_opnds[0] = new iRegPdstOper(); // dst 2684 m2->_opnds[1] = op_src; // src 2685 m2->_opnds[2] = new iRegPdstOper(); // toc 2686 2687 // Register allocation for new nodes. 2688 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2689 2690 nodes->push(m2); 2691 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 2692 } 2693 %} 2694 2695 // Enc_class needed as consttanttablebase is not supported by postalloc 2696 // expand. 2697 enc_class postalloc_expand_load_float_constant(regF dst, immF src, iRegLdst toc) %{ 2698 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2699 2700 MachNode *m2; 2701 if (large_constant_pool) { 2702 m2 = new loadConFCompNode(); 2703 } else { 2704 m2 = new loadConFNode(); 2705 } 2706 // inputs for new nodes 2707 m2->add_req(NULL, n_toc); 2708 2709 // operands for new nodes 2710 m2->_opnds[0] = op_dst; 2711 m2->_opnds[1] = op_src; 2712 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 2713 2714 // register allocation for new nodes 2715 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2716 nodes->push(m2); 2717 %} 2718 2719 // Enc_class needed as consttanttablebase is not supported by postalloc 2720 // expand. 2721 enc_class postalloc_expand_load_double_constant(regD dst, immD src, iRegLdst toc) %{ 2722 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2723 2724 MachNode *m2; 2725 if (large_constant_pool) { 2726 m2 = new loadConDCompNode(); 2727 } else { 2728 m2 = new loadConDNode(); 2729 } 2730 // inputs for new nodes 2731 m2->add_req(NULL, n_toc); 2732 2733 // operands for new nodes 2734 m2->_opnds[0] = op_dst; 2735 m2->_opnds[1] = op_src; 2736 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 2737 2738 // register allocation for new nodes 2739 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2740 nodes->push(m2); 2741 %} 2742 2743 enc_class enc_stw(iRegIsrc src, memory mem) %{ 2744 // TODO: PPC port $archOpcode(ppc64Opcode_stw); 2745 MacroAssembler _masm(&cbuf); 2746 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2747 __ stw($src$$Register, Idisp, $mem$$base$$Register); 2748 %} 2749 2750 enc_class enc_std(iRegIsrc src, memoryAlg4 mem) %{ 2751 // TODO: PPC port $archOpcode(ppc64Opcode_std); 2752 MacroAssembler _masm(&cbuf); 2753 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2754 // Operand 'ds' requires 4-alignment. 2755 assert((Idisp & 0x3) == 0, "unaligned offset"); 2756 __ std($src$$Register, Idisp, $mem$$base$$Register); 2757 %} 2758 2759 enc_class enc_stfs(RegF src, memory mem) %{ 2760 // TODO: PPC port $archOpcode(ppc64Opcode_stfs); 2761 MacroAssembler _masm(&cbuf); 2762 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2763 __ stfs($src$$FloatRegister, Idisp, $mem$$base$$Register); 2764 %} 2765 2766 enc_class enc_stfd(RegF src, memory mem) %{ 2767 // TODO: PPC port $archOpcode(ppc64Opcode_stfd); 2768 MacroAssembler _masm(&cbuf); 2769 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2770 __ stfd($src$$FloatRegister, Idisp, $mem$$base$$Register); 2771 %} 2772 2773 // Use release_store for card-marking to ensure that previous 2774 // oop-stores are visible before the card-mark change. 2775 enc_class enc_cms_card_mark(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 2776 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2777 // FIXME: Implement this as a cmove and use a fixed condition code 2778 // register which is written on every transition to compiled code, 2779 // e.g. in call-stub and when returning from runtime stubs. 2780 // 2781 // Proposed code sequence for the cmove implementation: 2782 // 2783 // Label skip_release; 2784 // __ beq(CCRfixed, skip_release); 2785 // __ release(); 2786 // __ bind(skip_release); 2787 // __ stb(card mark); 2788 2789 MacroAssembler _masm(&cbuf); 2790 Label skip_storestore; 2791 2792 #if 0 // TODO: PPC port 2793 // Check CMSCollectorCardTableModRefBSExt::_requires_release and do the 2794 // StoreStore barrier conditionally. 2795 __ lwz(R0, 0, $releaseFieldAddr$$Register); 2796 __ cmpwi($crx$$CondRegister, R0, 0); 2797 __ beq_predict_taken($crx$$CondRegister, skip_storestore); 2798 #endif 2799 __ li(R0, 0); 2800 __ membar(Assembler::StoreStore); 2801 #if 0 // TODO: PPC port 2802 __ bind(skip_storestore); 2803 #endif 2804 2805 // Do the store. 2806 if ($mem$$index == 0) { 2807 __ stb(R0, $mem$$disp, $mem$$base$$Register); 2808 } else { 2809 assert(0 == $mem$$disp, "no displacement possible with indexed load/stores on ppc"); 2810 __ stbx(R0, $mem$$base$$Register, $mem$$index$$Register); 2811 } 2812 %} 2813 2814 enc_class postalloc_expand_encode_oop(iRegNdst dst, iRegPdst src, flagsReg crx) %{ 2815 2816 if (VM_Version::has_isel()) { 2817 // use isel instruction with Power 7 2818 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 2819 encodeP_subNode *n_sub_base = new encodeP_subNode(); 2820 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 2821 cond_set_0_oopNode *n_cond_set = new cond_set_0_oopNode(); 2822 2823 n_compare->add_req(n_region, n_src); 2824 n_compare->_opnds[0] = op_crx; 2825 n_compare->_opnds[1] = op_src; 2826 n_compare->_opnds[2] = new immL16Oper(0); 2827 2828 n_sub_base->add_req(n_region, n_src); 2829 n_sub_base->_opnds[0] = op_dst; 2830 n_sub_base->_opnds[1] = op_src; 2831 n_sub_base->_bottom_type = _bottom_type; 2832 2833 n_shift->add_req(n_region, n_sub_base); 2834 n_shift->_opnds[0] = op_dst; 2835 n_shift->_opnds[1] = op_dst; 2836 n_shift->_bottom_type = _bottom_type; 2837 2838 n_cond_set->add_req(n_region, n_compare, n_shift); 2839 n_cond_set->_opnds[0] = op_dst; 2840 n_cond_set->_opnds[1] = op_crx; 2841 n_cond_set->_opnds[2] = op_dst; 2842 n_cond_set->_bottom_type = _bottom_type; 2843 2844 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 2845 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2846 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2847 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2848 2849 nodes->push(n_compare); 2850 nodes->push(n_sub_base); 2851 nodes->push(n_shift); 2852 nodes->push(n_cond_set); 2853 2854 } else { 2855 // before Power 7 2856 moveRegNode *n_move = new moveRegNode(); 2857 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 2858 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 2859 cond_sub_baseNode *n_sub_base = new cond_sub_baseNode(); 2860 2861 n_move->add_req(n_region, n_src); 2862 n_move->_opnds[0] = op_dst; 2863 n_move->_opnds[1] = op_src; 2864 ra_->set_oop(n_move, true); // Until here, 'n_move' still produces an oop. 2865 2866 n_compare->add_req(n_region, n_src); 2867 n_compare->add_prec(n_move); 2868 2869 n_compare->_opnds[0] = op_crx; 2870 n_compare->_opnds[1] = op_src; 2871 n_compare->_opnds[2] = new immL16Oper(0); 2872 2873 n_sub_base->add_req(n_region, n_compare, n_src); 2874 n_sub_base->_opnds[0] = op_dst; 2875 n_sub_base->_opnds[1] = op_crx; 2876 n_sub_base->_opnds[2] = op_src; 2877 n_sub_base->_bottom_type = _bottom_type; 2878 2879 n_shift->add_req(n_region, n_sub_base); 2880 n_shift->_opnds[0] = op_dst; 2881 n_shift->_opnds[1] = op_dst; 2882 n_shift->_bottom_type = _bottom_type; 2883 2884 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2885 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 2886 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2887 ra_->set_pair(n_move->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2888 2889 nodes->push(n_move); 2890 nodes->push(n_compare); 2891 nodes->push(n_sub_base); 2892 nodes->push(n_shift); 2893 } 2894 2895 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 2896 %} 2897 2898 enc_class postalloc_expand_encode_oop_not_null(iRegNdst dst, iRegPdst src) %{ 2899 2900 encodeP_subNode *n1 = new encodeP_subNode(); 2901 n1->add_req(n_region, n_src); 2902 n1->_opnds[0] = op_dst; 2903 n1->_opnds[1] = op_src; 2904 n1->_bottom_type = _bottom_type; 2905 2906 encodeP_shiftNode *n2 = new encodeP_shiftNode(); 2907 n2->add_req(n_region, n1); 2908 n2->_opnds[0] = op_dst; 2909 n2->_opnds[1] = op_dst; 2910 n2->_bottom_type = _bottom_type; 2911 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2912 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2913 2914 nodes->push(n1); 2915 nodes->push(n2); 2916 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 2917 %} 2918 2919 enc_class postalloc_expand_decode_oop(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 2920 decodeN_shiftNode *n_shift = new decodeN_shiftNode(); 2921 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 2922 2923 n_compare->add_req(n_region, n_src); 2924 n_compare->_opnds[0] = op_crx; 2925 n_compare->_opnds[1] = op_src; 2926 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 2927 2928 n_shift->add_req(n_region, n_src); 2929 n_shift->_opnds[0] = op_dst; 2930 n_shift->_opnds[1] = op_src; 2931 n_shift->_bottom_type = _bottom_type; 2932 2933 if (VM_Version::has_isel()) { 2934 // use isel instruction with Power 7 2935 2936 decodeN_addNode *n_add_base = new decodeN_addNode(); 2937 n_add_base->add_req(n_region, n_shift); 2938 n_add_base->_opnds[0] = op_dst; 2939 n_add_base->_opnds[1] = op_dst; 2940 n_add_base->_bottom_type = _bottom_type; 2941 2942 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 2943 n_cond_set->add_req(n_region, n_compare, n_add_base); 2944 n_cond_set->_opnds[0] = op_dst; 2945 n_cond_set->_opnds[1] = op_crx; 2946 n_cond_set->_opnds[2] = op_dst; 2947 n_cond_set->_bottom_type = _bottom_type; 2948 2949 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 2950 ra_->set_oop(n_cond_set, true); 2951 2952 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2953 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 2954 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2955 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2956 2957 nodes->push(n_compare); 2958 nodes->push(n_shift); 2959 nodes->push(n_add_base); 2960 nodes->push(n_cond_set); 2961 2962 } else { 2963 // before Power 7 2964 cond_add_baseNode *n_add_base = new cond_add_baseNode(); 2965 2966 n_add_base->add_req(n_region, n_compare, n_shift); 2967 n_add_base->_opnds[0] = op_dst; 2968 n_add_base->_opnds[1] = op_crx; 2969 n_add_base->_opnds[2] = op_dst; 2970 n_add_base->_bottom_type = _bottom_type; 2971 2972 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 2973 ra_->set_oop(n_add_base, true); 2974 2975 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2976 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 2977 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2978 2979 nodes->push(n_compare); 2980 nodes->push(n_shift); 2981 nodes->push(n_add_base); 2982 } 2983 %} 2984 2985 enc_class postalloc_expand_decode_oop_not_null(iRegPdst dst, iRegNsrc src) %{ 2986 decodeN_shiftNode *n1 = new decodeN_shiftNode(); 2987 n1->add_req(n_region, n_src); 2988 n1->_opnds[0] = op_dst; 2989 n1->_opnds[1] = op_src; 2990 n1->_bottom_type = _bottom_type; 2991 2992 decodeN_addNode *n2 = new decodeN_addNode(); 2993 n2->add_req(n_region, n1); 2994 n2->_opnds[0] = op_dst; 2995 n2->_opnds[1] = op_dst; 2996 n2->_bottom_type = _bottom_type; 2997 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2998 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2999 3000 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3001 ra_->set_oop(n2, true); 3002 3003 nodes->push(n1); 3004 nodes->push(n2); 3005 %} 3006 3007 enc_class enc_cmove_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src, cmpOp cmp) %{ 3008 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3009 3010 MacroAssembler _masm(&cbuf); 3011 int cc = $cmp$$cmpcode; 3012 int flags_reg = $crx$$reg; 3013 Label done; 3014 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3015 // Branch if not (cmp crx). 3016 __ bc(cc_to_inverse_boint(cc), cc_to_biint(cc, flags_reg), done); 3017 __ mr($dst$$Register, $src$$Register); 3018 // TODO PPC port __ endgroup_if_needed(_size == 12); 3019 __ bind(done); 3020 %} 3021 3022 enc_class enc_cmove_imm(iRegIdst dst, flagsRegSrc crx, immI16 src, cmpOp cmp) %{ 3023 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3024 3025 MacroAssembler _masm(&cbuf); 3026 Label done; 3027 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3028 // Branch if not (cmp crx). 3029 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 3030 __ li($dst$$Register, $src$$constant); 3031 // TODO PPC port __ endgroup_if_needed(_size == 12); 3032 __ bind(done); 3033 %} 3034 3035 // This enc_class is needed so that scheduler gets proper 3036 // input mapping for latency computation. 3037 enc_class enc_andc(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 3038 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 3039 MacroAssembler _masm(&cbuf); 3040 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 3041 %} 3042 3043 enc_class enc_convI2B_regI__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3044 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3045 3046 MacroAssembler _masm(&cbuf); 3047 3048 Label done; 3049 __ cmpwi($crx$$CondRegister, $src$$Register, 0); 3050 __ li($dst$$Register, $zero$$constant); 3051 __ beq($crx$$CondRegister, done); 3052 __ li($dst$$Register, $notzero$$constant); 3053 __ bind(done); 3054 %} 3055 3056 enc_class enc_convP2B_regP__cmove(iRegIdst dst, iRegPsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3057 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3058 3059 MacroAssembler _masm(&cbuf); 3060 3061 Label done; 3062 __ cmpdi($crx$$CondRegister, $src$$Register, 0); 3063 __ li($dst$$Register, $zero$$constant); 3064 __ beq($crx$$CondRegister, done); 3065 __ li($dst$$Register, $notzero$$constant); 3066 __ bind(done); 3067 %} 3068 3069 enc_class enc_cmove_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL mem ) %{ 3070 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3071 3072 MacroAssembler _masm(&cbuf); 3073 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3074 Label done; 3075 __ bso($crx$$CondRegister, done); 3076 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 3077 // TODO PPC port __ endgroup_if_needed(_size == 12); 3078 __ bind(done); 3079 %} 3080 3081 enc_class enc_bc(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3082 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3083 3084 MacroAssembler _masm(&cbuf); 3085 Label d; // dummy 3086 __ bind(d); 3087 Label* p = ($lbl$$label); 3088 // `p' is `NULL' when this encoding class is used only to 3089 // determine the size of the encoded instruction. 3090 Label& l = (NULL == p)? d : *(p); 3091 int cc = $cmp$$cmpcode; 3092 int flags_reg = $crx$$reg; 3093 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3094 int bhint = Assembler::bhintNoHint; 3095 3096 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3097 if (_prob <= PROB_NEVER) { 3098 bhint = Assembler::bhintIsNotTaken; 3099 } else if (_prob >= PROB_ALWAYS) { 3100 bhint = Assembler::bhintIsTaken; 3101 } 3102 } 3103 3104 __ bc(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3105 cc_to_biint(cc, flags_reg), 3106 l); 3107 %} 3108 3109 enc_class enc_bc_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3110 // The scheduler doesn't know about branch shortening, so we set the opcode 3111 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3112 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3113 3114 MacroAssembler _masm(&cbuf); 3115 Label d; // dummy 3116 __ bind(d); 3117 Label* p = ($lbl$$label); 3118 // `p' is `NULL' when this encoding class is used only to 3119 // determine the size of the encoded instruction. 3120 Label& l = (NULL == p)? d : *(p); 3121 int cc = $cmp$$cmpcode; 3122 int flags_reg = $crx$$reg; 3123 int bhint = Assembler::bhintNoHint; 3124 3125 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3126 if (_prob <= PROB_NEVER) { 3127 bhint = Assembler::bhintIsNotTaken; 3128 } else if (_prob >= PROB_ALWAYS) { 3129 bhint = Assembler::bhintIsTaken; 3130 } 3131 } 3132 3133 // Tell the conditional far branch to optimize itself when being relocated. 3134 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3135 cc_to_biint(cc, flags_reg), 3136 l, 3137 MacroAssembler::bc_far_optimize_on_relocate); 3138 %} 3139 3140 // Branch used with Power6 scheduling (can be shortened without changing the node). 3141 enc_class enc_bc_short_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3142 // The scheduler doesn't know about branch shortening, so we set the opcode 3143 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3144 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3145 3146 MacroAssembler _masm(&cbuf); 3147 Label d; // dummy 3148 __ bind(d); 3149 Label* p = ($lbl$$label); 3150 // `p' is `NULL' when this encoding class is used only to 3151 // determine the size of the encoded instruction. 3152 Label& l = (NULL == p)? d : *(p); 3153 int cc = $cmp$$cmpcode; 3154 int flags_reg = $crx$$reg; 3155 int bhint = Assembler::bhintNoHint; 3156 3157 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3158 if (_prob <= PROB_NEVER) { 3159 bhint = Assembler::bhintIsNotTaken; 3160 } else if (_prob >= PROB_ALWAYS) { 3161 bhint = Assembler::bhintIsTaken; 3162 } 3163 } 3164 3165 #if 0 // TODO: PPC port 3166 if (_size == 8) { 3167 // Tell the conditional far branch to optimize itself when being relocated. 3168 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3169 cc_to_biint(cc, flags_reg), 3170 l, 3171 MacroAssembler::bc_far_optimize_on_relocate); 3172 } else { 3173 __ bc (Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3174 cc_to_biint(cc, flags_reg), 3175 l); 3176 } 3177 #endif 3178 Unimplemented(); 3179 %} 3180 3181 // Postalloc expand emitter for loading a replicatef float constant from 3182 // the method's TOC. 3183 // Enc_class needed as consttanttablebase is not supported by postalloc 3184 // expand. 3185 enc_class postalloc_expand_load_replF_constant(iRegLdst dst, immF src, iRegLdst toc) %{ 3186 // Create new nodes. 3187 3188 // Make an operand with the bit pattern to load as float. 3189 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3190 3191 loadConLNodesTuple loadConLNodes = 3192 loadConLNodesTuple_create(ra_, n_toc, op_repl, 3193 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3194 3195 // Push new nodes. 3196 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 3197 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 3198 3199 assert(nodes->length() >= 1, "must have created at least 1 node"); 3200 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 3201 %} 3202 3203 // This enc_class is needed so that scheduler gets proper 3204 // input mapping for latency computation. 3205 enc_class enc_poll(immI dst, iRegLdst poll) %{ 3206 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 3207 // Fake operand dst needed for PPC scheduler. 3208 assert($dst$$constant == 0x0, "dst must be 0x0"); 3209 3210 MacroAssembler _masm(&cbuf); 3211 // Mark the code position where the load from the safepoint 3212 // polling page was emitted as relocInfo::poll_type. 3213 __ relocate(relocInfo::poll_type); 3214 __ load_from_polling_page($poll$$Register); 3215 %} 3216 3217 // A Java static call or a runtime call. 3218 // 3219 // Branch-and-link relative to a trampoline. 3220 // The trampoline loads the target address and does a long branch to there. 3221 // In case we call java, the trampoline branches to a interpreter_stub 3222 // which loads the inline cache and the real call target from the constant pool. 3223 // 3224 // This basically looks like this: 3225 // 3226 // >>>> consts -+ -+ 3227 // | |- offset1 3228 // [call target1] | <-+ 3229 // [IC cache] |- offset2 3230 // [call target2] <--+ 3231 // 3232 // <<<< consts 3233 // >>>> insts 3234 // 3235 // bl offset16 -+ -+ ??? // How many bits available? 3236 // | | 3237 // <<<< insts | | 3238 // >>>> stubs | | 3239 // | |- trampoline_stub_Reloc 3240 // trampoline stub: | <-+ 3241 // r2 = toc | 3242 // r2 = [r2 + offset1] | // Load call target1 from const section 3243 // mtctr r2 | 3244 // bctr |- static_stub_Reloc 3245 // comp_to_interp_stub: <---+ 3246 // r1 = toc 3247 // ICreg = [r1 + IC_offset] // Load IC from const section 3248 // r1 = [r1 + offset2] // Load call target2 from const section 3249 // mtctr r1 3250 // bctr 3251 // 3252 // <<<< stubs 3253 // 3254 // The call instruction in the code either 3255 // - Branches directly to a compiled method if the offset is encodable in instruction. 3256 // - Branches to the trampoline stub if the offset to the compiled method is not encodable. 3257 // - Branches to the compiled_to_interp stub if the target is interpreted. 3258 // 3259 // Further there are three relocations from the loads to the constants in 3260 // the constant section. 3261 // 3262 // Usage of r1 and r2 in the stubs allows to distinguish them. 3263 enc_class enc_java_static_call(method meth) %{ 3264 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3265 3266 MacroAssembler _masm(&cbuf); 3267 address entry_point = (address)$meth$$method; 3268 3269 if (!_method) { 3270 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3271 emit_call_with_trampoline_stub(_masm, entry_point, relocInfo::runtime_call_type); 3272 } else { 3273 // Remember the offset not the address. 3274 const int start_offset = __ offset(); 3275 // The trampoline stub. 3276 if (!Compile::current()->in_scratch_emit_size()) { 3277 // No entry point given, use the current pc. 3278 // Make sure branch fits into 3279 if (entry_point == 0) entry_point = __ pc(); 3280 3281 // Put the entry point as a constant into the constant pool. 3282 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 3283 if (entry_point_toc_addr == NULL) { 3284 ciEnv::current()->record_out_of_memory_failure(); 3285 return; 3286 } 3287 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 3288 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 3298 // The real call. 3299 // Note: At this point we do not have the address of the trampoline 3300 // stub, and the entry point might be too far away for bl, so __ pc() 3301 // serves as dummy and the bl will be patched later. 3302 cbuf.set_insts_mark(); 3303 __ bl(__ pc()); // Emits a relocation. 3304 3305 // The stub for call to interpreter. 3306 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); 3307 if (stub == NULL) { 3308 ciEnv::current()->record_failure("CodeCache is full"); 3309 return; 3310 } 3311 } 3312 %} 3313 3314 // Second node of expanded dynamic call - the call. 3315 enc_class enc_java_dynamic_call_sched(method meth) %{ 3316 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3317 3318 MacroAssembler _masm(&cbuf); 3319 3320 if (!ra_->C->in_scratch_emit_size()) { 3321 // Create a call trampoline stub for the given method. 3322 const address entry_point = !($meth$$method) ? 0 : (address)$meth$$method; 3323 const address entry_point_const = __ address_constant(entry_point, RelocationHolder::none); 3324 if (entry_point_const == NULL) { 3325 ciEnv::current()->record_out_of_memory_failure(); 3326 return; 3327 } 3328 const int entry_point_const_toc_offset = __ offset_to_method_toc(entry_point_const); 3329 CallStubImpl::emit_trampoline_stub(_masm, entry_point_const_toc_offset, __ offset()); 3330 if (ra_->C->env()->failing()) { return; } // Code cache may be full. 3331 3332 // Build relocation at call site with ic position as data. 3333 assert((_load_ic_hi_node != NULL && _load_ic_node == NULL) || 3334 (_load_ic_hi_node == NULL && _load_ic_node != NULL), 3335 "must have one, but can't have both"); 3336 assert((_load_ic_hi_node != NULL && _load_ic_hi_node->_cbuf_insts_offset != -1) || 3337 (_load_ic_node != NULL && _load_ic_node->_cbuf_insts_offset != -1), 3338 "must contain instruction offset"); 3339 const int virtual_call_oop_addr_offset = _load_ic_hi_node != NULL 3340 ? _load_ic_hi_node->_cbuf_insts_offset 3341 : _load_ic_node->_cbuf_insts_offset; 3342 const address virtual_call_oop_addr = __ addr_at(virtual_call_oop_addr_offset); 3343 assert(MacroAssembler::is_load_const_from_method_toc_at(virtual_call_oop_addr), 3344 "should be load from TOC"); 3345 int method_index = resolved_method_index(cbuf); 3346 __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr, method_index)); 3347 } 3348 3349 // At this point I do not have the address of the trampoline stub, 3350 // and the entry point might be too far away for bl. Pc() serves 3351 // as dummy and bl will be patched later. 3352 __ bl((address) __ pc()); 3353 %} 3354 3355 // postalloc expand emitter for virtual calls. 3356 enc_class postalloc_expand_java_dynamic_call_sched(method meth, iRegLdst toc) %{ 3357 3358 // Create the nodes for loading the IC from the TOC. 3359 loadConLNodesTuple loadConLNodes_IC = 3360 loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong)Universe::non_oop_word()), 3361 OptoReg::Name(R19_H_num), OptoReg::Name(R19_num)); 3362 3363 // Create the call node. 3364 CallDynamicJavaDirectSchedNode *call = new CallDynamicJavaDirectSchedNode(); 3365 call->_method_handle_invoke = _method_handle_invoke; 3366 call->_vtable_index = _vtable_index; 3367 call->_method = _method; 3368 call->_bci = _bci; 3369 call->_optimized_virtual = _optimized_virtual; 3370 call->_tf = _tf; 3371 call->_entry_point = _entry_point; 3372 call->_cnt = _cnt; 3373 call->_argsize = _argsize; 3374 call->_oop_map = _oop_map; 3375 call->_jvms = _jvms; 3376 call->_jvmadj = _jvmadj; 3377 call->_in_rms = _in_rms; 3378 call->_nesting = _nesting; 3379 call->_override_symbolic_info = _override_symbolic_info; 3380 3381 // New call needs all inputs of old call. 3382 // Req... 3383 for (uint i = 0; i < req(); ++i) { 3384 // The expanded node does not need toc any more. 3385 // Add the inline cache constant here instead. This expresses the 3386 // register of the inline cache must be live at the call. 3387 // Else we would have to adapt JVMState by -1. 3388 if (i == mach_constant_base_node_input()) { 3389 call->add_req(loadConLNodes_IC._last); 3390 } else { 3391 call->add_req(in(i)); 3392 } 3393 } 3394 // ...as well as prec 3395 for (uint i = req(); i < len(); ++i) { 3396 call->add_prec(in(i)); 3397 } 3398 3399 // Remember nodes loading the inline cache into r19. 3400 call->_load_ic_hi_node = loadConLNodes_IC._large_hi; 3401 call->_load_ic_node = loadConLNodes_IC._small; 3402 3403 // Operands for new nodes. 3404 call->_opnds[0] = _opnds[0]; 3405 call->_opnds[1] = _opnds[1]; 3406 3407 // Only the inline cache is associated with a register. 3408 assert(Matcher::inline_cache_reg() == OptoReg::Name(R19_num), "ic reg should be R19"); 3409 3410 // Push new nodes. 3411 if (loadConLNodes_IC._large_hi) nodes->push(loadConLNodes_IC._large_hi); 3412 if (loadConLNodes_IC._last) nodes->push(loadConLNodes_IC._last); 3413 nodes->push(call); 3414 %} 3415 3416 // Compound version of call dynamic 3417 // Toc is only passed so that it can be used in ins_encode statement. 3418 // In the code we have to use $constanttablebase. 3419 enc_class enc_java_dynamic_call(method meth, iRegLdst toc) %{ 3420 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3421 MacroAssembler _masm(&cbuf); 3422 int start_offset = __ offset(); 3423 3424 Register Rtoc = (ra_) ? $constanttablebase : R2_TOC; 3425 #if 0 3426 int vtable_index = this->_vtable_index; 3427 if (_vtable_index < 0) { 3428 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 3429 assert(_vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 3430 Register ic_reg = as_Register(Matcher::inline_cache_reg_encode()); 3431 3432 // Virtual call relocation will point to ic load. 3433 address virtual_call_meta_addr = __ pc(); 3434 // Load a clear inline cache. 3435 AddressLiteral empty_ic((address) Universe::non_oop_word()); 3436 bool success = __ load_const_from_method_toc(ic_reg, empty_ic, Rtoc, /*fixed_size*/ true); 3437 if (!success) { 3438 ciEnv::current()->record_out_of_memory_failure(); 3439 return; 3440 } 3441 // CALL to fixup routine. Fixup routine uses ScopeDesc info 3442 // to determine who we intended to call. 3443 __ relocate(virtual_call_Relocation::spec(virtual_call_meta_addr)); 3444 emit_call_with_trampoline_stub(_masm, (address)$meth$$method, relocInfo::none); 3445 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3446 "Fix constant in ret_addr_offset()"); 3447 } else { 3448 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 3449 // Go thru the vtable. Get receiver klass. Receiver already 3450 // checked for non-null. If we'll go thru a C2I adapter, the 3451 // interpreter expects method in R19_method. 3452 3453 __ load_klass(R11_scratch1, R3); 3454 3455 int entry_offset = in_bytes(Klass::vtable_start_offset()) + _vtable_index * vtableEntry::size_in_bytes(); 3456 int v_off = entry_offset + vtableEntry::method_offset_in_bytes(); 3457 __ li(R19_method, v_off); 3458 __ ldx(R19_method/*method oop*/, R19_method/*method offset*/, R11_scratch1/*class*/); 3459 // NOTE: for vtable dispatches, the vtable entry will never be 3460 // null. However it may very well end up in handle_wrong_method 3461 // if the method is abstract for the particular class. 3462 __ ld(R11_scratch1, in_bytes(Method::from_compiled_offset()), R19_method); 3463 // Call target. Either compiled code or C2I adapter. 3464 __ mtctr(R11_scratch1); 3465 __ bctrl(); 3466 if (((MachCallDynamicJavaNode*)this)->ret_addr_offset() != __ offset() - start_offset) { 3467 tty->print(" %d, %d\n", ((MachCallDynamicJavaNode*)this)->ret_addr_offset(),__ offset() - start_offset); 3468 } 3469 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3470 "Fix constant in ret_addr_offset()"); 3471 } 3472 #endif 3473 Unimplemented(); // ret_addr_offset not yet fixed. Depends on compressed oops (load klass!). 3474 %} 3475 3476 // a runtime call 3477 enc_class enc_java_to_runtime_call (method meth) %{ 3478 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3479 3480 MacroAssembler _masm(&cbuf); 3481 const address start_pc = __ pc(); 3482 3483 #if defined(ABI_ELFv2) 3484 address entry= !($meth$$method) ? NULL : (address)$meth$$method; 3485 __ call_c(entry, relocInfo::runtime_call_type); 3486 #else 3487 // The function we're going to call. 3488 FunctionDescriptor fdtemp; 3489 const FunctionDescriptor* fd = !($meth$$method) ? &fdtemp : (FunctionDescriptor*)$meth$$method; 3490 3491 Register Rtoc = R12_scratch2; 3492 // Calculate the method's TOC. 3493 __ calculate_address_from_global_toc(Rtoc, __ method_toc()); 3494 // Put entry, env, toc into the constant pool, this needs up to 3 constant 3495 // pool entries; call_c_using_toc will optimize the call. 3496 bool success = __ call_c_using_toc(fd, relocInfo::runtime_call_type, Rtoc); 3497 if (!success) { 3498 ciEnv::current()->record_out_of_memory_failure(); 3499 return; 3500 } 3501 #endif 3502 3503 // Check the ret_addr_offset. 3504 assert(((MachCallRuntimeNode*)this)->ret_addr_offset() == __ last_calls_return_pc() - start_pc, 3505 "Fix constant in ret_addr_offset()"); 3506 %} 3507 3508 // Move to ctr for leaf call. 3509 // This enc_class is needed so that scheduler gets proper 3510 // input mapping for latency computation. 3511 enc_class enc_leaf_call_mtctr(iRegLsrc src) %{ 3512 // TODO: PPC port $archOpcode(ppc64Opcode_mtctr); 3513 MacroAssembler _masm(&cbuf); 3514 __ mtctr($src$$Register); 3515 %} 3516 3517 // Postalloc expand emitter for runtime leaf calls. 3518 enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{ 3519 loadConLNodesTuple loadConLNodes_Entry; 3520 #if defined(ABI_ELFv2) 3521 jlong entry_address = (jlong) this->entry_point(); 3522 assert(entry_address, "need address here"); 3523 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3524 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3525 #else 3526 // Get the struct that describes the function we are about to call. 3527 FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point(); 3528 assert(fd, "need fd here"); 3529 jlong entry_address = (jlong) fd->entry(); 3530 // new nodes 3531 loadConLNodesTuple loadConLNodes_Env; 3532 loadConLNodesTuple loadConLNodes_Toc; 3533 3534 // Create nodes and operands for loading the entry point. 3535 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3536 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3537 3538 3539 // Create nodes and operands for loading the env pointer. 3540 if (fd->env() != NULL) { 3541 loadConLNodes_Env = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->env()), 3542 OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3543 } else { 3544 loadConLNodes_Env._large_hi = NULL; 3545 loadConLNodes_Env._large_lo = NULL; 3546 loadConLNodes_Env._small = NULL; 3547 loadConLNodes_Env._last = new loadConL16Node(); 3548 loadConLNodes_Env._last->_opnds[0] = new iRegLdstOper(); 3549 loadConLNodes_Env._last->_opnds[1] = new immL16Oper(0); 3550 ra_->set_pair(loadConLNodes_Env._last->_idx, OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3551 } 3552 3553 // Create nodes and operands for loading the Toc point. 3554 loadConLNodes_Toc = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->toc()), 3555 OptoReg::Name(R2_H_num), OptoReg::Name(R2_num)); 3556 #endif // ABI_ELFv2 3557 // mtctr node 3558 MachNode *mtctr = new CallLeafDirect_mtctrNode(); 3559 3560 assert(loadConLNodes_Entry._last != NULL, "entry must exist"); 3561 mtctr->add_req(0, loadConLNodes_Entry._last); 3562 3563 mtctr->_opnds[0] = new iRegLdstOper(); 3564 mtctr->_opnds[1] = new iRegLdstOper(); 3565 3566 // call node 3567 MachCallLeafNode *call = new CallLeafDirectNode(); 3568 3569 call->_opnds[0] = _opnds[0]; 3570 call->_opnds[1] = new methodOper((intptr_t) entry_address); // May get set later. 3571 3572 // Make the new call node look like the old one. 3573 call->_name = _name; 3574 call->_tf = _tf; 3575 call->_entry_point = _entry_point; 3576 call->_cnt = _cnt; 3577 call->_argsize = _argsize; 3578 call->_oop_map = _oop_map; 3579 guarantee(!_jvms, "You must clone the jvms and adapt the offsets by fix_jvms()."); 3580 call->_jvms = NULL; 3581 call->_jvmadj = _jvmadj; 3582 call->_in_rms = _in_rms; 3583 call->_nesting = _nesting; 3584 3585 3586 // New call needs all inputs of old call. 3587 // Req... 3588 for (uint i = 0; i < req(); ++i) { 3589 if (i != mach_constant_base_node_input()) { 3590 call->add_req(in(i)); 3591 } 3592 } 3593 3594 // These must be reqired edges, as the registers are live up to 3595 // the call. Else the constants are handled as kills. 3596 call->add_req(mtctr); 3597 #if !defined(ABI_ELFv2) 3598 call->add_req(loadConLNodes_Env._last); 3599 call->add_req(loadConLNodes_Toc._last); 3600 #endif 3601 3602 // ...as well as prec 3603 for (uint i = req(); i < len(); ++i) { 3604 call->add_prec(in(i)); 3605 } 3606 3607 // registers 3608 ra_->set1(mtctr->_idx, OptoReg::Name(SR_CTR_num)); 3609 3610 // Insert the new nodes. 3611 if (loadConLNodes_Entry._large_hi) nodes->push(loadConLNodes_Entry._large_hi); 3612 if (loadConLNodes_Entry._last) nodes->push(loadConLNodes_Entry._last); 3613 #if !defined(ABI_ELFv2) 3614 if (loadConLNodes_Env._large_hi) nodes->push(loadConLNodes_Env._large_hi); 3615 if (loadConLNodes_Env._last) nodes->push(loadConLNodes_Env._last); 3616 if (loadConLNodes_Toc._large_hi) nodes->push(loadConLNodes_Toc._large_hi); 3617 if (loadConLNodes_Toc._last) nodes->push(loadConLNodes_Toc._last); 3618 #endif 3619 nodes->push(mtctr); 3620 nodes->push(call); 3621 %} 3622 %} 3623 3624 //----------FRAME-------------------------------------------------------------- 3625 // Definition of frame structure and management information. 3626 3627 frame %{ 3628 // What direction does stack grow in (assumed to be same for native & Java). 3629 stack_direction(TOWARDS_LOW); 3630 3631 // These two registers define part of the calling convention between 3632 // compiled code and the interpreter. 3633 3634 // Inline Cache Register or method for I2C. 3635 inline_cache_reg(R19); // R19_method 3636 3637 // Method Oop Register when calling interpreter. 3638 interpreter_method_oop_reg(R19); // R19_method 3639 3640 // Optional: name the operand used by cisc-spilling to access 3641 // [stack_pointer + offset]. 3642 cisc_spilling_operand_name(indOffset); 3643 3644 // Number of stack slots consumed by a Monitor enter. 3645 sync_stack_slots((frame::jit_monitor_size / VMRegImpl::stack_slot_size)); 3646 3647 // Compiled code's Frame Pointer. 3648 frame_pointer(R1); // R1_SP 3649 3650 // Interpreter stores its frame pointer in a register which is 3651 // stored to the stack by I2CAdaptors. I2CAdaptors convert from 3652 // interpreted java to compiled java. 3653 // 3654 // R14_state holds pointer to caller's cInterpreter. 3655 interpreter_frame_pointer(R14); // R14_state 3656 3657 stack_alignment(frame::alignment_in_bytes); 3658 3659 in_preserve_stack_slots((frame::jit_in_preserve_size / VMRegImpl::stack_slot_size)); 3660 3661 // Number of outgoing stack slots killed above the 3662 // out_preserve_stack_slots for calls to C. Supports the var-args 3663 // backing area for register parms. 3664 // 3665 varargs_C_out_slots_killed(((frame::abi_reg_args_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size)); 3666 3667 // The after-PROLOG location of the return address. Location of 3668 // return address specifies a type (REG or STACK) and a number 3669 // representing the register number (i.e. - use a register name) or 3670 // stack slot. 3671 // 3672 // A: Link register is stored in stack slot ... 3673 // M: ... but it's in the caller's frame according to PPC-64 ABI. 3674 // J: Therefore, we make sure that the link register is also in R11_scratch1 3675 // at the end of the prolog. 3676 // B: We use R20, now. 3677 //return_addr(REG R20); 3678 3679 // G: After reading the comments made by all the luminaries on their 3680 // failure to tell the compiler where the return address really is, 3681 // I hardly dare to try myself. However, I'm convinced it's in slot 3682 // 4 what apparently works and saves us some spills. 3683 return_addr(STACK 4); 3684 3685 // This is the body of the function 3686 // 3687 // void Matcher::calling_convention(OptoRegPair* sig, // array of ideal regs 3688 // uint length, // length of array 3689 // bool is_outgoing) 3690 // 3691 // The `sig' array is to be updated. sig[j] represents the location 3692 // of the j-th argument, either a register or a stack slot. 3693 3694 // Comment taken from i486.ad: 3695 // Body of function which returns an integer array locating 3696 // arguments either in registers or in stack slots. Passed an array 3697 // of ideal registers called "sig" and a "length" count. Stack-slot 3698 // offsets are based on outgoing arguments, i.e. a CALLER setting up 3699 // arguments for a CALLEE. Incoming stack arguments are 3700 // automatically biased by the preserve_stack_slots field above. 3701 calling_convention %{ 3702 // No difference between ingoing/outgoing. Just pass false. 3703 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 3704 %} 3705 3706 // Comment taken from i486.ad: 3707 // Body of function which returns an integer array locating 3708 // arguments either in registers or in stack slots. Passed an array 3709 // of ideal registers called "sig" and a "length" count. Stack-slot 3710 // offsets are based on outgoing arguments, i.e. a CALLER setting up 3711 // arguments for a CALLEE. Incoming stack arguments are 3712 // automatically biased by the preserve_stack_slots field above. 3713 c_calling_convention %{ 3714 // This is obviously always outgoing. 3715 // C argument in register AND stack slot. 3716 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 3717 %} 3718 3719 // Location of native (C/C++) and interpreter return values. This 3720 // is specified to be the same as Java. In the 32-bit VM, long 3721 // values are actually returned from native calls in O0:O1 and 3722 // returned to the interpreter in I0:I1. The copying to and from 3723 // the register pairs is done by the appropriate call and epilog 3724 // opcodes. This simplifies the register allocator. 3725 c_return_value %{ 3726 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 3727 (ideal_reg == Op_RegN && Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0), 3728 "only return normal values"); 3729 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 3730 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 3731 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 3732 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 3733 %} 3734 3735 // Location of compiled Java return values. Same as C 3736 return_value %{ 3737 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 3738 (ideal_reg == Op_RegN && Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0), 3739 "only return normal values"); 3740 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 3741 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 3742 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 3743 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 3744 %} 3745 %} 3746 3747 3748 //----------ATTRIBUTES--------------------------------------------------------- 3749 3750 //----------Operand Attributes------------------------------------------------- 3751 op_attrib op_cost(1); // Required cost attribute. 3752 3753 //----------Instruction Attributes--------------------------------------------- 3754 3755 // Cost attribute. required. 3756 ins_attrib ins_cost(DEFAULT_COST); 3757 3758 // Is this instruction a non-matching short branch variant of some 3759 // long branch? Not required. 3760 ins_attrib ins_short_branch(0); 3761 3762 ins_attrib ins_is_TrapBasedCheckNode(true); 3763 3764 // Number of constants. 3765 // This instruction uses the given number of constants 3766 // (optional attribute). 3767 // This is needed to determine in time whether the constant pool will 3768 // exceed 4000 entries. Before postalloc_expand the overall number of constants 3769 // is determined. It's also used to compute the constant pool size 3770 // in Output(). 3771 ins_attrib ins_num_consts(0); 3772 3773 // Required alignment attribute (must be a power of 2) specifies the 3774 // alignment that some part of the instruction (not necessarily the 3775 // start) requires. If > 1, a compute_padding() function must be 3776 // provided for the instruction. 3777 ins_attrib ins_alignment(1); 3778 3779 // Enforce/prohibit rematerializations. 3780 // - If an instruction is attributed with 'ins_cannot_rematerialize(true)' 3781 // then rematerialization of that instruction is prohibited and the 3782 // instruction's value will be spilled if necessary. 3783 // Causes that MachNode::rematerialize() returns false. 3784 // - If an instruction is attributed with 'ins_should_rematerialize(true)' 3785 // then rematerialization should be enforced and a copy of the instruction 3786 // should be inserted if possible; rematerialization is not guaranteed. 3787 // Note: this may result in rematerializations in front of every use. 3788 // Causes that MachNode::rematerialize() can return true. 3789 // (optional attribute) 3790 ins_attrib ins_cannot_rematerialize(false); 3791 ins_attrib ins_should_rematerialize(false); 3792 3793 // Instruction has variable size depending on alignment. 3794 ins_attrib ins_variable_size_depending_on_alignment(false); 3795 3796 // Instruction is a nop. 3797 ins_attrib ins_is_nop(false); 3798 3799 // Instruction is mapped to a MachIfFastLock node (instead of MachFastLock). 3800 ins_attrib ins_use_mach_if_fast_lock_node(false); 3801 3802 // Field for the toc offset of a constant. 3803 // 3804 // This is needed if the toc offset is not encodable as an immediate in 3805 // the PPC load instruction. If so, the upper (hi) bits of the offset are 3806 // added to the toc, and from this a load with immediate is performed. 3807 // With postalloc expand, we get two nodes that require the same offset 3808 // but which don't know about each other. The offset is only known 3809 // when the constant is added to the constant pool during emitting. 3810 // It is generated in the 'hi'-node adding the upper bits, and saved 3811 // in this node. The 'lo'-node has a link to the 'hi'-node and reads 3812 // the offset from there when it gets encoded. 3813 ins_attrib ins_field_const_toc_offset(0); 3814 ins_attrib ins_field_const_toc_offset_hi_node(0); 3815 3816 // A field that can hold the instructions offset in the code buffer. 3817 // Set in the nodes emitter. 3818 ins_attrib ins_field_cbuf_insts_offset(-1); 3819 3820 // Fields for referencing a call's load-IC-node. 3821 // If the toc offset can not be encoded as an immediate in a load, we 3822 // use two nodes. 3823 ins_attrib ins_field_load_ic_hi_node(0); 3824 ins_attrib ins_field_load_ic_node(0); 3825 3826 //----------OPERANDS----------------------------------------------------------- 3827 // Operand definitions must precede instruction definitions for correct 3828 // parsing in the ADLC because operands constitute user defined types 3829 // which are used in instruction definitions. 3830 // 3831 // Formats are generated automatically for constants and base registers. 3832 3833 //----------Simple Operands---------------------------------------------------- 3834 // Immediate Operands 3835 3836 // Integer Immediate: 32-bit 3837 operand immI() %{ 3838 match(ConI); 3839 op_cost(40); 3840 format %{ %} 3841 interface(CONST_INTER); 3842 %} 3843 3844 operand immI8() %{ 3845 predicate(Assembler::is_simm(n->get_int(), 8)); 3846 op_cost(0); 3847 match(ConI); 3848 format %{ %} 3849 interface(CONST_INTER); 3850 %} 3851 3852 // Integer Immediate: 16-bit 3853 operand immI16() %{ 3854 predicate(Assembler::is_simm(n->get_int(), 16)); 3855 op_cost(0); 3856 match(ConI); 3857 format %{ %} 3858 interface(CONST_INTER); 3859 %} 3860 3861 // Integer Immediate: 32-bit, where lowest 16 bits are 0x0000. 3862 operand immIhi16() %{ 3863 predicate(((n->get_int() & 0xffff0000) != 0) && ((n->get_int() & 0xffff) == 0)); 3864 match(ConI); 3865 op_cost(0); 3866 format %{ %} 3867 interface(CONST_INTER); 3868 %} 3869 3870 operand immInegpow2() %{ 3871 predicate(is_power_of_2_long((jlong) (julong) (juint) (-(n->get_int())))); 3872 match(ConI); 3873 op_cost(0); 3874 format %{ %} 3875 interface(CONST_INTER); 3876 %} 3877 3878 operand immIpow2minus1() %{ 3879 predicate(is_power_of_2_long((((jlong) (n->get_int()))+1))); 3880 match(ConI); 3881 op_cost(0); 3882 format %{ %} 3883 interface(CONST_INTER); 3884 %} 3885 3886 operand immIpowerOf2() %{ 3887 predicate(is_power_of_2_long((((jlong) (julong) (juint) (n->get_int()))))); 3888 match(ConI); 3889 op_cost(0); 3890 format %{ %} 3891 interface(CONST_INTER); 3892 %} 3893 3894 // Unsigned Integer Immediate: the values 0-31 3895 operand uimmI5() %{ 3896 predicate(Assembler::is_uimm(n->get_int(), 5)); 3897 match(ConI); 3898 op_cost(0); 3899 format %{ %} 3900 interface(CONST_INTER); 3901 %} 3902 3903 // Unsigned Integer Immediate: 6-bit 3904 operand uimmI6() %{ 3905 predicate(Assembler::is_uimm(n->get_int(), 6)); 3906 match(ConI); 3907 op_cost(0); 3908 format %{ %} 3909 interface(CONST_INTER); 3910 %} 3911 3912 // Unsigned Integer Immediate: 6-bit int, greater than 32 3913 operand uimmI6_ge32() %{ 3914 predicate(Assembler::is_uimm(n->get_int(), 6) && n->get_int() >= 32); 3915 match(ConI); 3916 op_cost(0); 3917 format %{ %} 3918 interface(CONST_INTER); 3919 %} 3920 3921 // Unsigned Integer Immediate: 15-bit 3922 operand uimmI15() %{ 3923 predicate(Assembler::is_uimm(n->get_int(), 15)); 3924 match(ConI); 3925 op_cost(0); 3926 format %{ %} 3927 interface(CONST_INTER); 3928 %} 3929 3930 // Unsigned Integer Immediate: 16-bit 3931 operand uimmI16() %{ 3932 predicate(Assembler::is_uimm(n->get_int(), 16)); 3933 match(ConI); 3934 op_cost(0); 3935 format %{ %} 3936 interface(CONST_INTER); 3937 %} 3938 3939 // constant 'int 0'. 3940 operand immI_0() %{ 3941 predicate(n->get_int() == 0); 3942 match(ConI); 3943 op_cost(0); 3944 format %{ %} 3945 interface(CONST_INTER); 3946 %} 3947 3948 // constant 'int 1'. 3949 operand immI_1() %{ 3950 predicate(n->get_int() == 1); 3951 match(ConI); 3952 op_cost(0); 3953 format %{ %} 3954 interface(CONST_INTER); 3955 %} 3956 3957 // constant 'int -1'. 3958 operand immI_minus1() %{ 3959 predicate(n->get_int() == -1); 3960 match(ConI); 3961 op_cost(0); 3962 format %{ %} 3963 interface(CONST_INTER); 3964 %} 3965 3966 // int value 16. 3967 operand immI_16() %{ 3968 predicate(n->get_int() == 16); 3969 match(ConI); 3970 op_cost(0); 3971 format %{ %} 3972 interface(CONST_INTER); 3973 %} 3974 3975 // int value 24. 3976 operand immI_24() %{ 3977 predicate(n->get_int() == 24); 3978 match(ConI); 3979 op_cost(0); 3980 format %{ %} 3981 interface(CONST_INTER); 3982 %} 3983 3984 // Compressed oops constants 3985 // Pointer Immediate 3986 operand immN() %{ 3987 match(ConN); 3988 3989 op_cost(10); 3990 format %{ %} 3991 interface(CONST_INTER); 3992 %} 3993 3994 // NULL Pointer Immediate 3995 operand immN_0() %{ 3996 predicate(n->get_narrowcon() == 0); 3997 match(ConN); 3998 3999 op_cost(0); 4000 format %{ %} 4001 interface(CONST_INTER); 4002 %} 4003 4004 // Compressed klass constants 4005 operand immNKlass() %{ 4006 match(ConNKlass); 4007 4008 op_cost(0); 4009 format %{ %} 4010 interface(CONST_INTER); 4011 %} 4012 4013 // This operand can be used to avoid matching of an instruct 4014 // with chain rule. 4015 operand immNKlass_NM() %{ 4016 match(ConNKlass); 4017 predicate(false); 4018 op_cost(0); 4019 format %{ %} 4020 interface(CONST_INTER); 4021 %} 4022 4023 // Pointer Immediate: 64-bit 4024 operand immP() %{ 4025 match(ConP); 4026 op_cost(0); 4027 format %{ %} 4028 interface(CONST_INTER); 4029 %} 4030 4031 // Operand to avoid match of loadConP. 4032 // This operand can be used to avoid matching of an instruct 4033 // with chain rule. 4034 operand immP_NM() %{ 4035 match(ConP); 4036 predicate(false); 4037 op_cost(0); 4038 format %{ %} 4039 interface(CONST_INTER); 4040 %} 4041 4042 // costant 'pointer 0'. 4043 operand immP_0() %{ 4044 predicate(n->get_ptr() == 0); 4045 match(ConP); 4046 op_cost(0); 4047 format %{ %} 4048 interface(CONST_INTER); 4049 %} 4050 4051 // pointer 0x0 or 0x1 4052 operand immP_0or1() %{ 4053 predicate((n->get_ptr() == 0) || (n->get_ptr() == 1)); 4054 match(ConP); 4055 op_cost(0); 4056 format %{ %} 4057 interface(CONST_INTER); 4058 %} 4059 4060 operand immL() %{ 4061 match(ConL); 4062 op_cost(40); 4063 format %{ %} 4064 interface(CONST_INTER); 4065 %} 4066 4067 // Long Immediate: 16-bit 4068 operand immL16() %{ 4069 predicate(Assembler::is_simm(n->get_long(), 16)); 4070 match(ConL); 4071 op_cost(0); 4072 format %{ %} 4073 interface(CONST_INTER); 4074 %} 4075 4076 // Long Immediate: 16-bit, 4-aligned 4077 operand immL16Alg4() %{ 4078 predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0x3) == 0)); 4079 match(ConL); 4080 op_cost(0); 4081 format %{ %} 4082 interface(CONST_INTER); 4083 %} 4084 4085 // Long Immediate: 32-bit, where lowest 16 bits are 0x0000. 4086 operand immL32hi16() %{ 4087 predicate(Assembler::is_simm(n->get_long(), 32) && ((n->get_long() & 0xffffL) == 0L)); 4088 match(ConL); 4089 op_cost(0); 4090 format %{ %} 4091 interface(CONST_INTER); 4092 %} 4093 4094 // Long Immediate: 32-bit 4095 operand immL32() %{ 4096 predicate(Assembler::is_simm(n->get_long(), 32)); 4097 match(ConL); 4098 op_cost(0); 4099 format %{ %} 4100 interface(CONST_INTER); 4101 %} 4102 4103 // Long Immediate: 64-bit, where highest 16 bits are not 0x0000. 4104 operand immLhighest16() %{ 4105 predicate((n->get_long() & 0xffff000000000000L) != 0L && (n->get_long() & 0x0000ffffffffffffL) == 0L); 4106 match(ConL); 4107 op_cost(0); 4108 format %{ %} 4109 interface(CONST_INTER); 4110 %} 4111 4112 operand immLnegpow2() %{ 4113 predicate(is_power_of_2_long((jlong)-(n->get_long()))); 4114 match(ConL); 4115 op_cost(0); 4116 format %{ %} 4117 interface(CONST_INTER); 4118 %} 4119 4120 operand immLpow2minus1() %{ 4121 predicate(is_power_of_2_long((((jlong) (n->get_long()))+1)) && 4122 (n->get_long() != (jlong)0xffffffffffffffffL)); 4123 match(ConL); 4124 op_cost(0); 4125 format %{ %} 4126 interface(CONST_INTER); 4127 %} 4128 4129 // constant 'long 0'. 4130 operand immL_0() %{ 4131 predicate(n->get_long() == 0L); 4132 match(ConL); 4133 op_cost(0); 4134 format %{ %} 4135 interface(CONST_INTER); 4136 %} 4137 4138 // constat ' long -1'. 4139 operand immL_minus1() %{ 4140 predicate(n->get_long() == -1L); 4141 match(ConL); 4142 op_cost(0); 4143 format %{ %} 4144 interface(CONST_INTER); 4145 %} 4146 4147 // Long Immediate: low 32-bit mask 4148 operand immL_32bits() %{ 4149 predicate(n->get_long() == 0xFFFFFFFFL); 4150 match(ConL); 4151 op_cost(0); 4152 format %{ %} 4153 interface(CONST_INTER); 4154 %} 4155 4156 // Unsigned Long Immediate: 16-bit 4157 operand uimmL16() %{ 4158 predicate(Assembler::is_uimm(n->get_long(), 16)); 4159 match(ConL); 4160 op_cost(0); 4161 format %{ %} 4162 interface(CONST_INTER); 4163 %} 4164 4165 // Float Immediate 4166 operand immF() %{ 4167 match(ConF); 4168 op_cost(40); 4169 format %{ %} 4170 interface(CONST_INTER); 4171 %} 4172 4173 // Float Immediate: +0.0f. 4174 operand immF_0() %{ 4175 predicate(jint_cast(n->getf()) == 0); 4176 match(ConF); 4177 4178 op_cost(0); 4179 format %{ %} 4180 interface(CONST_INTER); 4181 %} 4182 4183 // Double Immediate 4184 operand immD() %{ 4185 match(ConD); 4186 op_cost(40); 4187 format %{ %} 4188 interface(CONST_INTER); 4189 %} 4190 4191 // Integer Register Operands 4192 // Integer Destination Register 4193 // See definition of reg_class bits32_reg_rw. 4194 operand iRegIdst() %{ 4195 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4196 match(RegI); 4197 match(rscratch1RegI); 4198 match(rscratch2RegI); 4199 match(rarg1RegI); 4200 match(rarg2RegI); 4201 match(rarg3RegI); 4202 match(rarg4RegI); 4203 format %{ %} 4204 interface(REG_INTER); 4205 %} 4206 4207 // Integer Source Register 4208 // See definition of reg_class bits32_reg_ro. 4209 operand iRegIsrc() %{ 4210 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4211 match(RegI); 4212 match(rscratch1RegI); 4213 match(rscratch2RegI); 4214 match(rarg1RegI); 4215 match(rarg2RegI); 4216 match(rarg3RegI); 4217 match(rarg4RegI); 4218 format %{ %} 4219 interface(REG_INTER); 4220 %} 4221 4222 operand rscratch1RegI() %{ 4223 constraint(ALLOC_IN_RC(rscratch1_bits32_reg)); 4224 match(iRegIdst); 4225 format %{ %} 4226 interface(REG_INTER); 4227 %} 4228 4229 operand rscratch2RegI() %{ 4230 constraint(ALLOC_IN_RC(rscratch2_bits32_reg)); 4231 match(iRegIdst); 4232 format %{ %} 4233 interface(REG_INTER); 4234 %} 4235 4236 operand rarg1RegI() %{ 4237 constraint(ALLOC_IN_RC(rarg1_bits32_reg)); 4238 match(iRegIdst); 4239 format %{ %} 4240 interface(REG_INTER); 4241 %} 4242 4243 operand rarg2RegI() %{ 4244 constraint(ALLOC_IN_RC(rarg2_bits32_reg)); 4245 match(iRegIdst); 4246 format %{ %} 4247 interface(REG_INTER); 4248 %} 4249 4250 operand rarg3RegI() %{ 4251 constraint(ALLOC_IN_RC(rarg3_bits32_reg)); 4252 match(iRegIdst); 4253 format %{ %} 4254 interface(REG_INTER); 4255 %} 4256 4257 operand rarg4RegI() %{ 4258 constraint(ALLOC_IN_RC(rarg4_bits32_reg)); 4259 match(iRegIdst); 4260 format %{ %} 4261 interface(REG_INTER); 4262 %} 4263 4264 operand rarg1RegL() %{ 4265 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4266 match(iRegLdst); 4267 format %{ %} 4268 interface(REG_INTER); 4269 %} 4270 4271 operand rarg2RegL() %{ 4272 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4273 match(iRegLdst); 4274 format %{ %} 4275 interface(REG_INTER); 4276 %} 4277 4278 operand rarg3RegL() %{ 4279 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4280 match(iRegLdst); 4281 format %{ %} 4282 interface(REG_INTER); 4283 %} 4284 4285 operand rarg4RegL() %{ 4286 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4287 match(iRegLdst); 4288 format %{ %} 4289 interface(REG_INTER); 4290 %} 4291 4292 // Pointer Destination Register 4293 // See definition of reg_class bits64_reg_rw. 4294 operand iRegPdst() %{ 4295 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4296 match(RegP); 4297 match(rscratch1RegP); 4298 match(rscratch2RegP); 4299 match(rarg1RegP); 4300 match(rarg2RegP); 4301 match(rarg3RegP); 4302 match(rarg4RegP); 4303 format %{ %} 4304 interface(REG_INTER); 4305 %} 4306 4307 // Pointer Destination Register 4308 // Operand not using r11 and r12 (killed in epilog). 4309 operand iRegPdstNoScratch() %{ 4310 constraint(ALLOC_IN_RC(bits64_reg_leaf_call)); 4311 match(RegP); 4312 match(rarg1RegP); 4313 match(rarg2RegP); 4314 match(rarg3RegP); 4315 match(rarg4RegP); 4316 format %{ %} 4317 interface(REG_INTER); 4318 %} 4319 4320 // Pointer Source Register 4321 // See definition of reg_class bits64_reg_ro. 4322 operand iRegPsrc() %{ 4323 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4324 match(RegP); 4325 match(iRegPdst); 4326 match(rscratch1RegP); 4327 match(rscratch2RegP); 4328 match(rarg1RegP); 4329 match(rarg2RegP); 4330 match(rarg3RegP); 4331 match(rarg4RegP); 4332 match(threadRegP); 4333 format %{ %} 4334 interface(REG_INTER); 4335 %} 4336 4337 // Thread operand. 4338 operand threadRegP() %{ 4339 constraint(ALLOC_IN_RC(thread_bits64_reg)); 4340 match(iRegPdst); 4341 format %{ "R16" %} 4342 interface(REG_INTER); 4343 %} 4344 4345 operand rscratch1RegP() %{ 4346 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4347 match(iRegPdst); 4348 format %{ "R11" %} 4349 interface(REG_INTER); 4350 %} 4351 4352 operand rscratch2RegP() %{ 4353 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4354 match(iRegPdst); 4355 format %{ %} 4356 interface(REG_INTER); 4357 %} 4358 4359 operand rarg1RegP() %{ 4360 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4361 match(iRegPdst); 4362 format %{ %} 4363 interface(REG_INTER); 4364 %} 4365 4366 operand rarg2RegP() %{ 4367 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4368 match(iRegPdst); 4369 format %{ %} 4370 interface(REG_INTER); 4371 %} 4372 4373 operand rarg3RegP() %{ 4374 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4375 match(iRegPdst); 4376 format %{ %} 4377 interface(REG_INTER); 4378 %} 4379 4380 operand rarg4RegP() %{ 4381 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4382 match(iRegPdst); 4383 format %{ %} 4384 interface(REG_INTER); 4385 %} 4386 4387 operand iRegNsrc() %{ 4388 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4389 match(RegN); 4390 match(iRegNdst); 4391 4392 format %{ %} 4393 interface(REG_INTER); 4394 %} 4395 4396 operand iRegNdst() %{ 4397 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4398 match(RegN); 4399 4400 format %{ %} 4401 interface(REG_INTER); 4402 %} 4403 4404 // Long Destination Register 4405 // See definition of reg_class bits64_reg_rw. 4406 operand iRegLdst() %{ 4407 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4408 match(RegL); 4409 match(rscratch1RegL); 4410 match(rscratch2RegL); 4411 format %{ %} 4412 interface(REG_INTER); 4413 %} 4414 4415 // Long Source Register 4416 // See definition of reg_class bits64_reg_ro. 4417 operand iRegLsrc() %{ 4418 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4419 match(RegL); 4420 match(iRegLdst); 4421 match(rscratch1RegL); 4422 match(rscratch2RegL); 4423 format %{ %} 4424 interface(REG_INTER); 4425 %} 4426 4427 // Special operand for ConvL2I. 4428 operand iRegL2Isrc(iRegLsrc reg) %{ 4429 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4430 match(ConvL2I reg); 4431 format %{ "ConvL2I($reg)" %} 4432 interface(REG_INTER) 4433 %} 4434 4435 operand rscratch1RegL() %{ 4436 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4437 match(RegL); 4438 format %{ %} 4439 interface(REG_INTER); 4440 %} 4441 4442 operand rscratch2RegL() %{ 4443 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4444 match(RegL); 4445 format %{ %} 4446 interface(REG_INTER); 4447 %} 4448 4449 // Condition Code Flag Registers 4450 operand flagsReg() %{ 4451 constraint(ALLOC_IN_RC(int_flags)); 4452 match(RegFlags); 4453 format %{ %} 4454 interface(REG_INTER); 4455 %} 4456 4457 operand flagsRegSrc() %{ 4458 constraint(ALLOC_IN_RC(int_flags_ro)); 4459 match(RegFlags); 4460 match(flagsReg); 4461 match(flagsRegCR0); 4462 format %{ %} 4463 interface(REG_INTER); 4464 %} 4465 4466 // Condition Code Flag Register CR0 4467 operand flagsRegCR0() %{ 4468 constraint(ALLOC_IN_RC(int_flags_CR0)); 4469 match(RegFlags); 4470 format %{ "CR0" %} 4471 interface(REG_INTER); 4472 %} 4473 4474 operand flagsRegCR1() %{ 4475 constraint(ALLOC_IN_RC(int_flags_CR1)); 4476 match(RegFlags); 4477 format %{ "CR1" %} 4478 interface(REG_INTER); 4479 %} 4480 4481 operand flagsRegCR6() %{ 4482 constraint(ALLOC_IN_RC(int_flags_CR6)); 4483 match(RegFlags); 4484 format %{ "CR6" %} 4485 interface(REG_INTER); 4486 %} 4487 4488 operand regCTR() %{ 4489 constraint(ALLOC_IN_RC(ctr_reg)); 4490 // RegFlags should work. Introducing a RegSpecial type would cause a 4491 // lot of changes. 4492 match(RegFlags); 4493 format %{"SR_CTR" %} 4494 interface(REG_INTER); 4495 %} 4496 4497 operand regD() %{ 4498 constraint(ALLOC_IN_RC(dbl_reg)); 4499 match(RegD); 4500 format %{ %} 4501 interface(REG_INTER); 4502 %} 4503 4504 operand regF() %{ 4505 constraint(ALLOC_IN_RC(flt_reg)); 4506 match(RegF); 4507 format %{ %} 4508 interface(REG_INTER); 4509 %} 4510 4511 // Special Registers 4512 4513 // Method Register 4514 operand inline_cache_regP(iRegPdst reg) %{ 4515 constraint(ALLOC_IN_RC(r19_bits64_reg)); // inline_cache_reg 4516 match(reg); 4517 format %{ %} 4518 interface(REG_INTER); 4519 %} 4520 4521 operand compiler_method_oop_regP(iRegPdst reg) %{ 4522 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); // compiler_method_oop_reg 4523 match(reg); 4524 format %{ %} 4525 interface(REG_INTER); 4526 %} 4527 4528 operand interpreter_method_oop_regP(iRegPdst reg) %{ 4529 constraint(ALLOC_IN_RC(r19_bits64_reg)); // interpreter_method_oop_reg 4530 match(reg); 4531 format %{ %} 4532 interface(REG_INTER); 4533 %} 4534 4535 // Operands to remove register moves in unscaled mode. 4536 // Match read/write registers with an EncodeP node if neither shift nor add are required. 4537 operand iRegP2N(iRegPsrc reg) %{ 4538 predicate(false /* TODO: PPC port MatchDecodeNodes*/&& Universe::narrow_oop_shift() == 0); 4539 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4540 match(EncodeP reg); 4541 format %{ "$reg" %} 4542 interface(REG_INTER) 4543 %} 4544 4545 operand iRegN2P(iRegNsrc reg) %{ 4546 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4547 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4548 match(DecodeN reg); 4549 format %{ "$reg" %} 4550 interface(REG_INTER) 4551 %} 4552 4553 operand iRegN2P_klass(iRegNsrc reg) %{ 4554 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 4555 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4556 match(DecodeNKlass reg); 4557 format %{ "$reg" %} 4558 interface(REG_INTER) 4559 %} 4560 4561 //----------Complex Operands--------------------------------------------------- 4562 // Indirect Memory Reference 4563 operand indirect(iRegPsrc reg) %{ 4564 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4565 match(reg); 4566 op_cost(100); 4567 format %{ "[$reg]" %} 4568 interface(MEMORY_INTER) %{ 4569 base($reg); 4570 index(0x0); 4571 scale(0x0); 4572 disp(0x0); 4573 %} 4574 %} 4575 4576 // Indirect with Offset 4577 operand indOffset16(iRegPsrc reg, immL16 offset) %{ 4578 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4579 match(AddP reg offset); 4580 op_cost(100); 4581 format %{ "[$reg + $offset]" %} 4582 interface(MEMORY_INTER) %{ 4583 base($reg); 4584 index(0x0); 4585 scale(0x0); 4586 disp($offset); 4587 %} 4588 %} 4589 4590 // Indirect with 4-aligned Offset 4591 operand indOffset16Alg4(iRegPsrc reg, immL16Alg4 offset) %{ 4592 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4593 match(AddP reg offset); 4594 op_cost(100); 4595 format %{ "[$reg + $offset]" %} 4596 interface(MEMORY_INTER) %{ 4597 base($reg); 4598 index(0x0); 4599 scale(0x0); 4600 disp($offset); 4601 %} 4602 %} 4603 4604 //----------Complex Operands for Compressed OOPs------------------------------- 4605 // Compressed OOPs with narrow_oop_shift == 0. 4606 4607 // Indirect Memory Reference, compressed OOP 4608 operand indirectNarrow(iRegNsrc reg) %{ 4609 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4610 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4611 match(DecodeN reg); 4612 op_cost(100); 4613 format %{ "[$reg]" %} 4614 interface(MEMORY_INTER) %{ 4615 base($reg); 4616 index(0x0); 4617 scale(0x0); 4618 disp(0x0); 4619 %} 4620 %} 4621 4622 operand indirectNarrow_klass(iRegNsrc reg) %{ 4623 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 4624 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4625 match(DecodeNKlass reg); 4626 op_cost(100); 4627 format %{ "[$reg]" %} 4628 interface(MEMORY_INTER) %{ 4629 base($reg); 4630 index(0x0); 4631 scale(0x0); 4632 disp(0x0); 4633 %} 4634 %} 4635 4636 // Indirect with Offset, compressed OOP 4637 operand indOffset16Narrow(iRegNsrc reg, immL16 offset) %{ 4638 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4639 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4640 match(AddP (DecodeN reg) offset); 4641 op_cost(100); 4642 format %{ "[$reg + $offset]" %} 4643 interface(MEMORY_INTER) %{ 4644 base($reg); 4645 index(0x0); 4646 scale(0x0); 4647 disp($offset); 4648 %} 4649 %} 4650 4651 operand indOffset16Narrow_klass(iRegNsrc reg, immL16 offset) %{ 4652 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 4653 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4654 match(AddP (DecodeNKlass reg) offset); 4655 op_cost(100); 4656 format %{ "[$reg + $offset]" %} 4657 interface(MEMORY_INTER) %{ 4658 base($reg); 4659 index(0x0); 4660 scale(0x0); 4661 disp($offset); 4662 %} 4663 %} 4664 4665 // Indirect with 4-aligned Offset, compressed OOP 4666 operand indOffset16NarrowAlg4(iRegNsrc reg, immL16Alg4 offset) %{ 4667 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4668 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4669 match(AddP (DecodeN reg) offset); 4670 op_cost(100); 4671 format %{ "[$reg + $offset]" %} 4672 interface(MEMORY_INTER) %{ 4673 base($reg); 4674 index(0x0); 4675 scale(0x0); 4676 disp($offset); 4677 %} 4678 %} 4679 4680 operand indOffset16NarrowAlg4_klass(iRegNsrc reg, immL16Alg4 offset) %{ 4681 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 4682 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4683 match(AddP (DecodeNKlass reg) offset); 4684 op_cost(100); 4685 format %{ "[$reg + $offset]" %} 4686 interface(MEMORY_INTER) %{ 4687 base($reg); 4688 index(0x0); 4689 scale(0x0); 4690 disp($offset); 4691 %} 4692 %} 4693 4694 //----------Special Memory Operands-------------------------------------------- 4695 // Stack Slot Operand 4696 // 4697 // This operand is used for loading and storing temporary values on 4698 // the stack where a match requires a value to flow through memory. 4699 operand stackSlotI(sRegI reg) %{ 4700 constraint(ALLOC_IN_RC(stack_slots)); 4701 op_cost(100); 4702 //match(RegI); 4703 format %{ "[sp+$reg]" %} 4704 interface(MEMORY_INTER) %{ 4705 base(0x1); // R1_SP 4706 index(0x0); 4707 scale(0x0); 4708 disp($reg); // Stack Offset 4709 %} 4710 %} 4711 4712 operand stackSlotL(sRegL reg) %{ 4713 constraint(ALLOC_IN_RC(stack_slots)); 4714 op_cost(100); 4715 //match(RegL); 4716 format %{ "[sp+$reg]" %} 4717 interface(MEMORY_INTER) %{ 4718 base(0x1); // R1_SP 4719 index(0x0); 4720 scale(0x0); 4721 disp($reg); // Stack Offset 4722 %} 4723 %} 4724 4725 operand stackSlotP(sRegP reg) %{ 4726 constraint(ALLOC_IN_RC(stack_slots)); 4727 op_cost(100); 4728 //match(RegP); 4729 format %{ "[sp+$reg]" %} 4730 interface(MEMORY_INTER) %{ 4731 base(0x1); // R1_SP 4732 index(0x0); 4733 scale(0x0); 4734 disp($reg); // Stack Offset 4735 %} 4736 %} 4737 4738 operand stackSlotF(sRegF reg) %{ 4739 constraint(ALLOC_IN_RC(stack_slots)); 4740 op_cost(100); 4741 //match(RegF); 4742 format %{ "[sp+$reg]" %} 4743 interface(MEMORY_INTER) %{ 4744 base(0x1); // R1_SP 4745 index(0x0); 4746 scale(0x0); 4747 disp($reg); // Stack Offset 4748 %} 4749 %} 4750 4751 operand stackSlotD(sRegD reg) %{ 4752 constraint(ALLOC_IN_RC(stack_slots)); 4753 op_cost(100); 4754 //match(RegD); 4755 format %{ "[sp+$reg]" %} 4756 interface(MEMORY_INTER) %{ 4757 base(0x1); // R1_SP 4758 index(0x0); 4759 scale(0x0); 4760 disp($reg); // Stack Offset 4761 %} 4762 %} 4763 4764 // Operands for expressing Control Flow 4765 // NOTE: Label is a predefined operand which should not be redefined in 4766 // the AD file. It is generically handled within the ADLC. 4767 4768 //----------Conditional Branch Operands---------------------------------------- 4769 // Comparison Op 4770 // 4771 // This is the operation of the comparison, and is limited to the 4772 // following set of codes: L (<), LE (<=), G (>), GE (>=), E (==), NE 4773 // (!=). 4774 // 4775 // Other attributes of the comparison, such as unsignedness, are specified 4776 // by the comparison instruction that sets a condition code flags register. 4777 // That result is represented by a flags operand whose subtype is appropriate 4778 // to the unsignedness (etc.) of the comparison. 4779 // 4780 // Later, the instruction which matches both the Comparison Op (a Bool) and 4781 // the flags (produced by the Cmp) specifies the coding of the comparison op 4782 // by matching a specific subtype of Bool operand below. 4783 4784 // When used for floating point comparisons: unordered same as less. 4785 operand cmpOp() %{ 4786 match(Bool); 4787 format %{ "" %} 4788 interface(COND_INTER) %{ 4789 // BO only encodes bit 4 of bcondCRbiIsX, as bits 1-3 are always '100'. 4790 // BO & BI 4791 equal(0xA); // 10 10: bcondCRbiIs1 & Condition::equal 4792 not_equal(0x2); // 00 10: bcondCRbiIs0 & Condition::equal 4793 less(0x8); // 10 00: bcondCRbiIs1 & Condition::less 4794 greater_equal(0x0); // 00 00: bcondCRbiIs0 & Condition::less 4795 less_equal(0x1); // 00 01: bcondCRbiIs0 & Condition::greater 4796 greater(0x9); // 10 01: bcondCRbiIs1 & Condition::greater 4797 overflow(0xB); // 10 11: bcondCRbiIs1 & Condition::summary_overflow 4798 no_overflow(0x3); // 00 11: bcondCRbiIs0 & Condition::summary_overflow 4799 %} 4800 %} 4801 4802 //----------OPERAND CLASSES---------------------------------------------------- 4803 // Operand Classes are groups of operands that are used to simplify 4804 // instruction definitions by not requiring the AD writer to specify 4805 // seperate instructions for every form of operand when the 4806 // instruction accepts multiple operand types with the same basic 4807 // encoding and format. The classic case of this is memory operands. 4808 // Indirect is not included since its use is limited to Compare & Swap. 4809 4810 opclass memory(indirect, indOffset16 /*, indIndex, tlsReference*/, indirectNarrow, indirectNarrow_klass, indOffset16Narrow, indOffset16Narrow_klass); 4811 // Memory operand where offsets are 4-aligned. Required for ld, std. 4812 opclass memoryAlg4(indirect, indOffset16Alg4, indirectNarrow, indOffset16NarrowAlg4, indOffset16NarrowAlg4_klass); 4813 opclass indirectMemory(indirect, indirectNarrow); 4814 4815 // Special opclass for I and ConvL2I. 4816 opclass iRegIsrc_iRegL2Isrc(iRegIsrc, iRegL2Isrc); 4817 4818 // Operand classes to match encode and decode. iRegN_P2N is only used 4819 // for storeN. I have never seen an encode node elsewhere. 4820 opclass iRegN_P2N(iRegNsrc, iRegP2N); 4821 opclass iRegP_N2P(iRegPsrc, iRegN2P, iRegN2P_klass); 4822 4823 //----------PIPELINE----------------------------------------------------------- 4824 4825 pipeline %{ 4826 4827 // See J.M.Tendler et al. "Power4 system microarchitecture", IBM 4828 // J. Res. & Dev., No. 1, Jan. 2002. 4829 4830 //----------ATTRIBUTES--------------------------------------------------------- 4831 attributes %{ 4832 4833 // Power4 instructions are of fixed length. 4834 fixed_size_instructions; 4835 4836 // TODO: if `bundle' means number of instructions fetched 4837 // per cycle, this is 8. If `bundle' means Power4 `group', that is 4838 // max instructions issued per cycle, this is 5. 4839 max_instructions_per_bundle = 8; 4840 4841 // A Power4 instruction is 4 bytes long. 4842 instruction_unit_size = 4; 4843 4844 // The Power4 processor fetches 64 bytes... 4845 instruction_fetch_unit_size = 64; 4846 4847 // ...in one line 4848 instruction_fetch_units = 1 4849 4850 // Unused, list one so that array generated by adlc is not empty. 4851 // Aix compiler chokes if _nop_count = 0. 4852 nops(fxNop); 4853 %} 4854 4855 //----------RESOURCES---------------------------------------------------------- 4856 // Resources are the functional units available to the machine 4857 resources( 4858 PPC_BR, // branch unit 4859 PPC_CR, // condition unit 4860 PPC_FX1, // integer arithmetic unit 1 4861 PPC_FX2, // integer arithmetic unit 2 4862 PPC_LDST1, // load/store unit 1 4863 PPC_LDST2, // load/store unit 2 4864 PPC_FP1, // float arithmetic unit 1 4865 PPC_FP2, // float arithmetic unit 2 4866 PPC_LDST = PPC_LDST1 | PPC_LDST2, 4867 PPC_FX = PPC_FX1 | PPC_FX2, 4868 PPC_FP = PPC_FP1 | PPC_FP2 4869 ); 4870 4871 //----------PIPELINE DESCRIPTION----------------------------------------------- 4872 // Pipeline Description specifies the stages in the machine's pipeline 4873 pipe_desc( 4874 // Power4 longest pipeline path 4875 PPC_IF, // instruction fetch 4876 PPC_IC, 4877 //PPC_BP, // branch prediction 4878 PPC_D0, // decode 4879 PPC_D1, // decode 4880 PPC_D2, // decode 4881 PPC_D3, // decode 4882 PPC_Xfer1, 4883 PPC_GD, // group definition 4884 PPC_MP, // map 4885 PPC_ISS, // issue 4886 PPC_RF, // resource fetch 4887 PPC_EX1, // execute (all units) 4888 PPC_EX2, // execute (FP, LDST) 4889 PPC_EX3, // execute (FP, LDST) 4890 PPC_EX4, // execute (FP) 4891 PPC_EX5, // execute (FP) 4892 PPC_EX6, // execute (FP) 4893 PPC_WB, // write back 4894 PPC_Xfer2, 4895 PPC_CP 4896 ); 4897 4898 //----------PIPELINE CLASSES--------------------------------------------------- 4899 // Pipeline Classes describe the stages in which input and output are 4900 // referenced by the hardware pipeline. 4901 4902 // Simple pipeline classes. 4903 4904 // Default pipeline class. 4905 pipe_class pipe_class_default() %{ 4906 single_instruction; 4907 fixed_latency(2); 4908 %} 4909 4910 // Pipeline class for empty instructions. 4911 pipe_class pipe_class_empty() %{ 4912 single_instruction; 4913 fixed_latency(0); 4914 %} 4915 4916 // Pipeline class for compares. 4917 pipe_class pipe_class_compare() %{ 4918 single_instruction; 4919 fixed_latency(16); 4920 %} 4921 4922 // Pipeline class for traps. 4923 pipe_class pipe_class_trap() %{ 4924 single_instruction; 4925 fixed_latency(100); 4926 %} 4927 4928 // Pipeline class for memory operations. 4929 pipe_class pipe_class_memory() %{ 4930 single_instruction; 4931 fixed_latency(16); 4932 %} 4933 4934 // Pipeline class for call. 4935 pipe_class pipe_class_call() %{ 4936 single_instruction; 4937 fixed_latency(100); 4938 %} 4939 4940 // Define the class for the Nop node. 4941 define %{ 4942 MachNop = pipe_class_default; 4943 %} 4944 4945 %} 4946 4947 //----------INSTRUCTIONS------------------------------------------------------- 4948 4949 // Naming of instructions: 4950 // opA_operB / opA_operB_operC: 4951 // Operation 'op' with one or two source operands 'oper'. Result 4952 // type is A, source operand types are B and C. 4953 // Iff A == B == C, B and C are left out. 4954 // 4955 // The instructions are ordered according to the following scheme: 4956 // - loads 4957 // - load constants 4958 // - prefetch 4959 // - store 4960 // - encode/decode 4961 // - membar 4962 // - conditional moves 4963 // - compare & swap 4964 // - arithmetic and logic operations 4965 // * int: Add, Sub, Mul, Div, Mod 4966 // * int: lShift, arShift, urShift, rot 4967 // * float: Add, Sub, Mul, Div 4968 // * and, or, xor ... 4969 // - register moves: float <-> int, reg <-> stack, repl 4970 // - cast (high level type cast, XtoP, castPP, castII, not_null etc. 4971 // - conv (low level type cast requiring bit changes (sign extend etc) 4972 // - compares, range & zero checks. 4973 // - branches 4974 // - complex operations, intrinsics, min, max, replicate 4975 // - lock 4976 // - Calls 4977 // 4978 // If there are similar instructions with different types they are sorted: 4979 // int before float 4980 // small before big 4981 // signed before unsigned 4982 // e.g., loadS before loadUS before loadI before loadF. 4983 4984 4985 //----------Load/Store Instructions-------------------------------------------- 4986 4987 //----------Load Instructions-------------------------------------------------- 4988 4989 // Converts byte to int. 4990 // As convB2I_reg, but without match rule. The match rule of convB2I_reg 4991 // reuses the 'amount' operand, but adlc expects that operand specification 4992 // and operands in match rule are equivalent. 4993 instruct convB2I_reg_2(iRegIdst dst, iRegIsrc src) %{ 4994 effect(DEF dst, USE src); 4995 format %{ "EXTSB $dst, $src \t// byte->int" %} 4996 size(4); 4997 ins_encode %{ 4998 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 4999 __ extsb($dst$$Register, $src$$Register); 5000 %} 5001 ins_pipe(pipe_class_default); 5002 %} 5003 5004 instruct loadUB_indirect(iRegIdst dst, indirectMemory mem) %{ 5005 // match-rule, false predicate 5006 match(Set dst (LoadB mem)); 5007 predicate(false); 5008 5009 format %{ "LBZ $dst, $mem" %} 5010 size(4); 5011 ins_encode( enc_lbz(dst, mem) ); 5012 ins_pipe(pipe_class_memory); 5013 %} 5014 5015 instruct loadUB_indirect_ac(iRegIdst dst, indirectMemory mem) %{ 5016 // match-rule, false predicate 5017 match(Set dst (LoadB mem)); 5018 predicate(false); 5019 5020 format %{ "LBZ $dst, $mem\n\t" 5021 "TWI $dst\n\t" 5022 "ISYNC" %} 5023 size(12); 5024 ins_encode( enc_lbz_ac(dst, mem) ); 5025 ins_pipe(pipe_class_memory); 5026 %} 5027 5028 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5029 instruct loadB_indirect_Ex(iRegIdst dst, indirectMemory mem) %{ 5030 match(Set dst (LoadB mem)); 5031 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5032 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5033 expand %{ 5034 iRegIdst tmp; 5035 loadUB_indirect(tmp, mem); 5036 convB2I_reg_2(dst, tmp); 5037 %} 5038 %} 5039 5040 instruct loadB_indirect_ac_Ex(iRegIdst dst, indirectMemory mem) %{ 5041 match(Set dst (LoadB mem)); 5042 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5043 expand %{ 5044 iRegIdst tmp; 5045 loadUB_indirect_ac(tmp, mem); 5046 convB2I_reg_2(dst, tmp); 5047 %} 5048 %} 5049 5050 instruct loadUB_indOffset16(iRegIdst dst, indOffset16 mem) %{ 5051 // match-rule, false predicate 5052 match(Set dst (LoadB mem)); 5053 predicate(false); 5054 5055 format %{ "LBZ $dst, $mem" %} 5056 size(4); 5057 ins_encode( enc_lbz(dst, mem) ); 5058 ins_pipe(pipe_class_memory); 5059 %} 5060 5061 instruct loadUB_indOffset16_ac(iRegIdst dst, indOffset16 mem) %{ 5062 // match-rule, false predicate 5063 match(Set dst (LoadB mem)); 5064 predicate(false); 5065 5066 format %{ "LBZ $dst, $mem\n\t" 5067 "TWI $dst\n\t" 5068 "ISYNC" %} 5069 size(12); 5070 ins_encode( enc_lbz_ac(dst, mem) ); 5071 ins_pipe(pipe_class_memory); 5072 %} 5073 5074 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5075 instruct loadB_indOffset16_Ex(iRegIdst dst, indOffset16 mem) %{ 5076 match(Set dst (LoadB mem)); 5077 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5078 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5079 5080 expand %{ 5081 iRegIdst tmp; 5082 loadUB_indOffset16(tmp, mem); 5083 convB2I_reg_2(dst, tmp); 5084 %} 5085 %} 5086 5087 instruct loadB_indOffset16_ac_Ex(iRegIdst dst, indOffset16 mem) %{ 5088 match(Set dst (LoadB mem)); 5089 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5090 5091 expand %{ 5092 iRegIdst tmp; 5093 loadUB_indOffset16_ac(tmp, mem); 5094 convB2I_reg_2(dst, tmp); 5095 %} 5096 %} 5097 5098 // Load Unsigned Byte (8bit UNsigned) into an int reg. 5099 instruct loadUB(iRegIdst dst, memory mem) %{ 5100 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5101 match(Set dst (LoadUB mem)); 5102 ins_cost(MEMORY_REF_COST); 5103 5104 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int" %} 5105 size(4); 5106 ins_encode( enc_lbz(dst, mem) ); 5107 ins_pipe(pipe_class_memory); 5108 %} 5109 5110 // Load Unsigned Byte (8bit UNsigned) acquire. 5111 instruct loadUB_ac(iRegIdst dst, memory mem) %{ 5112 match(Set dst (LoadUB mem)); 5113 ins_cost(3*MEMORY_REF_COST); 5114 5115 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int, acquire\n\t" 5116 "TWI $dst\n\t" 5117 "ISYNC" %} 5118 size(12); 5119 ins_encode( enc_lbz_ac(dst, mem) ); 5120 ins_pipe(pipe_class_memory); 5121 %} 5122 5123 // Load Unsigned Byte (8bit UNsigned) into a Long Register. 5124 instruct loadUB2L(iRegLdst dst, memory mem) %{ 5125 match(Set dst (ConvI2L (LoadUB mem))); 5126 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5127 ins_cost(MEMORY_REF_COST); 5128 5129 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long" %} 5130 size(4); 5131 ins_encode( enc_lbz(dst, mem) ); 5132 ins_pipe(pipe_class_memory); 5133 %} 5134 5135 instruct loadUB2L_ac(iRegLdst dst, memory mem) %{ 5136 match(Set dst (ConvI2L (LoadUB mem))); 5137 ins_cost(3*MEMORY_REF_COST); 5138 5139 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long, acquire\n\t" 5140 "TWI $dst\n\t" 5141 "ISYNC" %} 5142 size(12); 5143 ins_encode( enc_lbz_ac(dst, mem) ); 5144 ins_pipe(pipe_class_memory); 5145 %} 5146 5147 // Load Short (16bit signed) 5148 instruct loadS(iRegIdst dst, memory mem) %{ 5149 match(Set dst (LoadS mem)); 5150 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5151 ins_cost(MEMORY_REF_COST); 5152 5153 format %{ "LHA $dst, $mem" %} 5154 size(4); 5155 ins_encode %{ 5156 // TODO: PPC port $archOpcode(ppc64Opcode_lha); 5157 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5158 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5159 %} 5160 ins_pipe(pipe_class_memory); 5161 %} 5162 5163 // Load Short (16bit signed) acquire. 5164 instruct loadS_ac(iRegIdst dst, memory mem) %{ 5165 match(Set dst (LoadS mem)); 5166 ins_cost(3*MEMORY_REF_COST); 5167 5168 format %{ "LHA $dst, $mem\t acquire\n\t" 5169 "TWI $dst\n\t" 5170 "ISYNC" %} 5171 size(12); 5172 ins_encode %{ 5173 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5174 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5175 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5176 __ twi_0($dst$$Register); 5177 __ isync(); 5178 %} 5179 ins_pipe(pipe_class_memory); 5180 %} 5181 5182 // Load Char (16bit unsigned) 5183 instruct loadUS(iRegIdst dst, memory mem) %{ 5184 match(Set dst (LoadUS mem)); 5185 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5186 ins_cost(MEMORY_REF_COST); 5187 5188 format %{ "LHZ $dst, $mem" %} 5189 size(4); 5190 ins_encode( enc_lhz(dst, mem) ); 5191 ins_pipe(pipe_class_memory); 5192 %} 5193 5194 // Load Char (16bit unsigned) acquire. 5195 instruct loadUS_ac(iRegIdst dst, memory mem) %{ 5196 match(Set dst (LoadUS mem)); 5197 ins_cost(3*MEMORY_REF_COST); 5198 5199 format %{ "LHZ $dst, $mem \t// acquire\n\t" 5200 "TWI $dst\n\t" 5201 "ISYNC" %} 5202 size(12); 5203 ins_encode( enc_lhz_ac(dst, mem) ); 5204 ins_pipe(pipe_class_memory); 5205 %} 5206 5207 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register. 5208 instruct loadUS2L(iRegLdst dst, memory mem) %{ 5209 match(Set dst (ConvI2L (LoadUS mem))); 5210 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5211 ins_cost(MEMORY_REF_COST); 5212 5213 format %{ "LHZ $dst, $mem \t// short, zero-extend to long" %} 5214 size(4); 5215 ins_encode( enc_lhz(dst, mem) ); 5216 ins_pipe(pipe_class_memory); 5217 %} 5218 5219 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register acquire. 5220 instruct loadUS2L_ac(iRegLdst dst, memory mem) %{ 5221 match(Set dst (ConvI2L (LoadUS mem))); 5222 ins_cost(3*MEMORY_REF_COST); 5223 5224 format %{ "LHZ $dst, $mem \t// short, zero-extend to long, acquire\n\t" 5225 "TWI $dst\n\t" 5226 "ISYNC" %} 5227 size(12); 5228 ins_encode( enc_lhz_ac(dst, mem) ); 5229 ins_pipe(pipe_class_memory); 5230 %} 5231 5232 // Load Integer. 5233 instruct loadI(iRegIdst dst, memory mem) %{ 5234 match(Set dst (LoadI mem)); 5235 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5236 ins_cost(MEMORY_REF_COST); 5237 5238 format %{ "LWZ $dst, $mem" %} 5239 size(4); 5240 ins_encode( enc_lwz(dst, mem) ); 5241 ins_pipe(pipe_class_memory); 5242 %} 5243 5244 // Load Integer acquire. 5245 instruct loadI_ac(iRegIdst dst, memory mem) %{ 5246 match(Set dst (LoadI mem)); 5247 ins_cost(3*MEMORY_REF_COST); 5248 5249 format %{ "LWZ $dst, $mem \t// load acquire\n\t" 5250 "TWI $dst\n\t" 5251 "ISYNC" %} 5252 size(12); 5253 ins_encode( enc_lwz_ac(dst, mem) ); 5254 ins_pipe(pipe_class_memory); 5255 %} 5256 5257 // Match loading integer and casting it to unsigned int in 5258 // long register. 5259 // LoadI + ConvI2L + AndL 0xffffffff. 5260 instruct loadUI2L(iRegLdst dst, memory mem, immL_32bits mask) %{ 5261 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5262 predicate(_kids[0]->_kids[0]->_leaf->as_Load()->is_unordered()); 5263 ins_cost(MEMORY_REF_COST); 5264 5265 format %{ "LWZ $dst, $mem \t// zero-extend to long" %} 5266 size(4); 5267 ins_encode( enc_lwz(dst, mem) ); 5268 ins_pipe(pipe_class_memory); 5269 %} 5270 5271 // Match loading integer and casting it to long. 5272 instruct loadI2L(iRegLdst dst, memoryAlg4 mem) %{ 5273 match(Set dst (ConvI2L (LoadI mem))); 5274 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5275 ins_cost(MEMORY_REF_COST); 5276 5277 format %{ "LWA $dst, $mem \t// loadI2L" %} 5278 size(4); 5279 ins_encode %{ 5280 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5281 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5282 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5283 %} 5284 ins_pipe(pipe_class_memory); 5285 %} 5286 5287 // Match loading integer and casting it to long - acquire. 5288 instruct loadI2L_ac(iRegLdst dst, memoryAlg4 mem) %{ 5289 match(Set dst (ConvI2L (LoadI mem))); 5290 ins_cost(3*MEMORY_REF_COST); 5291 5292 format %{ "LWA $dst, $mem \t// loadI2L acquire" 5293 "TWI $dst\n\t" 5294 "ISYNC" %} 5295 size(12); 5296 ins_encode %{ 5297 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5298 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5299 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5300 __ twi_0($dst$$Register); 5301 __ isync(); 5302 %} 5303 ins_pipe(pipe_class_memory); 5304 %} 5305 5306 // Load Long - aligned 5307 instruct loadL(iRegLdst dst, memoryAlg4 mem) %{ 5308 match(Set dst (LoadL mem)); 5309 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5310 ins_cost(MEMORY_REF_COST); 5311 5312 format %{ "LD $dst, $mem \t// long" %} 5313 size(4); 5314 ins_encode( enc_ld(dst, mem) ); 5315 ins_pipe(pipe_class_memory); 5316 %} 5317 5318 // Load Long - aligned acquire. 5319 instruct loadL_ac(iRegLdst dst, memoryAlg4 mem) %{ 5320 match(Set dst (LoadL mem)); 5321 ins_cost(3*MEMORY_REF_COST); 5322 5323 format %{ "LD $dst, $mem \t// long acquire\n\t" 5324 "TWI $dst\n\t" 5325 "ISYNC" %} 5326 size(12); 5327 ins_encode( enc_ld_ac(dst, mem) ); 5328 ins_pipe(pipe_class_memory); 5329 %} 5330 5331 // Load Long - UNaligned 5332 instruct loadL_unaligned(iRegLdst dst, memoryAlg4 mem) %{ 5333 match(Set dst (LoadL_unaligned mem)); 5334 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 5335 ins_cost(MEMORY_REF_COST); 5336 5337 format %{ "LD $dst, $mem \t// unaligned long" %} 5338 size(4); 5339 ins_encode( enc_ld(dst, mem) ); 5340 ins_pipe(pipe_class_memory); 5341 %} 5342 5343 // Load nodes for superwords 5344 5345 // Load Aligned Packed Byte 5346 instruct loadV8(iRegLdst dst, memoryAlg4 mem) %{ 5347 predicate(n->as_LoadVector()->memory_size() == 8); 5348 match(Set dst (LoadVector mem)); 5349 ins_cost(MEMORY_REF_COST); 5350 5351 format %{ "LD $dst, $mem \t// load 8-byte Vector" %} 5352 size(4); 5353 ins_encode( enc_ld(dst, mem) ); 5354 ins_pipe(pipe_class_memory); 5355 %} 5356 5357 // Load Range, range = array length (=jint) 5358 instruct loadRange(iRegIdst dst, memory mem) %{ 5359 match(Set dst (LoadRange mem)); 5360 ins_cost(MEMORY_REF_COST); 5361 5362 format %{ "LWZ $dst, $mem \t// range" %} 5363 size(4); 5364 ins_encode( enc_lwz(dst, mem) ); 5365 ins_pipe(pipe_class_memory); 5366 %} 5367 5368 // Load Compressed Pointer 5369 instruct loadN(iRegNdst dst, memory mem) %{ 5370 match(Set dst (LoadN mem)); 5371 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5372 ins_cost(MEMORY_REF_COST); 5373 5374 format %{ "LWZ $dst, $mem \t// load compressed ptr" %} 5375 size(4); 5376 ins_encode( enc_lwz(dst, mem) ); 5377 ins_pipe(pipe_class_memory); 5378 %} 5379 5380 // Load Compressed Pointer acquire. 5381 instruct loadN_ac(iRegNdst dst, memory mem) %{ 5382 match(Set dst (LoadN mem)); 5383 ins_cost(3*MEMORY_REF_COST); 5384 5385 format %{ "LWZ $dst, $mem \t// load acquire compressed ptr\n\t" 5386 "TWI $dst\n\t" 5387 "ISYNC" %} 5388 size(12); 5389 ins_encode( enc_lwz_ac(dst, mem) ); 5390 ins_pipe(pipe_class_memory); 5391 %} 5392 5393 // Load Compressed Pointer and decode it if narrow_oop_shift == 0. 5394 instruct loadN2P_unscaled(iRegPdst dst, memory mem) %{ 5395 match(Set dst (DecodeN (LoadN mem))); 5396 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && Universe::narrow_oop_shift() == 0); 5397 ins_cost(MEMORY_REF_COST); 5398 5399 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5400 size(4); 5401 ins_encode( enc_lwz(dst, mem) ); 5402 ins_pipe(pipe_class_memory); 5403 %} 5404 5405 instruct loadN2P_klass_unscaled(iRegPdst dst, memory mem) %{ 5406 match(Set dst (DecodeNKlass (LoadNKlass mem))); 5407 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0 && 5408 _kids[0]->_leaf->as_Load()->is_unordered()); 5409 ins_cost(MEMORY_REF_COST); 5410 5411 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5412 size(4); 5413 ins_encode( enc_lwz(dst, mem) ); 5414 ins_pipe(pipe_class_memory); 5415 %} 5416 5417 // Load Pointer 5418 instruct loadP(iRegPdst dst, memoryAlg4 mem) %{ 5419 match(Set dst (LoadP mem)); 5420 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5421 ins_cost(MEMORY_REF_COST); 5422 5423 format %{ "LD $dst, $mem \t// ptr" %} 5424 size(4); 5425 ins_encode( enc_ld(dst, mem) ); 5426 ins_pipe(pipe_class_memory); 5427 %} 5428 5429 // Load Pointer acquire. 5430 instruct loadP_ac(iRegPdst dst, memoryAlg4 mem) %{ 5431 match(Set dst (LoadP mem)); 5432 ins_cost(3*MEMORY_REF_COST); 5433 5434 format %{ "LD $dst, $mem \t// ptr acquire\n\t" 5435 "TWI $dst\n\t" 5436 "ISYNC" %} 5437 size(12); 5438 ins_encode( enc_ld_ac(dst, mem) ); 5439 ins_pipe(pipe_class_memory); 5440 %} 5441 5442 // LoadP + CastP2L 5443 instruct loadP2X(iRegLdst dst, memoryAlg4 mem) %{ 5444 match(Set dst (CastP2X (LoadP mem))); 5445 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5446 ins_cost(MEMORY_REF_COST); 5447 5448 format %{ "LD $dst, $mem \t// ptr + p2x" %} 5449 size(4); 5450 ins_encode( enc_ld(dst, mem) ); 5451 ins_pipe(pipe_class_memory); 5452 %} 5453 5454 // Load compressed klass pointer. 5455 instruct loadNKlass(iRegNdst dst, memory mem) %{ 5456 match(Set dst (LoadNKlass mem)); 5457 ins_cost(MEMORY_REF_COST); 5458 5459 format %{ "LWZ $dst, $mem \t// compressed klass ptr" %} 5460 size(4); 5461 ins_encode( enc_lwz(dst, mem) ); 5462 ins_pipe(pipe_class_memory); 5463 %} 5464 5465 // Load Klass Pointer 5466 instruct loadKlass(iRegPdst dst, memoryAlg4 mem) %{ 5467 match(Set dst (LoadKlass mem)); 5468 ins_cost(MEMORY_REF_COST); 5469 5470 format %{ "LD $dst, $mem \t// klass ptr" %} 5471 size(4); 5472 ins_encode( enc_ld(dst, mem) ); 5473 ins_pipe(pipe_class_memory); 5474 %} 5475 5476 // Load Float 5477 instruct loadF(regF dst, memory mem) %{ 5478 match(Set dst (LoadF mem)); 5479 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5480 ins_cost(MEMORY_REF_COST); 5481 5482 format %{ "LFS $dst, $mem" %} 5483 size(4); 5484 ins_encode %{ 5485 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 5486 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5487 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5488 %} 5489 ins_pipe(pipe_class_memory); 5490 %} 5491 5492 // Load Float acquire. 5493 instruct loadF_ac(regF dst, memory mem, flagsRegCR0 cr0) %{ 5494 match(Set dst (LoadF mem)); 5495 effect(TEMP cr0); 5496 ins_cost(3*MEMORY_REF_COST); 5497 5498 format %{ "LFS $dst, $mem \t// acquire\n\t" 5499 "FCMPU cr0, $dst, $dst\n\t" 5500 "BNE cr0, next\n" 5501 "next:\n\t" 5502 "ISYNC" %} 5503 size(16); 5504 ins_encode %{ 5505 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5506 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5507 Label next; 5508 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5509 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 5510 __ bne(CCR0, next); 5511 __ bind(next); 5512 __ isync(); 5513 %} 5514 ins_pipe(pipe_class_memory); 5515 %} 5516 5517 // Load Double - aligned 5518 instruct loadD(regD dst, memory mem) %{ 5519 match(Set dst (LoadD mem)); 5520 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5521 ins_cost(MEMORY_REF_COST); 5522 5523 format %{ "LFD $dst, $mem" %} 5524 size(4); 5525 ins_encode( enc_lfd(dst, mem) ); 5526 ins_pipe(pipe_class_memory); 5527 %} 5528 5529 // Load Double - aligned acquire. 5530 instruct loadD_ac(regD dst, memory mem, flagsRegCR0 cr0) %{ 5531 match(Set dst (LoadD mem)); 5532 effect(TEMP cr0); 5533 ins_cost(3*MEMORY_REF_COST); 5534 5535 format %{ "LFD $dst, $mem \t// acquire\n\t" 5536 "FCMPU cr0, $dst, $dst\n\t" 5537 "BNE cr0, next\n" 5538 "next:\n\t" 5539 "ISYNC" %} 5540 size(16); 5541 ins_encode %{ 5542 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5543 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5544 Label next; 5545 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5546 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 5547 __ bne(CCR0, next); 5548 __ bind(next); 5549 __ isync(); 5550 %} 5551 ins_pipe(pipe_class_memory); 5552 %} 5553 5554 // Load Double - UNaligned 5555 instruct loadD_unaligned(regD dst, memory mem) %{ 5556 match(Set dst (LoadD_unaligned mem)); 5557 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 5558 ins_cost(MEMORY_REF_COST); 5559 5560 format %{ "LFD $dst, $mem" %} 5561 size(4); 5562 ins_encode( enc_lfd(dst, mem) ); 5563 ins_pipe(pipe_class_memory); 5564 %} 5565 5566 //----------Constants-------------------------------------------------------- 5567 5568 // Load MachConstantTableBase: add hi offset to global toc. 5569 // TODO: Handle hidden register r29 in bundler! 5570 instruct loadToc_hi(iRegLdst dst) %{ 5571 effect(DEF dst); 5572 ins_cost(DEFAULT_COST); 5573 5574 format %{ "ADDIS $dst, R29, DISP.hi \t// load TOC hi" %} 5575 size(4); 5576 ins_encode %{ 5577 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 5578 __ calculate_address_from_global_toc_hi16only($dst$$Register, __ method_toc()); 5579 %} 5580 ins_pipe(pipe_class_default); 5581 %} 5582 5583 // Load MachConstantTableBase: add lo offset to global toc. 5584 instruct loadToc_lo(iRegLdst dst, iRegLdst src) %{ 5585 effect(DEF dst, USE src); 5586 ins_cost(DEFAULT_COST); 5587 5588 format %{ "ADDI $dst, $src, DISP.lo \t// load TOC lo" %} 5589 size(4); 5590 ins_encode %{ 5591 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 5592 __ calculate_address_from_global_toc_lo16only($dst$$Register, __ method_toc()); 5593 %} 5594 ins_pipe(pipe_class_default); 5595 %} 5596 5597 // Load 16-bit integer constant 0xssss???? 5598 instruct loadConI16(iRegIdst dst, immI16 src) %{ 5599 match(Set dst src); 5600 5601 format %{ "LI $dst, $src" %} 5602 size(4); 5603 ins_encode %{ 5604 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 5605 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 5606 %} 5607 ins_pipe(pipe_class_default); 5608 %} 5609 5610 // Load integer constant 0x????0000 5611 instruct loadConIhi16(iRegIdst dst, immIhi16 src) %{ 5612 match(Set dst src); 5613 ins_cost(DEFAULT_COST); 5614 5615 format %{ "LIS $dst, $src.hi" %} 5616 size(4); 5617 ins_encode %{ 5618 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 5619 // Lis sign extends 16-bit src then shifts it 16 bit to the left. 5620 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 5621 %} 5622 ins_pipe(pipe_class_default); 5623 %} 5624 5625 // Part 2 of loading 32 bit constant: hi16 is is src1 (properly shifted 5626 // and sign extended), this adds the low 16 bits. 5627 instruct loadConI32_lo16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 5628 // no match-rule, false predicate 5629 effect(DEF dst, USE src1, USE src2); 5630 predicate(false); 5631 5632 format %{ "ORI $dst, $src1.hi, $src2.lo" %} 5633 size(4); 5634 ins_encode %{ 5635 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 5636 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 5637 %} 5638 ins_pipe(pipe_class_default); 5639 %} 5640 5641 instruct loadConI_Ex(iRegIdst dst, immI src) %{ 5642 match(Set dst src); 5643 ins_cost(DEFAULT_COST*2); 5644 5645 expand %{ 5646 // Would like to use $src$$constant. 5647 immI16 srcLo %{ _opnds[1]->constant() %} 5648 // srcHi can be 0000 if srcLo sign-extends to a negative number. 5649 immIhi16 srcHi %{ _opnds[1]->constant() %} 5650 iRegIdst tmpI; 5651 loadConIhi16(tmpI, srcHi); 5652 loadConI32_lo16(dst, tmpI, srcLo); 5653 %} 5654 %} 5655 5656 // No constant pool entries required. 5657 instruct loadConL16(iRegLdst dst, immL16 src) %{ 5658 match(Set dst src); 5659 5660 format %{ "LI $dst, $src \t// long" %} 5661 size(4); 5662 ins_encode %{ 5663 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 5664 __ li($dst$$Register, (int)((short) ($src$$constant & 0xFFFF))); 5665 %} 5666 ins_pipe(pipe_class_default); 5667 %} 5668 5669 // Load long constant 0xssssssss????0000 5670 instruct loadConL32hi16(iRegLdst dst, immL32hi16 src) %{ 5671 match(Set dst src); 5672 ins_cost(DEFAULT_COST); 5673 5674 format %{ "LIS $dst, $src.hi \t// long" %} 5675 size(4); 5676 ins_encode %{ 5677 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 5678 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 5679 %} 5680 ins_pipe(pipe_class_default); 5681 %} 5682 5683 // To load a 32 bit constant: merge lower 16 bits into already loaded 5684 // high 16 bits. 5685 instruct loadConL32_lo16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 5686 // no match-rule, false predicate 5687 effect(DEF dst, USE src1, USE src2); 5688 predicate(false); 5689 5690 format %{ "ORI $dst, $src1, $src2.lo" %} 5691 size(4); 5692 ins_encode %{ 5693 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 5694 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 5695 %} 5696 ins_pipe(pipe_class_default); 5697 %} 5698 5699 // Load 32-bit long constant 5700 instruct loadConL32_Ex(iRegLdst dst, immL32 src) %{ 5701 match(Set dst src); 5702 ins_cost(DEFAULT_COST*2); 5703 5704 expand %{ 5705 // Would like to use $src$$constant. 5706 immL16 srcLo %{ _opnds[1]->constant() /*& 0x0000FFFFL */%} 5707 // srcHi can be 0000 if srcLo sign-extends to a negative number. 5708 immL32hi16 srcHi %{ _opnds[1]->constant() /*& 0xFFFF0000L */%} 5709 iRegLdst tmpL; 5710 loadConL32hi16(tmpL, srcHi); 5711 loadConL32_lo16(dst, tmpL, srcLo); 5712 %} 5713 %} 5714 5715 // Load long constant 0x????000000000000. 5716 instruct loadConLhighest16_Ex(iRegLdst dst, immLhighest16 src) %{ 5717 match(Set dst src); 5718 ins_cost(DEFAULT_COST); 5719 5720 expand %{ 5721 immL32hi16 srcHi %{ _opnds[1]->constant() >> 32 /*& 0xFFFF0000L */%} 5722 immI shift32 %{ 32 %} 5723 iRegLdst tmpL; 5724 loadConL32hi16(tmpL, srcHi); 5725 lshiftL_regL_immI(dst, tmpL, shift32); 5726 %} 5727 %} 5728 5729 // Expand node for constant pool load: small offset. 5730 instruct loadConL(iRegLdst dst, immL src, iRegLdst toc) %{ 5731 effect(DEF dst, USE src, USE toc); 5732 ins_cost(MEMORY_REF_COST); 5733 5734 ins_num_consts(1); 5735 // Needed so that CallDynamicJavaDirect can compute the address of this 5736 // instruction for relocation. 5737 ins_field_cbuf_insts_offset(int); 5738 5739 format %{ "LD $dst, offset, $toc \t// load long $src from TOC" %} 5740 size(4); 5741 ins_encode( enc_load_long_constL(dst, src, toc) ); 5742 ins_pipe(pipe_class_memory); 5743 %} 5744 5745 // Expand node for constant pool load: large offset. 5746 instruct loadConL_hi(iRegLdst dst, immL src, iRegLdst toc) %{ 5747 effect(DEF dst, USE src, USE toc); 5748 predicate(false); 5749 5750 ins_num_consts(1); 5751 ins_field_const_toc_offset(int); 5752 // Needed so that CallDynamicJavaDirect can compute the address of this 5753 // instruction for relocation. 5754 ins_field_cbuf_insts_offset(int); 5755 5756 format %{ "ADDIS $dst, $toc, offset \t// load long $src from TOC (hi)" %} 5757 size(4); 5758 ins_encode( enc_load_long_constL_hi(dst, toc, src) ); 5759 ins_pipe(pipe_class_default); 5760 %} 5761 5762 // Expand node for constant pool load: large offset. 5763 // No constant pool entries required. 5764 instruct loadConL_lo(iRegLdst dst, immL src, iRegLdst base) %{ 5765 effect(DEF dst, USE src, USE base); 5766 predicate(false); 5767 5768 ins_field_const_toc_offset_hi_node(loadConL_hiNode*); 5769 5770 format %{ "LD $dst, offset, $base \t// load long $src from TOC (lo)" %} 5771 size(4); 5772 ins_encode %{ 5773 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 5774 int offset = ra_->C->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 5775 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 5776 %} 5777 ins_pipe(pipe_class_memory); 5778 %} 5779 5780 // Load long constant from constant table. Expand in case of 5781 // offset > 16 bit is needed. 5782 // Adlc adds toc node MachConstantTableBase. 5783 instruct loadConL_Ex(iRegLdst dst, immL src) %{ 5784 match(Set dst src); 5785 ins_cost(MEMORY_REF_COST); 5786 5787 format %{ "LD $dst, offset, $constanttablebase\t// load long $src from table, postalloc expanded" %} 5788 // We can not inline the enc_class for the expand as that does not support constanttablebase. 5789 postalloc_expand( postalloc_expand_load_long_constant(dst, src, constanttablebase) ); 5790 %} 5791 5792 // Load NULL as compressed oop. 5793 instruct loadConN0(iRegNdst dst, immN_0 src) %{ 5794 match(Set dst src); 5795 ins_cost(DEFAULT_COST); 5796 5797 format %{ "LI $dst, $src \t// compressed ptr" %} 5798 size(4); 5799 ins_encode %{ 5800 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 5801 __ li($dst$$Register, 0); 5802 %} 5803 ins_pipe(pipe_class_default); 5804 %} 5805 5806 // Load hi part of compressed oop constant. 5807 instruct loadConN_hi(iRegNdst dst, immN src) %{ 5808 effect(DEF dst, USE src); 5809 ins_cost(DEFAULT_COST); 5810 5811 format %{ "LIS $dst, $src \t// narrow oop hi" %} 5812 size(4); 5813 ins_encode %{ 5814 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 5815 __ lis($dst$$Register, (int)(short)(($src$$constant >> 16) & 0xffff)); 5816 %} 5817 ins_pipe(pipe_class_default); 5818 %} 5819 5820 // Add lo part of compressed oop constant to already loaded hi part. 5821 instruct loadConN_lo(iRegNdst dst, iRegNsrc src1, immN src2) %{ 5822 effect(DEF dst, USE src1, USE src2); 5823 ins_cost(DEFAULT_COST); 5824 5825 format %{ "ORI $dst, $src1, $src2 \t// narrow oop lo" %} 5826 size(4); 5827 ins_encode %{ 5828 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 5829 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 5830 int oop_index = __ oop_recorder()->find_index((jobject)$src2$$constant); 5831 RelocationHolder rspec = oop_Relocation::spec(oop_index); 5832 __ relocate(rspec, 1); 5833 __ ori($dst$$Register, $src1$$Register, $src2$$constant & 0xffff); 5834 %} 5835 ins_pipe(pipe_class_default); 5836 %} 5837 5838 // Needed to postalloc expand loadConN: ConN is loaded as ConI 5839 // leaving the upper 32 bits with sign-extension bits. 5840 // This clears these bits: dst = src & 0xFFFFFFFF. 5841 // TODO: Eventually call this maskN_regN_FFFFFFFF. 5842 instruct clearMs32b(iRegNdst dst, iRegNsrc src) %{ 5843 effect(DEF dst, USE src); 5844 predicate(false); 5845 5846 format %{ "MASK $dst, $src, 0xFFFFFFFF" %} // mask 5847 size(4); 5848 ins_encode %{ 5849 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 5850 __ clrldi($dst$$Register, $src$$Register, 0x20); 5851 %} 5852 ins_pipe(pipe_class_default); 5853 %} 5854 5855 // Optimize DecodeN for disjoint base. 5856 // Load base of compressed oops into a register 5857 instruct loadBase(iRegLdst dst) %{ 5858 effect(DEF dst); 5859 5860 format %{ "LoadConst $dst, heapbase" %} 5861 ins_encode %{ 5862 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5863 __ load_const_optimized($dst$$Register, Universe::narrow_oop_base(), R0); 5864 %} 5865 ins_pipe(pipe_class_default); 5866 %} 5867 5868 // Loading ConN must be postalloc expanded so that edges between 5869 // the nodes are safe. They may not interfere with a safepoint. 5870 // GL TODO: This needs three instructions: better put this into the constant pool. 5871 instruct loadConN_Ex(iRegNdst dst, immN src) %{ 5872 match(Set dst src); 5873 ins_cost(DEFAULT_COST*2); 5874 5875 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 5876 postalloc_expand %{ 5877 MachNode *m1 = new loadConN_hiNode(); 5878 MachNode *m2 = new loadConN_loNode(); 5879 MachNode *m3 = new clearMs32bNode(); 5880 m1->add_req(NULL); 5881 m2->add_req(NULL, m1); 5882 m3->add_req(NULL, m2); 5883 m1->_opnds[0] = op_dst; 5884 m1->_opnds[1] = op_src; 5885 m2->_opnds[0] = op_dst; 5886 m2->_opnds[1] = op_dst; 5887 m2->_opnds[2] = op_src; 5888 m3->_opnds[0] = op_dst; 5889 m3->_opnds[1] = op_dst; 5890 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5891 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5892 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5893 nodes->push(m1); 5894 nodes->push(m2); 5895 nodes->push(m3); 5896 %} 5897 %} 5898 5899 // We have seen a safepoint between the hi and lo parts, and this node was handled 5900 // as an oop. Therefore this needs a match rule so that build_oop_map knows this is 5901 // not a narrow oop. 5902 instruct loadConNKlass_hi(iRegNdst dst, immNKlass_NM src) %{ 5903 match(Set dst src); 5904 effect(DEF dst, USE src); 5905 ins_cost(DEFAULT_COST); 5906 5907 format %{ "LIS $dst, $src \t// narrow klass hi" %} 5908 size(4); 5909 ins_encode %{ 5910 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 5911 intptr_t Csrc = Klass::encode_klass((Klass *)$src$$constant); 5912 __ lis($dst$$Register, (int)(short)((Csrc >> 16) & 0xffff)); 5913 %} 5914 ins_pipe(pipe_class_default); 5915 %} 5916 5917 // As loadConNKlass_hi this must be recognized as narrow klass, not oop! 5918 instruct loadConNKlass_mask(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 5919 match(Set dst src1); 5920 effect(TEMP src2); 5921 ins_cost(DEFAULT_COST); 5922 5923 format %{ "MASK $dst, $src2, 0xFFFFFFFF" %} // mask 5924 size(4); 5925 ins_encode %{ 5926 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 5927 __ clrldi($dst$$Register, $src2$$Register, 0x20); 5928 %} 5929 ins_pipe(pipe_class_default); 5930 %} 5931 5932 // This needs a match rule so that build_oop_map knows this is 5933 // not a narrow oop. 5934 instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 5935 match(Set dst src1); 5936 effect(TEMP src2); 5937 ins_cost(DEFAULT_COST); 5938 5939 format %{ "ORI $dst, $src1, $src2 \t// narrow klass lo" %} 5940 size(4); 5941 ins_encode %{ 5942 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 5943 intptr_t Csrc = Klass::encode_klass((Klass *)$src1$$constant); 5944 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 5945 int klass_index = __ oop_recorder()->find_index((Klass *)$src1$$constant); 5946 RelocationHolder rspec = metadata_Relocation::spec(klass_index); 5947 5948 __ relocate(rspec, 1); 5949 __ ori($dst$$Register, $src2$$Register, Csrc & 0xffff); 5950 %} 5951 ins_pipe(pipe_class_default); 5952 %} 5953 5954 // Loading ConNKlass must be postalloc expanded so that edges between 5955 // the nodes are safe. They may not interfere with a safepoint. 5956 instruct loadConNKlass_Ex(iRegNdst dst, immNKlass src) %{ 5957 match(Set dst src); 5958 ins_cost(DEFAULT_COST*2); 5959 5960 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 5961 postalloc_expand %{ 5962 // Load high bits into register. Sign extended. 5963 MachNode *m1 = new loadConNKlass_hiNode(); 5964 m1->add_req(NULL); 5965 m1->_opnds[0] = op_dst; 5966 m1->_opnds[1] = op_src; 5967 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5968 nodes->push(m1); 5969 5970 MachNode *m2 = m1; 5971 if (!Assembler::is_uimm((jlong)Klass::encode_klass((Klass *)op_src->constant()), 31)) { 5972 // Value might be 1-extended. Mask out these bits. 5973 m2 = new loadConNKlass_maskNode(); 5974 m2->add_req(NULL, m1); 5975 m2->_opnds[0] = op_dst; 5976 m2->_opnds[1] = op_src; 5977 m2->_opnds[2] = op_dst; 5978 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5979 nodes->push(m2); 5980 } 5981 5982 MachNode *m3 = new loadConNKlass_loNode(); 5983 m3->add_req(NULL, m2); 5984 m3->_opnds[0] = op_dst; 5985 m3->_opnds[1] = op_src; 5986 m3->_opnds[2] = op_dst; 5987 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5988 nodes->push(m3); 5989 %} 5990 %} 5991 5992 // 0x1 is used in object initialization (initial object header). 5993 // No constant pool entries required. 5994 instruct loadConP0or1(iRegPdst dst, immP_0or1 src) %{ 5995 match(Set dst src); 5996 5997 format %{ "LI $dst, $src \t// ptr" %} 5998 size(4); 5999 ins_encode %{ 6000 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6001 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 6002 %} 6003 ins_pipe(pipe_class_default); 6004 %} 6005 6006 // Expand node for constant pool load: small offset. 6007 // The match rule is needed to generate the correct bottom_type(), 6008 // however this node should never match. The use of predicate is not 6009 // possible since ADLC forbids predicates for chain rules. The higher 6010 // costs do not prevent matching in this case. For that reason the 6011 // operand immP_NM with predicate(false) is used. 6012 instruct loadConP(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6013 match(Set dst src); 6014 effect(TEMP toc); 6015 6016 ins_num_consts(1); 6017 6018 format %{ "LD $dst, offset, $toc \t// load ptr $src from TOC" %} 6019 size(4); 6020 ins_encode( enc_load_long_constP(dst, src, toc) ); 6021 ins_pipe(pipe_class_memory); 6022 %} 6023 6024 // Expand node for constant pool load: large offset. 6025 instruct loadConP_hi(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6026 effect(DEF dst, USE src, USE toc); 6027 predicate(false); 6028 6029 ins_num_consts(1); 6030 ins_field_const_toc_offset(int); 6031 6032 format %{ "ADDIS $dst, $toc, offset \t// load ptr $src from TOC (hi)" %} 6033 size(4); 6034 ins_encode( enc_load_long_constP_hi(dst, src, toc) ); 6035 ins_pipe(pipe_class_default); 6036 %} 6037 6038 // Expand node for constant pool load: large offset. 6039 instruct loadConP_lo(iRegPdst dst, immP_NM src, iRegLdst base) %{ 6040 match(Set dst src); 6041 effect(TEMP base); 6042 6043 ins_field_const_toc_offset_hi_node(loadConP_hiNode*); 6044 6045 format %{ "LD $dst, offset, $base \t// load ptr $src from TOC (lo)" %} 6046 size(4); 6047 ins_encode %{ 6048 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 6049 int offset = ra_->C->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 6050 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 6051 %} 6052 ins_pipe(pipe_class_memory); 6053 %} 6054 6055 // Load pointer constant from constant table. Expand in case an 6056 // offset > 16 bit is needed. 6057 // Adlc adds toc node MachConstantTableBase. 6058 instruct loadConP_Ex(iRegPdst dst, immP src) %{ 6059 match(Set dst src); 6060 ins_cost(MEMORY_REF_COST); 6061 6062 // This rule does not use "expand" because then 6063 // the result type is not known to be an Oop. An ADLC 6064 // enhancement will be needed to make that work - not worth it! 6065 6066 // If this instruction rematerializes, it prolongs the live range 6067 // of the toc node, causing illegal graphs. 6068 // assert(edge_from_to(_reg_node[reg_lo],def)) fails in verify_good_schedule(). 6069 ins_cannot_rematerialize(true); 6070 6071 format %{ "LD $dst, offset, $constanttablebase \t// load ptr $src from table, postalloc expanded" %} 6072 postalloc_expand( postalloc_expand_load_ptr_constant(dst, src, constanttablebase) ); 6073 %} 6074 6075 // Expand node for constant pool load: small offset. 6076 instruct loadConF(regF dst, immF src, iRegLdst toc) %{ 6077 effect(DEF dst, USE src, USE toc); 6078 ins_cost(MEMORY_REF_COST); 6079 6080 ins_num_consts(1); 6081 6082 format %{ "LFS $dst, offset, $toc \t// load float $src from TOC" %} 6083 size(4); 6084 ins_encode %{ 6085 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 6086 address float_address = __ float_constant($src$$constant); 6087 if (float_address == NULL) { 6088 ciEnv::current()->record_out_of_memory_failure(); 6089 return; 6090 } 6091 __ lfs($dst$$FloatRegister, __ offset_to_method_toc(float_address), $toc$$Register); 6092 %} 6093 ins_pipe(pipe_class_memory); 6094 %} 6095 6096 // Expand node for constant pool load: large offset. 6097 instruct loadConFComp(regF dst, immF src, iRegLdst toc) %{ 6098 effect(DEF dst, USE src, USE toc); 6099 ins_cost(MEMORY_REF_COST); 6100 6101 ins_num_consts(1); 6102 6103 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6104 "LFS $dst, offset_lo, $toc \t// load float $src from TOC (hi/lo)\n\t" 6105 "ADDIS $toc, $toc, -offset_hi"%} 6106 size(12); 6107 ins_encode %{ 6108 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6109 FloatRegister Rdst = $dst$$FloatRegister; 6110 Register Rtoc = $toc$$Register; 6111 address float_address = __ float_constant($src$$constant); 6112 if (float_address == NULL) { 6113 ciEnv::current()->record_out_of_memory_failure(); 6114 return; 6115 } 6116 int offset = __ offset_to_method_toc(float_address); 6117 int hi = (offset + (1<<15))>>16; 6118 int lo = offset - hi * (1<<16); 6119 6120 __ addis(Rtoc, Rtoc, hi); 6121 __ lfs(Rdst, lo, Rtoc); 6122 __ addis(Rtoc, Rtoc, -hi); 6123 %} 6124 ins_pipe(pipe_class_memory); 6125 %} 6126 6127 // Adlc adds toc node MachConstantTableBase. 6128 instruct loadConF_Ex(regF dst, immF src) %{ 6129 match(Set dst src); 6130 ins_cost(MEMORY_REF_COST); 6131 6132 // See loadConP. 6133 ins_cannot_rematerialize(true); 6134 6135 format %{ "LFS $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6136 postalloc_expand( postalloc_expand_load_float_constant(dst, src, constanttablebase) ); 6137 %} 6138 6139 // Expand node for constant pool load: small offset. 6140 instruct loadConD(regD dst, immD src, iRegLdst toc) %{ 6141 effect(DEF dst, USE src, USE toc); 6142 ins_cost(MEMORY_REF_COST); 6143 6144 ins_num_consts(1); 6145 6146 format %{ "LFD $dst, offset, $toc \t// load double $src from TOC" %} 6147 size(4); 6148 ins_encode %{ 6149 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 6150 address float_address = __ double_constant($src$$constant); 6151 if (float_address == NULL) { 6152 ciEnv::current()->record_out_of_memory_failure(); 6153 return; 6154 } 6155 int offset = __ offset_to_method_toc(float_address); 6156 __ lfd($dst$$FloatRegister, offset, $toc$$Register); 6157 %} 6158 ins_pipe(pipe_class_memory); 6159 %} 6160 6161 // Expand node for constant pool load: large offset. 6162 instruct loadConDComp(regD dst, immD src, iRegLdst toc) %{ 6163 effect(DEF dst, USE src, USE toc); 6164 ins_cost(MEMORY_REF_COST); 6165 6166 ins_num_consts(1); 6167 6168 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6169 "LFD $dst, offset_lo, $toc \t// load double $src from TOC (hi/lo)\n\t" 6170 "ADDIS $toc, $toc, -offset_hi" %} 6171 size(12); 6172 ins_encode %{ 6173 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6174 FloatRegister Rdst = $dst$$FloatRegister; 6175 Register Rtoc = $toc$$Register; 6176 address float_address = __ double_constant($src$$constant); 6177 if (float_address == NULL) { 6178 ciEnv::current()->record_out_of_memory_failure(); 6179 return; 6180 } 6181 int offset = __ offset_to_method_toc(float_address); 6182 int hi = (offset + (1<<15))>>16; 6183 int lo = offset - hi * (1<<16); 6184 6185 __ addis(Rtoc, Rtoc, hi); 6186 __ lfd(Rdst, lo, Rtoc); 6187 __ addis(Rtoc, Rtoc, -hi); 6188 %} 6189 ins_pipe(pipe_class_memory); 6190 %} 6191 6192 // Adlc adds toc node MachConstantTableBase. 6193 instruct loadConD_Ex(regD dst, immD src) %{ 6194 match(Set dst src); 6195 ins_cost(MEMORY_REF_COST); 6196 6197 // See loadConP. 6198 ins_cannot_rematerialize(true); 6199 6200 format %{ "ConD $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6201 postalloc_expand( postalloc_expand_load_double_constant(dst, src, constanttablebase) ); 6202 %} 6203 6204 // Prefetch instructions. 6205 // Must be safe to execute with invalid address (cannot fault). 6206 6207 // Special prefetch versions which use the dcbz instruction. 6208 instruct prefetch_alloc_zero(indirectMemory mem, iRegLsrc src) %{ 6209 match(PrefetchAllocation (AddP mem src)); 6210 predicate(AllocatePrefetchStyle == 3); 6211 ins_cost(MEMORY_REF_COST); 6212 6213 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many with zero" %} 6214 size(4); 6215 ins_encode %{ 6216 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6217 __ dcbz($src$$Register, $mem$$base$$Register); 6218 %} 6219 ins_pipe(pipe_class_memory); 6220 %} 6221 6222 instruct prefetch_alloc_zero_no_offset(indirectMemory mem) %{ 6223 match(PrefetchAllocation mem); 6224 predicate(AllocatePrefetchStyle == 3); 6225 ins_cost(MEMORY_REF_COST); 6226 6227 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many with zero" %} 6228 size(4); 6229 ins_encode %{ 6230 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6231 __ dcbz($mem$$base$$Register); 6232 %} 6233 ins_pipe(pipe_class_memory); 6234 %} 6235 6236 instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{ 6237 match(PrefetchAllocation (AddP mem src)); 6238 predicate(AllocatePrefetchStyle != 3); 6239 ins_cost(MEMORY_REF_COST); 6240 6241 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many" %} 6242 size(4); 6243 ins_encode %{ 6244 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6245 __ dcbtst($src$$Register, $mem$$base$$Register); 6246 %} 6247 ins_pipe(pipe_class_memory); 6248 %} 6249 6250 instruct prefetch_alloc_no_offset(indirectMemory mem) %{ 6251 match(PrefetchAllocation mem); 6252 predicate(AllocatePrefetchStyle != 3); 6253 ins_cost(MEMORY_REF_COST); 6254 6255 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many" %} 6256 size(4); 6257 ins_encode %{ 6258 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6259 __ dcbtst($mem$$base$$Register); 6260 %} 6261 ins_pipe(pipe_class_memory); 6262 %} 6263 6264 //----------Store Instructions------------------------------------------------- 6265 6266 // Store Byte 6267 instruct storeB(memory mem, iRegIsrc src) %{ 6268 match(Set mem (StoreB mem src)); 6269 ins_cost(MEMORY_REF_COST); 6270 6271 format %{ "STB $src, $mem \t// byte" %} 6272 size(4); 6273 ins_encode %{ 6274 // TODO: PPC port $archOpcode(ppc64Opcode_stb); 6275 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6276 __ stb($src$$Register, Idisp, $mem$$base$$Register); 6277 %} 6278 ins_pipe(pipe_class_memory); 6279 %} 6280 6281 // Store Char/Short 6282 instruct storeC(memory mem, iRegIsrc src) %{ 6283 match(Set mem (StoreC mem src)); 6284 ins_cost(MEMORY_REF_COST); 6285 6286 format %{ "STH $src, $mem \t// short" %} 6287 size(4); 6288 ins_encode %{ 6289 // TODO: PPC port $archOpcode(ppc64Opcode_sth); 6290 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6291 __ sth($src$$Register, Idisp, $mem$$base$$Register); 6292 %} 6293 ins_pipe(pipe_class_memory); 6294 %} 6295 6296 // Store Integer 6297 instruct storeI(memory mem, iRegIsrc src) %{ 6298 match(Set mem (StoreI mem src)); 6299 ins_cost(MEMORY_REF_COST); 6300 6301 format %{ "STW $src, $mem" %} 6302 size(4); 6303 ins_encode( enc_stw(src, mem) ); 6304 ins_pipe(pipe_class_memory); 6305 %} 6306 6307 // ConvL2I + StoreI. 6308 instruct storeI_convL2I(memory mem, iRegLsrc src) %{ 6309 match(Set mem (StoreI mem (ConvL2I src))); 6310 ins_cost(MEMORY_REF_COST); 6311 6312 format %{ "STW l2i($src), $mem" %} 6313 size(4); 6314 ins_encode( enc_stw(src, mem) ); 6315 ins_pipe(pipe_class_memory); 6316 %} 6317 6318 // Store Long 6319 instruct storeL(memoryAlg4 mem, iRegLsrc src) %{ 6320 match(Set mem (StoreL mem src)); 6321 ins_cost(MEMORY_REF_COST); 6322 6323 format %{ "STD $src, $mem \t// long" %} 6324 size(4); 6325 ins_encode( enc_std(src, mem) ); 6326 ins_pipe(pipe_class_memory); 6327 %} 6328 6329 // Store super word nodes. 6330 6331 // Store Aligned Packed Byte long register to memory 6332 instruct storeA8B(memoryAlg4 mem, iRegLsrc src) %{ 6333 predicate(n->as_StoreVector()->memory_size() == 8); 6334 match(Set mem (StoreVector mem src)); 6335 ins_cost(MEMORY_REF_COST); 6336 6337 format %{ "STD $mem, $src \t// packed8B" %} 6338 size(4); 6339 ins_encode( enc_std(src, mem) ); 6340 ins_pipe(pipe_class_memory); 6341 %} 6342 6343 // Store Compressed Oop 6344 instruct storeN(memory dst, iRegN_P2N src) %{ 6345 match(Set dst (StoreN dst src)); 6346 ins_cost(MEMORY_REF_COST); 6347 6348 format %{ "STW $src, $dst \t// compressed oop" %} 6349 size(4); 6350 ins_encode( enc_stw(src, dst) ); 6351 ins_pipe(pipe_class_memory); 6352 %} 6353 6354 // Store Compressed KLass 6355 instruct storeNKlass(memory dst, iRegN_P2N src) %{ 6356 match(Set dst (StoreNKlass dst src)); 6357 ins_cost(MEMORY_REF_COST); 6358 6359 format %{ "STW $src, $dst \t// compressed klass" %} 6360 size(4); 6361 ins_encode( enc_stw(src, dst) ); 6362 ins_pipe(pipe_class_memory); 6363 %} 6364 6365 // Store Pointer 6366 instruct storeP(memoryAlg4 dst, iRegPsrc src) %{ 6367 match(Set dst (StoreP dst src)); 6368 ins_cost(MEMORY_REF_COST); 6369 6370 format %{ "STD $src, $dst \t// ptr" %} 6371 size(4); 6372 ins_encode( enc_std(src, dst) ); 6373 ins_pipe(pipe_class_memory); 6374 %} 6375 6376 // Store Float 6377 instruct storeF(memory mem, regF src) %{ 6378 match(Set mem (StoreF mem src)); 6379 ins_cost(MEMORY_REF_COST); 6380 6381 format %{ "STFS $src, $mem" %} 6382 size(4); 6383 ins_encode( enc_stfs(src, mem) ); 6384 ins_pipe(pipe_class_memory); 6385 %} 6386 6387 // Store Double 6388 instruct storeD(memory mem, regD src) %{ 6389 match(Set mem (StoreD mem src)); 6390 ins_cost(MEMORY_REF_COST); 6391 6392 format %{ "STFD $src, $mem" %} 6393 size(4); 6394 ins_encode( enc_stfd(src, mem) ); 6395 ins_pipe(pipe_class_memory); 6396 %} 6397 6398 //----------Store Instructions With Zeros-------------------------------------- 6399 6400 // Card-mark for CMS garbage collection. 6401 // This cardmark does an optimization so that it must not always 6402 // do a releasing store. For this, it gets the address of 6403 // CMSCollectorCardTableModRefBSExt::_requires_release as input. 6404 // (Using releaseFieldAddr in the match rule is a hack.) 6405 instruct storeCM_CMS(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 6406 match(Set mem (StoreCM mem releaseFieldAddr)); 6407 effect(TEMP crx); 6408 predicate(false); 6409 ins_cost(MEMORY_REF_COST); 6410 6411 // See loadConP. 6412 ins_cannot_rematerialize(true); 6413 6414 format %{ "STB #0, $mem \t// CMS card-mark byte (must be 0!), checking requires_release in [$releaseFieldAddr]" %} 6415 ins_encode( enc_cms_card_mark(mem, releaseFieldAddr, crx) ); 6416 ins_pipe(pipe_class_memory); 6417 %} 6418 6419 // Card-mark for CMS garbage collection. 6420 // This cardmark does an optimization so that it must not always 6421 // do a releasing store. For this, it needs the constant address of 6422 // CMSCollectorCardTableModRefBSExt::_requires_release. 6423 // This constant address is split off here by expand so we can use 6424 // adlc / matcher functionality to load it from the constant section. 6425 instruct storeCM_CMS_ExEx(memory mem, immI_0 zero) %{ 6426 match(Set mem (StoreCM mem zero)); 6427 predicate(UseConcMarkSweepGC); 6428 6429 expand %{ 6430 immL baseImm %{ 0 /* TODO: PPC port (jlong)CMSCollectorCardTableModRefBSExt::requires_release_address() */ %} 6431 iRegLdst releaseFieldAddress; 6432 flagsReg crx; 6433 loadConL_Ex(releaseFieldAddress, baseImm); 6434 storeCM_CMS(mem, releaseFieldAddress, crx); 6435 %} 6436 %} 6437 6438 instruct storeCM_G1(memory mem, immI_0 zero) %{ 6439 match(Set mem (StoreCM mem zero)); 6440 predicate(UseG1GC); 6441 ins_cost(MEMORY_REF_COST); 6442 6443 ins_cannot_rematerialize(true); 6444 6445 format %{ "STB #0, $mem \t// CMS card-mark byte store (G1)" %} 6446 size(8); 6447 ins_encode %{ 6448 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6449 __ li(R0, 0); 6450 //__ release(); // G1: oops are allowed to get visible after dirty marking 6451 guarantee($mem$$base$$Register != R1_SP, "use frame_slots_bias"); 6452 __ stb(R0, $mem$$disp, $mem$$base$$Register); 6453 %} 6454 ins_pipe(pipe_class_memory); 6455 %} 6456 6457 // Convert oop pointer into compressed form. 6458 6459 // Nodes for postalloc expand. 6460 6461 // Shift node for expand. 6462 instruct encodeP_shift(iRegNdst dst, iRegNsrc src) %{ 6463 // The match rule is needed to make it a 'MachTypeNode'! 6464 match(Set dst (EncodeP src)); 6465 predicate(false); 6466 6467 format %{ "SRDI $dst, $src, 3 \t// encode" %} 6468 size(4); 6469 ins_encode %{ 6470 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6471 __ srdi($dst$$Register, $src$$Register, Universe::narrow_oop_shift() & 0x3f); 6472 %} 6473 ins_pipe(pipe_class_default); 6474 %} 6475 6476 // Add node for expand. 6477 instruct encodeP_sub(iRegPdst dst, iRegPdst src) %{ 6478 // The match rule is needed to make it a 'MachTypeNode'! 6479 match(Set dst (EncodeP src)); 6480 predicate(false); 6481 6482 format %{ "SUB $dst, $src, oop_base \t// encode" %} 6483 ins_encode %{ 6484 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6485 __ sub_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 6486 %} 6487 ins_pipe(pipe_class_default); 6488 %} 6489 6490 // Conditional sub base. 6491 instruct cond_sub_base(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6492 // The match rule is needed to make it a 'MachTypeNode'! 6493 match(Set dst (EncodeP (Binary crx src1))); 6494 predicate(false); 6495 6496 format %{ "BEQ $crx, done\n\t" 6497 "SUB $dst, $src1, heapbase \t// encode: subtract base if != NULL\n" 6498 "done:" %} 6499 ins_encode %{ 6500 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6501 Label done; 6502 __ beq($crx$$CondRegister, done); 6503 __ sub_const_optimized($dst$$Register, $src1$$Register, Universe::narrow_oop_base(), R0); 6504 __ bind(done); 6505 %} 6506 ins_pipe(pipe_class_default); 6507 %} 6508 6509 // Power 7 can use isel instruction 6510 instruct cond_set_0_oop(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6511 // The match rule is needed to make it a 'MachTypeNode'! 6512 match(Set dst (EncodeP (Binary crx src1))); 6513 predicate(false); 6514 6515 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// encode: preserve 0" %} 6516 size(4); 6517 ins_encode %{ 6518 // This is a Power7 instruction for which no machine description exists. 6519 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6520 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 6521 %} 6522 ins_pipe(pipe_class_default); 6523 %} 6524 6525 // Disjoint narrow oop base. 6526 instruct encodeP_Disjoint(iRegNdst dst, iRegPsrc src) %{ 6527 match(Set dst (EncodeP src)); 6528 predicate(Universe::narrow_oop_base_disjoint()); 6529 6530 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 6531 size(4); 6532 ins_encode %{ 6533 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6534 __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_oop_shift(), 32); 6535 %} 6536 ins_pipe(pipe_class_default); 6537 %} 6538 6539 // shift != 0, base != 0 6540 instruct encodeP_Ex(iRegNdst dst, flagsReg crx, iRegPsrc src) %{ 6541 match(Set dst (EncodeP src)); 6542 effect(TEMP crx); 6543 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull && 6544 Universe::narrow_oop_shift() != 0 && 6545 Universe::narrow_oop_base_overlaps()); 6546 6547 format %{ "EncodeP $dst, $crx, $src \t// postalloc expanded" %} 6548 postalloc_expand( postalloc_expand_encode_oop(dst, src, crx)); 6549 %} 6550 6551 // shift != 0, base != 0 6552 instruct encodeP_not_null_Ex(iRegNdst dst, iRegPsrc src) %{ 6553 match(Set dst (EncodeP src)); 6554 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull && 6555 Universe::narrow_oop_shift() != 0 && 6556 Universe::narrow_oop_base_overlaps()); 6557 6558 format %{ "EncodeP $dst, $src\t// $src != Null, postalloc expanded" %} 6559 postalloc_expand( postalloc_expand_encode_oop_not_null(dst, src) ); 6560 %} 6561 6562 // shift != 0, base == 0 6563 // TODO: This is the same as encodeP_shift. Merge! 6564 instruct encodeP_not_null_base_null(iRegNdst dst, iRegPsrc src) %{ 6565 match(Set dst (EncodeP src)); 6566 predicate(Universe::narrow_oop_shift() != 0 && 6567 Universe::narrow_oop_base() ==0); 6568 6569 format %{ "SRDI $dst, $src, #3 \t// encodeP, $src != NULL" %} 6570 size(4); 6571 ins_encode %{ 6572 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6573 __ srdi($dst$$Register, $src$$Register, Universe::narrow_oop_shift() & 0x3f); 6574 %} 6575 ins_pipe(pipe_class_default); 6576 %} 6577 6578 // Compressed OOPs with narrow_oop_shift == 0. 6579 // shift == 0, base == 0 6580 instruct encodeP_narrow_oop_shift_0(iRegNdst dst, iRegPsrc src) %{ 6581 match(Set dst (EncodeP src)); 6582 predicate(Universe::narrow_oop_shift() == 0); 6583 6584 format %{ "MR $dst, $src \t// Ptr->Narrow" %} 6585 // variable size, 0 or 4. 6586 ins_encode %{ 6587 // TODO: PPC port $archOpcode(ppc64Opcode_or); 6588 __ mr_if_needed($dst$$Register, $src$$Register); 6589 %} 6590 ins_pipe(pipe_class_default); 6591 %} 6592 6593 // Decode nodes. 6594 6595 // Shift node for expand. 6596 instruct decodeN_shift(iRegPdst dst, iRegPsrc src) %{ 6597 // The match rule is needed to make it a 'MachTypeNode'! 6598 match(Set dst (DecodeN src)); 6599 predicate(false); 6600 6601 format %{ "SLDI $dst, $src, #3 \t// DecodeN" %} 6602 size(4); 6603 ins_encode %{ 6604 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 6605 __ sldi($dst$$Register, $src$$Register, Universe::narrow_oop_shift()); 6606 %} 6607 ins_pipe(pipe_class_default); 6608 %} 6609 6610 // Add node for expand. 6611 instruct decodeN_add(iRegPdst dst, iRegPdst src) %{ 6612 // The match rule is needed to make it a 'MachTypeNode'! 6613 match(Set dst (DecodeN src)); 6614 predicate(false); 6615 6616 format %{ "ADD $dst, $src, heapbase \t// DecodeN, add oop base" %} 6617 ins_encode %{ 6618 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6619 __ add_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 6620 %} 6621 ins_pipe(pipe_class_default); 6622 %} 6623 6624 // conditianal add base for expand 6625 instruct cond_add_base(iRegPdst dst, flagsRegSrc crx, iRegPsrc src) %{ 6626 // The match rule is needed to make it a 'MachTypeNode'! 6627 // NOTICE that the rule is nonsense - we just have to make sure that: 6628 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 6629 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 6630 match(Set dst (DecodeN (Binary crx src))); 6631 predicate(false); 6632 6633 format %{ "BEQ $crx, done\n\t" 6634 "ADD $dst, $src, heapbase \t// DecodeN: add oop base if $src != NULL\n" 6635 "done:" %} 6636 ins_encode %{ 6637 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6638 Label done; 6639 __ beq($crx$$CondRegister, done); 6640 __ add_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 6641 __ bind(done); 6642 %} 6643 ins_pipe(pipe_class_default); 6644 %} 6645 6646 instruct cond_set_0_ptr(iRegPdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6647 // The match rule is needed to make it a 'MachTypeNode'! 6648 // NOTICE that the rule is nonsense - we just have to make sure that: 6649 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 6650 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 6651 match(Set dst (DecodeN (Binary crx src1))); 6652 predicate(false); 6653 6654 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// decode: preserve 0" %} 6655 size(4); 6656 ins_encode %{ 6657 // This is a Power7 instruction for which no machine description exists. 6658 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6659 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 6660 %} 6661 ins_pipe(pipe_class_default); 6662 %} 6663 6664 // shift != 0, base != 0 6665 instruct decodeN_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 6666 match(Set dst (DecodeN src)); 6667 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 6668 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 6669 Universe::narrow_oop_shift() != 0 && 6670 Universe::narrow_oop_base() != 0); 6671 ins_cost(4 * DEFAULT_COST); // Should be more expensive than decodeN_Disjoint_isel_Ex. 6672 effect(TEMP crx); 6673 6674 format %{ "DecodeN $dst, $src \t// Kills $crx, postalloc expanded" %} 6675 postalloc_expand( postalloc_expand_decode_oop(dst, src, crx) ); 6676 %} 6677 6678 // shift != 0, base == 0 6679 instruct decodeN_nullBase(iRegPdst dst, iRegNsrc src) %{ 6680 match(Set dst (DecodeN src)); 6681 predicate(Universe::narrow_oop_shift() != 0 && 6682 Universe::narrow_oop_base() == 0); 6683 6684 format %{ "SLDI $dst, $src, #3 \t// DecodeN (zerobased)" %} 6685 size(4); 6686 ins_encode %{ 6687 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 6688 __ sldi($dst$$Register, $src$$Register, Universe::narrow_oop_shift()); 6689 %} 6690 ins_pipe(pipe_class_default); 6691 %} 6692 6693 // Optimize DecodeN for disjoint base. 6694 // Shift narrow oop and or it into register that already contains the heap base. 6695 // Base == dst must hold, and is assured by construction in postaloc_expand. 6696 instruct decodeN_mergeDisjoint(iRegPdst dst, iRegNsrc src, iRegLsrc base) %{ 6697 match(Set dst (DecodeN src)); 6698 effect(TEMP base); 6699 predicate(false); 6700 6701 format %{ "RLDIMI $dst, $src, shift, 32-shift \t// DecodeN (disjoint base)" %} 6702 size(4); 6703 ins_encode %{ 6704 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 6705 __ rldimi($dst$$Register, $src$$Register, Universe::narrow_oop_shift(), 32-Universe::narrow_oop_shift()); 6706 %} 6707 ins_pipe(pipe_class_default); 6708 %} 6709 6710 // Optimize DecodeN for disjoint base. 6711 // This node requires only one cycle on the critical path. 6712 // We must postalloc_expand as we can not express use_def effects where 6713 // the used register is L and the def'ed register P. 6714 instruct decodeN_Disjoint_notNull_Ex(iRegPdst dst, iRegNsrc src) %{ 6715 match(Set dst (DecodeN src)); 6716 effect(TEMP_DEF dst); 6717 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 6718 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 6719 Universe::narrow_oop_base_disjoint()); 6720 ins_cost(DEFAULT_COST); 6721 6722 format %{ "MOV $dst, heapbase \t\n" 6723 "RLDIMI $dst, $src, shift, 32-shift \t// decode with disjoint base" %} 6724 postalloc_expand %{ 6725 loadBaseNode *n1 = new loadBaseNode(); 6726 n1->add_req(NULL); 6727 n1->_opnds[0] = op_dst; 6728 6729 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 6730 n2->add_req(n_region, n_src, n1); 6731 n2->_opnds[0] = op_dst; 6732 n2->_opnds[1] = op_src; 6733 n2->_opnds[2] = op_dst; 6734 n2->_bottom_type = _bottom_type; 6735 6736 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6737 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6738 6739 nodes->push(n1); 6740 nodes->push(n2); 6741 %} 6742 %} 6743 6744 instruct decodeN_Disjoint_isel_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 6745 match(Set dst (DecodeN src)); 6746 effect(TEMP_DEF dst, TEMP crx); 6747 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 6748 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 6749 Universe::narrow_oop_base_disjoint() && VM_Version::has_isel()); 6750 ins_cost(3 * DEFAULT_COST); 6751 6752 format %{ "DecodeN $dst, $src \t// decode with disjoint base using isel" %} 6753 postalloc_expand %{ 6754 loadBaseNode *n1 = new loadBaseNode(); 6755 n1->add_req(NULL); 6756 n1->_opnds[0] = op_dst; 6757 6758 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 6759 n_compare->add_req(n_region, n_src); 6760 n_compare->_opnds[0] = op_crx; 6761 n_compare->_opnds[1] = op_src; 6762 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 6763 6764 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 6765 n2->add_req(n_region, n_src, n1); 6766 n2->_opnds[0] = op_dst; 6767 n2->_opnds[1] = op_src; 6768 n2->_opnds[2] = op_dst; 6769 n2->_bottom_type = _bottom_type; 6770 6771 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 6772 n_cond_set->add_req(n_region, n_compare, n2); 6773 n_cond_set->_opnds[0] = op_dst; 6774 n_cond_set->_opnds[1] = op_crx; 6775 n_cond_set->_opnds[2] = op_dst; 6776 n_cond_set->_bottom_type = _bottom_type; 6777 6778 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 6779 ra_->set_oop(n_cond_set, true); 6780 6781 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6782 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 6783 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6784 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6785 6786 nodes->push(n1); 6787 nodes->push(n_compare); 6788 nodes->push(n2); 6789 nodes->push(n_cond_set); 6790 %} 6791 %} 6792 6793 // src != 0, shift != 0, base != 0 6794 instruct decodeN_notNull_addBase_Ex(iRegPdst dst, iRegNsrc src) %{ 6795 match(Set dst (DecodeN src)); 6796 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 6797 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 6798 Universe::narrow_oop_shift() != 0 && 6799 Universe::narrow_oop_base() != 0); 6800 ins_cost(2 * DEFAULT_COST); 6801 6802 format %{ "DecodeN $dst, $src \t// $src != NULL, postalloc expanded" %} 6803 postalloc_expand( postalloc_expand_decode_oop_not_null(dst, src)); 6804 %} 6805 6806 // Compressed OOPs with narrow_oop_shift == 0. 6807 instruct decodeN_unscaled(iRegPdst dst, iRegNsrc src) %{ 6808 match(Set dst (DecodeN src)); 6809 predicate(Universe::narrow_oop_shift() == 0); 6810 ins_cost(DEFAULT_COST); 6811 6812 format %{ "MR $dst, $src \t// DecodeN (unscaled)" %} 6813 // variable size, 0 or 4. 6814 ins_encode %{ 6815 // TODO: PPC port $archOpcode(ppc64Opcode_or); 6816 __ mr_if_needed($dst$$Register, $src$$Register); 6817 %} 6818 ins_pipe(pipe_class_default); 6819 %} 6820 6821 // Convert compressed oop into int for vectors alignment masking. 6822 instruct decodeN2I_unscaled(iRegIdst dst, iRegNsrc src) %{ 6823 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6824 predicate(Universe::narrow_oop_shift() == 0); 6825 ins_cost(DEFAULT_COST); 6826 6827 format %{ "MR $dst, $src \t// (int)DecodeN (unscaled)" %} 6828 // variable size, 0 or 4. 6829 ins_encode %{ 6830 // TODO: PPC port $archOpcode(ppc64Opcode_or); 6831 __ mr_if_needed($dst$$Register, $src$$Register); 6832 %} 6833 ins_pipe(pipe_class_default); 6834 %} 6835 6836 // Convert klass pointer into compressed form. 6837 6838 // Nodes for postalloc expand. 6839 6840 // Shift node for expand. 6841 instruct encodePKlass_shift(iRegNdst dst, iRegNsrc src) %{ 6842 // The match rule is needed to make it a 'MachTypeNode'! 6843 match(Set dst (EncodePKlass src)); 6844 predicate(false); 6845 6846 format %{ "SRDI $dst, $src, 3 \t// encode" %} 6847 size(4); 6848 ins_encode %{ 6849 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6850 __ srdi($dst$$Register, $src$$Register, Universe::narrow_klass_shift()); 6851 %} 6852 ins_pipe(pipe_class_default); 6853 %} 6854 6855 // Add node for expand. 6856 instruct encodePKlass_sub_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 6857 // The match rule is needed to make it a 'MachTypeNode'! 6858 match(Set dst (EncodePKlass (Binary base src))); 6859 predicate(false); 6860 6861 format %{ "SUB $dst, $base, $src \t// encode" %} 6862 size(4); 6863 ins_encode %{ 6864 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 6865 __ subf($dst$$Register, $base$$Register, $src$$Register); 6866 %} 6867 ins_pipe(pipe_class_default); 6868 %} 6869 6870 // Disjoint narrow oop base. 6871 instruct encodePKlass_Disjoint(iRegNdst dst, iRegPsrc src) %{ 6872 match(Set dst (EncodePKlass src)); 6873 predicate(false /* TODO: PPC port Universe::narrow_klass_base_disjoint()*/); 6874 6875 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 6876 size(4); 6877 ins_encode %{ 6878 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6879 __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_klass_shift(), 32); 6880 %} 6881 ins_pipe(pipe_class_default); 6882 %} 6883 6884 // shift != 0, base != 0 6885 instruct encodePKlass_not_null_Ex(iRegNdst dst, iRegLsrc base, iRegPsrc src) %{ 6886 match(Set dst (EncodePKlass (Binary base src))); 6887 predicate(false); 6888 6889 format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 6890 postalloc_expand %{ 6891 encodePKlass_sub_baseNode *n1 = new encodePKlass_sub_baseNode(); 6892 n1->add_req(n_region, n_base, n_src); 6893 n1->_opnds[0] = op_dst; 6894 n1->_opnds[1] = op_base; 6895 n1->_opnds[2] = op_src; 6896 n1->_bottom_type = _bottom_type; 6897 6898 encodePKlass_shiftNode *n2 = new encodePKlass_shiftNode(); 6899 n2->add_req(n_region, n1); 6900 n2->_opnds[0] = op_dst; 6901 n2->_opnds[1] = op_dst; 6902 n2->_bottom_type = _bottom_type; 6903 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6904 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6905 6906 nodes->push(n1); 6907 nodes->push(n2); 6908 %} 6909 %} 6910 6911 // shift != 0, base != 0 6912 instruct encodePKlass_not_null_ExEx(iRegNdst dst, iRegPsrc src) %{ 6913 match(Set dst (EncodePKlass src)); 6914 //predicate(Universe::narrow_klass_shift() != 0 && 6915 // true /* TODO: PPC port Universe::narrow_klass_base_overlaps()*/); 6916 6917 //format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 6918 ins_cost(DEFAULT_COST*2); // Don't count constant. 6919 expand %{ 6920 immL baseImm %{ (jlong)(intptr_t)Universe::narrow_klass_base() %} 6921 iRegLdst base; 6922 loadConL_Ex(base, baseImm); 6923 encodePKlass_not_null_Ex(dst, base, src); 6924 %} 6925 %} 6926 6927 // Decode nodes. 6928 6929 // Shift node for expand. 6930 instruct decodeNKlass_shift(iRegPdst dst, iRegPsrc src) %{ 6931 // The match rule is needed to make it a 'MachTypeNode'! 6932 match(Set dst (DecodeNKlass src)); 6933 predicate(false); 6934 6935 format %{ "SLDI $dst, $src, #3 \t// DecodeNKlass" %} 6936 size(4); 6937 ins_encode %{ 6938 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 6939 __ sldi($dst$$Register, $src$$Register, Universe::narrow_klass_shift()); 6940 %} 6941 ins_pipe(pipe_class_default); 6942 %} 6943 6944 // Add node for expand. 6945 6946 instruct decodeNKlass_add_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 6947 // The match rule is needed to make it a 'MachTypeNode'! 6948 match(Set dst (DecodeNKlass (Binary base src))); 6949 predicate(false); 6950 6951 format %{ "ADD $dst, $base, $src \t// DecodeNKlass, add klass base" %} 6952 size(4); 6953 ins_encode %{ 6954 // TODO: PPC port $archOpcode(ppc64Opcode_add); 6955 __ add($dst$$Register, $base$$Register, $src$$Register); 6956 %} 6957 ins_pipe(pipe_class_default); 6958 %} 6959 6960 // src != 0, shift != 0, base != 0 6961 instruct decodeNKlass_notNull_addBase_Ex(iRegPdst dst, iRegLsrc base, iRegNsrc src) %{ 6962 match(Set dst (DecodeNKlass (Binary base src))); 6963 //effect(kill src); // We need a register for the immediate result after shifting. 6964 predicate(false); 6965 6966 format %{ "DecodeNKlass $dst = $base + ($src << 3) \t// $src != NULL, postalloc expanded" %} 6967 postalloc_expand %{ 6968 decodeNKlass_add_baseNode *n1 = new decodeNKlass_add_baseNode(); 6969 n1->add_req(n_region, n_base, n_src); 6970 n1->_opnds[0] = op_dst; 6971 n1->_opnds[1] = op_base; 6972 n1->_opnds[2] = op_src; 6973 n1->_bottom_type = _bottom_type; 6974 6975 decodeNKlass_shiftNode *n2 = new decodeNKlass_shiftNode(); 6976 n2->add_req(n_region, n1); 6977 n2->_opnds[0] = op_dst; 6978 n2->_opnds[1] = op_dst; 6979 n2->_bottom_type = _bottom_type; 6980 6981 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6982 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6983 6984 nodes->push(n1); 6985 nodes->push(n2); 6986 %} 6987 %} 6988 6989 // src != 0, shift != 0, base != 0 6990 instruct decodeNKlass_notNull_addBase_ExEx(iRegPdst dst, iRegNsrc src) %{ 6991 match(Set dst (DecodeNKlass src)); 6992 // predicate(Universe::narrow_klass_shift() != 0 && 6993 // Universe::narrow_klass_base() != 0); 6994 6995 //format %{ "DecodeNKlass $dst, $src \t// $src != NULL, expanded" %} 6996 6997 ins_cost(DEFAULT_COST*2); // Don't count constant. 6998 expand %{ 6999 // We add first, then we shift. Like this, we can get along with one register less. 7000 // But we have to load the base pre-shifted. 7001 immL baseImm %{ (jlong)((intptr_t)Universe::narrow_klass_base() >> Universe::narrow_klass_shift()) %} 7002 iRegLdst base; 7003 loadConL_Ex(base, baseImm); 7004 decodeNKlass_notNull_addBase_Ex(dst, base, src); 7005 %} 7006 %} 7007 7008 //----------MemBar Instructions----------------------------------------------- 7009 // Memory barrier flavors 7010 7011 instruct membar_acquire() %{ 7012 match(LoadFence); 7013 ins_cost(4*MEMORY_REF_COST); 7014 7015 format %{ "MEMBAR-acquire" %} 7016 size(4); 7017 ins_encode %{ 7018 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7019 __ acquire(); 7020 %} 7021 ins_pipe(pipe_class_default); 7022 %} 7023 7024 instruct unnecessary_membar_acquire() %{ 7025 match(MemBarAcquire); 7026 ins_cost(0); 7027 7028 format %{ " -- \t// redundant MEMBAR-acquire - empty" %} 7029 size(0); 7030 ins_encode( /*empty*/ ); 7031 ins_pipe(pipe_class_default); 7032 %} 7033 7034 instruct membar_acquire_lock() %{ 7035 match(MemBarAcquireLock); 7036 ins_cost(0); 7037 7038 format %{ " -- \t// redundant MEMBAR-acquire - empty (acquire as part of CAS in prior FastLock)" %} 7039 size(0); 7040 ins_encode( /*empty*/ ); 7041 ins_pipe(pipe_class_default); 7042 %} 7043 7044 instruct membar_release() %{ 7045 match(MemBarRelease); 7046 match(StoreFence); 7047 ins_cost(4*MEMORY_REF_COST); 7048 7049 format %{ "MEMBAR-release" %} 7050 size(4); 7051 ins_encode %{ 7052 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7053 __ release(); 7054 %} 7055 ins_pipe(pipe_class_default); 7056 %} 7057 7058 instruct membar_storestore() %{ 7059 match(MemBarStoreStore); 7060 ins_cost(4*MEMORY_REF_COST); 7061 7062 format %{ "MEMBAR-store-store" %} 7063 size(4); 7064 ins_encode %{ 7065 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7066 __ membar(Assembler::StoreStore); 7067 %} 7068 ins_pipe(pipe_class_default); 7069 %} 7070 7071 instruct membar_release_lock() %{ 7072 match(MemBarReleaseLock); 7073 ins_cost(0); 7074 7075 format %{ " -- \t// redundant MEMBAR-release - empty (release in FastUnlock)" %} 7076 size(0); 7077 ins_encode( /*empty*/ ); 7078 ins_pipe(pipe_class_default); 7079 %} 7080 7081 instruct membar_volatile() %{ 7082 match(MemBarVolatile); 7083 ins_cost(4*MEMORY_REF_COST); 7084 7085 format %{ "MEMBAR-volatile" %} 7086 size(4); 7087 ins_encode %{ 7088 // TODO: PPC port $archOpcode(ppc64Opcode_sync); 7089 __ fence(); 7090 %} 7091 ins_pipe(pipe_class_default); 7092 %} 7093 7094 // This optimization is wrong on PPC. The following pattern is not supported: 7095 // MemBarVolatile 7096 // ^ ^ 7097 // | | 7098 // CtrlProj MemProj 7099 // ^ ^ 7100 // | | 7101 // | Load 7102 // | 7103 // MemBarVolatile 7104 // 7105 // The first MemBarVolatile could get optimized out! According to 7106 // Vladimir, this pattern can not occur on Oracle platforms. 7107 // However, it does occur on PPC64 (because of membars in 7108 // inline_unsafe_load_store). 7109 // 7110 // Add this node again if we found a good solution for inline_unsafe_load_store(). 7111 // Don't forget to look at the implementation of post_store_load_barrier again, 7112 // we did other fixes in that method. 7113 //instruct unnecessary_membar_volatile() %{ 7114 // match(MemBarVolatile); 7115 // predicate(Matcher::post_store_load_barrier(n)); 7116 // ins_cost(0); 7117 // 7118 // format %{ " -- \t// redundant MEMBAR-volatile - empty" %} 7119 // size(0); 7120 // ins_encode( /*empty*/ ); 7121 // ins_pipe(pipe_class_default); 7122 //%} 7123 7124 instruct membar_CPUOrder() %{ 7125 match(MemBarCPUOrder); 7126 ins_cost(0); 7127 7128 format %{ " -- \t// MEMBAR-CPUOrder - empty: PPC64 processors are self-consistent." %} 7129 size(0); 7130 ins_encode( /*empty*/ ); 7131 ins_pipe(pipe_class_default); 7132 %} 7133 7134 //----------Conditional Move--------------------------------------------------- 7135 7136 // Cmove using isel. 7137 instruct cmovI_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7138 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7139 predicate(VM_Version::has_isel()); 7140 ins_cost(DEFAULT_COST); 7141 7142 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7143 size(4); 7144 ins_encode %{ 7145 // This is a Power7 instruction for which no machine description 7146 // exists. Anyways, the scheduler should be off on Power7. 7147 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7148 int cc = $cmp$$cmpcode; 7149 __ isel($dst$$Register, $crx$$CondRegister, 7150 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7151 %} 7152 ins_pipe(pipe_class_default); 7153 %} 7154 7155 instruct cmovI_reg(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7156 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7157 predicate(!VM_Version::has_isel()); 7158 ins_cost(DEFAULT_COST+BRANCH_COST); 7159 7160 ins_variable_size_depending_on_alignment(true); 7161 7162 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7163 // Worst case is branch + move + stop, no stop without scheduler 7164 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7165 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7166 ins_pipe(pipe_class_default); 7167 %} 7168 7169 instruct cmovI_imm(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, immI16 src) %{ 7170 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7171 ins_cost(DEFAULT_COST+BRANCH_COST); 7172 7173 ins_variable_size_depending_on_alignment(true); 7174 7175 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7176 // Worst case is branch + move + stop, no stop without scheduler 7177 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7178 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7179 ins_pipe(pipe_class_default); 7180 %} 7181 7182 // Cmove using isel. 7183 instruct cmovL_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7184 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7185 predicate(VM_Version::has_isel()); 7186 ins_cost(DEFAULT_COST); 7187 7188 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7189 size(4); 7190 ins_encode %{ 7191 // This is a Power7 instruction for which no machine description 7192 // exists. Anyways, the scheduler should be off on Power7. 7193 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7194 int cc = $cmp$$cmpcode; 7195 __ isel($dst$$Register, $crx$$CondRegister, 7196 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7197 %} 7198 ins_pipe(pipe_class_default); 7199 %} 7200 7201 instruct cmovL_reg(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7202 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7203 predicate(!VM_Version::has_isel()); 7204 ins_cost(DEFAULT_COST+BRANCH_COST); 7205 7206 ins_variable_size_depending_on_alignment(true); 7207 7208 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7209 // Worst case is branch + move + stop, no stop without scheduler. 7210 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7211 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7212 ins_pipe(pipe_class_default); 7213 %} 7214 7215 instruct cmovL_imm(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, immL16 src) %{ 7216 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7217 ins_cost(DEFAULT_COST+BRANCH_COST); 7218 7219 ins_variable_size_depending_on_alignment(true); 7220 7221 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7222 // Worst case is branch + move + stop, no stop without scheduler. 7223 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7224 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7225 ins_pipe(pipe_class_default); 7226 %} 7227 7228 // Cmove using isel. 7229 instruct cmovN_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7230 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7231 predicate(VM_Version::has_isel()); 7232 ins_cost(DEFAULT_COST); 7233 7234 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7235 size(4); 7236 ins_encode %{ 7237 // This is a Power7 instruction for which no machine description 7238 // exists. Anyways, the scheduler should be off on Power7. 7239 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7240 int cc = $cmp$$cmpcode; 7241 __ isel($dst$$Register, $crx$$CondRegister, 7242 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7243 %} 7244 ins_pipe(pipe_class_default); 7245 %} 7246 7247 // Conditional move for RegN. Only cmov(reg, reg). 7248 instruct cmovN_reg(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7249 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7250 predicate(!VM_Version::has_isel()); 7251 ins_cost(DEFAULT_COST+BRANCH_COST); 7252 7253 ins_variable_size_depending_on_alignment(true); 7254 7255 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7256 // Worst case is branch + move + stop, no stop without scheduler. 7257 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7258 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7259 ins_pipe(pipe_class_default); 7260 %} 7261 7262 instruct cmovN_imm(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, immN_0 src) %{ 7263 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7264 ins_cost(DEFAULT_COST+BRANCH_COST); 7265 7266 ins_variable_size_depending_on_alignment(true); 7267 7268 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7269 // Worst case is branch + move + stop, no stop without scheduler. 7270 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7271 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7272 ins_pipe(pipe_class_default); 7273 %} 7274 7275 // Cmove using isel. 7276 instruct cmovP_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegPsrc src) %{ 7277 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7278 predicate(VM_Version::has_isel()); 7279 ins_cost(DEFAULT_COST); 7280 7281 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7282 size(4); 7283 ins_encode %{ 7284 // This is a Power7 instruction for which no machine description 7285 // exists. Anyways, the scheduler should be off on Power7. 7286 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7287 int cc = $cmp$$cmpcode; 7288 __ isel($dst$$Register, $crx$$CondRegister, 7289 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7290 %} 7291 ins_pipe(pipe_class_default); 7292 %} 7293 7294 instruct cmovP_reg(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegP_N2P src) %{ 7295 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7296 predicate(!VM_Version::has_isel()); 7297 ins_cost(DEFAULT_COST+BRANCH_COST); 7298 7299 ins_variable_size_depending_on_alignment(true); 7300 7301 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7302 // Worst case is branch + move + stop, no stop without scheduler. 7303 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7304 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7305 ins_pipe(pipe_class_default); 7306 %} 7307 7308 instruct cmovP_imm(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, immP_0 src) %{ 7309 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7310 ins_cost(DEFAULT_COST+BRANCH_COST); 7311 7312 ins_variable_size_depending_on_alignment(true); 7313 7314 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7315 // Worst case is branch + move + stop, no stop without scheduler. 7316 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7317 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7318 ins_pipe(pipe_class_default); 7319 %} 7320 7321 instruct cmovF_reg(cmpOp cmp, flagsRegSrc crx, regF dst, regF src) %{ 7322 match(Set dst (CMoveF (Binary cmp crx) (Binary dst src))); 7323 ins_cost(DEFAULT_COST+BRANCH_COST); 7324 7325 ins_variable_size_depending_on_alignment(true); 7326 7327 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7328 // Worst case is branch + move + stop, no stop without scheduler. 7329 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 7330 ins_encode %{ 7331 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7332 Label done; 7333 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7334 // Branch if not (cmp crx). 7335 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7336 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7337 // TODO PPC port __ endgroup_if_needed(_size == 12); 7338 __ bind(done); 7339 %} 7340 ins_pipe(pipe_class_default); 7341 %} 7342 7343 instruct cmovD_reg(cmpOp cmp, flagsRegSrc crx, regD dst, regD src) %{ 7344 match(Set dst (CMoveD (Binary cmp crx) (Binary dst src))); 7345 ins_cost(DEFAULT_COST+BRANCH_COST); 7346 7347 ins_variable_size_depending_on_alignment(true); 7348 7349 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7350 // Worst case is branch + move + stop, no stop without scheduler. 7351 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 7352 ins_encode %{ 7353 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7354 Label done; 7355 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7356 // Branch if not (cmp crx). 7357 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7358 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7359 // TODO PPC port __ endgroup_if_needed(_size == 12); 7360 __ bind(done); 7361 %} 7362 ins_pipe(pipe_class_default); 7363 %} 7364 7365 //----------Conditional_store-------------------------------------------------- 7366 // Conditional-store of the updated heap-top. 7367 // Used during allocation of the shared heap. 7368 // Sets flags (EQ) on success. Implemented with a CASA on Sparc. 7369 7370 // As compareAndSwapL, but return flag register instead of boolean value in 7371 // int register. 7372 // Used by sun/misc/AtomicLongCSImpl.java. 7373 // Mem_ptr must be a memory operand, else this node does not get 7374 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7375 // can be rematerialized which leads to errors. 7376 instruct storeLConditional_regP_regL_regL(flagsReg crx, indirect mem_ptr, iRegLsrc oldVal, iRegLsrc newVal, flagsRegCR0 cr0) %{ 7377 match(Set crx (StoreLConditional mem_ptr (Binary oldVal newVal))); 7378 effect(TEMP cr0); 7379 format %{ "CMPXCHGD if ($crx = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7380 ins_encode %{ 7381 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7382 __ cmpxchgd($crx$$CondRegister, R0, $oldVal$$Register, $newVal$$Register, $mem_ptr$$Register, 7383 MacroAssembler::MemBarAcq, MacroAssembler::cmpxchgx_hint_atomic_update(), 7384 noreg, NULL, true); 7385 %} 7386 ins_pipe(pipe_class_default); 7387 %} 7388 7389 // As compareAndSwapP, but return flag register instead of boolean value in 7390 // int register. 7391 // This instruction is matched if UseTLAB is off. 7392 // Mem_ptr must be a memory operand, else this node does not get 7393 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7394 // can be rematerialized which leads to errors. 7395 instruct storePConditional_regP_regP_regP(flagsRegCR0 cr0, indirect mem_ptr, iRegPsrc oldVal, iRegPsrc newVal) %{ 7396 match(Set cr0 (StorePConditional mem_ptr (Binary oldVal newVal))); 7397 ins_cost(2*MEMORY_REF_COST); 7398 7399 format %{ "STDCX_ if ($cr0 = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7400 ins_encode %{ 7401 // TODO: PPC port $archOpcode(ppc64Opcode_stdcx_); 7402 __ stdcx_($newVal$$Register, $mem_ptr$$Register); 7403 %} 7404 ins_pipe(pipe_class_memory); 7405 %} 7406 7407 // Implement LoadPLocked. Must be ordered against changes of the memory location 7408 // by storePConditional. 7409 // Don't know whether this is ever used. 7410 instruct loadPLocked(iRegPdst dst, memory mem) %{ 7411 match(Set dst (LoadPLocked mem)); 7412 ins_cost(2*MEMORY_REF_COST); 7413 7414 format %{ "LDARX $dst, $mem \t// loadPLocked\n\t" %} 7415 size(4); 7416 ins_encode %{ 7417 // TODO: PPC port $archOpcode(ppc64Opcode_ldarx); 7418 __ ldarx($dst$$Register, $mem$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 7419 %} 7420 ins_pipe(pipe_class_memory); 7421 %} 7422 7423 //----------Compare-And-Swap--------------------------------------------------- 7424 7425 // CompareAndSwap{P,I,L} have more than one output, therefore "CmpI 7426 // (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be 7427 // matched. 7428 7429 // Strong versions: 7430 7431 instruct compareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7432 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7433 predicate(VM_Version::has_lqarx()); 7434 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7435 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7436 ins_encode %{ 7437 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7438 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7439 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7440 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7441 $res$$Register, true); 7442 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7443 __ isync(); 7444 } else { 7445 __ sync(); 7446 } 7447 %} 7448 ins_pipe(pipe_class_default); 7449 %} 7450 7451 instruct compareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7452 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7453 predicate(!VM_Version::has_lqarx()); 7454 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7455 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7456 ins_encode %{ 7457 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7458 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7459 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7460 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7461 $res$$Register, true); 7462 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7463 __ isync(); 7464 } else { 7465 __ sync(); 7466 } 7467 %} 7468 ins_pipe(pipe_class_default); 7469 %} 7470 7471 instruct compareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7472 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7473 predicate(VM_Version::has_lqarx()); 7474 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7475 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7476 ins_encode %{ 7477 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7478 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7479 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7480 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7481 $res$$Register, true); 7482 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7483 __ isync(); 7484 } else { 7485 __ sync(); 7486 } 7487 %} 7488 ins_pipe(pipe_class_default); 7489 %} 7490 7491 instruct compareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7492 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7493 predicate(!VM_Version::has_lqarx()); 7494 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7495 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7496 ins_encode %{ 7497 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7498 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7499 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7500 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7501 $res$$Register, true); 7502 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7503 __ isync(); 7504 } else { 7505 __ sync(); 7506 } 7507 %} 7508 ins_pipe(pipe_class_default); 7509 %} 7510 7511 instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7512 match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2))); 7513 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7514 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7515 ins_encode %{ 7516 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7517 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7518 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7519 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7520 $res$$Register, true); 7521 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7522 __ isync(); 7523 } else { 7524 __ sync(); 7525 } 7526 %} 7527 ins_pipe(pipe_class_default); 7528 %} 7529 7530 instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 7531 match(Set res (CompareAndSwapN mem_ptr (Binary src1 src2))); 7532 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7533 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7534 ins_encode %{ 7535 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7536 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7537 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7538 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7539 $res$$Register, true); 7540 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7541 __ isync(); 7542 } else { 7543 __ sync(); 7544 } 7545 %} 7546 ins_pipe(pipe_class_default); 7547 %} 7548 7549 instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 7550 match(Set res (CompareAndSwapL mem_ptr (Binary src1 src2))); 7551 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7552 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 7553 ins_encode %{ 7554 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7555 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7556 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7557 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7558 $res$$Register, NULL, true); 7559 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7560 __ isync(); 7561 } else { 7562 __ sync(); 7563 } 7564 %} 7565 ins_pipe(pipe_class_default); 7566 %} 7567 7568 instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 7569 match(Set res (CompareAndSwapP mem_ptr (Binary src1 src2))); 7570 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7571 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 7572 ins_encode %{ 7573 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7574 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7575 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7576 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7577 $res$$Register, NULL, true); 7578 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7579 __ isync(); 7580 } else { 7581 __ sync(); 7582 } 7583 %} 7584 ins_pipe(pipe_class_default); 7585 %} 7586 7587 // Weak versions: 7588 7589 instruct weakCompareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7590 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7591 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7592 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7593 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7594 ins_encode %{ 7595 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7596 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7597 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7598 MacroAssembler::MemBarNone, 7599 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7600 %} 7601 ins_pipe(pipe_class_default); 7602 %} 7603 7604 instruct weakCompareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7605 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7606 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 7607 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7608 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7609 ins_encode %{ 7610 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7611 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7612 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7613 MacroAssembler::MemBarNone, 7614 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7615 %} 7616 ins_pipe(pipe_class_default); 7617 %} 7618 7619 instruct weakCompareAndSwapB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7620 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7621 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 7622 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7623 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 7624 ins_encode %{ 7625 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7626 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7627 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7628 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7629 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7630 %} 7631 ins_pipe(pipe_class_default); 7632 %} 7633 7634 instruct weakCompareAndSwapB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7635 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7636 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 7637 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7638 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 7639 ins_encode %{ 7640 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7641 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7642 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7643 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7644 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7645 %} 7646 ins_pipe(pipe_class_default); 7647 %} 7648 7649 instruct weakCompareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7650 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 7651 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7652 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7653 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7654 ins_encode %{ 7655 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7656 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7657 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7658 MacroAssembler::MemBarNone, 7659 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7660 %} 7661 ins_pipe(pipe_class_default); 7662 %} 7663 7664 instruct weakCompareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7665 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 7666 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 7667 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7668 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7669 ins_encode %{ 7670 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7671 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7672 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7673 MacroAssembler::MemBarNone, 7674 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7675 %} 7676 ins_pipe(pipe_class_default); 7677 %} 7678 7679 instruct weakCompareAndSwapS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7680 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 7681 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 7682 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7683 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 7684 ins_encode %{ 7685 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7686 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7687 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7688 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7689 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7690 %} 7691 ins_pipe(pipe_class_default); 7692 %} 7693 7694 instruct weakCompareAndSwapS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7695 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 7696 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 7697 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7698 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 7699 ins_encode %{ 7700 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7701 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7702 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7703 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7704 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7705 %} 7706 ins_pipe(pipe_class_default); 7707 %} 7708 7709 instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7710 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 7711 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7712 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7713 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7714 ins_encode %{ 7715 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7716 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7717 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7718 MacroAssembler::MemBarNone, 7719 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7720 %} 7721 ins_pipe(pipe_class_default); 7722 %} 7723 7724 instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7725 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 7726 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 7727 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7728 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 7729 ins_encode %{ 7730 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7731 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7732 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 7733 // value is never passed to caller. 7734 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7735 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7736 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7737 %} 7738 ins_pipe(pipe_class_default); 7739 %} 7740 7741 instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 7742 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 7743 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7744 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7745 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7746 ins_encode %{ 7747 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7748 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7749 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7750 MacroAssembler::MemBarNone, 7751 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7752 %} 7753 ins_pipe(pipe_class_default); 7754 %} 7755 7756 instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 7757 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 7758 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 7759 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7760 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 7761 ins_encode %{ 7762 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7763 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7764 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 7765 // value is never passed to caller. 7766 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7767 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7768 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7769 %} 7770 ins_pipe(pipe_class_default); 7771 %} 7772 7773 instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 7774 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 7775 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7776 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7777 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 7778 ins_encode %{ 7779 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7780 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7781 // value is never passed to caller. 7782 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7783 MacroAssembler::MemBarNone, 7784 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 7785 %} 7786 ins_pipe(pipe_class_default); 7787 %} 7788 7789 instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 7790 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 7791 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 7792 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7793 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %} 7794 ins_encode %{ 7795 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7796 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7797 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 7798 // value is never passed to caller. 7799 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7800 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7801 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 7802 %} 7803 ins_pipe(pipe_class_default); 7804 %} 7805 7806 instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 7807 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 7808 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7809 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7810 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 7811 ins_encode %{ 7812 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7813 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7814 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7815 MacroAssembler::MemBarNone, 7816 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 7817 %} 7818 ins_pipe(pipe_class_default); 7819 %} 7820 7821 instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 7822 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 7823 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 7824 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7825 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 7826 ins_encode %{ 7827 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7828 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7829 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 7830 // value is never passed to caller. 7831 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7832 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7833 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 7834 %} 7835 ins_pipe(pipe_class_default); 7836 %} 7837 7838 // CompareAndExchange 7839 7840 instruct compareAndExchangeB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7841 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 7842 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7843 effect(TEMP_DEF res, TEMP cr0); 7844 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 7845 ins_encode %{ 7846 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7847 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7848 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7849 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7850 noreg, true); 7851 %} 7852 ins_pipe(pipe_class_default); 7853 %} 7854 7855 instruct compareAndExchangeB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 7856 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 7857 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 7858 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 7859 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 7860 ins_encode %{ 7861 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7862 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7863 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 7864 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7865 noreg, true); 7866 %} 7867 ins_pipe(pipe_class_default); 7868 %} 7869 7870 instruct compareAndExchangeB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7871 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 7872 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 7873 effect(TEMP_DEF res, TEMP cr0); 7874 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 7875 ins_encode %{ 7876 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7877 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7878 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7879 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7880 noreg, true); 7881 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7882 __ isync(); 7883 } else { 7884 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 7885 __ sync(); 7886 } 7887 %} 7888 ins_pipe(pipe_class_default); 7889 %} 7890 7891 instruct compareAndExchangeB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 7892 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 7893 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 7894 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 7895 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 7896 ins_encode %{ 7897 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7898 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7899 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 7900 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7901 noreg, true); 7902 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7903 __ isync(); 7904 } else { 7905 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 7906 __ sync(); 7907 } 7908 %} 7909 ins_pipe(pipe_class_default); 7910 %} 7911 7912 instruct compareAndExchangeS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7913 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 7914 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7915 effect(TEMP_DEF res, TEMP cr0); 7916 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 7917 ins_encode %{ 7918 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7919 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7920 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7921 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7922 noreg, true); 7923 %} 7924 ins_pipe(pipe_class_default); 7925 %} 7926 7927 instruct compareAndExchangeS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 7928 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 7929 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 7930 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 7931 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 7932 ins_encode %{ 7933 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7934 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7935 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 7936 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7937 noreg, true); 7938 %} 7939 ins_pipe(pipe_class_default); 7940 %} 7941 7942 instruct compareAndExchangeS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7943 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 7944 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 7945 effect(TEMP_DEF res, TEMP cr0); 7946 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 7947 ins_encode %{ 7948 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7949 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7950 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7951 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7952 noreg, true); 7953 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7954 __ isync(); 7955 } else { 7956 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 7957 __ sync(); 7958 } 7959 %} 7960 ins_pipe(pipe_class_default); 7961 %} 7962 7963 instruct compareAndExchangeS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 7964 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 7965 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 7966 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 7967 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 7968 ins_encode %{ 7969 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7970 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7971 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 7972 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7973 noreg, true); 7974 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7975 __ isync(); 7976 } else { 7977 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 7978 __ sync(); 7979 } 7980 %} 7981 ins_pipe(pipe_class_default); 7982 %} 7983 7984 instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7985 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 7986 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7987 effect(TEMP_DEF res, TEMP cr0); 7988 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %} 7989 ins_encode %{ 7990 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7991 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7992 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7993 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7994 noreg, true); 7995 %} 7996 ins_pipe(pipe_class_default); 7997 %} 7998 7999 instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8000 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8001 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8002 effect(TEMP_DEF res, TEMP cr0); 8003 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %} 8004 ins_encode %{ 8005 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8006 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8007 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8008 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8009 noreg, true); 8010 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8011 __ isync(); 8012 } else { 8013 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8014 __ sync(); 8015 } 8016 %} 8017 ins_pipe(pipe_class_default); 8018 %} 8019 8020 instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8021 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8022 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8023 effect(TEMP_DEF res, TEMP cr0); 8024 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8025 ins_encode %{ 8026 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8027 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8028 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8029 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8030 noreg, true); 8031 %} 8032 ins_pipe(pipe_class_default); 8033 %} 8034 8035 instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8036 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8037 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8038 effect(TEMP_DEF res, TEMP cr0); 8039 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8040 ins_encode %{ 8041 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8042 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8043 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8044 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8045 noreg, true); 8046 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8047 __ isync(); 8048 } else { 8049 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8050 __ sync(); 8051 } 8052 %} 8053 ins_pipe(pipe_class_default); 8054 %} 8055 8056 instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8057 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8058 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8059 effect(TEMP_DEF res, TEMP cr0); 8060 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %} 8061 ins_encode %{ 8062 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8063 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8064 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8065 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8066 noreg, NULL, true); 8067 %} 8068 ins_pipe(pipe_class_default); 8069 %} 8070 8071 instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8072 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8073 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8074 effect(TEMP_DEF res, TEMP cr0); 8075 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %} 8076 ins_encode %{ 8077 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8078 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8079 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8080 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8081 noreg, NULL, true); 8082 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8083 __ isync(); 8084 } else { 8085 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8086 __ sync(); 8087 } 8088 %} 8089 ins_pipe(pipe_class_default); 8090 %} 8091 8092 instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8093 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8094 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8095 effect(TEMP_DEF res, TEMP cr0); 8096 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8097 ins_encode %{ 8098 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8099 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8100 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8101 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8102 noreg, NULL, true); 8103 %} 8104 ins_pipe(pipe_class_default); 8105 %} 8106 8107 instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8108 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8109 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8110 effect(TEMP_DEF res, TEMP cr0); 8111 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8112 ins_encode %{ 8113 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8114 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8115 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8116 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8117 noreg, NULL, true); 8118 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8119 __ isync(); 8120 } else { 8121 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8122 __ sync(); 8123 } 8124 %} 8125 ins_pipe(pipe_class_default); 8126 %} 8127 8128 // Special RMW 8129 8130 instruct getAndAddB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8131 match(Set res (GetAndAddB mem_ptr src)); 8132 predicate(VM_Version::has_lqarx()); 8133 effect(TEMP_DEF res, TEMP cr0); 8134 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8135 ins_encode %{ 8136 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8137 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8138 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8139 __ isync(); 8140 } else { 8141 __ sync(); 8142 } 8143 %} 8144 ins_pipe(pipe_class_default); 8145 %} 8146 8147 instruct getAndAddB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8148 match(Set res (GetAndAddB mem_ptr src)); 8149 predicate(!VM_Version::has_lqarx()); 8150 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8151 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8152 ins_encode %{ 8153 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8154 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8155 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8156 __ isync(); 8157 } else { 8158 __ sync(); 8159 } 8160 %} 8161 ins_pipe(pipe_class_default); 8162 %} 8163 8164 instruct getAndAddS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8165 match(Set res (GetAndAddS mem_ptr src)); 8166 predicate(VM_Version::has_lqarx()); 8167 effect(TEMP_DEF res, TEMP cr0); 8168 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8169 ins_encode %{ 8170 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8171 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8172 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8173 __ isync(); 8174 } else { 8175 __ sync(); 8176 } 8177 %} 8178 ins_pipe(pipe_class_default); 8179 %} 8180 8181 instruct getAndAddS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8182 match(Set res (GetAndAddS mem_ptr src)); 8183 predicate(!VM_Version::has_lqarx()); 8184 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8185 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8186 ins_encode %{ 8187 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8188 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8189 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8190 __ isync(); 8191 } else { 8192 __ sync(); 8193 } 8194 %} 8195 ins_pipe(pipe_class_default); 8196 %} 8197 8198 instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8199 match(Set res (GetAndAddI mem_ptr src)); 8200 effect(TEMP_DEF res, TEMP cr0); 8201 format %{ "GetAndAddI $res, $mem_ptr, $src" %} 8202 ins_encode %{ 8203 __ getandaddw($res$$Register, $src$$Register, $mem_ptr$$Register, 8204 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8205 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8206 __ isync(); 8207 } else { 8208 __ sync(); 8209 } 8210 %} 8211 ins_pipe(pipe_class_default); 8212 %} 8213 8214 instruct getAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8215 match(Set res (GetAndAddL mem_ptr src)); 8216 effect(TEMP_DEF res, TEMP cr0); 8217 format %{ "GetAndAddL $res, $mem_ptr, $src" %} 8218 ins_encode %{ 8219 __ getandaddd($res$$Register, $src$$Register, $mem_ptr$$Register, 8220 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8221 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8222 __ isync(); 8223 } else { 8224 __ sync(); 8225 } 8226 %} 8227 ins_pipe(pipe_class_default); 8228 %} 8229 8230 instruct getAndSetB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8231 match(Set res (GetAndSetB mem_ptr src)); 8232 predicate(VM_Version::has_lqarx()); 8233 effect(TEMP_DEF res, TEMP cr0); 8234 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8235 ins_encode %{ 8236 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8237 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8238 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8239 __ isync(); 8240 } else { 8241 __ sync(); 8242 } 8243 %} 8244 ins_pipe(pipe_class_default); 8245 %} 8246 8247 instruct getAndSetB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8248 match(Set res (GetAndSetB mem_ptr src)); 8249 predicate(!VM_Version::has_lqarx()); 8250 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8251 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8252 ins_encode %{ 8253 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8254 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8255 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8256 __ isync(); 8257 } else { 8258 __ sync(); 8259 } 8260 %} 8261 ins_pipe(pipe_class_default); 8262 %} 8263 8264 instruct getAndSetS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8265 match(Set res (GetAndSetS mem_ptr src)); 8266 predicate(VM_Version::has_lqarx()); 8267 effect(TEMP_DEF res, TEMP cr0); 8268 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8269 ins_encode %{ 8270 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8271 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8272 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8273 __ isync(); 8274 } else { 8275 __ sync(); 8276 } 8277 %} 8278 ins_pipe(pipe_class_default); 8279 %} 8280 8281 instruct getAndSetS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8282 match(Set res (GetAndSetS mem_ptr src)); 8283 predicate(!VM_Version::has_lqarx()); 8284 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8285 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8286 ins_encode %{ 8287 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8288 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8289 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8290 __ isync(); 8291 } else { 8292 __ sync(); 8293 } 8294 %} 8295 ins_pipe(pipe_class_default); 8296 %} 8297 8298 instruct getAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8299 match(Set res (GetAndSetI mem_ptr src)); 8300 effect(TEMP_DEF res, TEMP cr0); 8301 format %{ "GetAndSetI $res, $mem_ptr, $src" %} 8302 ins_encode %{ 8303 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8304 MacroAssembler::cmpxchgx_hint_atomic_update()); 8305 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8306 __ isync(); 8307 } else { 8308 __ sync(); 8309 } 8310 %} 8311 ins_pipe(pipe_class_default); 8312 %} 8313 8314 instruct getAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8315 match(Set res (GetAndSetL mem_ptr src)); 8316 effect(TEMP_DEF res, TEMP cr0); 8317 format %{ "GetAndSetL $res, $mem_ptr, $src" %} 8318 ins_encode %{ 8319 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8320 MacroAssembler::cmpxchgx_hint_atomic_update()); 8321 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8322 __ isync(); 8323 } else { 8324 __ sync(); 8325 } 8326 %} 8327 ins_pipe(pipe_class_default); 8328 %} 8329 8330 instruct getAndSetP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src, flagsRegCR0 cr0) %{ 8331 match(Set res (GetAndSetP mem_ptr src)); 8332 effect(TEMP_DEF res, TEMP cr0); 8333 format %{ "GetAndSetP $res, $mem_ptr, $src" %} 8334 ins_encode %{ 8335 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8336 MacroAssembler::cmpxchgx_hint_atomic_update()); 8337 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8338 __ isync(); 8339 } else { 8340 __ sync(); 8341 } 8342 %} 8343 ins_pipe(pipe_class_default); 8344 %} 8345 8346 instruct getAndSetN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src, flagsRegCR0 cr0) %{ 8347 match(Set res (GetAndSetN mem_ptr src)); 8348 effect(TEMP_DEF res, TEMP cr0); 8349 format %{ "GetAndSetN $res, $mem_ptr, $src" %} 8350 ins_encode %{ 8351 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8352 MacroAssembler::cmpxchgx_hint_atomic_update()); 8353 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8354 __ isync(); 8355 } else { 8356 __ sync(); 8357 } 8358 %} 8359 ins_pipe(pipe_class_default); 8360 %} 8361 8362 //----------Arithmetic Instructions-------------------------------------------- 8363 // Addition Instructions 8364 8365 // Register Addition 8366 instruct addI_reg_reg(iRegIdst dst, iRegIsrc_iRegL2Isrc src1, iRegIsrc_iRegL2Isrc src2) %{ 8367 match(Set dst (AddI src1 src2)); 8368 format %{ "ADD $dst, $src1, $src2" %} 8369 size(4); 8370 ins_encode %{ 8371 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8372 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8373 %} 8374 ins_pipe(pipe_class_default); 8375 %} 8376 8377 // Expand does not work with above instruct. (??) 8378 instruct addI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8379 // no match-rule 8380 effect(DEF dst, USE src1, USE src2); 8381 format %{ "ADD $dst, $src1, $src2" %} 8382 size(4); 8383 ins_encode %{ 8384 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8385 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8386 %} 8387 ins_pipe(pipe_class_default); 8388 %} 8389 8390 instruct tree_addI_addI_addI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 8391 match(Set dst (AddI (AddI (AddI src1 src2) src3) src4)); 8392 ins_cost(DEFAULT_COST*3); 8393 8394 expand %{ 8395 // FIXME: we should do this in the ideal world. 8396 iRegIdst tmp1; 8397 iRegIdst tmp2; 8398 addI_reg_reg(tmp1, src1, src2); 8399 addI_reg_reg_2(tmp2, src3, src4); // Adlc complains about addI_reg_reg. 8400 addI_reg_reg(dst, tmp1, tmp2); 8401 %} 8402 %} 8403 8404 // Immediate Addition 8405 instruct addI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 8406 match(Set dst (AddI src1 src2)); 8407 format %{ "ADDI $dst, $src1, $src2" %} 8408 size(4); 8409 ins_encode %{ 8410 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8411 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8412 %} 8413 ins_pipe(pipe_class_default); 8414 %} 8415 8416 // Immediate Addition with 16-bit shifted operand 8417 instruct addI_reg_immhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2) %{ 8418 match(Set dst (AddI src1 src2)); 8419 format %{ "ADDIS $dst, $src1, $src2" %} 8420 size(4); 8421 ins_encode %{ 8422 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8423 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8424 %} 8425 ins_pipe(pipe_class_default); 8426 %} 8427 8428 // Long Addition 8429 instruct addL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8430 match(Set dst (AddL src1 src2)); 8431 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8432 size(4); 8433 ins_encode %{ 8434 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8435 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8436 %} 8437 ins_pipe(pipe_class_default); 8438 %} 8439 8440 // Expand does not work with above instruct. (??) 8441 instruct addL_reg_reg_2(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8442 // no match-rule 8443 effect(DEF dst, USE src1, USE src2); 8444 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8445 size(4); 8446 ins_encode %{ 8447 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8448 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8449 %} 8450 ins_pipe(pipe_class_default); 8451 %} 8452 8453 instruct tree_addL_addL_addL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2, iRegLsrc src3, iRegLsrc src4) %{ 8454 match(Set dst (AddL (AddL (AddL src1 src2) src3) src4)); 8455 ins_cost(DEFAULT_COST*3); 8456 8457 expand %{ 8458 // FIXME: we should do this in the ideal world. 8459 iRegLdst tmp1; 8460 iRegLdst tmp2; 8461 addL_reg_reg(tmp1, src1, src2); 8462 addL_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 8463 addL_reg_reg(dst, tmp1, tmp2); 8464 %} 8465 %} 8466 8467 // AddL + ConvL2I. 8468 instruct addI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8469 match(Set dst (ConvL2I (AddL src1 src2))); 8470 8471 format %{ "ADD $dst, $src1, $src2 \t// long + l2i" %} 8472 size(4); 8473 ins_encode %{ 8474 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8475 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8476 %} 8477 ins_pipe(pipe_class_default); 8478 %} 8479 8480 // No constant pool entries required. 8481 instruct addL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 8482 match(Set dst (AddL src1 src2)); 8483 8484 format %{ "ADDI $dst, $src1, $src2" %} 8485 size(4); 8486 ins_encode %{ 8487 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8488 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8489 %} 8490 ins_pipe(pipe_class_default); 8491 %} 8492 8493 // Long Immediate Addition with 16-bit shifted operand. 8494 // No constant pool entries required. 8495 instruct addL_reg_immhi16(iRegLdst dst, iRegLsrc src1, immL32hi16 src2) %{ 8496 match(Set dst (AddL src1 src2)); 8497 8498 format %{ "ADDIS $dst, $src1, $src2" %} 8499 size(4); 8500 ins_encode %{ 8501 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8502 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8503 %} 8504 ins_pipe(pipe_class_default); 8505 %} 8506 8507 // Pointer Register Addition 8508 instruct addP_reg_reg(iRegPdst dst, iRegP_N2P src1, iRegLsrc src2) %{ 8509 match(Set dst (AddP src1 src2)); 8510 format %{ "ADD $dst, $src1, $src2" %} 8511 size(4); 8512 ins_encode %{ 8513 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8514 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8515 %} 8516 ins_pipe(pipe_class_default); 8517 %} 8518 8519 // Pointer Immediate Addition 8520 // No constant pool entries required. 8521 instruct addP_reg_imm16(iRegPdst dst, iRegP_N2P src1, immL16 src2) %{ 8522 match(Set dst (AddP src1 src2)); 8523 8524 format %{ "ADDI $dst, $src1, $src2" %} 8525 size(4); 8526 ins_encode %{ 8527 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8528 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8529 %} 8530 ins_pipe(pipe_class_default); 8531 %} 8532 8533 // Pointer Immediate Addition with 16-bit shifted operand. 8534 // No constant pool entries required. 8535 instruct addP_reg_immhi16(iRegPdst dst, iRegP_N2P src1, immL32hi16 src2) %{ 8536 match(Set dst (AddP src1 src2)); 8537 8538 format %{ "ADDIS $dst, $src1, $src2" %} 8539 size(4); 8540 ins_encode %{ 8541 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8542 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8543 %} 8544 ins_pipe(pipe_class_default); 8545 %} 8546 8547 //--------------------- 8548 // Subtraction Instructions 8549 8550 // Register Subtraction 8551 instruct subI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8552 match(Set dst (SubI src1 src2)); 8553 format %{ "SUBF $dst, $src2, $src1" %} 8554 size(4); 8555 ins_encode %{ 8556 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 8557 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 8558 %} 8559 ins_pipe(pipe_class_default); 8560 %} 8561 8562 // Immediate Subtraction 8563 // Immediate Subtraction: The compiler converts "x-c0" into "x+ -c0" (see SubLNode::Ideal), 8564 // Don't try to use addi with - $src2$$constant since it can overflow when $src2$$constant == minI16. 8565 8566 // SubI from constant (using subfic). 8567 instruct subI_imm16_reg(iRegIdst dst, immI16 src1, iRegIsrc src2) %{ 8568 match(Set dst (SubI src1 src2)); 8569 format %{ "SUBI $dst, $src1, $src2" %} 8570 8571 size(4); 8572 ins_encode %{ 8573 // TODO: PPC port $archOpcode(ppc64Opcode_subfic); 8574 __ subfic($dst$$Register, $src2$$Register, $src1$$constant); 8575 %} 8576 ins_pipe(pipe_class_default); 8577 %} 8578 8579 // Turn the sign-bit of an integer into a 32-bit mask, 0x0...0 for 8580 // positive integers and 0xF...F for negative ones. 8581 instruct signmask32I_regI(iRegIdst dst, iRegIsrc src) %{ 8582 // no match-rule, false predicate 8583 effect(DEF dst, USE src); 8584 predicate(false); 8585 8586 format %{ "SRAWI $dst, $src, #31" %} 8587 size(4); 8588 ins_encode %{ 8589 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 8590 __ srawi($dst$$Register, $src$$Register, 0x1f); 8591 %} 8592 ins_pipe(pipe_class_default); 8593 %} 8594 8595 instruct absI_reg_Ex(iRegIdst dst, iRegIsrc src) %{ 8596 match(Set dst (AbsI src)); 8597 ins_cost(DEFAULT_COST*3); 8598 8599 expand %{ 8600 iRegIdst tmp1; 8601 iRegIdst tmp2; 8602 signmask32I_regI(tmp1, src); 8603 xorI_reg_reg(tmp2, tmp1, src); 8604 subI_reg_reg(dst, tmp2, tmp1); 8605 %} 8606 %} 8607 8608 instruct negI_regI(iRegIdst dst, immI_0 zero, iRegIsrc src2) %{ 8609 match(Set dst (SubI zero src2)); 8610 format %{ "NEG $dst, $src2" %} 8611 size(4); 8612 ins_encode %{ 8613 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 8614 __ neg($dst$$Register, $src2$$Register); 8615 %} 8616 ins_pipe(pipe_class_default); 8617 %} 8618 8619 // Long subtraction 8620 instruct subL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8621 match(Set dst (SubL src1 src2)); 8622 format %{ "SUBF $dst, $src2, $src1 \t// long" %} 8623 size(4); 8624 ins_encode %{ 8625 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 8626 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 8627 %} 8628 ins_pipe(pipe_class_default); 8629 %} 8630 8631 // SubL + convL2I. 8632 instruct subI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8633 match(Set dst (ConvL2I (SubL src1 src2))); 8634 8635 format %{ "SUBF $dst, $src2, $src1 \t// long + l2i" %} 8636 size(4); 8637 ins_encode %{ 8638 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 8639 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 8640 %} 8641 ins_pipe(pipe_class_default); 8642 %} 8643 8644 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 8645 // positive longs and 0xF...F for negative ones. 8646 instruct signmask64I_regL(iRegIdst dst, iRegLsrc src) %{ 8647 // no match-rule, false predicate 8648 effect(DEF dst, USE src); 8649 predicate(false); 8650 8651 format %{ "SRADI $dst, $src, #63" %} 8652 size(4); 8653 ins_encode %{ 8654 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 8655 __ sradi($dst$$Register, $src$$Register, 0x3f); 8656 %} 8657 ins_pipe(pipe_class_default); 8658 %} 8659 8660 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 8661 // positive longs and 0xF...F for negative ones. 8662 instruct signmask64L_regL(iRegLdst dst, iRegLsrc src) %{ 8663 // no match-rule, false predicate 8664 effect(DEF dst, USE src); 8665 predicate(false); 8666 8667 format %{ "SRADI $dst, $src, #63" %} 8668 size(4); 8669 ins_encode %{ 8670 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 8671 __ sradi($dst$$Register, $src$$Register, 0x3f); 8672 %} 8673 ins_pipe(pipe_class_default); 8674 %} 8675 8676 // Long negation 8677 instruct negL_reg_reg(iRegLdst dst, immL_0 zero, iRegLsrc src2) %{ 8678 match(Set dst (SubL zero src2)); 8679 format %{ "NEG $dst, $src2 \t// long" %} 8680 size(4); 8681 ins_encode %{ 8682 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 8683 __ neg($dst$$Register, $src2$$Register); 8684 %} 8685 ins_pipe(pipe_class_default); 8686 %} 8687 8688 // NegL + ConvL2I. 8689 instruct negI_con0_regL(iRegIdst dst, immL_0 zero, iRegLsrc src2) %{ 8690 match(Set dst (ConvL2I (SubL zero src2))); 8691 8692 format %{ "NEG $dst, $src2 \t// long + l2i" %} 8693 size(4); 8694 ins_encode %{ 8695 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 8696 __ neg($dst$$Register, $src2$$Register); 8697 %} 8698 ins_pipe(pipe_class_default); 8699 %} 8700 8701 // Multiplication Instructions 8702 // Integer Multiplication 8703 8704 // Register Multiplication 8705 instruct mulI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8706 match(Set dst (MulI src1 src2)); 8707 ins_cost(DEFAULT_COST); 8708 8709 format %{ "MULLW $dst, $src1, $src2" %} 8710 size(4); 8711 ins_encode %{ 8712 // TODO: PPC port $archOpcode(ppc64Opcode_mullw); 8713 __ mullw($dst$$Register, $src1$$Register, $src2$$Register); 8714 %} 8715 ins_pipe(pipe_class_default); 8716 %} 8717 8718 // Immediate Multiplication 8719 instruct mulI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 8720 match(Set dst (MulI src1 src2)); 8721 ins_cost(DEFAULT_COST); 8722 8723 format %{ "MULLI $dst, $src1, $src2" %} 8724 size(4); 8725 ins_encode %{ 8726 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 8727 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 8728 %} 8729 ins_pipe(pipe_class_default); 8730 %} 8731 8732 instruct mulL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8733 match(Set dst (MulL src1 src2)); 8734 ins_cost(DEFAULT_COST); 8735 8736 format %{ "MULLD $dst $src1, $src2 \t// long" %} 8737 size(4); 8738 ins_encode %{ 8739 // TODO: PPC port $archOpcode(ppc64Opcode_mulld); 8740 __ mulld($dst$$Register, $src1$$Register, $src2$$Register); 8741 %} 8742 ins_pipe(pipe_class_default); 8743 %} 8744 8745 // Multiply high for optimized long division by constant. 8746 instruct mulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8747 match(Set dst (MulHiL src1 src2)); 8748 ins_cost(DEFAULT_COST); 8749 8750 format %{ "MULHD $dst $src1, $src2 \t// long" %} 8751 size(4); 8752 ins_encode %{ 8753 // TODO: PPC port $archOpcode(ppc64Opcode_mulhd); 8754 __ mulhd($dst$$Register, $src1$$Register, $src2$$Register); 8755 %} 8756 ins_pipe(pipe_class_default); 8757 %} 8758 8759 // Immediate Multiplication 8760 instruct mulL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 8761 match(Set dst (MulL src1 src2)); 8762 ins_cost(DEFAULT_COST); 8763 8764 format %{ "MULLI $dst, $src1, $src2" %} 8765 size(4); 8766 ins_encode %{ 8767 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 8768 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 8769 %} 8770 ins_pipe(pipe_class_default); 8771 %} 8772 8773 // Integer Division with Immediate -1: Negate. 8774 instruct divI_reg_immIvalueMinus1(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 8775 match(Set dst (DivI src1 src2)); 8776 ins_cost(DEFAULT_COST); 8777 8778 format %{ "NEG $dst, $src1 \t// /-1" %} 8779 size(4); 8780 ins_encode %{ 8781 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 8782 __ neg($dst$$Register, $src1$$Register); 8783 %} 8784 ins_pipe(pipe_class_default); 8785 %} 8786 8787 // Integer Division with constant, but not -1. 8788 // We should be able to improve this by checking the type of src2. 8789 // It might well be that src2 is known to be positive. 8790 instruct divI_reg_regnotMinus1(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8791 match(Set dst (DivI src1 src2)); 8792 predicate(n->in(2)->find_int_con(-1) != -1); // src2 is a constant, but not -1 8793 ins_cost(2*DEFAULT_COST); 8794 8795 format %{ "DIVW $dst, $src1, $src2 \t// /not-1" %} 8796 size(4); 8797 ins_encode %{ 8798 // TODO: PPC port $archOpcode(ppc64Opcode_divw); 8799 __ divw($dst$$Register, $src1$$Register, $src2$$Register); 8800 %} 8801 ins_pipe(pipe_class_default); 8802 %} 8803 8804 instruct cmovI_bne_negI_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src1) %{ 8805 effect(USE_DEF dst, USE src1, USE crx); 8806 predicate(false); 8807 8808 ins_variable_size_depending_on_alignment(true); 8809 8810 format %{ "CMOVE $dst, neg($src1), $crx" %} 8811 // Worst case is branch + move + stop, no stop without scheduler. 8812 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 8813 ins_encode %{ 8814 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 8815 Label done; 8816 __ bne($crx$$CondRegister, done); 8817 __ neg($dst$$Register, $src1$$Register); 8818 // TODO PPC port __ endgroup_if_needed(_size == 12); 8819 __ bind(done); 8820 %} 8821 ins_pipe(pipe_class_default); 8822 %} 8823 8824 // Integer Division with Registers not containing constants. 8825 instruct divI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8826 match(Set dst (DivI src1 src2)); 8827 ins_cost(10*DEFAULT_COST); 8828 8829 expand %{ 8830 immI16 imm %{ (int)-1 %} 8831 flagsReg tmp1; 8832 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 8833 divI_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 8834 cmovI_bne_negI_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 8835 %} 8836 %} 8837 8838 // Long Division with Immediate -1: Negate. 8839 instruct divL_reg_immLvalueMinus1(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 8840 match(Set dst (DivL src1 src2)); 8841 ins_cost(DEFAULT_COST); 8842 8843 format %{ "NEG $dst, $src1 \t// /-1, long" %} 8844 size(4); 8845 ins_encode %{ 8846 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 8847 __ neg($dst$$Register, $src1$$Register); 8848 %} 8849 ins_pipe(pipe_class_default); 8850 %} 8851 8852 // Long Division with constant, but not -1. 8853 instruct divL_reg_regnotMinus1(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8854 match(Set dst (DivL src1 src2)); 8855 predicate(n->in(2)->find_long_con(-1L) != -1L); // Src2 is a constant, but not -1. 8856 ins_cost(2*DEFAULT_COST); 8857 8858 format %{ "DIVD $dst, $src1, $src2 \t// /not-1, long" %} 8859 size(4); 8860 ins_encode %{ 8861 // TODO: PPC port $archOpcode(ppc64Opcode_divd); 8862 __ divd($dst$$Register, $src1$$Register, $src2$$Register); 8863 %} 8864 ins_pipe(pipe_class_default); 8865 %} 8866 8867 instruct cmovL_bne_negL_reg(iRegLdst dst, flagsRegSrc crx, iRegLsrc src1) %{ 8868 effect(USE_DEF dst, USE src1, USE crx); 8869 predicate(false); 8870 8871 ins_variable_size_depending_on_alignment(true); 8872 8873 format %{ "CMOVE $dst, neg($src1), $crx" %} 8874 // Worst case is branch + move + stop, no stop without scheduler. 8875 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 8876 ins_encode %{ 8877 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 8878 Label done; 8879 __ bne($crx$$CondRegister, done); 8880 __ neg($dst$$Register, $src1$$Register); 8881 // TODO PPC port __ endgroup_if_needed(_size == 12); 8882 __ bind(done); 8883 %} 8884 ins_pipe(pipe_class_default); 8885 %} 8886 8887 // Long Division with Registers not containing constants. 8888 instruct divL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8889 match(Set dst (DivL src1 src2)); 8890 ins_cost(10*DEFAULT_COST); 8891 8892 expand %{ 8893 immL16 imm %{ (int)-1 %} 8894 flagsReg tmp1; 8895 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 8896 divL_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 8897 cmovL_bne_negL_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 8898 %} 8899 %} 8900 8901 // Integer Remainder with registers. 8902 instruct modI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8903 match(Set dst (ModI src1 src2)); 8904 ins_cost(10*DEFAULT_COST); 8905 8906 expand %{ 8907 immI16 imm %{ (int)-1 %} 8908 flagsReg tmp1; 8909 iRegIdst tmp2; 8910 iRegIdst tmp3; 8911 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 8912 divI_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 8913 cmovI_bne_negI_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 8914 mulI_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 8915 subI_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 8916 %} 8917 %} 8918 8919 // Long Remainder with registers 8920 instruct modL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8921 match(Set dst (ModL src1 src2)); 8922 ins_cost(10*DEFAULT_COST); 8923 8924 expand %{ 8925 immL16 imm %{ (int)-1 %} 8926 flagsReg tmp1; 8927 iRegLdst tmp2; 8928 iRegLdst tmp3; 8929 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 8930 divL_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 8931 cmovL_bne_negL_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 8932 mulL_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 8933 subL_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 8934 %} 8935 %} 8936 8937 // Integer Shift Instructions 8938 8939 // Register Shift Left 8940 8941 // Clear all but the lowest #mask bits. 8942 // Used to normalize shift amounts in registers. 8943 instruct maskI_reg_imm(iRegIdst dst, iRegIsrc src, uimmI6 mask) %{ 8944 // no match-rule, false predicate 8945 effect(DEF dst, USE src, USE mask); 8946 predicate(false); 8947 8948 format %{ "MASK $dst, $src, $mask \t// clear $mask upper bits" %} 8949 size(4); 8950 ins_encode %{ 8951 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 8952 __ clrldi($dst$$Register, $src$$Register, $mask$$constant); 8953 %} 8954 ins_pipe(pipe_class_default); 8955 %} 8956 8957 instruct lShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8958 // no match-rule, false predicate 8959 effect(DEF dst, USE src1, USE src2); 8960 predicate(false); 8961 8962 format %{ "SLW $dst, $src1, $src2" %} 8963 size(4); 8964 ins_encode %{ 8965 // TODO: PPC port $archOpcode(ppc64Opcode_slw); 8966 __ slw($dst$$Register, $src1$$Register, $src2$$Register); 8967 %} 8968 ins_pipe(pipe_class_default); 8969 %} 8970 8971 instruct lShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8972 match(Set dst (LShiftI src1 src2)); 8973 ins_cost(DEFAULT_COST*2); 8974 expand %{ 8975 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 8976 iRegIdst tmpI; 8977 maskI_reg_imm(tmpI, src2, mask); 8978 lShiftI_reg_reg(dst, src1, tmpI); 8979 %} 8980 %} 8981 8982 // Register Shift Left Immediate 8983 instruct lShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 8984 match(Set dst (LShiftI src1 src2)); 8985 8986 format %{ "SLWI $dst, $src1, ($src2 & 0x1f)" %} 8987 size(4); 8988 ins_encode %{ 8989 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 8990 __ slwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 8991 %} 8992 ins_pipe(pipe_class_default); 8993 %} 8994 8995 // AndI with negpow2-constant + LShiftI 8996 instruct lShiftI_andI_immInegpow2_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 8997 match(Set dst (LShiftI (AndI src1 src2) src3)); 8998 predicate(UseRotateAndMaskInstructionsPPC64); 8999 9000 format %{ "RLWINM $dst, lShiftI(AndI($src1, $src2), $src3)" %} 9001 size(4); 9002 ins_encode %{ 9003 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9004 long src2 = $src2$$constant; 9005 long src3 = $src3$$constant; 9006 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9007 if (maskbits >= 32) { 9008 __ li($dst$$Register, 0); // addi 9009 } else { 9010 __ rlwinm($dst$$Register, $src1$$Register, src3 & 0x1f, 0, (31-maskbits) & 0x1f); 9011 } 9012 %} 9013 ins_pipe(pipe_class_default); 9014 %} 9015 9016 // RShiftI + AndI with negpow2-constant + LShiftI 9017 instruct lShiftI_andI_immInegpow2_rShiftI_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9018 match(Set dst (LShiftI (AndI (RShiftI src1 src3) src2) src3)); 9019 predicate(UseRotateAndMaskInstructionsPPC64); 9020 9021 format %{ "RLWINM $dst, lShiftI(AndI(RShiftI($src1, $src3), $src2), $src3)" %} 9022 size(4); 9023 ins_encode %{ 9024 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9025 long src2 = $src2$$constant; 9026 long src3 = $src3$$constant; 9027 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9028 if (maskbits >= 32) { 9029 __ li($dst$$Register, 0); // addi 9030 } else { 9031 __ rlwinm($dst$$Register, $src1$$Register, 0, 0, (31-maskbits) & 0x1f); 9032 } 9033 %} 9034 ins_pipe(pipe_class_default); 9035 %} 9036 9037 instruct lShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9038 // no match-rule, false predicate 9039 effect(DEF dst, USE src1, USE src2); 9040 predicate(false); 9041 9042 format %{ "SLD $dst, $src1, $src2" %} 9043 size(4); 9044 ins_encode %{ 9045 // TODO: PPC port $archOpcode(ppc64Opcode_sld); 9046 __ sld($dst$$Register, $src1$$Register, $src2$$Register); 9047 %} 9048 ins_pipe(pipe_class_default); 9049 %} 9050 9051 // Register Shift Left 9052 instruct lShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9053 match(Set dst (LShiftL src1 src2)); 9054 ins_cost(DEFAULT_COST*2); 9055 expand %{ 9056 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9057 iRegIdst tmpI; 9058 maskI_reg_imm(tmpI, src2, mask); 9059 lShiftL_regL_regI(dst, src1, tmpI); 9060 %} 9061 %} 9062 9063 // Register Shift Left Immediate 9064 instruct lshiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9065 match(Set dst (LShiftL src1 src2)); 9066 format %{ "SLDI $dst, $src1, ($src2 & 0x3f)" %} 9067 size(4); 9068 ins_encode %{ 9069 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9070 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9071 %} 9072 ins_pipe(pipe_class_default); 9073 %} 9074 9075 // If we shift more than 32 bits, we need not convert I2L. 9076 instruct lShiftL_regI_immGE32(iRegLdst dst, iRegIsrc src1, uimmI6_ge32 src2) %{ 9077 match(Set dst (LShiftL (ConvI2L src1) src2)); 9078 ins_cost(DEFAULT_COST); 9079 9080 size(4); 9081 format %{ "SLDI $dst, i2l($src1), $src2" %} 9082 ins_encode %{ 9083 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9084 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9085 %} 9086 ins_pipe(pipe_class_default); 9087 %} 9088 9089 // Shift a postivie int to the left. 9090 // Clrlsldi clears the upper 32 bits and shifts. 9091 instruct scaledPositiveI2L_lShiftL_convI2L_reg_imm6(iRegLdst dst, iRegIsrc src1, uimmI6 src2) %{ 9092 match(Set dst (LShiftL (ConvI2L src1) src2)); 9093 predicate(((ConvI2LNode*)(_kids[0]->_leaf))->type()->is_long()->is_positive_int()); 9094 9095 format %{ "SLDI $dst, i2l(positive_int($src1)), $src2" %} 9096 size(4); 9097 ins_encode %{ 9098 // TODO: PPC port $archOpcode(ppc64Opcode_rldic); 9099 __ clrlsldi($dst$$Register, $src1$$Register, 0x20, $src2$$constant); 9100 %} 9101 ins_pipe(pipe_class_default); 9102 %} 9103 9104 instruct arShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9105 // no match-rule, false predicate 9106 effect(DEF dst, USE src1, USE src2); 9107 predicate(false); 9108 9109 format %{ "SRAW $dst, $src1, $src2" %} 9110 size(4); 9111 ins_encode %{ 9112 // TODO: PPC port $archOpcode(ppc64Opcode_sraw); 9113 __ sraw($dst$$Register, $src1$$Register, $src2$$Register); 9114 %} 9115 ins_pipe(pipe_class_default); 9116 %} 9117 9118 // Register Arithmetic Shift Right 9119 instruct arShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9120 match(Set dst (RShiftI src1 src2)); 9121 ins_cost(DEFAULT_COST*2); 9122 expand %{ 9123 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9124 iRegIdst tmpI; 9125 maskI_reg_imm(tmpI, src2, mask); 9126 arShiftI_reg_reg(dst, src1, tmpI); 9127 %} 9128 %} 9129 9130 // Register Arithmetic Shift Right Immediate 9131 instruct arShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9132 match(Set dst (RShiftI src1 src2)); 9133 9134 format %{ "SRAWI $dst, $src1, ($src2 & 0x1f)" %} 9135 size(4); 9136 ins_encode %{ 9137 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 9138 __ srawi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9139 %} 9140 ins_pipe(pipe_class_default); 9141 %} 9142 9143 instruct arShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9144 // no match-rule, false predicate 9145 effect(DEF dst, USE src1, USE src2); 9146 predicate(false); 9147 9148 format %{ "SRAD $dst, $src1, $src2" %} 9149 size(4); 9150 ins_encode %{ 9151 // TODO: PPC port $archOpcode(ppc64Opcode_srad); 9152 __ srad($dst$$Register, $src1$$Register, $src2$$Register); 9153 %} 9154 ins_pipe(pipe_class_default); 9155 %} 9156 9157 // Register Shift Right Arithmetic Long 9158 instruct arShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9159 match(Set dst (RShiftL src1 src2)); 9160 ins_cost(DEFAULT_COST*2); 9161 9162 expand %{ 9163 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9164 iRegIdst tmpI; 9165 maskI_reg_imm(tmpI, src2, mask); 9166 arShiftL_regL_regI(dst, src1, tmpI); 9167 %} 9168 %} 9169 9170 // Register Shift Right Immediate 9171 instruct arShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9172 match(Set dst (RShiftL src1 src2)); 9173 9174 format %{ "SRADI $dst, $src1, ($src2 & 0x3f)" %} 9175 size(4); 9176 ins_encode %{ 9177 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9178 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9179 %} 9180 ins_pipe(pipe_class_default); 9181 %} 9182 9183 // RShiftL + ConvL2I 9184 instruct convL2I_arShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9185 match(Set dst (ConvL2I (RShiftL src1 src2))); 9186 9187 format %{ "SRADI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9188 size(4); 9189 ins_encode %{ 9190 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9191 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9192 %} 9193 ins_pipe(pipe_class_default); 9194 %} 9195 9196 instruct urShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9197 // no match-rule, false predicate 9198 effect(DEF dst, USE src1, USE src2); 9199 predicate(false); 9200 9201 format %{ "SRW $dst, $src1, $src2" %} 9202 size(4); 9203 ins_encode %{ 9204 // TODO: PPC port $archOpcode(ppc64Opcode_srw); 9205 __ srw($dst$$Register, $src1$$Register, $src2$$Register); 9206 %} 9207 ins_pipe(pipe_class_default); 9208 %} 9209 9210 // Register Shift Right 9211 instruct urShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9212 match(Set dst (URShiftI src1 src2)); 9213 ins_cost(DEFAULT_COST*2); 9214 9215 expand %{ 9216 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9217 iRegIdst tmpI; 9218 maskI_reg_imm(tmpI, src2, mask); 9219 urShiftI_reg_reg(dst, src1, tmpI); 9220 %} 9221 %} 9222 9223 // Register Shift Right Immediate 9224 instruct urShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9225 match(Set dst (URShiftI src1 src2)); 9226 9227 format %{ "SRWI $dst, $src1, ($src2 & 0x1f)" %} 9228 size(4); 9229 ins_encode %{ 9230 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9231 __ srwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9232 %} 9233 ins_pipe(pipe_class_default); 9234 %} 9235 9236 instruct urShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9237 // no match-rule, false predicate 9238 effect(DEF dst, USE src1, USE src2); 9239 predicate(false); 9240 9241 format %{ "SRD $dst, $src1, $src2" %} 9242 size(4); 9243 ins_encode %{ 9244 // TODO: PPC port $archOpcode(ppc64Opcode_srd); 9245 __ srd($dst$$Register, $src1$$Register, $src2$$Register); 9246 %} 9247 ins_pipe(pipe_class_default); 9248 %} 9249 9250 // Register Shift Right 9251 instruct urShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9252 match(Set dst (URShiftL src1 src2)); 9253 ins_cost(DEFAULT_COST*2); 9254 9255 expand %{ 9256 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9257 iRegIdst tmpI; 9258 maskI_reg_imm(tmpI, src2, mask); 9259 urShiftL_regL_regI(dst, src1, tmpI); 9260 %} 9261 %} 9262 9263 // Register Shift Right Immediate 9264 instruct urShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9265 match(Set dst (URShiftL src1 src2)); 9266 9267 format %{ "SRDI $dst, $src1, ($src2 & 0x3f)" %} 9268 size(4); 9269 ins_encode %{ 9270 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9271 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9272 %} 9273 ins_pipe(pipe_class_default); 9274 %} 9275 9276 // URShiftL + ConvL2I. 9277 instruct convL2I_urShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9278 match(Set dst (ConvL2I (URShiftL src1 src2))); 9279 9280 format %{ "SRDI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9281 size(4); 9282 ins_encode %{ 9283 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9284 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9285 %} 9286 ins_pipe(pipe_class_default); 9287 %} 9288 9289 // Register Shift Right Immediate with a CastP2X 9290 instruct shrP_convP2X_reg_imm6(iRegLdst dst, iRegP_N2P src1, uimmI6 src2) %{ 9291 match(Set dst (URShiftL (CastP2X src1) src2)); 9292 9293 format %{ "SRDI $dst, $src1, $src2 \t// Cast ptr $src1 to long and shift" %} 9294 size(4); 9295 ins_encode %{ 9296 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9297 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9298 %} 9299 ins_pipe(pipe_class_default); 9300 %} 9301 9302 instruct sxtI_reg(iRegIdst dst, iRegIsrc src) %{ 9303 match(Set dst (ConvL2I (ConvI2L src))); 9304 9305 format %{ "EXTSW $dst, $src \t// int->int" %} 9306 size(4); 9307 ins_encode %{ 9308 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 9309 __ extsw($dst$$Register, $src$$Register); 9310 %} 9311 ins_pipe(pipe_class_default); 9312 %} 9313 9314 //----------Rotate Instructions------------------------------------------------ 9315 9316 // Rotate Left by 8-bit immediate 9317 instruct rotlI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 lshift, immI8 rshift) %{ 9318 match(Set dst (OrI (LShiftI src lshift) (URShiftI src rshift))); 9319 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9320 9321 format %{ "ROTLWI $dst, $src, $lshift" %} 9322 size(4); 9323 ins_encode %{ 9324 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9325 __ rotlwi($dst$$Register, $src$$Register, $lshift$$constant); 9326 %} 9327 ins_pipe(pipe_class_default); 9328 %} 9329 9330 // Rotate Right by 8-bit immediate 9331 instruct rotrI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 rshift, immI8 lshift) %{ 9332 match(Set dst (OrI (URShiftI src rshift) (LShiftI src lshift))); 9333 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9334 9335 format %{ "ROTRWI $dst, $rshift" %} 9336 size(4); 9337 ins_encode %{ 9338 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9339 __ rotrwi($dst$$Register, $src$$Register, $rshift$$constant); 9340 %} 9341 ins_pipe(pipe_class_default); 9342 %} 9343 9344 //----------Floating Point Arithmetic Instructions----------------------------- 9345 9346 // Add float single precision 9347 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{ 9348 match(Set dst (AddF src1 src2)); 9349 9350 format %{ "FADDS $dst, $src1, $src2" %} 9351 size(4); 9352 ins_encode %{ 9353 // TODO: PPC port $archOpcode(ppc64Opcode_fadds); 9354 __ fadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9355 %} 9356 ins_pipe(pipe_class_default); 9357 %} 9358 9359 // Add float double precision 9360 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{ 9361 match(Set dst (AddD src1 src2)); 9362 9363 format %{ "FADD $dst, $src1, $src2" %} 9364 size(4); 9365 ins_encode %{ 9366 // TODO: PPC port $archOpcode(ppc64Opcode_fadd); 9367 __ fadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9368 %} 9369 ins_pipe(pipe_class_default); 9370 %} 9371 9372 // Sub float single precision 9373 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{ 9374 match(Set dst (SubF src1 src2)); 9375 9376 format %{ "FSUBS $dst, $src1, $src2" %} 9377 size(4); 9378 ins_encode %{ 9379 // TODO: PPC port $archOpcode(ppc64Opcode_fsubs); 9380 __ fsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9381 %} 9382 ins_pipe(pipe_class_default); 9383 %} 9384 9385 // Sub float double precision 9386 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{ 9387 match(Set dst (SubD src1 src2)); 9388 format %{ "FSUB $dst, $src1, $src2" %} 9389 size(4); 9390 ins_encode %{ 9391 // TODO: PPC port $archOpcode(ppc64Opcode_fsub); 9392 __ fsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9393 %} 9394 ins_pipe(pipe_class_default); 9395 %} 9396 9397 // Mul float single precision 9398 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{ 9399 match(Set dst (MulF src1 src2)); 9400 format %{ "FMULS $dst, $src1, $src2" %} 9401 size(4); 9402 ins_encode %{ 9403 // TODO: PPC port $archOpcode(ppc64Opcode_fmuls); 9404 __ fmuls($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9405 %} 9406 ins_pipe(pipe_class_default); 9407 %} 9408 9409 // Mul float double precision 9410 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{ 9411 match(Set dst (MulD src1 src2)); 9412 format %{ "FMUL $dst, $src1, $src2" %} 9413 size(4); 9414 ins_encode %{ 9415 // TODO: PPC port $archOpcode(ppc64Opcode_fmul); 9416 __ fmul($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9417 %} 9418 ins_pipe(pipe_class_default); 9419 %} 9420 9421 // Div float single precision 9422 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{ 9423 match(Set dst (DivF src1 src2)); 9424 format %{ "FDIVS $dst, $src1, $src2" %} 9425 size(4); 9426 ins_encode %{ 9427 // TODO: PPC port $archOpcode(ppc64Opcode_fdivs); 9428 __ fdivs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9429 %} 9430 ins_pipe(pipe_class_default); 9431 %} 9432 9433 // Div float double precision 9434 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{ 9435 match(Set dst (DivD src1 src2)); 9436 format %{ "FDIV $dst, $src1, $src2" %} 9437 size(4); 9438 ins_encode %{ 9439 // TODO: PPC port $archOpcode(ppc64Opcode_fdiv); 9440 __ fdiv($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9441 %} 9442 ins_pipe(pipe_class_default); 9443 %} 9444 9445 // Absolute float single precision 9446 instruct absF_reg(regF dst, regF src) %{ 9447 match(Set dst (AbsF src)); 9448 format %{ "FABS $dst, $src \t// float" %} 9449 size(4); 9450 ins_encode %{ 9451 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 9452 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9453 %} 9454 ins_pipe(pipe_class_default); 9455 %} 9456 9457 // Absolute float double precision 9458 instruct absD_reg(regD dst, regD src) %{ 9459 match(Set dst (AbsD src)); 9460 format %{ "FABS $dst, $src \t// double" %} 9461 size(4); 9462 ins_encode %{ 9463 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 9464 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9465 %} 9466 ins_pipe(pipe_class_default); 9467 %} 9468 9469 instruct negF_reg(regF dst, regF src) %{ 9470 match(Set dst (NegF src)); 9471 format %{ "FNEG $dst, $src \t// float" %} 9472 size(4); 9473 ins_encode %{ 9474 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 9475 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 9476 %} 9477 ins_pipe(pipe_class_default); 9478 %} 9479 9480 instruct negD_reg(regD dst, regD src) %{ 9481 match(Set dst (NegD src)); 9482 format %{ "FNEG $dst, $src \t// double" %} 9483 size(4); 9484 ins_encode %{ 9485 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 9486 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 9487 %} 9488 ins_pipe(pipe_class_default); 9489 %} 9490 9491 // AbsF + NegF. 9492 instruct negF_absF_reg(regF dst, regF src) %{ 9493 match(Set dst (NegF (AbsF src))); 9494 format %{ "FNABS $dst, $src \t// float" %} 9495 size(4); 9496 ins_encode %{ 9497 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 9498 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 9499 %} 9500 ins_pipe(pipe_class_default); 9501 %} 9502 9503 // AbsD + NegD. 9504 instruct negD_absD_reg(regD dst, regD src) %{ 9505 match(Set dst (NegD (AbsD src))); 9506 format %{ "FNABS $dst, $src \t// double" %} 9507 size(4); 9508 ins_encode %{ 9509 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 9510 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 9511 %} 9512 ins_pipe(pipe_class_default); 9513 %} 9514 9515 // VM_Version::has_fsqrt() decides if this node will be used. 9516 // Sqrt float double precision 9517 instruct sqrtD_reg(regD dst, regD src) %{ 9518 match(Set dst (SqrtD src)); 9519 format %{ "FSQRT $dst, $src" %} 9520 size(4); 9521 ins_encode %{ 9522 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrt); 9523 __ fsqrt($dst$$FloatRegister, $src$$FloatRegister); 9524 %} 9525 ins_pipe(pipe_class_default); 9526 %} 9527 9528 // Single-precision sqrt. 9529 instruct sqrtF_reg(regF dst, regF src) %{ 9530 match(Set dst (ConvD2F (SqrtD (ConvF2D src)))); 9531 predicate(VM_Version::has_fsqrts()); 9532 ins_cost(DEFAULT_COST); 9533 9534 format %{ "FSQRTS $dst, $src" %} 9535 size(4); 9536 ins_encode %{ 9537 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrts); 9538 __ fsqrts($dst$$FloatRegister, $src$$FloatRegister); 9539 %} 9540 ins_pipe(pipe_class_default); 9541 %} 9542 9543 instruct roundDouble_nop(regD dst) %{ 9544 match(Set dst (RoundDouble dst)); 9545 ins_cost(0); 9546 9547 format %{ " -- \t// RoundDouble not needed - empty" %} 9548 size(0); 9549 // PPC results are already "rounded" (i.e., normal-format IEEE). 9550 ins_encode( /*empty*/ ); 9551 ins_pipe(pipe_class_default); 9552 %} 9553 9554 instruct roundFloat_nop(regF dst) %{ 9555 match(Set dst (RoundFloat dst)); 9556 ins_cost(0); 9557 9558 format %{ " -- \t// RoundFloat not needed - empty" %} 9559 size(0); 9560 // PPC results are already "rounded" (i.e., normal-format IEEE). 9561 ins_encode( /*empty*/ ); 9562 ins_pipe(pipe_class_default); 9563 %} 9564 9565 //----------Logical Instructions----------------------------------------------- 9566 9567 // And Instructions 9568 9569 // Register And 9570 instruct andI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9571 match(Set dst (AndI src1 src2)); 9572 format %{ "AND $dst, $src1, $src2" %} 9573 size(4); 9574 ins_encode %{ 9575 // TODO: PPC port $archOpcode(ppc64Opcode_and); 9576 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 9577 %} 9578 ins_pipe(pipe_class_default); 9579 %} 9580 9581 // Immediate And 9582 instruct andI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2, flagsRegCR0 cr0) %{ 9583 match(Set dst (AndI src1 src2)); 9584 effect(KILL cr0); 9585 9586 format %{ "ANDI $dst, $src1, $src2" %} 9587 size(4); 9588 ins_encode %{ 9589 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 9590 // FIXME: avoid andi_ ? 9591 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 9592 %} 9593 ins_pipe(pipe_class_default); 9594 %} 9595 9596 // Immediate And where the immediate is a negative power of 2. 9597 instruct andI_reg_immInegpow2(iRegIdst dst, iRegIsrc src1, immInegpow2 src2) %{ 9598 match(Set dst (AndI src1 src2)); 9599 format %{ "ANDWI $dst, $src1, $src2" %} 9600 size(4); 9601 ins_encode %{ 9602 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9603 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)(julong)(juint)-($src2$$constant))); 9604 %} 9605 ins_pipe(pipe_class_default); 9606 %} 9607 9608 instruct andI_reg_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immIpow2minus1 src2) %{ 9609 match(Set dst (AndI src1 src2)); 9610 format %{ "ANDWI $dst, $src1, $src2" %} 9611 size(4); 9612 ins_encode %{ 9613 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9614 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 9615 %} 9616 ins_pipe(pipe_class_default); 9617 %} 9618 9619 instruct andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src1, immIpowerOf2 src2) %{ 9620 match(Set dst (AndI src1 src2)); 9621 predicate(UseRotateAndMaskInstructionsPPC64); 9622 format %{ "ANDWI $dst, $src1, $src2" %} 9623 size(4); 9624 ins_encode %{ 9625 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9626 __ rlwinm($dst$$Register, $src1$$Register, 0, 9627 (31-log2_long((jlong) $src2$$constant)) & 0x1f, (31-log2_long((jlong) $src2$$constant)) & 0x1f); 9628 %} 9629 ins_pipe(pipe_class_default); 9630 %} 9631 9632 // Register And Long 9633 instruct andL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9634 match(Set dst (AndL src1 src2)); 9635 ins_cost(DEFAULT_COST); 9636 9637 format %{ "AND $dst, $src1, $src2 \t// long" %} 9638 size(4); 9639 ins_encode %{ 9640 // TODO: PPC port $archOpcode(ppc64Opcode_and); 9641 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 9642 %} 9643 ins_pipe(pipe_class_default); 9644 %} 9645 9646 // Immediate And long 9647 instruct andL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2, flagsRegCR0 cr0) %{ 9648 match(Set dst (AndL src1 src2)); 9649 effect(KILL cr0); 9650 9651 format %{ "ANDI $dst, $src1, $src2 \t// long" %} 9652 size(4); 9653 ins_encode %{ 9654 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 9655 // FIXME: avoid andi_ ? 9656 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 9657 %} 9658 ins_pipe(pipe_class_default); 9659 %} 9660 9661 // Immediate And Long where the immediate is a negative power of 2. 9662 instruct andL_reg_immLnegpow2(iRegLdst dst, iRegLsrc src1, immLnegpow2 src2) %{ 9663 match(Set dst (AndL src1 src2)); 9664 format %{ "ANDDI $dst, $src1, $src2" %} 9665 size(4); 9666 ins_encode %{ 9667 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9668 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)-$src2$$constant)); 9669 %} 9670 ins_pipe(pipe_class_default); 9671 %} 9672 9673 instruct andL_reg_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 9674 match(Set dst (AndL src1 src2)); 9675 format %{ "ANDDI $dst, $src1, $src2" %} 9676 size(4); 9677 ins_encode %{ 9678 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9679 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 9680 %} 9681 ins_pipe(pipe_class_default); 9682 %} 9683 9684 // AndL + ConvL2I. 9685 instruct convL2I_andL_reg_immLpow2minus1(iRegIdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 9686 match(Set dst (ConvL2I (AndL src1 src2))); 9687 ins_cost(DEFAULT_COST); 9688 9689 format %{ "ANDDI $dst, $src1, $src2 \t// long + l2i" %} 9690 size(4); 9691 ins_encode %{ 9692 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9693 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 9694 %} 9695 ins_pipe(pipe_class_default); 9696 %} 9697 9698 // Or Instructions 9699 9700 // Register Or 9701 instruct orI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9702 match(Set dst (OrI src1 src2)); 9703 format %{ "OR $dst, $src1, $src2" %} 9704 size(4); 9705 ins_encode %{ 9706 // TODO: PPC port $archOpcode(ppc64Opcode_or); 9707 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 9708 %} 9709 ins_pipe(pipe_class_default); 9710 %} 9711 9712 // Expand does not work with above instruct. (??) 9713 instruct orI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9714 // no match-rule 9715 effect(DEF dst, USE src1, USE src2); 9716 format %{ "OR $dst, $src1, $src2" %} 9717 size(4); 9718 ins_encode %{ 9719 // TODO: PPC port $archOpcode(ppc64Opcode_or); 9720 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 9721 %} 9722 ins_pipe(pipe_class_default); 9723 %} 9724 9725 instruct tree_orI_orI_orI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 9726 match(Set dst (OrI (OrI (OrI src1 src2) src3) src4)); 9727 ins_cost(DEFAULT_COST*3); 9728 9729 expand %{ 9730 // FIXME: we should do this in the ideal world. 9731 iRegIdst tmp1; 9732 iRegIdst tmp2; 9733 orI_reg_reg(tmp1, src1, src2); 9734 orI_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 9735 orI_reg_reg(dst, tmp1, tmp2); 9736 %} 9737 %} 9738 9739 // Immediate Or 9740 instruct orI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 9741 match(Set dst (OrI src1 src2)); 9742 format %{ "ORI $dst, $src1, $src2" %} 9743 size(4); 9744 ins_encode %{ 9745 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 9746 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 9747 %} 9748 ins_pipe(pipe_class_default); 9749 %} 9750 9751 // Register Or Long 9752 instruct orL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9753 match(Set dst (OrL src1 src2)); 9754 ins_cost(DEFAULT_COST); 9755 9756 size(4); 9757 format %{ "OR $dst, $src1, $src2 \t// long" %} 9758 ins_encode %{ 9759 // TODO: PPC port $archOpcode(ppc64Opcode_or); 9760 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 9761 %} 9762 ins_pipe(pipe_class_default); 9763 %} 9764 9765 // OrL + ConvL2I. 9766 instruct orI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9767 match(Set dst (ConvL2I (OrL src1 src2))); 9768 ins_cost(DEFAULT_COST); 9769 9770 format %{ "OR $dst, $src1, $src2 \t// long + l2i" %} 9771 size(4); 9772 ins_encode %{ 9773 // TODO: PPC port $archOpcode(ppc64Opcode_or); 9774 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 9775 %} 9776 ins_pipe(pipe_class_default); 9777 %} 9778 9779 // Immediate Or long 9780 instruct orL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 con) %{ 9781 match(Set dst (OrL src1 con)); 9782 ins_cost(DEFAULT_COST); 9783 9784 format %{ "ORI $dst, $src1, $con \t// long" %} 9785 size(4); 9786 ins_encode %{ 9787 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 9788 __ ori($dst$$Register, $src1$$Register, ($con$$constant) & 0xFFFF); 9789 %} 9790 ins_pipe(pipe_class_default); 9791 %} 9792 9793 // Xor Instructions 9794 9795 // Register Xor 9796 instruct xorI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9797 match(Set dst (XorI src1 src2)); 9798 format %{ "XOR $dst, $src1, $src2" %} 9799 size(4); 9800 ins_encode %{ 9801 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 9802 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 9803 %} 9804 ins_pipe(pipe_class_default); 9805 %} 9806 9807 // Expand does not work with above instruct. (??) 9808 instruct xorI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9809 // no match-rule 9810 effect(DEF dst, USE src1, USE src2); 9811 format %{ "XOR $dst, $src1, $src2" %} 9812 size(4); 9813 ins_encode %{ 9814 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 9815 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 9816 %} 9817 ins_pipe(pipe_class_default); 9818 %} 9819 9820 instruct tree_xorI_xorI_xorI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 9821 match(Set dst (XorI (XorI (XorI src1 src2) src3) src4)); 9822 ins_cost(DEFAULT_COST*3); 9823 9824 expand %{ 9825 // FIXME: we should do this in the ideal world. 9826 iRegIdst tmp1; 9827 iRegIdst tmp2; 9828 xorI_reg_reg(tmp1, src1, src2); 9829 xorI_reg_reg_2(tmp2, src3, src4); // Adlc complains about xorI_reg_reg. 9830 xorI_reg_reg(dst, tmp1, tmp2); 9831 %} 9832 %} 9833 9834 // Immediate Xor 9835 instruct xorI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 9836 match(Set dst (XorI src1 src2)); 9837 format %{ "XORI $dst, $src1, $src2" %} 9838 size(4); 9839 ins_encode %{ 9840 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 9841 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 9842 %} 9843 ins_pipe(pipe_class_default); 9844 %} 9845 9846 // Register Xor Long 9847 instruct xorL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9848 match(Set dst (XorL src1 src2)); 9849 ins_cost(DEFAULT_COST); 9850 9851 format %{ "XOR $dst, $src1, $src2 \t// long" %} 9852 size(4); 9853 ins_encode %{ 9854 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 9855 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 9856 %} 9857 ins_pipe(pipe_class_default); 9858 %} 9859 9860 // XorL + ConvL2I. 9861 instruct xorI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9862 match(Set dst (ConvL2I (XorL src1 src2))); 9863 ins_cost(DEFAULT_COST); 9864 9865 format %{ "XOR $dst, $src1, $src2 \t// long + l2i" %} 9866 size(4); 9867 ins_encode %{ 9868 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 9869 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 9870 %} 9871 ins_pipe(pipe_class_default); 9872 %} 9873 9874 // Immediate Xor Long 9875 instruct xorL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2) %{ 9876 match(Set dst (XorL src1 src2)); 9877 ins_cost(DEFAULT_COST); 9878 9879 format %{ "XORI $dst, $src1, $src2 \t// long" %} 9880 size(4); 9881 ins_encode %{ 9882 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 9883 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 9884 %} 9885 ins_pipe(pipe_class_default); 9886 %} 9887 9888 instruct notI_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 9889 match(Set dst (XorI src1 src2)); 9890 ins_cost(DEFAULT_COST); 9891 9892 format %{ "NOT $dst, $src1 ($src2)" %} 9893 size(4); 9894 ins_encode %{ 9895 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 9896 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 9897 %} 9898 ins_pipe(pipe_class_default); 9899 %} 9900 9901 instruct notL_reg(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 9902 match(Set dst (XorL src1 src2)); 9903 ins_cost(DEFAULT_COST); 9904 9905 format %{ "NOT $dst, $src1 ($src2) \t// long" %} 9906 size(4); 9907 ins_encode %{ 9908 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 9909 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 9910 %} 9911 ins_pipe(pipe_class_default); 9912 %} 9913 9914 // And-complement 9915 instruct andcI_reg_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2, iRegIsrc src3) %{ 9916 match(Set dst (AndI (XorI src1 src2) src3)); 9917 ins_cost(DEFAULT_COST); 9918 9919 format %{ "ANDW $dst, xori($src1, $src2), $src3" %} 9920 size(4); 9921 ins_encode( enc_andc(dst, src3, src1) ); 9922 ins_pipe(pipe_class_default); 9923 %} 9924 9925 // And-complement 9926 instruct andcL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9927 // no match-rule, false predicate 9928 effect(DEF dst, USE src1, USE src2); 9929 predicate(false); 9930 9931 format %{ "ANDC $dst, $src1, $src2" %} 9932 size(4); 9933 ins_encode %{ 9934 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 9935 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 9936 %} 9937 ins_pipe(pipe_class_default); 9938 %} 9939 9940 //----------Moves between int/long and float/double---------------------------- 9941 // 9942 // The following rules move values from int/long registers/stack-locations 9943 // to float/double registers/stack-locations and vice versa, without doing any 9944 // conversions. These rules are used to implement the bit-conversion methods 9945 // of java.lang.Float etc., e.g. 9946 // int floatToIntBits(float value) 9947 // float intBitsToFloat(int bits) 9948 // 9949 // Notes on the implementation on ppc64: 9950 // We only provide rules which move between a register and a stack-location, 9951 // because we always have to go through memory when moving between a float 9952 // register and an integer register. 9953 9954 //---------- Chain stack slots between similar types -------- 9955 9956 // These are needed so that the rules below can match. 9957 9958 // Load integer from stack slot 9959 instruct stkI_to_regI(iRegIdst dst, stackSlotI src) %{ 9960 match(Set dst src); 9961 ins_cost(MEMORY_REF_COST); 9962 9963 format %{ "LWZ $dst, $src" %} 9964 size(4); 9965 ins_encode( enc_lwz(dst, src) ); 9966 ins_pipe(pipe_class_memory); 9967 %} 9968 9969 // Store integer to stack slot 9970 instruct regI_to_stkI(stackSlotI dst, iRegIsrc src) %{ 9971 match(Set dst src); 9972 ins_cost(MEMORY_REF_COST); 9973 9974 format %{ "STW $src, $dst \t// stk" %} 9975 size(4); 9976 ins_encode( enc_stw(src, dst) ); // rs=rt 9977 ins_pipe(pipe_class_memory); 9978 %} 9979 9980 // Load long from stack slot 9981 instruct stkL_to_regL(iRegLdst dst, stackSlotL src) %{ 9982 match(Set dst src); 9983 ins_cost(MEMORY_REF_COST); 9984 9985 format %{ "LD $dst, $src \t// long" %} 9986 size(4); 9987 ins_encode( enc_ld(dst, src) ); 9988 ins_pipe(pipe_class_memory); 9989 %} 9990 9991 // Store long to stack slot 9992 instruct regL_to_stkL(stackSlotL dst, iRegLsrc src) %{ 9993 match(Set dst src); 9994 ins_cost(MEMORY_REF_COST); 9995 9996 format %{ "STD $src, $dst \t// long" %} 9997 size(4); 9998 ins_encode( enc_std(src, dst) ); // rs=rt 9999 ins_pipe(pipe_class_memory); 10000 %} 10001 10002 //----------Moves between int and float 10003 10004 // Move float value from float stack-location to integer register. 10005 instruct moveF2I_stack_reg(iRegIdst dst, stackSlotF src) %{ 10006 match(Set dst (MoveF2I src)); 10007 ins_cost(MEMORY_REF_COST); 10008 10009 format %{ "LWZ $dst, $src \t// MoveF2I" %} 10010 size(4); 10011 ins_encode( enc_lwz(dst, src) ); 10012 ins_pipe(pipe_class_memory); 10013 %} 10014 10015 // Move float value from float register to integer stack-location. 10016 instruct moveF2I_reg_stack(stackSlotI dst, regF src) %{ 10017 match(Set dst (MoveF2I src)); 10018 ins_cost(MEMORY_REF_COST); 10019 10020 format %{ "STFS $src, $dst \t// MoveF2I" %} 10021 size(4); 10022 ins_encode( enc_stfs(src, dst) ); 10023 ins_pipe(pipe_class_memory); 10024 %} 10025 10026 // Move integer value from integer stack-location to float register. 10027 instruct moveI2F_stack_reg(regF dst, stackSlotI src) %{ 10028 match(Set dst (MoveI2F src)); 10029 ins_cost(MEMORY_REF_COST); 10030 10031 format %{ "LFS $dst, $src \t// MoveI2F" %} 10032 size(4); 10033 ins_encode %{ 10034 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 10035 int Idisp = $src$$disp + frame_slots_bias($src$$base, ra_); 10036 __ lfs($dst$$FloatRegister, Idisp, $src$$base$$Register); 10037 %} 10038 ins_pipe(pipe_class_memory); 10039 %} 10040 10041 // Move integer value from integer register to float stack-location. 10042 instruct moveI2F_reg_stack(stackSlotF dst, iRegIsrc src) %{ 10043 match(Set dst (MoveI2F src)); 10044 ins_cost(MEMORY_REF_COST); 10045 10046 format %{ "STW $src, $dst \t// MoveI2F" %} 10047 size(4); 10048 ins_encode( enc_stw(src, dst) ); 10049 ins_pipe(pipe_class_memory); 10050 %} 10051 10052 //----------Moves between long and float 10053 10054 instruct moveF2L_reg_stack(stackSlotL dst, regF src) %{ 10055 // no match-rule, false predicate 10056 effect(DEF dst, USE src); 10057 predicate(false); 10058 10059 format %{ "storeD $src, $dst \t// STACK" %} 10060 size(4); 10061 ins_encode( enc_stfd(src, dst) ); 10062 ins_pipe(pipe_class_default); 10063 %} 10064 10065 //----------Moves between long and double 10066 10067 // Move double value from double stack-location to long register. 10068 instruct moveD2L_stack_reg(iRegLdst dst, stackSlotD src) %{ 10069 match(Set dst (MoveD2L src)); 10070 ins_cost(MEMORY_REF_COST); 10071 size(4); 10072 format %{ "LD $dst, $src \t// MoveD2L" %} 10073 ins_encode( enc_ld(dst, src) ); 10074 ins_pipe(pipe_class_memory); 10075 %} 10076 10077 // Move double value from double register to long stack-location. 10078 instruct moveD2L_reg_stack(stackSlotL dst, regD src) %{ 10079 match(Set dst (MoveD2L src)); 10080 effect(DEF dst, USE src); 10081 ins_cost(MEMORY_REF_COST); 10082 10083 format %{ "STFD $src, $dst \t// MoveD2L" %} 10084 size(4); 10085 ins_encode( enc_stfd(src, dst) ); 10086 ins_pipe(pipe_class_memory); 10087 %} 10088 10089 // Move long value from long stack-location to double register. 10090 instruct moveL2D_stack_reg(regD dst, stackSlotL src) %{ 10091 match(Set dst (MoveL2D src)); 10092 ins_cost(MEMORY_REF_COST); 10093 10094 format %{ "LFD $dst, $src \t// MoveL2D" %} 10095 size(4); 10096 ins_encode( enc_lfd(dst, src) ); 10097 ins_pipe(pipe_class_memory); 10098 %} 10099 10100 // Move long value from long register to double stack-location. 10101 instruct moveL2D_reg_stack(stackSlotD dst, iRegLsrc src) %{ 10102 match(Set dst (MoveL2D src)); 10103 ins_cost(MEMORY_REF_COST); 10104 10105 format %{ "STD $src, $dst \t// MoveL2D" %} 10106 size(4); 10107 ins_encode( enc_std(src, dst) ); 10108 ins_pipe(pipe_class_memory); 10109 %} 10110 10111 //----------Register Move Instructions----------------------------------------- 10112 10113 // Replicate for Superword 10114 10115 instruct moveReg(iRegLdst dst, iRegIsrc src) %{ 10116 predicate(false); 10117 effect(DEF dst, USE src); 10118 10119 format %{ "MR $dst, $src \t// replicate " %} 10120 // variable size, 0 or 4. 10121 ins_encode %{ 10122 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10123 __ mr_if_needed($dst$$Register, $src$$Register); 10124 %} 10125 ins_pipe(pipe_class_default); 10126 %} 10127 10128 //----------Cast instructions (Java-level type cast)--------------------------- 10129 10130 // Cast Long to Pointer for unsafe natives. 10131 instruct castX2P(iRegPdst dst, iRegLsrc src) %{ 10132 match(Set dst (CastX2P src)); 10133 10134 format %{ "MR $dst, $src \t// Long->Ptr" %} 10135 // variable size, 0 or 4. 10136 ins_encode %{ 10137 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10138 __ mr_if_needed($dst$$Register, $src$$Register); 10139 %} 10140 ins_pipe(pipe_class_default); 10141 %} 10142 10143 // Cast Pointer to Long for unsafe natives. 10144 instruct castP2X(iRegLdst dst, iRegP_N2P src) %{ 10145 match(Set dst (CastP2X src)); 10146 10147 format %{ "MR $dst, $src \t// Ptr->Long" %} 10148 // variable size, 0 or 4. 10149 ins_encode %{ 10150 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10151 __ mr_if_needed($dst$$Register, $src$$Register); 10152 %} 10153 ins_pipe(pipe_class_default); 10154 %} 10155 10156 instruct castPP(iRegPdst dst) %{ 10157 match(Set dst (CastPP dst)); 10158 format %{ " -- \t// castPP of $dst" %} 10159 size(0); 10160 ins_encode( /*empty*/ ); 10161 ins_pipe(pipe_class_default); 10162 %} 10163 10164 instruct castII(iRegIdst dst) %{ 10165 match(Set dst (CastII dst)); 10166 format %{ " -- \t// castII of $dst" %} 10167 size(0); 10168 ins_encode( /*empty*/ ); 10169 ins_pipe(pipe_class_default); 10170 %} 10171 10172 instruct checkCastPP(iRegPdst dst) %{ 10173 match(Set dst (CheckCastPP dst)); 10174 format %{ " -- \t// checkcastPP of $dst" %} 10175 size(0); 10176 ins_encode( /*empty*/ ); 10177 ins_pipe(pipe_class_default); 10178 %} 10179 10180 //----------Convert instructions----------------------------------------------- 10181 10182 // Convert to boolean. 10183 10184 // int_to_bool(src) : { 1 if src != 0 10185 // { 0 else 10186 // 10187 // strategy: 10188 // 1) Count leading zeros of 32 bit-value src, 10189 // this returns 32 (0b10.0000) iff src == 0 and <32 otherwise. 10190 // 2) Shift 5 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10191 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10192 10193 // convI2Bool 10194 instruct convI2Bool_reg__cntlz_Ex(iRegIdst dst, iRegIsrc src) %{ 10195 match(Set dst (Conv2B src)); 10196 predicate(UseCountLeadingZerosInstructionsPPC64); 10197 ins_cost(DEFAULT_COST); 10198 10199 expand %{ 10200 immI shiftAmount %{ 0x5 %} 10201 uimmI16 mask %{ 0x1 %} 10202 iRegIdst tmp1; 10203 iRegIdst tmp2; 10204 countLeadingZerosI(tmp1, src); 10205 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10206 xorI_reg_uimm16(dst, tmp2, mask); 10207 %} 10208 %} 10209 10210 instruct convI2Bool_reg__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx) %{ 10211 match(Set dst (Conv2B src)); 10212 effect(TEMP crx); 10213 predicate(!UseCountLeadingZerosInstructionsPPC64); 10214 ins_cost(DEFAULT_COST); 10215 10216 format %{ "CMPWI $crx, $src, #0 \t// convI2B" 10217 "LI $dst, #0\n\t" 10218 "BEQ $crx, done\n\t" 10219 "LI $dst, #1\n" 10220 "done:" %} 10221 size(16); 10222 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x0, 0x1) ); 10223 ins_pipe(pipe_class_compare); 10224 %} 10225 10226 // ConvI2B + XorI 10227 instruct xorI_convI2Bool_reg_immIvalue1__cntlz_Ex(iRegIdst dst, iRegIsrc src, immI_1 mask) %{ 10228 match(Set dst (XorI (Conv2B src) mask)); 10229 predicate(UseCountLeadingZerosInstructionsPPC64); 10230 ins_cost(DEFAULT_COST); 10231 10232 expand %{ 10233 immI shiftAmount %{ 0x5 %} 10234 iRegIdst tmp1; 10235 countLeadingZerosI(tmp1, src); 10236 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10237 %} 10238 %} 10239 10240 instruct xorI_convI2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI_1 mask) %{ 10241 match(Set dst (XorI (Conv2B src) mask)); 10242 effect(TEMP crx); 10243 predicate(!UseCountLeadingZerosInstructionsPPC64); 10244 ins_cost(DEFAULT_COST); 10245 10246 format %{ "CMPWI $crx, $src, #0 \t// Xor(convI2B($src), $mask)" 10247 "LI $dst, #1\n\t" 10248 "BEQ $crx, done\n\t" 10249 "LI $dst, #0\n" 10250 "done:" %} 10251 size(16); 10252 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x1, 0x0) ); 10253 ins_pipe(pipe_class_compare); 10254 %} 10255 10256 // AndI 0b0..010..0 + ConvI2B 10257 instruct convI2Bool_andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src, immIpowerOf2 mask) %{ 10258 match(Set dst (Conv2B (AndI src mask))); 10259 predicate(UseRotateAndMaskInstructionsPPC64); 10260 ins_cost(DEFAULT_COST); 10261 10262 format %{ "RLWINM $dst, $src, $mask \t// convI2B(AndI($src, $mask))" %} 10263 size(4); 10264 ins_encode %{ 10265 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 10266 __ rlwinm($dst$$Register, $src$$Register, (32-log2_long((jlong)$mask$$constant)) & 0x1f, 31, 31); 10267 %} 10268 ins_pipe(pipe_class_default); 10269 %} 10270 10271 // Convert pointer to boolean. 10272 // 10273 // ptr_to_bool(src) : { 1 if src != 0 10274 // { 0 else 10275 // 10276 // strategy: 10277 // 1) Count leading zeros of 64 bit-value src, 10278 // this returns 64 (0b100.0000) iff src == 0 and <64 otherwise. 10279 // 2) Shift 6 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10280 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10281 10282 // ConvP2B 10283 instruct convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src) %{ 10284 match(Set dst (Conv2B src)); 10285 predicate(UseCountLeadingZerosInstructionsPPC64); 10286 ins_cost(DEFAULT_COST); 10287 10288 expand %{ 10289 immI shiftAmount %{ 0x6 %} 10290 uimmI16 mask %{ 0x1 %} 10291 iRegIdst tmp1; 10292 iRegIdst tmp2; 10293 countLeadingZerosP(tmp1, src); 10294 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10295 xorI_reg_uimm16(dst, tmp2, mask); 10296 %} 10297 %} 10298 10299 instruct convP2Bool_reg__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx) %{ 10300 match(Set dst (Conv2B src)); 10301 effect(TEMP crx); 10302 predicate(!UseCountLeadingZerosInstructionsPPC64); 10303 ins_cost(DEFAULT_COST); 10304 10305 format %{ "CMPDI $crx, $src, #0 \t// convP2B" 10306 "LI $dst, #0\n\t" 10307 "BEQ $crx, done\n\t" 10308 "LI $dst, #1\n" 10309 "done:" %} 10310 size(16); 10311 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x0, 0x1) ); 10312 ins_pipe(pipe_class_compare); 10313 %} 10314 10315 // ConvP2B + XorI 10316 instruct xorI_convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src, immI_1 mask) %{ 10317 match(Set dst (XorI (Conv2B src) mask)); 10318 predicate(UseCountLeadingZerosInstructionsPPC64); 10319 ins_cost(DEFAULT_COST); 10320 10321 expand %{ 10322 immI shiftAmount %{ 0x6 %} 10323 iRegIdst tmp1; 10324 countLeadingZerosP(tmp1, src); 10325 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10326 %} 10327 %} 10328 10329 instruct xorI_convP2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx, immI_1 mask) %{ 10330 match(Set dst (XorI (Conv2B src) mask)); 10331 effect(TEMP crx); 10332 predicate(!UseCountLeadingZerosInstructionsPPC64); 10333 ins_cost(DEFAULT_COST); 10334 10335 format %{ "CMPDI $crx, $src, #0 \t// XorI(convP2B($src), $mask)" 10336 "LI $dst, #1\n\t" 10337 "BEQ $crx, done\n\t" 10338 "LI $dst, #0\n" 10339 "done:" %} 10340 size(16); 10341 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x1, 0x0) ); 10342 ins_pipe(pipe_class_compare); 10343 %} 10344 10345 // if src1 < src2, return -1 else return 0 10346 instruct cmpLTMask_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10347 match(Set dst (CmpLTMask src1 src2)); 10348 ins_cost(DEFAULT_COST*4); 10349 10350 expand %{ 10351 iRegLdst src1s; 10352 iRegLdst src2s; 10353 iRegLdst diff; 10354 convI2L_reg(src1s, src1); // Ensure proper sign extension. 10355 convI2L_reg(src2s, src2); // Ensure proper sign extension. 10356 subL_reg_reg(diff, src1s, src2s); 10357 // Need to consider >=33 bit result, therefore we need signmaskL. 10358 signmask64I_regL(dst, diff); 10359 %} 10360 %} 10361 10362 instruct cmpLTMask_reg_immI0(iRegIdst dst, iRegIsrc src1, immI_0 src2) %{ 10363 match(Set dst (CmpLTMask src1 src2)); // if src1 < src2, return -1 else return 0 10364 format %{ "SRAWI $dst, $src1, $src2 \t// CmpLTMask" %} 10365 size(4); 10366 ins_encode %{ 10367 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 10368 __ srawi($dst$$Register, $src1$$Register, 0x1f); 10369 %} 10370 ins_pipe(pipe_class_default); 10371 %} 10372 10373 //----------Arithmetic Conversion Instructions--------------------------------- 10374 10375 // Convert to Byte -- nop 10376 // Convert to Short -- nop 10377 10378 // Convert to Int 10379 10380 instruct convB2I_reg(iRegIdst dst, iRegIsrc src, immI_24 amount) %{ 10381 match(Set dst (RShiftI (LShiftI src amount) amount)); 10382 format %{ "EXTSB $dst, $src \t// byte->int" %} 10383 size(4); 10384 ins_encode %{ 10385 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 10386 __ extsb($dst$$Register, $src$$Register); 10387 %} 10388 ins_pipe(pipe_class_default); 10389 %} 10390 10391 // LShiftI 16 + RShiftI 16 converts short to int. 10392 instruct convS2I_reg(iRegIdst dst, iRegIsrc src, immI_16 amount) %{ 10393 match(Set dst (RShiftI (LShiftI src amount) amount)); 10394 format %{ "EXTSH $dst, $src \t// short->int" %} 10395 size(4); 10396 ins_encode %{ 10397 // TODO: PPC port $archOpcode(ppc64Opcode_extsh); 10398 __ extsh($dst$$Register, $src$$Register); 10399 %} 10400 ins_pipe(pipe_class_default); 10401 %} 10402 10403 // ConvL2I + ConvI2L: Sign extend int in long register. 10404 instruct sxtI_L2L_reg(iRegLdst dst, iRegLsrc src) %{ 10405 match(Set dst (ConvI2L (ConvL2I src))); 10406 10407 format %{ "EXTSW $dst, $src \t// long->long" %} 10408 size(4); 10409 ins_encode %{ 10410 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 10411 __ extsw($dst$$Register, $src$$Register); 10412 %} 10413 ins_pipe(pipe_class_default); 10414 %} 10415 10416 instruct convL2I_reg(iRegIdst dst, iRegLsrc src) %{ 10417 match(Set dst (ConvL2I src)); 10418 format %{ "MR $dst, $src \t// long->int" %} 10419 // variable size, 0 or 4 10420 ins_encode %{ 10421 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10422 __ mr_if_needed($dst$$Register, $src$$Register); 10423 %} 10424 ins_pipe(pipe_class_default); 10425 %} 10426 10427 instruct convD2IRaw_regD(regD dst, regD src) %{ 10428 // no match-rule, false predicate 10429 effect(DEF dst, USE src); 10430 predicate(false); 10431 10432 format %{ "FCTIWZ $dst, $src \t// convD2I, $src != NaN" %} 10433 size(4); 10434 ins_encode %{ 10435 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz);; 10436 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 10437 %} 10438 ins_pipe(pipe_class_default); 10439 %} 10440 10441 instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL src) %{ 10442 // no match-rule, false predicate 10443 effect(DEF dst, USE crx, USE src); 10444 predicate(false); 10445 10446 ins_variable_size_depending_on_alignment(true); 10447 10448 format %{ "cmovI $crx, $dst, $src" %} 10449 // Worst case is branch + move + stop, no stop without scheduler. 10450 size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 10451 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 10452 ins_pipe(pipe_class_default); 10453 %} 10454 10455 instruct cmovI_bso_stackSlotL_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, stackSlotL mem) %{ 10456 // no match-rule, false predicate 10457 effect(DEF dst, USE crx, USE mem); 10458 predicate(false); 10459 10460 format %{ "CmovI $dst, $crx, $mem \t// postalloc expanded" %} 10461 postalloc_expand %{ 10462 // 10463 // replaces 10464 // 10465 // region dst crx mem 10466 // \ | | / 10467 // dst=cmovI_bso_stackSlotL_conLvalue0 10468 // 10469 // with 10470 // 10471 // region dst 10472 // \ / 10473 // dst=loadConI16(0) 10474 // | 10475 // ^ region dst crx mem 10476 // | \ | | / 10477 // dst=cmovI_bso_stackSlotL 10478 // 10479 10480 // Create new nodes. 10481 MachNode *m1 = new loadConI16Node(); 10482 MachNode *m2 = new cmovI_bso_stackSlotLNode(); 10483 10484 // inputs for new nodes 10485 m1->add_req(n_region); 10486 m2->add_req(n_region, n_crx, n_mem); 10487 10488 // precedences for new nodes 10489 m2->add_prec(m1); 10490 10491 // operands for new nodes 10492 m1->_opnds[0] = op_dst; 10493 m1->_opnds[1] = new immI16Oper(0); 10494 10495 m2->_opnds[0] = op_dst; 10496 m2->_opnds[1] = op_crx; 10497 m2->_opnds[2] = op_mem; 10498 10499 // registers for new nodes 10500 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10501 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10502 10503 // Insert new nodes. 10504 nodes->push(m1); 10505 nodes->push(m2); 10506 %} 10507 %} 10508 10509 // Double to Int conversion, NaN is mapped to 0. 10510 instruct convD2I_reg_ExEx(iRegIdst dst, regD src) %{ 10511 match(Set dst (ConvD2I src)); 10512 ins_cost(DEFAULT_COST); 10513 10514 expand %{ 10515 regD tmpD; 10516 stackSlotL tmpS; 10517 flagsReg crx; 10518 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10519 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 10520 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 10521 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 10522 %} 10523 %} 10524 10525 instruct convF2IRaw_regF(regF dst, regF src) %{ 10526 // no match-rule, false predicate 10527 effect(DEF dst, USE src); 10528 predicate(false); 10529 10530 format %{ "FCTIWZ $dst, $src \t// convF2I, $src != NaN" %} 10531 size(4); 10532 ins_encode %{ 10533 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 10534 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 10535 %} 10536 ins_pipe(pipe_class_default); 10537 %} 10538 10539 // Float to Int conversion, NaN is mapped to 0. 10540 instruct convF2I_regF_ExEx(iRegIdst dst, regF src) %{ 10541 match(Set dst (ConvF2I src)); 10542 ins_cost(DEFAULT_COST); 10543 10544 expand %{ 10545 regF tmpF; 10546 stackSlotL tmpS; 10547 flagsReg crx; 10548 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10549 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 10550 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 10551 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 10552 %} 10553 %} 10554 10555 // Convert to Long 10556 10557 instruct convI2L_reg(iRegLdst dst, iRegIsrc src) %{ 10558 match(Set dst (ConvI2L src)); 10559 format %{ "EXTSW $dst, $src \t// int->long" %} 10560 size(4); 10561 ins_encode %{ 10562 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 10563 __ extsw($dst$$Register, $src$$Register); 10564 %} 10565 ins_pipe(pipe_class_default); 10566 %} 10567 10568 // Zero-extend: convert unsigned int to long (convUI2L). 10569 instruct zeroExtendL_regI(iRegLdst dst, iRegIsrc src, immL_32bits mask) %{ 10570 match(Set dst (AndL (ConvI2L src) mask)); 10571 ins_cost(DEFAULT_COST); 10572 10573 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 10574 size(4); 10575 ins_encode %{ 10576 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10577 __ clrldi($dst$$Register, $src$$Register, 32); 10578 %} 10579 ins_pipe(pipe_class_default); 10580 %} 10581 10582 // Zero-extend: convert unsigned int to long in long register. 10583 instruct zeroExtendL_regL(iRegLdst dst, iRegLsrc src, immL_32bits mask) %{ 10584 match(Set dst (AndL src mask)); 10585 ins_cost(DEFAULT_COST); 10586 10587 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 10588 size(4); 10589 ins_encode %{ 10590 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10591 __ clrldi($dst$$Register, $src$$Register, 32); 10592 %} 10593 ins_pipe(pipe_class_default); 10594 %} 10595 10596 instruct convF2LRaw_regF(regF dst, regF src) %{ 10597 // no match-rule, false predicate 10598 effect(DEF dst, USE src); 10599 predicate(false); 10600 10601 format %{ "FCTIDZ $dst, $src \t// convF2L, $src != NaN" %} 10602 size(4); 10603 ins_encode %{ 10604 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 10605 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 10606 %} 10607 ins_pipe(pipe_class_default); 10608 %} 10609 10610 instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL src) %{ 10611 // no match-rule, false predicate 10612 effect(DEF dst, USE crx, USE src); 10613 predicate(false); 10614 10615 ins_variable_size_depending_on_alignment(true); 10616 10617 format %{ "cmovL $crx, $dst, $src" %} 10618 // Worst case is branch + move + stop, no stop without scheduler. 10619 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 10620 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 10621 ins_pipe(pipe_class_default); 10622 %} 10623 10624 instruct cmovL_bso_stackSlotL_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, stackSlotL mem) %{ 10625 // no match-rule, false predicate 10626 effect(DEF dst, USE crx, USE mem); 10627 predicate(false); 10628 10629 format %{ "CmovL $dst, $crx, $mem \t// postalloc expanded" %} 10630 postalloc_expand %{ 10631 // 10632 // replaces 10633 // 10634 // region dst crx mem 10635 // \ | | / 10636 // dst=cmovL_bso_stackSlotL_conLvalue0 10637 // 10638 // with 10639 // 10640 // region dst 10641 // \ / 10642 // dst=loadConL16(0) 10643 // | 10644 // ^ region dst crx mem 10645 // | \ | | / 10646 // dst=cmovL_bso_stackSlotL 10647 // 10648 10649 // Create new nodes. 10650 MachNode *m1 = new loadConL16Node(); 10651 MachNode *m2 = new cmovL_bso_stackSlotLNode(); 10652 10653 // inputs for new nodes 10654 m1->add_req(n_region); 10655 m2->add_req(n_region, n_crx, n_mem); 10656 m2->add_prec(m1); 10657 10658 // operands for new nodes 10659 m1->_opnds[0] = op_dst; 10660 m1->_opnds[1] = new immL16Oper(0); 10661 m2->_opnds[0] = op_dst; 10662 m2->_opnds[1] = op_crx; 10663 m2->_opnds[2] = op_mem; 10664 10665 // registers for new nodes 10666 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10667 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10668 10669 // Insert new nodes. 10670 nodes->push(m1); 10671 nodes->push(m2); 10672 %} 10673 %} 10674 10675 // Float to Long conversion, NaN is mapped to 0. 10676 instruct convF2L_reg_ExEx(iRegLdst dst, regF src) %{ 10677 match(Set dst (ConvF2L src)); 10678 ins_cost(DEFAULT_COST); 10679 10680 expand %{ 10681 regF tmpF; 10682 stackSlotL tmpS; 10683 flagsReg crx; 10684 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10685 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 10686 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 10687 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 10688 %} 10689 %} 10690 10691 instruct convD2LRaw_regD(regD dst, regD src) %{ 10692 // no match-rule, false predicate 10693 effect(DEF dst, USE src); 10694 predicate(false); 10695 10696 format %{ "FCTIDZ $dst, $src \t// convD2L $src != NaN" %} 10697 size(4); 10698 ins_encode %{ 10699 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 10700 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 10701 %} 10702 ins_pipe(pipe_class_default); 10703 %} 10704 10705 // Double to Long conversion, NaN is mapped to 0. 10706 instruct convD2L_reg_ExEx(iRegLdst dst, regD src) %{ 10707 match(Set dst (ConvD2L src)); 10708 ins_cost(DEFAULT_COST); 10709 10710 expand %{ 10711 regD tmpD; 10712 stackSlotL tmpS; 10713 flagsReg crx; 10714 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10715 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 10716 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 10717 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 10718 %} 10719 %} 10720 10721 // Convert to Float 10722 10723 // Placed here as needed in expand. 10724 instruct convL2DRaw_regD(regD dst, regD src) %{ 10725 // no match-rule, false predicate 10726 effect(DEF dst, USE src); 10727 predicate(false); 10728 10729 format %{ "FCFID $dst, $src \t// convL2D" %} 10730 size(4); 10731 ins_encode %{ 10732 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 10733 __ fcfid($dst$$FloatRegister, $src$$FloatRegister); 10734 %} 10735 ins_pipe(pipe_class_default); 10736 %} 10737 10738 // Placed here as needed in expand. 10739 instruct convD2F_reg(regF dst, regD src) %{ 10740 match(Set dst (ConvD2F src)); 10741 format %{ "FRSP $dst, $src \t// convD2F" %} 10742 size(4); 10743 ins_encode %{ 10744 // TODO: PPC port $archOpcode(ppc64Opcode_frsp); 10745 __ frsp($dst$$FloatRegister, $src$$FloatRegister); 10746 %} 10747 ins_pipe(pipe_class_default); 10748 %} 10749 10750 // Integer to Float conversion. 10751 instruct convI2F_ireg_Ex(regF dst, iRegIsrc src) %{ 10752 match(Set dst (ConvI2F src)); 10753 predicate(!VM_Version::has_fcfids()); 10754 ins_cost(DEFAULT_COST); 10755 10756 expand %{ 10757 iRegLdst tmpL; 10758 stackSlotL tmpS; 10759 regD tmpD; 10760 regD tmpD2; 10761 convI2L_reg(tmpL, src); // Sign-extension int to long. 10762 regL_to_stkL(tmpS, tmpL); // Store long to stack. 10763 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 10764 convL2DRaw_regD(tmpD2, tmpD); // Convert to double. 10765 convD2F_reg(dst, tmpD2); // Convert double to float. 10766 %} 10767 %} 10768 10769 instruct convL2FRaw_regF(regF dst, regD src) %{ 10770 // no match-rule, false predicate 10771 effect(DEF dst, USE src); 10772 predicate(false); 10773 10774 format %{ "FCFIDS $dst, $src \t// convL2F" %} 10775 size(4); 10776 ins_encode %{ 10777 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 10778 __ fcfids($dst$$FloatRegister, $src$$FloatRegister); 10779 %} 10780 ins_pipe(pipe_class_default); 10781 %} 10782 10783 // Integer to Float conversion. Special version for Power7. 10784 instruct convI2F_ireg_fcfids_Ex(regF dst, iRegIsrc src) %{ 10785 match(Set dst (ConvI2F src)); 10786 predicate(VM_Version::has_fcfids()); 10787 ins_cost(DEFAULT_COST); 10788 10789 expand %{ 10790 iRegLdst tmpL; 10791 stackSlotL tmpS; 10792 regD tmpD; 10793 convI2L_reg(tmpL, src); // Sign-extension int to long. 10794 regL_to_stkL(tmpS, tmpL); // Store long to stack. 10795 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 10796 convL2FRaw_regF(dst, tmpD); // Convert to float. 10797 %} 10798 %} 10799 10800 // L2F to avoid runtime call. 10801 instruct convL2F_ireg_fcfids_Ex(regF dst, iRegLsrc src) %{ 10802 match(Set dst (ConvL2F src)); 10803 predicate(VM_Version::has_fcfids()); 10804 ins_cost(DEFAULT_COST); 10805 10806 expand %{ 10807 stackSlotL tmpS; 10808 regD tmpD; 10809 regL_to_stkL(tmpS, src); // Store long to stack. 10810 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 10811 convL2FRaw_regF(dst, tmpD); // Convert to float. 10812 %} 10813 %} 10814 10815 // Moved up as used in expand. 10816 //instruct convD2F_reg(regF dst, regD src) %{%} 10817 10818 // Convert to Double 10819 10820 // Integer to Double conversion. 10821 instruct convI2D_reg_Ex(regD dst, iRegIsrc src) %{ 10822 match(Set dst (ConvI2D src)); 10823 ins_cost(DEFAULT_COST); 10824 10825 expand %{ 10826 iRegLdst tmpL; 10827 stackSlotL tmpS; 10828 regD tmpD; 10829 convI2L_reg(tmpL, src); // Sign-extension int to long. 10830 regL_to_stkL(tmpS, tmpL); // Store long to stack. 10831 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 10832 convL2DRaw_regD(dst, tmpD); // Convert to double. 10833 %} 10834 %} 10835 10836 // Long to Double conversion 10837 instruct convL2D_reg_Ex(regD dst, stackSlotL src) %{ 10838 match(Set dst (ConvL2D src)); 10839 ins_cost(DEFAULT_COST + MEMORY_REF_COST); 10840 10841 expand %{ 10842 regD tmpD; 10843 moveL2D_stack_reg(tmpD, src); 10844 convL2DRaw_regD(dst, tmpD); 10845 %} 10846 %} 10847 10848 instruct convF2D_reg(regD dst, regF src) %{ 10849 match(Set dst (ConvF2D src)); 10850 format %{ "FMR $dst, $src \t// float->double" %} 10851 // variable size, 0 or 4 10852 ins_encode %{ 10853 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 10854 __ fmr_if_needed($dst$$FloatRegister, $src$$FloatRegister); 10855 %} 10856 ins_pipe(pipe_class_default); 10857 %} 10858 10859 //----------Control Flow Instructions------------------------------------------ 10860 // Compare Instructions 10861 10862 // Compare Integers 10863 instruct cmpI_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 10864 match(Set crx (CmpI src1 src2)); 10865 size(4); 10866 format %{ "CMPW $crx, $src1, $src2" %} 10867 ins_encode %{ 10868 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 10869 __ cmpw($crx$$CondRegister, $src1$$Register, $src2$$Register); 10870 %} 10871 ins_pipe(pipe_class_compare); 10872 %} 10873 10874 instruct cmpI_reg_imm16(flagsReg crx, iRegIsrc src1, immI16 src2) %{ 10875 match(Set crx (CmpI src1 src2)); 10876 format %{ "CMPWI $crx, $src1, $src2" %} 10877 size(4); 10878 ins_encode %{ 10879 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 10880 __ cmpwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 10881 %} 10882 ins_pipe(pipe_class_compare); 10883 %} 10884 10885 // (src1 & src2) == 0? 10886 instruct testI_reg_imm(flagsRegCR0 cr0, iRegIsrc src1, uimmI16 src2, immI_0 zero) %{ 10887 match(Set cr0 (CmpI (AndI src1 src2) zero)); 10888 // r0 is killed 10889 format %{ "ANDI R0, $src1, $src2 \t// BTST int" %} 10890 size(4); 10891 ins_encode %{ 10892 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 10893 __ andi_(R0, $src1$$Register, $src2$$constant); 10894 %} 10895 ins_pipe(pipe_class_compare); 10896 %} 10897 10898 instruct cmpL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 10899 match(Set crx (CmpL src1 src2)); 10900 format %{ "CMPD $crx, $src1, $src2" %} 10901 size(4); 10902 ins_encode %{ 10903 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 10904 __ cmpd($crx$$CondRegister, $src1$$Register, $src2$$Register); 10905 %} 10906 ins_pipe(pipe_class_compare); 10907 %} 10908 10909 instruct cmpL_reg_imm16(flagsReg crx, iRegLsrc src1, immL16 src2) %{ 10910 match(Set crx (CmpL src1 src2)); 10911 format %{ "CMPDI $crx, $src1, $src2" %} 10912 size(4); 10913 ins_encode %{ 10914 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 10915 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 10916 %} 10917 ins_pipe(pipe_class_compare); 10918 %} 10919 10920 instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zero) %{ 10921 match(Set cr0 (CmpL (AndL src1 src2) zero)); 10922 // r0 is killed 10923 format %{ "AND R0, $src1, $src2 \t// BTST long" %} 10924 size(4); 10925 ins_encode %{ 10926 // TODO: PPC port $archOpcode(ppc64Opcode_and_); 10927 __ and_(R0, $src1$$Register, $src2$$Register); 10928 %} 10929 ins_pipe(pipe_class_compare); 10930 %} 10931 10932 instruct testL_reg_imm(flagsRegCR0 cr0, iRegLsrc src1, uimmL16 src2, immL_0 zero) %{ 10933 match(Set cr0 (CmpL (AndL src1 src2) zero)); 10934 // r0 is killed 10935 format %{ "ANDI R0, $src1, $src2 \t// BTST long" %} 10936 size(4); 10937 ins_encode %{ 10938 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 10939 __ andi_(R0, $src1$$Register, $src2$$constant); 10940 %} 10941 ins_pipe(pipe_class_compare); 10942 %} 10943 10944 instruct cmovI_conIvalueMinus1_conIvalue1(iRegIdst dst, flagsRegSrc crx) %{ 10945 // no match-rule, false predicate 10946 effect(DEF dst, USE crx); 10947 predicate(false); 10948 10949 ins_variable_size_depending_on_alignment(true); 10950 10951 format %{ "cmovI $crx, $dst, -1, 0, +1" %} 10952 // Worst case is branch + move + branch + move + stop, no stop without scheduler. 10953 size(false /* TODO: PPC PORTInsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 20 : 16); 10954 ins_encode %{ 10955 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 10956 Label done; 10957 // li(Rdst, 0); // equal -> 0 10958 __ beq($crx$$CondRegister, done); 10959 __ li($dst$$Register, 1); // greater -> +1 10960 __ bgt($crx$$CondRegister, done); 10961 __ li($dst$$Register, -1); // unordered or less -> -1 10962 // TODO: PPC port__ endgroup_if_needed(_size == 20); 10963 __ bind(done); 10964 %} 10965 ins_pipe(pipe_class_compare); 10966 %} 10967 10968 instruct cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(iRegIdst dst, flagsRegSrc crx) %{ 10969 // no match-rule, false predicate 10970 effect(DEF dst, USE crx); 10971 predicate(false); 10972 10973 format %{ "CmovI $crx, $dst, -1, 0, +1 \t// postalloc expanded" %} 10974 postalloc_expand %{ 10975 // 10976 // replaces 10977 // 10978 // region crx 10979 // \ | 10980 // dst=cmovI_conIvalueMinus1_conIvalue0_conIvalue1 10981 // 10982 // with 10983 // 10984 // region 10985 // \ 10986 // dst=loadConI16(0) 10987 // | 10988 // ^ region crx 10989 // | \ | 10990 // dst=cmovI_conIvalueMinus1_conIvalue1 10991 // 10992 10993 // Create new nodes. 10994 MachNode *m1 = new loadConI16Node(); 10995 MachNode *m2 = new cmovI_conIvalueMinus1_conIvalue1Node(); 10996 10997 // inputs for new nodes 10998 m1->add_req(n_region); 10999 m2->add_req(n_region, n_crx); 11000 m2->add_prec(m1); 11001 11002 // operands for new nodes 11003 m1->_opnds[0] = op_dst; 11004 m1->_opnds[1] = new immI16Oper(0); 11005 m2->_opnds[0] = op_dst; 11006 m2->_opnds[1] = op_crx; 11007 11008 // registers for new nodes 11009 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11010 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11011 11012 // Insert new nodes. 11013 nodes->push(m1); 11014 nodes->push(m2); 11015 %} 11016 %} 11017 11018 // Manifest a CmpL3 result in an integer register. Very painful. 11019 // This is the test to avoid. 11020 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 11021 instruct cmpL3_reg_reg_ExEx(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 11022 match(Set dst (CmpL3 src1 src2)); 11023 ins_cost(DEFAULT_COST*5+BRANCH_COST); 11024 11025 expand %{ 11026 flagsReg tmp1; 11027 cmpL_reg_reg(tmp1, src1, src2); 11028 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 11029 %} 11030 %} 11031 11032 // Implicit range checks. 11033 // A range check in the ideal world has one of the following shapes: 11034 // - (If le (CmpU length index)), (IfTrue throw exception) 11035 // - (If lt (CmpU index length)), (IfFalse throw exception) 11036 // 11037 // Match range check 'If le (CmpU length index)'. 11038 instruct rangeCheck_iReg_uimm15(cmpOp cmp, iRegIsrc src_length, uimmI15 index, label labl) %{ 11039 match(If cmp (CmpU src_length index)); 11040 effect(USE labl); 11041 predicate(TrapBasedRangeChecks && 11042 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le && 11043 PROB_UNLIKELY(_leaf->as_If()->_prob) >= PROB_ALWAYS && 11044 (Matcher::branches_to_uncommon_trap(_leaf))); 11045 11046 ins_is_TrapBasedCheckNode(true); 11047 11048 format %{ "TWI $index $cmp $src_length \t// RangeCheck => trap $labl" %} 11049 size(4); 11050 ins_encode %{ 11051 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 11052 if ($cmp$$cmpcode == 0x1 /* less_equal */) { 11053 __ trap_range_check_le($src_length$$Register, $index$$constant); 11054 } else { 11055 // Both successors are uncommon traps, probability is 0. 11056 // Node got flipped during fixup flow. 11057 assert($cmp$$cmpcode == 0x9, "must be greater"); 11058 __ trap_range_check_g($src_length$$Register, $index$$constant); 11059 } 11060 %} 11061 ins_pipe(pipe_class_trap); 11062 %} 11063 11064 // Match range check 'If lt (CmpU index length)'. 11065 instruct rangeCheck_iReg_iReg(cmpOp cmp, iRegIsrc src_index, iRegIsrc src_length, label labl) %{ 11066 match(If cmp (CmpU src_index src_length)); 11067 effect(USE labl); 11068 predicate(TrapBasedRangeChecks && 11069 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 11070 _leaf->as_If()->_prob >= PROB_ALWAYS && 11071 (Matcher::branches_to_uncommon_trap(_leaf))); 11072 11073 ins_is_TrapBasedCheckNode(true); 11074 11075 format %{ "TW $src_index $cmp $src_length \t// RangeCheck => trap $labl" %} 11076 size(4); 11077 ins_encode %{ 11078 // TODO: PPC port $archOpcode(ppc64Opcode_tw); 11079 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 11080 __ trap_range_check_ge($src_index$$Register, $src_length$$Register); 11081 } else { 11082 // Both successors are uncommon traps, probability is 0. 11083 // Node got flipped during fixup flow. 11084 assert($cmp$$cmpcode == 0x8, "must be less"); 11085 __ trap_range_check_l($src_index$$Register, $src_length$$Register); 11086 } 11087 %} 11088 ins_pipe(pipe_class_trap); 11089 %} 11090 11091 // Match range check 'If lt (CmpU index length)'. 11092 instruct rangeCheck_uimm15_iReg(cmpOp cmp, iRegIsrc src_index, uimmI15 length, label labl) %{ 11093 match(If cmp (CmpU src_index length)); 11094 effect(USE labl); 11095 predicate(TrapBasedRangeChecks && 11096 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 11097 _leaf->as_If()->_prob >= PROB_ALWAYS && 11098 (Matcher::branches_to_uncommon_trap(_leaf))); 11099 11100 ins_is_TrapBasedCheckNode(true); 11101 11102 format %{ "TWI $src_index $cmp $length \t// RangeCheck => trap $labl" %} 11103 size(4); 11104 ins_encode %{ 11105 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 11106 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 11107 __ trap_range_check_ge($src_index$$Register, $length$$constant); 11108 } else { 11109 // Both successors are uncommon traps, probability is 0. 11110 // Node got flipped during fixup flow. 11111 assert($cmp$$cmpcode == 0x8, "must be less"); 11112 __ trap_range_check_l($src_index$$Register, $length$$constant); 11113 } 11114 %} 11115 ins_pipe(pipe_class_trap); 11116 %} 11117 11118 instruct compU_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 11119 match(Set crx (CmpU src1 src2)); 11120 format %{ "CMPLW $crx, $src1, $src2 \t// unsigned" %} 11121 size(4); 11122 ins_encode %{ 11123 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11124 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11125 %} 11126 ins_pipe(pipe_class_compare); 11127 %} 11128 11129 instruct compU_reg_uimm16(flagsReg crx, iRegIsrc src1, uimmI16 src2) %{ 11130 match(Set crx (CmpU src1 src2)); 11131 size(4); 11132 format %{ "CMPLWI $crx, $src1, $src2" %} 11133 ins_encode %{ 11134 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 11135 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11136 %} 11137 ins_pipe(pipe_class_compare); 11138 %} 11139 11140 // Implicit zero checks (more implicit null checks). 11141 // No constant pool entries required. 11142 instruct zeroCheckN_iReg_imm0(cmpOp cmp, iRegNsrc value, immN_0 zero, label labl) %{ 11143 match(If cmp (CmpN value zero)); 11144 effect(USE labl); 11145 predicate(TrapBasedNullChecks && 11146 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 11147 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 11148 Matcher::branches_to_uncommon_trap(_leaf)); 11149 ins_cost(1); 11150 11151 ins_is_TrapBasedCheckNode(true); 11152 11153 format %{ "TDI $value $cmp $zero \t// ZeroCheckN => trap $labl" %} 11154 size(4); 11155 ins_encode %{ 11156 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 11157 if ($cmp$$cmpcode == 0xA) { 11158 __ trap_null_check($value$$Register); 11159 } else { 11160 // Both successors are uncommon traps, probability is 0. 11161 // Node got flipped during fixup flow. 11162 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 11163 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 11164 } 11165 %} 11166 ins_pipe(pipe_class_trap); 11167 %} 11168 11169 // Compare narrow oops. 11170 instruct cmpN_reg_reg(flagsReg crx, iRegNsrc src1, iRegNsrc src2) %{ 11171 match(Set crx (CmpN src1 src2)); 11172 11173 size(4); 11174 ins_cost(2); 11175 format %{ "CMPLW $crx, $src1, $src2 \t// compressed ptr" %} 11176 ins_encode %{ 11177 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11178 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11179 %} 11180 ins_pipe(pipe_class_compare); 11181 %} 11182 11183 instruct cmpN_reg_imm0(flagsReg crx, iRegNsrc src1, immN_0 src2) %{ 11184 match(Set crx (CmpN src1 src2)); 11185 // Make this more expensive than zeroCheckN_iReg_imm0. 11186 ins_cost(2); 11187 11188 format %{ "CMPLWI $crx, $src1, $src2 \t// compressed ptr" %} 11189 size(4); 11190 ins_encode %{ 11191 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 11192 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11193 %} 11194 ins_pipe(pipe_class_compare); 11195 %} 11196 11197 // Implicit zero checks (more implicit null checks). 11198 // No constant pool entries required. 11199 instruct zeroCheckP_reg_imm0(cmpOp cmp, iRegP_N2P value, immP_0 zero, label labl) %{ 11200 match(If cmp (CmpP value zero)); 11201 effect(USE labl); 11202 predicate(TrapBasedNullChecks && 11203 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 11204 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 11205 Matcher::branches_to_uncommon_trap(_leaf)); 11206 ins_cost(1); // Should not be cheaper than zeroCheckN. 11207 11208 ins_is_TrapBasedCheckNode(true); 11209 11210 format %{ "TDI $value $cmp $zero \t// ZeroCheckP => trap $labl" %} 11211 size(4); 11212 ins_encode %{ 11213 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 11214 if ($cmp$$cmpcode == 0xA) { 11215 __ trap_null_check($value$$Register); 11216 } else { 11217 // Both successors are uncommon traps, probability is 0. 11218 // Node got flipped during fixup flow. 11219 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 11220 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 11221 } 11222 %} 11223 ins_pipe(pipe_class_trap); 11224 %} 11225 11226 // Compare Pointers 11227 instruct cmpP_reg_reg(flagsReg crx, iRegP_N2P src1, iRegP_N2P src2) %{ 11228 match(Set crx (CmpP src1 src2)); 11229 format %{ "CMPLD $crx, $src1, $src2 \t// ptr" %} 11230 size(4); 11231 ins_encode %{ 11232 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11233 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 11234 %} 11235 ins_pipe(pipe_class_compare); 11236 %} 11237 11238 // Used in postalloc expand. 11239 instruct cmpP_reg_imm16(flagsReg crx, iRegPsrc src1, immL16 src2) %{ 11240 // This match rule prevents reordering of node before a safepoint. 11241 // This only makes sense if this instructions is used exclusively 11242 // for the expansion of EncodeP! 11243 match(Set crx (CmpP src1 src2)); 11244 predicate(false); 11245 11246 format %{ "CMPDI $crx, $src1, $src2" %} 11247 size(4); 11248 ins_encode %{ 11249 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11250 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11251 %} 11252 ins_pipe(pipe_class_compare); 11253 %} 11254 11255 //----------Float Compares---------------------------------------------------- 11256 11257 instruct cmpFUnordered_reg_reg(flagsReg crx, regF src1, regF src2) %{ 11258 // Needs matchrule, see cmpDUnordered. 11259 match(Set crx (CmpF src1 src2)); 11260 // no match-rule, false predicate 11261 predicate(false); 11262 11263 format %{ "cmpFUrd $crx, $src1, $src2" %} 11264 size(4); 11265 ins_encode %{ 11266 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 11267 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 11268 %} 11269 ins_pipe(pipe_class_default); 11270 %} 11271 11272 instruct cmov_bns_less(flagsReg crx) %{ 11273 // no match-rule, false predicate 11274 effect(DEF crx); 11275 predicate(false); 11276 11277 ins_variable_size_depending_on_alignment(true); 11278 11279 format %{ "cmov $crx" %} 11280 // Worst case is branch + move + stop, no stop without scheduler. 11281 size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 16 : 12); 11282 ins_encode %{ 11283 // TODO: PPC port $archOpcode(ppc64Opcode_cmovecr); 11284 Label done; 11285 __ bns($crx$$CondRegister, done); // not unordered -> keep crx 11286 __ li(R0, 0); 11287 __ cmpwi($crx$$CondRegister, R0, 1); // unordered -> set crx to 'less' 11288 // TODO PPC port __ endgroup_if_needed(_size == 16); 11289 __ bind(done); 11290 %} 11291 ins_pipe(pipe_class_default); 11292 %} 11293 11294 // Compare floating, generate condition code. 11295 instruct cmpF_reg_reg_Ex(flagsReg crx, regF src1, regF src2) %{ 11296 // FIXME: should we match 'If cmp (CmpF src1 src2))' ?? 11297 // 11298 // The following code sequence occurs a lot in mpegaudio: 11299 // 11300 // block BXX: 11301 // 0: instruct cmpFUnordered_reg_reg (cmpF_reg_reg-0): 11302 // cmpFUrd CCR6, F11, F9 11303 // 4: instruct cmov_bns_less (cmpF_reg_reg-1): 11304 // cmov CCR6 11305 // 8: instruct branchConSched: 11306 // B_FARle CCR6, B56 P=0.500000 C=-1.000000 11307 match(Set crx (CmpF src1 src2)); 11308 ins_cost(DEFAULT_COST+BRANCH_COST); 11309 11310 format %{ "CmpF $crx, $src1, $src2 \t// postalloc expanded" %} 11311 postalloc_expand %{ 11312 // 11313 // replaces 11314 // 11315 // region src1 src2 11316 // \ | | 11317 // crx=cmpF_reg_reg 11318 // 11319 // with 11320 // 11321 // region src1 src2 11322 // \ | | 11323 // crx=cmpFUnordered_reg_reg 11324 // | 11325 // ^ region 11326 // | \ 11327 // crx=cmov_bns_less 11328 // 11329 11330 // Create new nodes. 11331 MachNode *m1 = new cmpFUnordered_reg_regNode(); 11332 MachNode *m2 = new cmov_bns_lessNode(); 11333 11334 // inputs for new nodes 11335 m1->add_req(n_region, n_src1, n_src2); 11336 m2->add_req(n_region); 11337 m2->add_prec(m1); 11338 11339 // operands for new nodes 11340 m1->_opnds[0] = op_crx; 11341 m1->_opnds[1] = op_src1; 11342 m1->_opnds[2] = op_src2; 11343 m2->_opnds[0] = op_crx; 11344 11345 // registers for new nodes 11346 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 11347 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 11348 11349 // Insert new nodes. 11350 nodes->push(m1); 11351 nodes->push(m2); 11352 %} 11353 %} 11354 11355 // Compare float, generate -1,0,1 11356 instruct cmpF3_reg_reg_ExEx(iRegIdst dst, regF src1, regF src2) %{ 11357 match(Set dst (CmpF3 src1 src2)); 11358 ins_cost(DEFAULT_COST*5+BRANCH_COST); 11359 11360 expand %{ 11361 flagsReg tmp1; 11362 cmpFUnordered_reg_reg(tmp1, src1, src2); 11363 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 11364 %} 11365 %} 11366 11367 instruct cmpDUnordered_reg_reg(flagsReg crx, regD src1, regD src2) %{ 11368 // Needs matchrule so that ideal opcode is Cmp. This causes that gcm places the 11369 // node right before the conditional move using it. 11370 // In jck test api/java_awt/geom/QuadCurve2DFloat/index.html#SetCurveTesttestCase7, 11371 // compilation of java.awt.geom.RectangularShape::getBounds()Ljava/awt/Rectangle 11372 // crashed in register allocation where the flags Reg between cmpDUnoredered and a 11373 // conditional move was supposed to be spilled. 11374 match(Set crx (CmpD src1 src2)); 11375 // False predicate, shall not be matched. 11376 predicate(false); 11377 11378 format %{ "cmpFUrd $crx, $src1, $src2" %} 11379 size(4); 11380 ins_encode %{ 11381 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 11382 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 11383 %} 11384 ins_pipe(pipe_class_default); 11385 %} 11386 11387 instruct cmpD_reg_reg_Ex(flagsReg crx, regD src1, regD src2) %{ 11388 match(Set crx (CmpD src1 src2)); 11389 ins_cost(DEFAULT_COST+BRANCH_COST); 11390 11391 format %{ "CmpD $crx, $src1, $src2 \t// postalloc expanded" %} 11392 postalloc_expand %{ 11393 // 11394 // replaces 11395 // 11396 // region src1 src2 11397 // \ | | 11398 // crx=cmpD_reg_reg 11399 // 11400 // with 11401 // 11402 // region src1 src2 11403 // \ | | 11404 // crx=cmpDUnordered_reg_reg 11405 // | 11406 // ^ region 11407 // | \ 11408 // crx=cmov_bns_less 11409 // 11410 11411 // create new nodes 11412 MachNode *m1 = new cmpDUnordered_reg_regNode(); 11413 MachNode *m2 = new cmov_bns_lessNode(); 11414 11415 // inputs for new nodes 11416 m1->add_req(n_region, n_src1, n_src2); 11417 m2->add_req(n_region); 11418 m2->add_prec(m1); 11419 11420 // operands for new nodes 11421 m1->_opnds[0] = op_crx; 11422 m1->_opnds[1] = op_src1; 11423 m1->_opnds[2] = op_src2; 11424 m2->_opnds[0] = op_crx; 11425 11426 // registers for new nodes 11427 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 11428 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 11429 11430 // Insert new nodes. 11431 nodes->push(m1); 11432 nodes->push(m2); 11433 %} 11434 %} 11435 11436 // Compare double, generate -1,0,1 11437 instruct cmpD3_reg_reg_ExEx(iRegIdst dst, regD src1, regD src2) %{ 11438 match(Set dst (CmpD3 src1 src2)); 11439 ins_cost(DEFAULT_COST*5+BRANCH_COST); 11440 11441 expand %{ 11442 flagsReg tmp1; 11443 cmpDUnordered_reg_reg(tmp1, src1, src2); 11444 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 11445 %} 11446 %} 11447 11448 //----------Branches--------------------------------------------------------- 11449 // Jump 11450 11451 // Direct Branch. 11452 instruct branch(label labl) %{ 11453 match(Goto); 11454 effect(USE labl); 11455 ins_cost(BRANCH_COST); 11456 11457 format %{ "B $labl" %} 11458 size(4); 11459 ins_encode %{ 11460 // TODO: PPC port $archOpcode(ppc64Opcode_b); 11461 Label d; // dummy 11462 __ bind(d); 11463 Label* p = $labl$$label; 11464 // `p' is `NULL' when this encoding class is used only to 11465 // determine the size of the encoded instruction. 11466 Label& l = (NULL == p)? d : *(p); 11467 __ b(l); 11468 %} 11469 ins_pipe(pipe_class_default); 11470 %} 11471 11472 // Conditional Near Branch 11473 instruct branchCon(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 11474 // Same match rule as `branchConFar'. 11475 match(If cmp crx); 11476 effect(USE lbl); 11477 ins_cost(BRANCH_COST); 11478 11479 // If set to 1 this indicates that the current instruction is a 11480 // short variant of a long branch. This avoids using this 11481 // instruction in first-pass matching. It will then only be used in 11482 // the `Shorten_branches' pass. 11483 ins_short_branch(1); 11484 11485 format %{ "B$cmp $crx, $lbl" %} 11486 size(4); 11487 ins_encode( enc_bc(crx, cmp, lbl) ); 11488 ins_pipe(pipe_class_default); 11489 %} 11490 11491 // This is for cases when the ppc64 `bc' instruction does not 11492 // reach far enough. So we emit a far branch here, which is more 11493 // expensive. 11494 // 11495 // Conditional Far Branch 11496 instruct branchConFar(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 11497 // Same match rule as `branchCon'. 11498 match(If cmp crx); 11499 effect(USE crx, USE lbl); 11500 predicate(!false /* TODO: PPC port HB_Schedule*/); 11501 // Higher cost than `branchCon'. 11502 ins_cost(5*BRANCH_COST); 11503 11504 // This is not a short variant of a branch, but the long variant. 11505 ins_short_branch(0); 11506 11507 format %{ "B_FAR$cmp $crx, $lbl" %} 11508 size(8); 11509 ins_encode( enc_bc_far(crx, cmp, lbl) ); 11510 ins_pipe(pipe_class_default); 11511 %} 11512 11513 // Conditional Branch used with Power6 scheduler (can be far or short). 11514 instruct branchConSched(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 11515 // Same match rule as `branchCon'. 11516 match(If cmp crx); 11517 effect(USE crx, USE lbl); 11518 predicate(false /* TODO: PPC port HB_Schedule*/); 11519 // Higher cost than `branchCon'. 11520 ins_cost(5*BRANCH_COST); 11521 11522 // Actually size doesn't depend on alignment but on shortening. 11523 ins_variable_size_depending_on_alignment(true); 11524 // long variant. 11525 ins_short_branch(0); 11526 11527 format %{ "B_FAR$cmp $crx, $lbl" %} 11528 size(8); // worst case 11529 ins_encode( enc_bc_short_far(crx, cmp, lbl) ); 11530 ins_pipe(pipe_class_default); 11531 %} 11532 11533 instruct branchLoopEnd(cmpOp cmp, flagsRegSrc crx, label labl) %{ 11534 match(CountedLoopEnd cmp crx); 11535 effect(USE labl); 11536 ins_cost(BRANCH_COST); 11537 11538 // short variant. 11539 ins_short_branch(1); 11540 11541 format %{ "B$cmp $crx, $labl \t// counted loop end" %} 11542 size(4); 11543 ins_encode( enc_bc(crx, cmp, labl) ); 11544 ins_pipe(pipe_class_default); 11545 %} 11546 11547 instruct branchLoopEndFar(cmpOp cmp, flagsRegSrc crx, label labl) %{ 11548 match(CountedLoopEnd cmp crx); 11549 effect(USE labl); 11550 predicate(!false /* TODO: PPC port HB_Schedule */); 11551 ins_cost(BRANCH_COST); 11552 11553 // Long variant. 11554 ins_short_branch(0); 11555 11556 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 11557 size(8); 11558 ins_encode( enc_bc_far(crx, cmp, labl) ); 11559 ins_pipe(pipe_class_default); 11560 %} 11561 11562 // Conditional Branch used with Power6 scheduler (can be far or short). 11563 instruct branchLoopEndSched(cmpOp cmp, flagsRegSrc crx, label labl) %{ 11564 match(CountedLoopEnd cmp crx); 11565 effect(USE labl); 11566 predicate(false /* TODO: PPC port HB_Schedule */); 11567 // Higher cost than `branchCon'. 11568 ins_cost(5*BRANCH_COST); 11569 11570 // Actually size doesn't depend on alignment but on shortening. 11571 ins_variable_size_depending_on_alignment(true); 11572 // Long variant. 11573 ins_short_branch(0); 11574 11575 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 11576 size(8); // worst case 11577 ins_encode( enc_bc_short_far(crx, cmp, labl) ); 11578 ins_pipe(pipe_class_default); 11579 %} 11580 11581 // ============================================================================ 11582 // Java runtime operations, intrinsics and other complex operations. 11583 11584 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass 11585 // array for an instance of the superklass. Set a hidden internal cache on a 11586 // hit (cache is checked with exposed code in gen_subtype_check()). Return 11587 // not zero for a miss or zero for a hit. The encoding ALSO sets flags. 11588 // 11589 // GL TODO: Improve this. 11590 // - result should not be a TEMP 11591 // - Add match rule as on sparc avoiding additional Cmp. 11592 instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass, 11593 iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{ 11594 match(Set result (PartialSubtypeCheck subklass superklass)); 11595 effect(TEMP_DEF result, TEMP tmp_klass, TEMP tmp_arrayptr); 11596 ins_cost(DEFAULT_COST*10); 11597 11598 format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %} 11599 ins_encode %{ 11600 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11601 __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register, 11602 $tmp_klass$$Register, NULL, $result$$Register); 11603 %} 11604 ins_pipe(pipe_class_default); 11605 %} 11606 11607 // inlined locking and unlocking 11608 11609 instruct cmpFastLock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2) %{ 11610 match(Set crx (FastLock oop box)); 11611 effect(TEMP tmp1, TEMP tmp2); 11612 predicate(!Compile::current()->use_rtm()); 11613 11614 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2" %} 11615 ins_encode %{ 11616 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11617 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 11618 $tmp1$$Register, $tmp2$$Register, /*tmp3*/ R0, 11619 UseBiasedLocking && !UseOptoBiasInlining); 11620 // If locking was successfull, crx should indicate 'EQ'. 11621 // The compiler generates a branch to the runtime call to 11622 // _complete_monitor_locking_Java for the case where crx is 'NE'. 11623 %} 11624 ins_pipe(pipe_class_compare); 11625 %} 11626 11627 // Separate version for TM. Use bound register for box to enable USE_KILL. 11628 instruct cmpFastLock_tm(flagsReg crx, iRegPdst oop, rarg2RegP box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 11629 match(Set crx (FastLock oop box)); 11630 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL box); 11631 predicate(Compile::current()->use_rtm()); 11632 11633 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2, $tmp3 (TM)" %} 11634 ins_encode %{ 11635 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11636 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 11637 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 11638 /*Biased Locking*/ false, 11639 _rtm_counters, _stack_rtm_counters, 11640 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 11641 /*TM*/ true, ra_->C->profile_rtm()); 11642 // If locking was successfull, crx should indicate 'EQ'. 11643 // The compiler generates a branch to the runtime call to 11644 // _complete_monitor_locking_Java for the case where crx is 'NE'. 11645 %} 11646 ins_pipe(pipe_class_compare); 11647 %} 11648 11649 instruct cmpFastUnlock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 11650 match(Set crx (FastUnlock oop box)); 11651 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 11652 predicate(!Compile::current()->use_rtm()); 11653 11654 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2" %} 11655 ins_encode %{ 11656 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11657 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 11658 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 11659 UseBiasedLocking && !UseOptoBiasInlining, 11660 false); 11661 // If unlocking was successfull, crx should indicate 'EQ'. 11662 // The compiler generates a branch to the runtime call to 11663 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 11664 %} 11665 ins_pipe(pipe_class_compare); 11666 %} 11667 11668 instruct cmpFastUnlock_tm(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 11669 match(Set crx (FastUnlock oop box)); 11670 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 11671 predicate(Compile::current()->use_rtm()); 11672 11673 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2 (TM)" %} 11674 ins_encode %{ 11675 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11676 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 11677 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 11678 /*Biased Locking*/ false, /*TM*/ true); 11679 // If unlocking was successfull, crx should indicate 'EQ'. 11680 // The compiler generates a branch to the runtime call to 11681 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 11682 %} 11683 ins_pipe(pipe_class_compare); 11684 %} 11685 11686 // Align address. 11687 instruct align_addr(iRegPdst dst, iRegPsrc src, immLnegpow2 mask) %{ 11688 match(Set dst (CastX2P (AndL (CastP2X src) mask))); 11689 11690 format %{ "ANDDI $dst, $src, $mask \t// next aligned address" %} 11691 size(4); 11692 ins_encode %{ 11693 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 11694 __ clrrdi($dst$$Register, $src$$Register, log2_long((jlong)-$mask$$constant)); 11695 %} 11696 ins_pipe(pipe_class_default); 11697 %} 11698 11699 // Array size computation. 11700 instruct array_size(iRegLdst dst, iRegPsrc end, iRegPsrc start) %{ 11701 match(Set dst (SubL (CastP2X end) (CastP2X start))); 11702 11703 format %{ "SUB $dst, $end, $start \t// array size in bytes" %} 11704 size(4); 11705 ins_encode %{ 11706 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 11707 __ subf($dst$$Register, $start$$Register, $end$$Register); 11708 %} 11709 ins_pipe(pipe_class_default); 11710 %} 11711 11712 // Clear-array with dynamic array-size. 11713 instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 11714 match(Set dummy (ClearArray cnt base)); 11715 effect(USE_KILL cnt, USE_KILL base, KILL ctr); 11716 ins_cost(MEMORY_REF_COST); 11717 11718 ins_alignment(4); // 'compute_padding()' gets called, up to this number-1 nops will get inserted. 11719 11720 format %{ "ClearArray $cnt, $base" %} 11721 ins_encode %{ 11722 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11723 __ clear_memory_doubleword($base$$Register, $cnt$$Register); // kills cnt, base, R0 11724 %} 11725 ins_pipe(pipe_class_default); 11726 %} 11727 11728 instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 11729 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 11730 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 11731 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11732 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 11733 ins_cost(300); 11734 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 11735 ins_encode %{ 11736 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11737 __ string_compare($str1$$Register, $str2$$Register, 11738 $cnt1$$Register, $cnt2$$Register, 11739 $tmp$$Register, 11740 $result$$Register, StrIntrinsicNode::LL); 11741 %} 11742 ins_pipe(pipe_class_default); 11743 %} 11744 11745 instruct string_compareU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 11746 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 11747 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 11748 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11749 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 11750 ins_cost(300); 11751 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 11752 ins_encode %{ 11753 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11754 __ string_compare($str1$$Register, $str2$$Register, 11755 $cnt1$$Register, $cnt2$$Register, 11756 $tmp$$Register, 11757 $result$$Register, StrIntrinsicNode::UU); 11758 %} 11759 ins_pipe(pipe_class_default); 11760 %} 11761 11762 instruct string_compareLU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 11763 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 11764 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 11765 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11766 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 11767 ins_cost(300); 11768 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 11769 ins_encode %{ 11770 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11771 __ string_compare($str1$$Register, $str2$$Register, 11772 $cnt1$$Register, $cnt2$$Register, 11773 $tmp$$Register, 11774 $result$$Register, StrIntrinsicNode::LU); 11775 %} 11776 ins_pipe(pipe_class_default); 11777 %} 11778 11779 instruct string_compareUL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 11780 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 11781 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 11782 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11783 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 11784 ins_cost(300); 11785 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 11786 ins_encode %{ 11787 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11788 __ string_compare($str2$$Register, $str1$$Register, 11789 $cnt2$$Register, $cnt1$$Register, 11790 $tmp$$Register, 11791 $result$$Register, StrIntrinsicNode::UL); 11792 %} 11793 ins_pipe(pipe_class_default); 11794 %} 11795 11796 instruct string_equalsL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 11797 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 11798 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 11799 match(Set result (StrEquals (Binary str1 str2) cnt)); 11800 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 11801 ins_cost(300); 11802 format %{ "String Equals byte[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 11803 ins_encode %{ 11804 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11805 __ array_equals(false, $str1$$Register, $str2$$Register, 11806 $cnt$$Register, $tmp$$Register, 11807 $result$$Register, true /* byte */); 11808 %} 11809 ins_pipe(pipe_class_default); 11810 %} 11811 11812 instruct string_equalsU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 11813 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 11814 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 11815 match(Set result (StrEquals (Binary str1 str2) cnt)); 11816 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 11817 ins_cost(300); 11818 format %{ "String Equals char[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 11819 ins_encode %{ 11820 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11821 __ array_equals(false, $str1$$Register, $str2$$Register, 11822 $cnt$$Register, $tmp$$Register, 11823 $result$$Register, false /* byte */); 11824 %} 11825 ins_pipe(pipe_class_default); 11826 %} 11827 11828 instruct array_equalsB(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 11829 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 11830 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11831 match(Set result (AryEq ary1 ary2)); 11832 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 11833 ins_cost(300); 11834 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 11835 ins_encode %{ 11836 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11837 __ array_equals(true, $ary1$$Register, $ary2$$Register, 11838 $tmp1$$Register, $tmp2$$Register, 11839 $result$$Register, true /* byte */); 11840 %} 11841 ins_pipe(pipe_class_default); 11842 %} 11843 11844 instruct array_equalsC(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 11845 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 11846 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11847 match(Set result (AryEq ary1 ary2)); 11848 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 11849 ins_cost(300); 11850 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 11851 ins_encode %{ 11852 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11853 __ array_equals(true, $ary1$$Register, $ary2$$Register, 11854 $tmp1$$Register, $tmp2$$Register, 11855 $result$$Register, false /* byte */); 11856 %} 11857 ins_pipe(pipe_class_default); 11858 %} 11859 11860 instruct indexOf_imm1_char_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 11861 immP needleImm, immL offsetImm, immI_1 needlecntImm, 11862 iRegIdst tmp1, iRegIdst tmp2, 11863 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 11864 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 11865 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 11866 // Required for EA: check if it is still a type_array. 11867 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 11868 ins_cost(150); 11869 11870 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 11871 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 11872 11873 ins_encode %{ 11874 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11875 immPOper *needleOper = (immPOper *)$needleImm; 11876 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 11877 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 11878 jchar chr; 11879 #ifdef VM_LITTLE_ENDIAN 11880 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 11881 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 11882 #else 11883 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 11884 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 11885 #endif 11886 __ string_indexof_char($result$$Register, 11887 $haystack$$Register, $haycnt$$Register, 11888 R0, chr, 11889 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 11890 %} 11891 ins_pipe(pipe_class_compare); 11892 %} 11893 11894 instruct indexOf_imm1_char_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 11895 immP needleImm, immL offsetImm, immI_1 needlecntImm, 11896 iRegIdst tmp1, iRegIdst tmp2, 11897 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 11898 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 11899 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 11900 // Required for EA: check if it is still a type_array. 11901 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 11902 ins_cost(150); 11903 11904 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 11905 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 11906 11907 ins_encode %{ 11908 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11909 immPOper *needleOper = (immPOper *)$needleImm; 11910 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 11911 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 11912 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 11913 __ string_indexof_char($result$$Register, 11914 $haystack$$Register, $haycnt$$Register, 11915 R0, chr, 11916 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 11917 %} 11918 ins_pipe(pipe_class_compare); 11919 %} 11920 11921 instruct indexOf_imm1_char_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 11922 immP needleImm, immL offsetImm, immI_1 needlecntImm, 11923 iRegIdst tmp1, iRegIdst tmp2, 11924 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 11925 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 11926 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 11927 // Required for EA: check if it is still a type_array. 11928 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 11929 ins_cost(150); 11930 11931 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 11932 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 11933 11934 ins_encode %{ 11935 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11936 immPOper *needleOper = (immPOper *)$needleImm; 11937 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 11938 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 11939 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 11940 __ string_indexof_char($result$$Register, 11941 $haystack$$Register, $haycnt$$Register, 11942 R0, chr, 11943 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 11944 %} 11945 ins_pipe(pipe_class_compare); 11946 %} 11947 11948 instruct indexOf_imm1_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 11949 rscratch2RegP needle, immI_1 needlecntImm, 11950 iRegIdst tmp1, iRegIdst tmp2, 11951 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 11952 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 11953 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 11954 // Required for EA: check if it is still a type_array. 11955 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 11956 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 11957 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 11958 ins_cost(180); 11959 11960 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 11961 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 11962 ins_encode %{ 11963 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11964 Node *ndl = in(operand_index($needle)); // The node that defines needle. 11965 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 11966 guarantee(needle_values, "sanity"); 11967 jchar chr; 11968 #ifdef VM_LITTLE_ENDIAN 11969 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 11970 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 11971 #else 11972 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 11973 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 11974 #endif 11975 __ string_indexof_char($result$$Register, 11976 $haystack$$Register, $haycnt$$Register, 11977 R0, chr, 11978 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 11979 %} 11980 ins_pipe(pipe_class_compare); 11981 %} 11982 11983 instruct indexOf_imm1_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 11984 rscratch2RegP needle, immI_1 needlecntImm, 11985 iRegIdst tmp1, iRegIdst tmp2, 11986 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 11987 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 11988 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 11989 // Required for EA: check if it is still a type_array. 11990 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 11991 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 11992 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 11993 ins_cost(180); 11994 11995 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 11996 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 11997 ins_encode %{ 11998 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11999 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12000 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12001 guarantee(needle_values, "sanity"); 12002 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12003 __ string_indexof_char($result$$Register, 12004 $haystack$$Register, $haycnt$$Register, 12005 R0, chr, 12006 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 12007 %} 12008 ins_pipe(pipe_class_compare); 12009 %} 12010 12011 instruct indexOf_imm1_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12012 rscratch2RegP needle, immI_1 needlecntImm, 12013 iRegIdst tmp1, iRegIdst tmp2, 12014 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12015 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12016 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12017 // Required for EA: check if it is still a type_array. 12018 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 12019 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12020 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12021 ins_cost(180); 12022 12023 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12024 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12025 ins_encode %{ 12026 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12027 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12028 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12029 guarantee(needle_values, "sanity"); 12030 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12031 __ string_indexof_char($result$$Register, 12032 $haystack$$Register, $haycnt$$Register, 12033 R0, chr, 12034 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12035 %} 12036 ins_pipe(pipe_class_compare); 12037 %} 12038 12039 instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12040 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2, 12041 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12042 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch)); 12043 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12044 ins_cost(180); 12045 12046 format %{ "String IndexOfChar $haystack[0..$haycnt], $ch" 12047 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12048 ins_encode %{ 12049 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12050 __ string_indexof_char($result$$Register, 12051 $haystack$$Register, $haycnt$$Register, 12052 $ch$$Register, 0 /* this is not used if the character is already in a register */, 12053 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12054 %} 12055 ins_pipe(pipe_class_compare); 12056 %} 12057 12058 instruct indexOf_imm_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 12059 iRegPsrc needle, uimmI15 needlecntImm, 12060 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 12061 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12062 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12063 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 12064 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12065 // Required for EA: check if it is still a type_array. 12066 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 12067 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12068 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12069 ins_cost(250); 12070 12071 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12072 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 12073 ins_encode %{ 12074 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12075 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12076 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12077 12078 __ string_indexof($result$$Register, 12079 $haystack$$Register, $haycnt$$Register, 12080 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 12081 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 12082 %} 12083 ins_pipe(pipe_class_compare); 12084 %} 12085 12086 instruct indexOf_imm_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 12087 iRegPsrc needle, uimmI15 needlecntImm, 12088 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 12089 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12090 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12091 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 12092 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12093 // Required for EA: check if it is still a type_array. 12094 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 12095 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12096 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12097 ins_cost(250); 12098 12099 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12100 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 12101 ins_encode %{ 12102 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12103 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12104 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12105 12106 __ string_indexof($result$$Register, 12107 $haystack$$Register, $haycnt$$Register, 12108 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 12109 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 12110 %} 12111 ins_pipe(pipe_class_compare); 12112 %} 12113 12114 instruct indexOf_imm_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 12115 iRegPsrc needle, uimmI15 needlecntImm, 12116 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 12117 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12118 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12119 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 12120 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12121 // Required for EA: check if it is still a type_array. 12122 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 12123 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12124 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12125 ins_cost(250); 12126 12127 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12128 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 12129 ins_encode %{ 12130 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12131 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12132 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12133 12134 __ string_indexof($result$$Register, 12135 $haystack$$Register, $haycnt$$Register, 12136 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 12137 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 12138 %} 12139 ins_pipe(pipe_class_compare); 12140 %} 12141 12142 instruct indexOf_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 12143 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 12144 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12145 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 12146 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 12147 TEMP_DEF result, 12148 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12149 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 12150 ins_cost(300); 12151 12152 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 12153 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 12154 ins_encode %{ 12155 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12156 __ string_indexof($result$$Register, 12157 $haystack$$Register, $haycnt$$Register, 12158 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 12159 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 12160 %} 12161 ins_pipe(pipe_class_compare); 12162 %} 12163 12164 instruct indexOf_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 12165 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 12166 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12167 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 12168 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 12169 TEMP_DEF result, 12170 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12171 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 12172 ins_cost(300); 12173 12174 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 12175 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 12176 ins_encode %{ 12177 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12178 __ string_indexof($result$$Register, 12179 $haystack$$Register, $haycnt$$Register, 12180 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 12181 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 12182 %} 12183 ins_pipe(pipe_class_compare); 12184 %} 12185 12186 instruct indexOf_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 12187 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 12188 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12189 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 12190 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 12191 TEMP_DEF result, 12192 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12193 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 12194 ins_cost(300); 12195 12196 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 12197 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 12198 ins_encode %{ 12199 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12200 __ string_indexof($result$$Register, 12201 $haystack$$Register, $haycnt$$Register, 12202 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 12203 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 12204 %} 12205 ins_pipe(pipe_class_compare); 12206 %} 12207 12208 // char[] to byte[] compression 12209 instruct string_compress(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 12210 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 12211 match(Set result (StrCompressedCopy src (Binary dst len))); 12212 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 12213 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 12214 ins_cost(300); 12215 format %{ "String Compress $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 12216 ins_encode %{ 12217 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12218 Label Lskip, Ldone; 12219 __ li($result$$Register, 0); 12220 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 12221 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Ldone); 12222 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 12223 __ beq(CCR0, Lskip); 12224 __ string_compress($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register, Ldone); 12225 __ bind(Lskip); 12226 __ mr($result$$Register, $len$$Register); 12227 __ bind(Ldone); 12228 %} 12229 ins_pipe(pipe_class_default); 12230 %} 12231 12232 // byte[] to char[] inflation 12233 instruct string_inflate(Universe dummy, rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegLdst tmp1, 12234 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 12235 match(Set dummy (StrInflatedCopy src (Binary dst len))); 12236 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 12237 ins_cost(300); 12238 format %{ "String Inflate $src,$dst,$len \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 12239 ins_encode %{ 12240 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12241 Label Ldone; 12242 __ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 12243 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register); 12244 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 12245 __ beq(CCR0, Ldone); 12246 __ string_inflate($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register); 12247 __ bind(Ldone); 12248 %} 12249 ins_pipe(pipe_class_default); 12250 %} 12251 12252 // StringCoding.java intrinsics 12253 instruct has_negatives(rarg1RegP ary1, iRegIsrc len, iRegIdst result, iRegLdst tmp1, iRegLdst tmp2, 12254 regCTR ctr, flagsRegCR0 cr0) 12255 %{ 12256 match(Set result (HasNegatives ary1 len)); 12257 effect(TEMP_DEF result, USE_KILL ary1, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0); 12258 ins_cost(300); 12259 format %{ "has negatives byte[] $ary1,$len -> $result \t// KILL $tmp1, $tmp2" %} 12260 ins_encode %{ 12261 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12262 __ has_negatives($ary1$$Register, $len$$Register, $result$$Register, 12263 $tmp1$$Register, $tmp2$$Register); 12264 %} 12265 ins_pipe(pipe_class_default); 12266 %} 12267 12268 // encode char[] to byte[] in ISO_8859_1 12269 instruct encode_iso_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 12270 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 12271 match(Set result (EncodeISOArray src (Binary dst len))); 12272 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 12273 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 12274 ins_cost(300); 12275 format %{ "Encode array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 12276 ins_encode %{ 12277 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12278 Label Lslow, Lfailure1, Lfailure2, Ldone; 12279 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 12280 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Lfailure1); 12281 __ rldicl_($result$$Register, $len$$Register, 0, 64-3); // Remaining characters. 12282 __ beq(CCR0, Ldone); 12283 __ bind(Lslow); 12284 __ string_compress($src$$Register, $dst$$Register, $result$$Register, $tmp2$$Register, Lfailure2); 12285 __ li($result$$Register, 0); 12286 __ b(Ldone); 12287 12288 __ bind(Lfailure1); 12289 __ mr($result$$Register, $len$$Register); 12290 __ mfctr($tmp1$$Register); 12291 __ rldimi_($result$$Register, $tmp1$$Register, 3, 0); // Remaining characters. 12292 __ beq(CCR0, Ldone); 12293 __ b(Lslow); 12294 12295 __ bind(Lfailure2); 12296 __ mfctr($result$$Register); // Remaining characters. 12297 12298 __ bind(Ldone); 12299 __ subf($result$$Register, $result$$Register, $len$$Register); 12300 %} 12301 ins_pipe(pipe_class_default); 12302 %} 12303 12304 12305 //---------- Min/Max Instructions --------------------------------------------- 12306 12307 instruct minI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 12308 match(Set dst (MinI src1 src2)); 12309 ins_cost(DEFAULT_COST*6); 12310 12311 expand %{ 12312 iRegLdst src1s; 12313 iRegLdst src2s; 12314 iRegLdst diff; 12315 iRegLdst sm; 12316 iRegLdst doz; // difference or zero 12317 convI2L_reg(src1s, src1); // Ensure proper sign extension. 12318 convI2L_reg(src2s, src2); // Ensure proper sign extension. 12319 subL_reg_reg(diff, src2s, src1s); 12320 // Need to consider >=33 bit result, therefore we need signmaskL. 12321 signmask64L_regL(sm, diff); 12322 andL_reg_reg(doz, diff, sm); // <=0 12323 addI_regL_regL(dst, doz, src1s); 12324 %} 12325 %} 12326 12327 instruct minI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 12328 match(Set dst (MinI src1 src2)); 12329 effect(KILL cr0); 12330 predicate(VM_Version::has_isel()); 12331 ins_cost(DEFAULT_COST*2); 12332 12333 ins_encode %{ 12334 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12335 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 12336 __ isel($dst$$Register, CCR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register); 12337 %} 12338 ins_pipe(pipe_class_default); 12339 %} 12340 12341 instruct maxI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 12342 match(Set dst (MaxI src1 src2)); 12343 ins_cost(DEFAULT_COST*6); 12344 12345 expand %{ 12346 iRegLdst src1s; 12347 iRegLdst src2s; 12348 iRegLdst diff; 12349 iRegLdst sm; 12350 iRegLdst doz; // difference or zero 12351 convI2L_reg(src1s, src1); // Ensure proper sign extension. 12352 convI2L_reg(src2s, src2); // Ensure proper sign extension. 12353 subL_reg_reg(diff, src2s, src1s); 12354 // Need to consider >=33 bit result, therefore we need signmaskL. 12355 signmask64L_regL(sm, diff); 12356 andcL_reg_reg(doz, diff, sm); // >=0 12357 addI_regL_regL(dst, doz, src1s); 12358 %} 12359 %} 12360 12361 instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 12362 match(Set dst (MaxI src1 src2)); 12363 effect(KILL cr0); 12364 predicate(VM_Version::has_isel()); 12365 ins_cost(DEFAULT_COST*2); 12366 12367 ins_encode %{ 12368 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12369 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 12370 __ isel($dst$$Register, CCR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register); 12371 %} 12372 ins_pipe(pipe_class_default); 12373 %} 12374 12375 //---------- Population Count Instructions ------------------------------------ 12376 12377 // Popcnt for Power7. 12378 instruct popCountI(iRegIdst dst, iRegIsrc src) %{ 12379 match(Set dst (PopCountI src)); 12380 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 12381 ins_cost(DEFAULT_COST); 12382 12383 format %{ "POPCNTW $dst, $src" %} 12384 size(4); 12385 ins_encode %{ 12386 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 12387 __ popcntw($dst$$Register, $src$$Register); 12388 %} 12389 ins_pipe(pipe_class_default); 12390 %} 12391 12392 // Popcnt for Power7. 12393 instruct popCountL(iRegIdst dst, iRegLsrc src) %{ 12394 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 12395 match(Set dst (PopCountL src)); 12396 ins_cost(DEFAULT_COST); 12397 12398 format %{ "POPCNTD $dst, $src" %} 12399 size(4); 12400 ins_encode %{ 12401 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 12402 __ popcntd($dst$$Register, $src$$Register); 12403 %} 12404 ins_pipe(pipe_class_default); 12405 %} 12406 12407 instruct countLeadingZerosI(iRegIdst dst, iRegIsrc src) %{ 12408 match(Set dst (CountLeadingZerosI src)); 12409 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 12410 ins_cost(DEFAULT_COST); 12411 12412 format %{ "CNTLZW $dst, $src" %} 12413 size(4); 12414 ins_encode %{ 12415 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzw); 12416 __ cntlzw($dst$$Register, $src$$Register); 12417 %} 12418 ins_pipe(pipe_class_default); 12419 %} 12420 12421 instruct countLeadingZerosL(iRegIdst dst, iRegLsrc src) %{ 12422 match(Set dst (CountLeadingZerosL src)); 12423 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 12424 ins_cost(DEFAULT_COST); 12425 12426 format %{ "CNTLZD $dst, $src" %} 12427 size(4); 12428 ins_encode %{ 12429 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 12430 __ cntlzd($dst$$Register, $src$$Register); 12431 %} 12432 ins_pipe(pipe_class_default); 12433 %} 12434 12435 instruct countLeadingZerosP(iRegIdst dst, iRegPsrc src) %{ 12436 // no match-rule, false predicate 12437 effect(DEF dst, USE src); 12438 predicate(false); 12439 12440 format %{ "CNTLZD $dst, $src" %} 12441 size(4); 12442 ins_encode %{ 12443 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 12444 __ cntlzd($dst$$Register, $src$$Register); 12445 %} 12446 ins_pipe(pipe_class_default); 12447 %} 12448 12449 instruct countTrailingZerosI_Ex(iRegIdst dst, iRegIsrc src) %{ 12450 match(Set dst (CountTrailingZerosI src)); 12451 predicate(UseCountLeadingZerosInstructionsPPC64); 12452 ins_cost(DEFAULT_COST); 12453 12454 expand %{ 12455 immI16 imm1 %{ (int)-1 %} 12456 immI16 imm2 %{ (int)32 %} 12457 immI_minus1 m1 %{ -1 %} 12458 iRegIdst tmpI1; 12459 iRegIdst tmpI2; 12460 iRegIdst tmpI3; 12461 addI_reg_imm16(tmpI1, src, imm1); 12462 andcI_reg_reg(tmpI2, src, m1, tmpI1); 12463 countLeadingZerosI(tmpI3, tmpI2); 12464 subI_imm16_reg(dst, imm2, tmpI3); 12465 %} 12466 %} 12467 12468 instruct countTrailingZerosL_Ex(iRegIdst dst, iRegLsrc src) %{ 12469 match(Set dst (CountTrailingZerosL src)); 12470 predicate(UseCountLeadingZerosInstructionsPPC64); 12471 ins_cost(DEFAULT_COST); 12472 12473 expand %{ 12474 immL16 imm1 %{ (long)-1 %} 12475 immI16 imm2 %{ (int)64 %} 12476 iRegLdst tmpL1; 12477 iRegLdst tmpL2; 12478 iRegIdst tmpL3; 12479 addL_reg_imm16(tmpL1, src, imm1); 12480 andcL_reg_reg(tmpL2, tmpL1, src); 12481 countLeadingZerosL(tmpL3, tmpL2); 12482 subI_imm16_reg(dst, imm2, tmpL3); 12483 %} 12484 %} 12485 12486 // Expand nodes for byte_reverse_int. 12487 instruct insrwi_a(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 12488 effect(DEF dst, USE src, USE pos, USE shift); 12489 predicate(false); 12490 12491 format %{ "INSRWI $dst, $src, $pos, $shift" %} 12492 size(4); 12493 ins_encode %{ 12494 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 12495 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 12496 %} 12497 ins_pipe(pipe_class_default); 12498 %} 12499 12500 // As insrwi_a, but with USE_DEF. 12501 instruct insrwi(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 12502 effect(USE_DEF dst, USE src, USE pos, USE shift); 12503 predicate(false); 12504 12505 format %{ "INSRWI $dst, $src, $pos, $shift" %} 12506 size(4); 12507 ins_encode %{ 12508 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 12509 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 12510 %} 12511 ins_pipe(pipe_class_default); 12512 %} 12513 12514 // Just slightly faster than java implementation. 12515 instruct bytes_reverse_int_Ex(iRegIdst dst, iRegIsrc src) %{ 12516 match(Set dst (ReverseBytesI src)); 12517 predicate(UseCountLeadingZerosInstructionsPPC64); 12518 ins_cost(DEFAULT_COST); 12519 12520 expand %{ 12521 immI16 imm24 %{ (int) 24 %} 12522 immI16 imm16 %{ (int) 16 %} 12523 immI16 imm8 %{ (int) 8 %} 12524 immI16 imm4 %{ (int) 4 %} 12525 immI16 imm0 %{ (int) 0 %} 12526 iRegLdst tmpI1; 12527 iRegLdst tmpI2; 12528 iRegLdst tmpI3; 12529 12530 urShiftI_reg_imm(tmpI1, src, imm24); 12531 insrwi_a(dst, tmpI1, imm24, imm8); 12532 urShiftI_reg_imm(tmpI2, src, imm16); 12533 insrwi(dst, tmpI2, imm8, imm16); 12534 urShiftI_reg_imm(tmpI3, src, imm8); 12535 insrwi(dst, tmpI3, imm8, imm8); 12536 insrwi(dst, src, imm0, imm8); 12537 %} 12538 %} 12539 12540 //---------- Replicate Vector Instructions ------------------------------------ 12541 12542 // Insrdi does replicate if src == dst. 12543 instruct repl32(iRegLdst dst) %{ 12544 predicate(false); 12545 effect(USE_DEF dst); 12546 12547 format %{ "INSRDI $dst, #0, $dst, #32 \t// replicate" %} 12548 size(4); 12549 ins_encode %{ 12550 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 12551 __ insrdi($dst$$Register, $dst$$Register, 32, 0); 12552 %} 12553 ins_pipe(pipe_class_default); 12554 %} 12555 12556 // Insrdi does replicate if src == dst. 12557 instruct repl48(iRegLdst dst) %{ 12558 predicate(false); 12559 effect(USE_DEF dst); 12560 12561 format %{ "INSRDI $dst, #0, $dst, #48 \t// replicate" %} 12562 size(4); 12563 ins_encode %{ 12564 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 12565 __ insrdi($dst$$Register, $dst$$Register, 48, 0); 12566 %} 12567 ins_pipe(pipe_class_default); 12568 %} 12569 12570 // Insrdi does replicate if src == dst. 12571 instruct repl56(iRegLdst dst) %{ 12572 predicate(false); 12573 effect(USE_DEF dst); 12574 12575 format %{ "INSRDI $dst, #0, $dst, #56 \t// replicate" %} 12576 size(4); 12577 ins_encode %{ 12578 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 12579 __ insrdi($dst$$Register, $dst$$Register, 56, 0); 12580 %} 12581 ins_pipe(pipe_class_default); 12582 %} 12583 12584 instruct repl8B_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 12585 match(Set dst (ReplicateB src)); 12586 predicate(n->as_Vector()->length() == 8); 12587 expand %{ 12588 moveReg(dst, src); 12589 repl56(dst); 12590 repl48(dst); 12591 repl32(dst); 12592 %} 12593 %} 12594 12595 instruct repl8B_immI0(iRegLdst dst, immI_0 zero) %{ 12596 match(Set dst (ReplicateB zero)); 12597 predicate(n->as_Vector()->length() == 8); 12598 format %{ "LI $dst, #0 \t// replicate8B" %} 12599 size(4); 12600 ins_encode %{ 12601 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12602 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 12603 %} 12604 ins_pipe(pipe_class_default); 12605 %} 12606 12607 instruct repl8B_immIminus1(iRegLdst dst, immI_minus1 src) %{ 12608 match(Set dst (ReplicateB src)); 12609 predicate(n->as_Vector()->length() == 8); 12610 format %{ "LI $dst, #-1 \t// replicate8B" %} 12611 size(4); 12612 ins_encode %{ 12613 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12614 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 12615 %} 12616 ins_pipe(pipe_class_default); 12617 %} 12618 12619 instruct repl4S_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 12620 match(Set dst (ReplicateS src)); 12621 predicate(n->as_Vector()->length() == 4); 12622 expand %{ 12623 moveReg(dst, src); 12624 repl48(dst); 12625 repl32(dst); 12626 %} 12627 %} 12628 12629 instruct repl4S_immI0(iRegLdst dst, immI_0 zero) %{ 12630 match(Set dst (ReplicateS zero)); 12631 predicate(n->as_Vector()->length() == 4); 12632 format %{ "LI $dst, #0 \t// replicate4C" %} 12633 size(4); 12634 ins_encode %{ 12635 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12636 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 12637 %} 12638 ins_pipe(pipe_class_default); 12639 %} 12640 12641 instruct repl4S_immIminus1(iRegLdst dst, immI_minus1 src) %{ 12642 match(Set dst (ReplicateS src)); 12643 predicate(n->as_Vector()->length() == 4); 12644 format %{ "LI $dst, -1 \t// replicate4C" %} 12645 size(4); 12646 ins_encode %{ 12647 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12648 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 12649 %} 12650 ins_pipe(pipe_class_default); 12651 %} 12652 12653 instruct repl2I_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 12654 match(Set dst (ReplicateI src)); 12655 predicate(n->as_Vector()->length() == 2); 12656 ins_cost(2 * DEFAULT_COST); 12657 expand %{ 12658 moveReg(dst, src); 12659 repl32(dst); 12660 %} 12661 %} 12662 12663 instruct repl2I_immI0(iRegLdst dst, immI_0 zero) %{ 12664 match(Set dst (ReplicateI zero)); 12665 predicate(n->as_Vector()->length() == 2); 12666 format %{ "LI $dst, #0 \t// replicate4C" %} 12667 size(4); 12668 ins_encode %{ 12669 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12670 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 12671 %} 12672 ins_pipe(pipe_class_default); 12673 %} 12674 12675 instruct repl2I_immIminus1(iRegLdst dst, immI_minus1 src) %{ 12676 match(Set dst (ReplicateI src)); 12677 predicate(n->as_Vector()->length() == 2); 12678 format %{ "LI $dst, -1 \t// replicate4C" %} 12679 size(4); 12680 ins_encode %{ 12681 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12682 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 12683 %} 12684 ins_pipe(pipe_class_default); 12685 %} 12686 12687 // Move float to int register via stack, replicate. 12688 instruct repl2F_reg_Ex(iRegLdst dst, regF src) %{ 12689 match(Set dst (ReplicateF src)); 12690 predicate(n->as_Vector()->length() == 2); 12691 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST); 12692 expand %{ 12693 stackSlotL tmpS; 12694 iRegIdst tmpI; 12695 moveF2I_reg_stack(tmpS, src); // Move float to stack. 12696 moveF2I_stack_reg(tmpI, tmpS); // Move stack to int reg. 12697 moveReg(dst, tmpI); // Move int to long reg. 12698 repl32(dst); // Replicate bitpattern. 12699 %} 12700 %} 12701 12702 // Replicate scalar constant to packed float values in Double register 12703 instruct repl2F_immF_Ex(iRegLdst dst, immF src) %{ 12704 match(Set dst (ReplicateF src)); 12705 predicate(n->as_Vector()->length() == 2); 12706 ins_cost(5 * DEFAULT_COST); 12707 12708 format %{ "LD $dst, offset, $constanttablebase\t// load replicated float $src $src from table, postalloc expanded" %} 12709 postalloc_expand( postalloc_expand_load_replF_constant(dst, src, constanttablebase) ); 12710 %} 12711 12712 // Replicate scalar zero constant to packed float values in Double register 12713 instruct repl2F_immF0(iRegLdst dst, immF_0 zero) %{ 12714 match(Set dst (ReplicateF zero)); 12715 predicate(n->as_Vector()->length() == 2); 12716 12717 format %{ "LI $dst, #0 \t// replicate2F" %} 12718 ins_encode %{ 12719 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12720 __ li($dst$$Register, 0x0); 12721 %} 12722 ins_pipe(pipe_class_default); 12723 %} 12724 12725 12726 //----------Overflow Math Instructions----------------------------------------- 12727 12728 // Note that we have to make sure that XER.SO is reset before using overflow instructions. 12729 // Simple Overflow operations can be matched by very few instructions (e.g. addExact: xor, and_, bc). 12730 // Seems like only Long intrinsincs have an advantage. (The only expensive one is OverflowMulL.) 12731 12732 instruct overflowAddL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 12733 match(Set cr0 (OverflowAddL op1 op2)); 12734 12735 format %{ "add_ $op1, $op2\t# overflow check long" %} 12736 ins_encode %{ 12737 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12738 __ li(R0, 0); 12739 __ mtxer(R0); // clear XER.SO 12740 __ addo_(R0, $op1$$Register, $op2$$Register); 12741 %} 12742 ins_pipe(pipe_class_default); 12743 %} 12744 12745 instruct overflowSubL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 12746 match(Set cr0 (OverflowSubL op1 op2)); 12747 12748 format %{ "subfo_ R0, $op2, $op1\t# overflow check long" %} 12749 ins_encode %{ 12750 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12751 __ li(R0, 0); 12752 __ mtxer(R0); // clear XER.SO 12753 __ subfo_(R0, $op2$$Register, $op1$$Register); 12754 %} 12755 ins_pipe(pipe_class_default); 12756 %} 12757 12758 instruct overflowNegL_reg(flagsRegCR0 cr0, immL_0 zero, iRegLsrc op2) %{ 12759 match(Set cr0 (OverflowSubL zero op2)); 12760 12761 format %{ "nego_ R0, $op2\t# overflow check long" %} 12762 ins_encode %{ 12763 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12764 __ li(R0, 0); 12765 __ mtxer(R0); // clear XER.SO 12766 __ nego_(R0, $op2$$Register); 12767 %} 12768 ins_pipe(pipe_class_default); 12769 %} 12770 12771 instruct overflowMulL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 12772 match(Set cr0 (OverflowMulL op1 op2)); 12773 12774 format %{ "mulldo_ R0, $op1, $op2\t# overflow check long" %} 12775 ins_encode %{ 12776 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12777 __ li(R0, 0); 12778 __ mtxer(R0); // clear XER.SO 12779 __ mulldo_(R0, $op1$$Register, $op2$$Register); 12780 %} 12781 ins_pipe(pipe_class_default); 12782 %} 12783 12784 12785 // ============================================================================ 12786 // Safepoint Instruction 12787 12788 instruct safePoint_poll(iRegPdst poll) %{ 12789 match(SafePoint poll); 12790 predicate(LoadPollAddressFromThread); 12791 12792 // It caused problems to add the effect that r0 is killed, but this 12793 // effect no longer needs to be mentioned, since r0 is not contained 12794 // in a reg_class. 12795 12796 format %{ "LD R0, #0, $poll \t// Safepoint poll for GC" %} 12797 size(4); 12798 ins_encode( enc_poll(0x0, poll) ); 12799 ins_pipe(pipe_class_default); 12800 %} 12801 12802 // Safepoint without per-thread support. Load address of page to poll 12803 // as constant. 12804 // Rscratch2RegP is R12. 12805 // LoadConPollAddr node is added in pd_post_matching_hook(). It must be 12806 // a seperate node so that the oop map is at the right location. 12807 instruct safePoint_poll_conPollAddr(rscratch2RegP poll) %{ 12808 match(SafePoint poll); 12809 predicate(!LoadPollAddressFromThread); 12810 12811 // It caused problems to add the effect that r0 is killed, but this 12812 // effect no longer needs to be mentioned, since r0 is not contained 12813 // in a reg_class. 12814 12815 format %{ "LD R0, #0, R12 \t// Safepoint poll for GC" %} 12816 ins_encode( enc_poll(0x0, poll) ); 12817 ins_pipe(pipe_class_default); 12818 %} 12819 12820 // ============================================================================ 12821 // Call Instructions 12822 12823 // Call Java Static Instruction 12824 12825 // Schedulable version of call static node. 12826 instruct CallStaticJavaDirect(method meth) %{ 12827 match(CallStaticJava); 12828 effect(USE meth); 12829 ins_cost(CALL_COST); 12830 12831 ins_num_consts(3 /* up to 3 patchable constants: inline cache, 2 call targets. */); 12832 12833 format %{ "CALL,static $meth \t// ==> " %} 12834 size(4); 12835 ins_encode( enc_java_static_call(meth) ); 12836 ins_pipe(pipe_class_call); 12837 %} 12838 12839 // Call Java Dynamic Instruction 12840 12841 // Used by postalloc expand of CallDynamicJavaDirectSchedEx (actual call). 12842 // Loading of IC was postalloc expanded. The nodes loading the IC are reachable 12843 // via fields ins_field_load_ic_hi_node and ins_field_load_ic_node. 12844 // The call destination must still be placed in the constant pool. 12845 instruct CallDynamicJavaDirectSched(method meth) %{ 12846 match(CallDynamicJava); // To get all the data fields we need ... 12847 effect(USE meth); 12848 predicate(false); // ... but never match. 12849 12850 ins_field_load_ic_hi_node(loadConL_hiNode*); 12851 ins_field_load_ic_node(loadConLNode*); 12852 ins_num_consts(1 /* 1 patchable constant: call destination */); 12853 12854 format %{ "BL \t// dynamic $meth ==> " %} 12855 size(4); 12856 ins_encode( enc_java_dynamic_call_sched(meth) ); 12857 ins_pipe(pipe_class_call); 12858 %} 12859 12860 // Schedulable (i.e. postalloc expanded) version of call dynamic java. 12861 // We use postalloc expanded calls if we use inline caches 12862 // and do not update method data. 12863 // 12864 // This instruction has two constants: inline cache (IC) and call destination. 12865 // Loading the inline cache will be postalloc expanded, thus leaving a call with 12866 // one constant. 12867 instruct CallDynamicJavaDirectSched_Ex(method meth) %{ 12868 match(CallDynamicJava); 12869 effect(USE meth); 12870 predicate(UseInlineCaches); 12871 ins_cost(CALL_COST); 12872 12873 ins_num_consts(2 /* 2 patchable constants: inline cache, call destination. */); 12874 12875 format %{ "CALL,dynamic $meth \t// postalloc expanded" %} 12876 postalloc_expand( postalloc_expand_java_dynamic_call_sched(meth, constanttablebase) ); 12877 %} 12878 12879 // Compound version of call dynamic java 12880 // We use postalloc expanded calls if we use inline caches 12881 // and do not update method data. 12882 instruct CallDynamicJavaDirect(method meth) %{ 12883 match(CallDynamicJava); 12884 effect(USE meth); 12885 predicate(!UseInlineCaches); 12886 ins_cost(CALL_COST); 12887 12888 // Enc_java_to_runtime_call needs up to 4 constants (method data oop). 12889 ins_num_consts(4); 12890 12891 format %{ "CALL,dynamic $meth \t// ==> " %} 12892 ins_encode( enc_java_dynamic_call(meth, constanttablebase) ); 12893 ins_pipe(pipe_class_call); 12894 %} 12895 12896 // Call Runtime Instruction 12897 12898 instruct CallRuntimeDirect(method meth) %{ 12899 match(CallRuntime); 12900 effect(USE meth); 12901 ins_cost(CALL_COST); 12902 12903 // Enc_java_to_runtime_call needs up to 3 constants: call target, 12904 // env for callee, C-toc. 12905 ins_num_consts(3); 12906 12907 format %{ "CALL,runtime" %} 12908 ins_encode( enc_java_to_runtime_call(meth) ); 12909 ins_pipe(pipe_class_call); 12910 %} 12911 12912 // Call Leaf 12913 12914 // Used by postalloc expand of CallLeafDirect_Ex (mtctr). 12915 instruct CallLeafDirect_mtctr(iRegLdst dst, iRegLsrc src) %{ 12916 effect(DEF dst, USE src); 12917 12918 ins_num_consts(1); 12919 12920 format %{ "MTCTR $src" %} 12921 size(4); 12922 ins_encode( enc_leaf_call_mtctr(src) ); 12923 ins_pipe(pipe_class_default); 12924 %} 12925 12926 // Used by postalloc expand of CallLeafDirect_Ex (actual call). 12927 instruct CallLeafDirect(method meth) %{ 12928 match(CallLeaf); // To get the data all the data fields we need ... 12929 effect(USE meth); 12930 predicate(false); // but never match. 12931 12932 format %{ "BCTRL \t// leaf call $meth ==> " %} 12933 size(4); 12934 ins_encode %{ 12935 // TODO: PPC port $archOpcode(ppc64Opcode_bctrl); 12936 __ bctrl(); 12937 %} 12938 ins_pipe(pipe_class_call); 12939 %} 12940 12941 // postalloc expand of CallLeafDirect. 12942 // Load adress to call from TOC, then bl to it. 12943 instruct CallLeafDirect_Ex(method meth) %{ 12944 match(CallLeaf); 12945 effect(USE meth); 12946 ins_cost(CALL_COST); 12947 12948 // Postalloc_expand_java_to_runtime_call needs up to 3 constants: call target, 12949 // env for callee, C-toc. 12950 ins_num_consts(3); 12951 12952 format %{ "CALL,runtime leaf $meth \t// postalloc expanded" %} 12953 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 12954 %} 12955 12956 // Call runtime without safepoint - same as CallLeaf. 12957 // postalloc expand of CallLeafNoFPDirect. 12958 // Load adress to call from TOC, then bl to it. 12959 instruct CallLeafNoFPDirect_Ex(method meth) %{ 12960 match(CallLeafNoFP); 12961 effect(USE meth); 12962 ins_cost(CALL_COST); 12963 12964 // Enc_java_to_runtime_call needs up to 3 constants: call target, 12965 // env for callee, C-toc. 12966 ins_num_consts(3); 12967 12968 format %{ "CALL,runtime leaf nofp $meth \t// postalloc expanded" %} 12969 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 12970 %} 12971 12972 // Tail Call; Jump from runtime stub to Java code. 12973 // Also known as an 'interprocedural jump'. 12974 // Target of jump will eventually return to caller. 12975 // TailJump below removes the return address. 12976 instruct TailCalljmpInd(iRegPdstNoScratch jump_target, inline_cache_regP method_oop) %{ 12977 match(TailCall jump_target method_oop); 12978 ins_cost(CALL_COST); 12979 12980 format %{ "MTCTR $jump_target \t// $method_oop holds method oop\n\t" 12981 "BCTR \t// tail call" %} 12982 size(8); 12983 ins_encode %{ 12984 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12985 __ mtctr($jump_target$$Register); 12986 __ bctr(); 12987 %} 12988 ins_pipe(pipe_class_call); 12989 %} 12990 12991 // Return Instruction 12992 instruct Ret() %{ 12993 match(Return); 12994 format %{ "BLR \t// branch to link register" %} 12995 size(4); 12996 ins_encode %{ 12997 // TODO: PPC port $archOpcode(ppc64Opcode_blr); 12998 // LR is restored in MachEpilogNode. Just do the RET here. 12999 __ blr(); 13000 %} 13001 ins_pipe(pipe_class_default); 13002 %} 13003 13004 // Tail Jump; remove the return address; jump to target. 13005 // TailCall above leaves the return address around. 13006 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2). 13007 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a 13008 // "restore" before this instruction (in Epilogue), we need to materialize it 13009 // in %i0. 13010 instruct tailjmpInd(iRegPdstNoScratch jump_target, rarg1RegP ex_oop) %{ 13011 match(TailJump jump_target ex_oop); 13012 ins_cost(CALL_COST); 13013 13014 format %{ "LD R4_ARG2 = LR\n\t" 13015 "MTCTR $jump_target\n\t" 13016 "BCTR \t// TailJump, exception oop: $ex_oop" %} 13017 size(12); 13018 ins_encode %{ 13019 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13020 __ ld(R4_ARG2/* issuing pc */, _abi(lr), R1_SP); 13021 __ mtctr($jump_target$$Register); 13022 __ bctr(); 13023 %} 13024 ins_pipe(pipe_class_call); 13025 %} 13026 13027 // Create exception oop: created by stack-crawling runtime code. 13028 // Created exception is now available to this handler, and is setup 13029 // just prior to jumping to this handler. No code emitted. 13030 instruct CreateException(rarg1RegP ex_oop) %{ 13031 match(Set ex_oop (CreateEx)); 13032 ins_cost(0); 13033 13034 format %{ " -- \t// exception oop; no code emitted" %} 13035 size(0); 13036 ins_encode( /*empty*/ ); 13037 ins_pipe(pipe_class_default); 13038 %} 13039 13040 // Rethrow exception: The exception oop will come in the first 13041 // argument position. Then JUMP (not call) to the rethrow stub code. 13042 instruct RethrowException() %{ 13043 match(Rethrow); 13044 ins_cost(CALL_COST); 13045 13046 format %{ "Jmp rethrow_stub" %} 13047 ins_encode %{ 13048 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13049 cbuf.set_insts_mark(); 13050 __ b64_patchable((address)OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type); 13051 %} 13052 ins_pipe(pipe_class_call); 13053 %} 13054 13055 // Die now. 13056 instruct ShouldNotReachHere() %{ 13057 match(Halt); 13058 ins_cost(CALL_COST); 13059 13060 format %{ "ShouldNotReachHere" %} 13061 size(4); 13062 ins_encode %{ 13063 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 13064 __ trap_should_not_reach_here(); 13065 %} 13066 ins_pipe(pipe_class_default); 13067 %} 13068 13069 // This name is KNOWN by the ADLC and cannot be changed. The ADLC 13070 // forces a 'TypeRawPtr::BOTTOM' output type for this guy. 13071 // Get a DEF on threadRegP, no costs, no encoding, use 13072 // 'ins_should_rematerialize(true)' to avoid spilling. 13073 instruct tlsLoadP(threadRegP dst) %{ 13074 match(Set dst (ThreadLocal)); 13075 ins_cost(0); 13076 13077 ins_should_rematerialize(true); 13078 13079 format %{ " -- \t// $dst=Thread::current(), empty" %} 13080 size(0); 13081 ins_encode( /*empty*/ ); 13082 ins_pipe(pipe_class_empty); 13083 %} 13084 13085 //---Some PPC specific nodes--------------------------------------------------- 13086 13087 // Stop a group. 13088 instruct endGroup() %{ 13089 ins_cost(0); 13090 13091 ins_is_nop(true); 13092 13093 format %{ "End Bundle (ori r1, r1, 0)" %} 13094 size(4); 13095 ins_encode %{ 13096 // TODO: PPC port $archOpcode(ppc64Opcode_endgroup); 13097 __ endgroup(); 13098 %} 13099 ins_pipe(pipe_class_default); 13100 %} 13101 13102 // Nop instructions 13103 13104 instruct fxNop() %{ 13105 ins_cost(0); 13106 13107 ins_is_nop(true); 13108 13109 format %{ "fxNop" %} 13110 size(4); 13111 ins_encode %{ 13112 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 13113 __ nop(); 13114 %} 13115 ins_pipe(pipe_class_default); 13116 %} 13117 13118 instruct fpNop0() %{ 13119 ins_cost(0); 13120 13121 ins_is_nop(true); 13122 13123 format %{ "fpNop0" %} 13124 size(4); 13125 ins_encode %{ 13126 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 13127 __ fpnop0(); 13128 %} 13129 ins_pipe(pipe_class_default); 13130 %} 13131 13132 instruct fpNop1() %{ 13133 ins_cost(0); 13134 13135 ins_is_nop(true); 13136 13137 format %{ "fpNop1" %} 13138 size(4); 13139 ins_encode %{ 13140 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 13141 __ fpnop1(); 13142 %} 13143 ins_pipe(pipe_class_default); 13144 %} 13145 13146 instruct brNop0() %{ 13147 ins_cost(0); 13148 size(4); 13149 format %{ "brNop0" %} 13150 ins_encode %{ 13151 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 13152 __ brnop0(); 13153 %} 13154 ins_is_nop(true); 13155 ins_pipe(pipe_class_default); 13156 %} 13157 13158 instruct brNop1() %{ 13159 ins_cost(0); 13160 13161 ins_is_nop(true); 13162 13163 format %{ "brNop1" %} 13164 size(4); 13165 ins_encode %{ 13166 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 13167 __ brnop1(); 13168 %} 13169 ins_pipe(pipe_class_default); 13170 %} 13171 13172 instruct brNop2() %{ 13173 ins_cost(0); 13174 13175 ins_is_nop(true); 13176 13177 format %{ "brNop2" %} 13178 size(4); 13179 ins_encode %{ 13180 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 13181 __ brnop2(); 13182 %} 13183 ins_pipe(pipe_class_default); 13184 %} 13185 13186 //----------PEEPHOLE RULES----------------------------------------------------- 13187 // These must follow all instruction definitions as they use the names 13188 // defined in the instructions definitions. 13189 // 13190 // peepmatch ( root_instr_name [preceeding_instruction]* ); 13191 // 13192 // peepconstraint %{ 13193 // (instruction_number.operand_name relational_op instruction_number.operand_name 13194 // [, ...] ); 13195 // // instruction numbers are zero-based using left to right order in peepmatch 13196 // 13197 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 13198 // // provide an instruction_number.operand_name for each operand that appears 13199 // // in the replacement instruction's match rule 13200 // 13201 // ---------VM FLAGS--------------------------------------------------------- 13202 // 13203 // All peephole optimizations can be turned off using -XX:-OptoPeephole 13204 // 13205 // Each peephole rule is given an identifying number starting with zero and 13206 // increasing by one in the order seen by the parser. An individual peephole 13207 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 13208 // on the command-line. 13209 // 13210 // ---------CURRENT LIMITATIONS---------------------------------------------- 13211 // 13212 // Only match adjacent instructions in same basic block 13213 // Only equality constraints 13214 // Only constraints between operands, not (0.dest_reg == EAX_enc) 13215 // Only one replacement instruction 13216 // 13217 // ---------EXAMPLE---------------------------------------------------------- 13218 // 13219 // // pertinent parts of existing instructions in architecture description 13220 // instruct movI(eRegI dst, eRegI src) %{ 13221 // match(Set dst (CopyI src)); 13222 // %} 13223 // 13224 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{ 13225 // match(Set dst (AddI dst src)); 13226 // effect(KILL cr); 13227 // %} 13228 // 13229 // // Change (inc mov) to lea 13230 // peephole %{ 13231 // // increment preceeded by register-register move 13232 // peepmatch ( incI_eReg movI ); 13233 // // require that the destination register of the increment 13234 // // match the destination register of the move 13235 // peepconstraint ( 0.dst == 1.dst ); 13236 // // construct a replacement instruction that sets 13237 // // the destination to ( move's source register + one ) 13238 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 13239 // %} 13240 // 13241 // Implementation no longer uses movX instructions since 13242 // machine-independent system no longer uses CopyX nodes. 13243 // 13244 // peephole %{ 13245 // peepmatch ( incI_eReg movI ); 13246 // peepconstraint ( 0.dst == 1.dst ); 13247 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 13248 // %} 13249 // 13250 // peephole %{ 13251 // peepmatch ( decI_eReg movI ); 13252 // peepconstraint ( 0.dst == 1.dst ); 13253 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 13254 // %} 13255 // 13256 // peephole %{ 13257 // peepmatch ( addI_eReg_imm movI ); 13258 // peepconstraint ( 0.dst == 1.dst ); 13259 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 13260 // %} 13261 // 13262 // peephole %{ 13263 // peepmatch ( addP_eReg_imm movP ); 13264 // peepconstraint ( 0.dst == 1.dst ); 13265 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) ); 13266 // %} 13267 13268 // // Change load of spilled value to only a spill 13269 // instruct storeI(memory mem, eRegI src) %{ 13270 // match(Set mem (StoreI mem src)); 13271 // %} 13272 // 13273 // instruct loadI(eRegI dst, memory mem) %{ 13274 // match(Set dst (LoadI mem)); 13275 // %} 13276 // 13277 peephole %{ 13278 peepmatch ( loadI storeI ); 13279 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 13280 peepreplace ( storeI( 1.mem 1.mem 1.src ) ); 13281 %} 13282 13283 peephole %{ 13284 peepmatch ( loadL storeL ); 13285 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 13286 peepreplace ( storeL( 1.mem 1.mem 1.src ) ); 13287 %} 13288 13289 peephole %{ 13290 peepmatch ( loadP storeP ); 13291 peepconstraint ( 1.src == 0.dst, 1.dst == 0.mem ); 13292 peepreplace ( storeP( 1.dst 1.dst 1.src ) ); 13293 %} 13294 13295 //----------SMARTSPILL RULES--------------------------------------------------- 13296 // These must follow all instruction definitions as they use the names 13297 // defined in the instructions definitions.