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 // Put the entry point as a constant into the constant pool. 1101 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 1102 if (entry_point_toc_addr == NULL) { 1103 ciEnv::current()->record_out_of_memory_failure(); 1104 return offsets; 1105 } 1106 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 1107 1108 // Emit the trampoline stub which will be related to the branch-and-link below. 1109 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, offsets.insts_call_instruction_offset); 1110 if (ciEnv::current()->failing()) { return offsets; } // Code cache may be full. 1111 __ relocate(rtype); 1112 1113 // Note: At this point we do not have the address of the trampoline 1114 // stub, and the entry point might be too far away for bl, so __ pc() 1115 // serves as dummy and the bl will be patched later. 1116 __ bl((address) __ pc()); 1117 1118 offsets.ret_addr_offset = __ offset() - start_offset; 1119 1120 return offsets; 1121 } 1122 1123 //============================================================================= 1124 1125 // Factory for creating loadConL* nodes for large/small constant pool. 1126 1127 static inline jlong replicate_immF(float con) { 1128 // Replicate float con 2 times and pack into vector. 1129 int val = *((int*)&con); 1130 jlong lval = val; 1131 lval = (lval << 32) | (lval & 0xFFFFFFFFl); 1132 return lval; 1133 } 1134 1135 //============================================================================= 1136 1137 const RegMask& MachConstantBaseNode::_out_RegMask = BITS64_CONSTANT_TABLE_BASE_mask(); 1138 int Compile::ConstantTable::calculate_table_base_offset() const { 1139 return 0; // absolute addressing, no offset 1140 } 1141 1142 bool MachConstantBaseNode::requires_postalloc_expand() const { return true; } 1143 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 1144 iRegPdstOper *op_dst = new iRegPdstOper(); 1145 MachNode *m1 = new loadToc_hiNode(); 1146 MachNode *m2 = new loadToc_loNode(); 1147 1148 m1->add_req(NULL); 1149 m2->add_req(NULL, m1); 1150 m1->_opnds[0] = op_dst; 1151 m2->_opnds[0] = op_dst; 1152 m2->_opnds[1] = op_dst; 1153 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 1154 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 1155 nodes->push(m1); 1156 nodes->push(m2); 1157 } 1158 1159 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1160 // Is postalloc expanded. 1161 ShouldNotReachHere(); 1162 } 1163 1164 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 1165 return 0; 1166 } 1167 1168 #ifndef PRODUCT 1169 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1170 st->print("-- \t// MachConstantBaseNode (empty encoding)"); 1171 } 1172 #endif 1173 1174 //============================================================================= 1175 1176 #ifndef PRODUCT 1177 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1178 Compile* C = ra_->C; 1179 const long framesize = C->frame_slots() << LogBytesPerInt; 1180 1181 st->print("PROLOG\n\t"); 1182 if (C->need_stack_bang(framesize)) { 1183 st->print("stack_overflow_check\n\t"); 1184 } 1185 1186 if (!false /* TODO: PPC port C->is_frameless_method()*/) { 1187 st->print("save return pc\n\t"); 1188 st->print("push frame %ld\n\t", -framesize); 1189 } 1190 } 1191 #endif 1192 1193 // Macro used instead of the common __ to emulate the pipes of PPC. 1194 // Instead of e.g. __ ld(...) one hase to write ___(ld) ld(...) This enables the 1195 // micro scheduler to cope with "hand written" assembler like in the prolog. Though 1196 // still no scheduling of this code is possible, the micro scheduler is aware of the 1197 // code and can update its internal data. The following mechanism is used to achieve this: 1198 // The micro scheduler calls size() of each compound node during scheduling. size() does a 1199 // dummy emit and only during this dummy emit C->hb_scheduling() is not NULL. 1200 #if 0 // TODO: PPC port 1201 #define ___(op) if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1202 C->hb_scheduling()->_pdScheduling->PdEmulatePipe(ppc64Opcode_##op); \ 1203 _masm. 1204 #define ___stop if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1205 C->hb_scheduling()->_pdScheduling->PdEmulatePipe(archOpcode_none) 1206 #define ___advance if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1207 C->hb_scheduling()->_pdScheduling->advance_offset 1208 #else 1209 #define ___(op) if (UsePower6SchedulerPPC64) \ 1210 Unimplemented(); \ 1211 _masm. 1212 #define ___stop if (UsePower6SchedulerPPC64) \ 1213 Unimplemented() 1214 #define ___advance if (UsePower6SchedulerPPC64) \ 1215 Unimplemented() 1216 #endif 1217 1218 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1219 Compile* C = ra_->C; 1220 MacroAssembler _masm(&cbuf); 1221 1222 const long framesize = C->frame_size_in_bytes(); 1223 assert(framesize % (2 * wordSize) == 0, "must preserve 2*wordSize alignment"); 1224 1225 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; 1226 1227 const Register return_pc = R20; // Must match return_addr() in frame section. 1228 const Register callers_sp = R21; 1229 const Register push_frame_temp = R22; 1230 const Register toc_temp = R23; 1231 assert_different_registers(R11, return_pc, callers_sp, push_frame_temp, toc_temp); 1232 1233 if (method_is_frameless) { 1234 // Add nop at beginning of all frameless methods to prevent any 1235 // oop instructions from getting overwritten by make_not_entrant 1236 // (patching attempt would fail). 1237 ___(nop) nop(); 1238 } else { 1239 // Get return pc. 1240 ___(mflr) mflr(return_pc); 1241 } 1242 1243 // Calls to C2R adapters often do not accept exceptional returns. 1244 // We require that their callers must bang for them. But be 1245 // careful, because some VM calls (such as call site linkage) can 1246 // use several kilobytes of stack. But the stack safety zone should 1247 // account for that. See bugs 4446381, 4468289, 4497237. 1248 1249 int bangsize = C->bang_size_in_bytes(); 1250 assert(bangsize >= framesize || bangsize <= 0, "stack bang size incorrect"); 1251 if (C->need_stack_bang(bangsize) && UseStackBanging) { 1252 // Unfortunately we cannot use the function provided in 1253 // assembler.cpp as we have to emulate the pipes. So I had to 1254 // insert the code of generate_stack_overflow_check(), see 1255 // assembler.cpp for some illuminative comments. 1256 const int page_size = os::vm_page_size(); 1257 int bang_end = JavaThread::stack_shadow_zone_size(); 1258 1259 // This is how far the previous frame's stack banging extended. 1260 const int bang_end_safe = bang_end; 1261 1262 if (bangsize > page_size) { 1263 bang_end += bangsize; 1264 } 1265 1266 int bang_offset = bang_end_safe; 1267 1268 while (bang_offset <= bang_end) { 1269 // Need at least one stack bang at end of shadow zone. 1270 1271 // Again I had to copy code, this time from assembler_ppc.cpp, 1272 // bang_stack_with_offset - see there for comments. 1273 1274 // Stack grows down, caller passes positive offset. 1275 assert(bang_offset > 0, "must bang with positive offset"); 1276 1277 long stdoffset = -bang_offset; 1278 1279 if (Assembler::is_simm(stdoffset, 16)) { 1280 // Signed 16 bit offset, a simple std is ok. 1281 if (UseLoadInstructionsForStackBangingPPC64) { 1282 ___(ld) ld(R0, (int)(signed short)stdoffset, R1_SP); 1283 } else { 1284 ___(std) std(R0, (int)(signed short)stdoffset, R1_SP); 1285 } 1286 } else if (Assembler::is_simm(stdoffset, 31)) { 1287 // Use largeoffset calculations for addis & ld/std. 1288 const int hi = MacroAssembler::largeoffset_si16_si16_hi(stdoffset); 1289 const int lo = MacroAssembler::largeoffset_si16_si16_lo(stdoffset); 1290 1291 Register tmp = R11; 1292 ___(addis) addis(tmp, R1_SP, hi); 1293 if (UseLoadInstructionsForStackBangingPPC64) { 1294 ___(ld) ld(R0, lo, tmp); 1295 } else { 1296 ___(std) std(R0, lo, tmp); 1297 } 1298 } else { 1299 ShouldNotReachHere(); 1300 } 1301 1302 bang_offset += page_size; 1303 } 1304 // R11 trashed 1305 } // C->need_stack_bang(framesize) && UseStackBanging 1306 1307 unsigned int bytes = (unsigned int)framesize; 1308 long offset = Assembler::align_addr(bytes, frame::alignment_in_bytes); 1309 ciMethod *currMethod = C->method(); 1310 1311 // Optimized version for most common case. 1312 if (UsePower6SchedulerPPC64 && 1313 !method_is_frameless && Assembler::is_simm((int)(-offset), 16) && 1314 !(false /* ConstantsALot TODO: PPC port*/)) { 1315 ___(or) mr(callers_sp, R1_SP); 1316 ___(std) std(return_pc, _abi(lr), R1_SP); 1317 ___(stdu) stdu(R1_SP, -offset, R1_SP); 1318 return; 1319 } 1320 1321 if (!method_is_frameless) { 1322 // Get callers sp. 1323 ___(or) mr(callers_sp, R1_SP); 1324 1325 // Push method's frame, modifies SP. 1326 assert(Assembler::is_uimm(framesize, 32U), "wrong type"); 1327 // The ABI is already accounted for in 'framesize' via the 1328 // 'out_preserve' area. 1329 Register tmp = push_frame_temp; 1330 // Had to insert code of push_frame((unsigned int)framesize, push_frame_temp). 1331 if (Assembler::is_simm(-offset, 16)) { 1332 ___(stdu) stdu(R1_SP, -offset, R1_SP); 1333 } else { 1334 long x = -offset; 1335 // Had to insert load_const(tmp, -offset). 1336 ___(addis) lis( tmp, (int)((signed short)(((x >> 32) & 0xffff0000) >> 16))); 1337 ___(ori) ori( tmp, tmp, ((x >> 32) & 0x0000ffff)); 1338 ___(rldicr) sldi(tmp, tmp, 32); 1339 ___(oris) oris(tmp, tmp, (x & 0xffff0000) >> 16); 1340 ___(ori) ori( tmp, tmp, (x & 0x0000ffff)); 1341 1342 ___(stdux) stdux(R1_SP, R1_SP, tmp); 1343 } 1344 } 1345 #if 0 // TODO: PPC port 1346 // For testing large constant pools, emit a lot of constants to constant pool. 1347 // "Randomize" const_size. 1348 if (ConstantsALot) { 1349 const int num_consts = const_size(); 1350 for (int i = 0; i < num_consts; i++) { 1351 __ long_constant(0xB0B5B00BBABE); 1352 } 1353 } 1354 #endif 1355 if (!method_is_frameless) { 1356 // Save return pc. 1357 ___(std) std(return_pc, _abi(lr), callers_sp); 1358 } 1359 1360 C->set_frame_complete(cbuf.insts_size()); 1361 } 1362 #undef ___ 1363 #undef ___stop 1364 #undef ___advance 1365 1366 uint MachPrologNode::size(PhaseRegAlloc *ra_) const { 1367 // Variable size. determine dynamically. 1368 return MachNode::size(ra_); 1369 } 1370 1371 int MachPrologNode::reloc() const { 1372 // Return number of relocatable values contained in this instruction. 1373 return 1; // 1 reloc entry for load_const(toc). 1374 } 1375 1376 //============================================================================= 1377 1378 #ifndef PRODUCT 1379 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1380 Compile* C = ra_->C; 1381 1382 st->print("EPILOG\n\t"); 1383 st->print("restore return pc\n\t"); 1384 st->print("pop frame\n\t"); 1385 1386 if (do_polling() && C->is_method_compilation()) { 1387 st->print("touch polling page\n\t"); 1388 } 1389 } 1390 #endif 1391 1392 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1393 Compile* C = ra_->C; 1394 MacroAssembler _masm(&cbuf); 1395 1396 const long framesize = ((long)C->frame_slots()) << LogBytesPerInt; 1397 assert(framesize >= 0, "negative frame-size?"); 1398 1399 const bool method_needs_polling = do_polling() && C->is_method_compilation(); 1400 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; 1401 const Register return_pc = R31; // Must survive C-call to enable_stack_reserved_zone(). 1402 const Register polling_page = R12; 1403 1404 if (!method_is_frameless) { 1405 // Restore return pc relative to callers' sp. 1406 __ ld(return_pc, ((int)framesize) + _abi(lr), R1_SP); 1407 } 1408 1409 if (method_needs_polling) { 1410 if (LoadPollAddressFromThread) { 1411 // TODO: PPC port __ ld(polling_page, in_bytes(JavaThread::poll_address_offset()), R16_thread); 1412 Unimplemented(); 1413 } else { 1414 __ load_const_optimized(polling_page, (long)(address) os::get_polling_page()); // TODO: PPC port: get_standard_polling_page() 1415 } 1416 } 1417 1418 if (!method_is_frameless) { 1419 // Move return pc to LR. 1420 __ mtlr(return_pc); 1421 // Pop frame (fixed frame-size). 1422 __ addi(R1_SP, R1_SP, (int)framesize); 1423 } 1424 1425 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1426 __ reserved_stack_check(return_pc); 1427 } 1428 1429 if (method_needs_polling) { 1430 // We need to mark the code position where the load from the safepoint 1431 // polling page was emitted as relocInfo::poll_return_type here. 1432 __ relocate(relocInfo::poll_return_type); 1433 __ load_from_polling_page(polling_page); 1434 } 1435 } 1436 1437 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 1438 // Variable size. Determine dynamically. 1439 return MachNode::size(ra_); 1440 } 1441 1442 int MachEpilogNode::reloc() const { 1443 // Return number of relocatable values contained in this instruction. 1444 return 1; // 1 for load_from_polling_page. 1445 } 1446 1447 const Pipeline * MachEpilogNode::pipeline() const { 1448 return MachNode::pipeline_class(); 1449 } 1450 1451 // This method seems to be obsolete. It is declared in machnode.hpp 1452 // and defined in all *.ad files, but it is never called. Should we 1453 // get rid of it? 1454 int MachEpilogNode::safepoint_offset() const { 1455 assert(do_polling(), "no return for this epilog node"); 1456 return 0; 1457 } 1458 1459 #if 0 // TODO: PPC port 1460 void MachLoadPollAddrLateNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1461 MacroAssembler _masm(&cbuf); 1462 if (LoadPollAddressFromThread) { 1463 _masm.ld(R11, in_bytes(JavaThread::poll_address_offset()), R16_thread); 1464 } else { 1465 _masm.nop(); 1466 } 1467 } 1468 1469 uint MachLoadPollAddrLateNode::size(PhaseRegAlloc* ra_) const { 1470 if (LoadPollAddressFromThread) { 1471 return 4; 1472 } else { 1473 return 4; 1474 } 1475 } 1476 1477 #ifndef PRODUCT 1478 void MachLoadPollAddrLateNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1479 st->print_cr(" LD R11, PollAddressOffset, R16_thread \t// LoadPollAddressFromThread"); 1480 } 1481 #endif 1482 1483 const RegMask &MachLoadPollAddrLateNode::out_RegMask() const { 1484 return RSCRATCH1_BITS64_REG_mask(); 1485 } 1486 #endif // PPC port 1487 1488 // ============================================================================= 1489 1490 // Figure out which register class each belongs in: rc_int, rc_float or 1491 // rc_stack. 1492 enum RC { rc_bad, rc_int, rc_float, rc_stack }; 1493 1494 static enum RC rc_class(OptoReg::Name reg) { 1495 // Return the register class for the given register. The given register 1496 // reg is a <register>_num value, which is an index into the MachRegisterNumbers 1497 // enumeration in adGlobals_ppc.hpp. 1498 1499 if (reg == OptoReg::Bad) return rc_bad; 1500 1501 // We have 64 integer register halves, starting at index 0. 1502 if (reg < 64) return rc_int; 1503 1504 // We have 64 floating-point register halves, starting at index 64. 1505 if (reg < 64+64) return rc_float; 1506 1507 // Between float regs & stack are the flags regs. 1508 assert(OptoReg::is_stack(reg), "blow up if spilling flags"); 1509 1510 return rc_stack; 1511 } 1512 1513 static int ld_st_helper(CodeBuffer *cbuf, const char *op_str, uint opcode, int reg, int offset, 1514 bool do_print, Compile* C, outputStream *st) { 1515 1516 assert(opcode == Assembler::LD_OPCODE || 1517 opcode == Assembler::STD_OPCODE || 1518 opcode == Assembler::LWZ_OPCODE || 1519 opcode == Assembler::STW_OPCODE || 1520 opcode == Assembler::LFD_OPCODE || 1521 opcode == Assembler::STFD_OPCODE || 1522 opcode == Assembler::LFS_OPCODE || 1523 opcode == Assembler::STFS_OPCODE, 1524 "opcode not supported"); 1525 1526 if (cbuf) { 1527 int d = 1528 (Assembler::LD_OPCODE == opcode || Assembler::STD_OPCODE == opcode) ? 1529 Assembler::ds(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/) 1530 : Assembler::d1(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); // Makes no difference in opt build. 1531 emit_long(*cbuf, opcode | Assembler::rt(Matcher::_regEncode[reg]) | d | Assembler::ra(R1_SP)); 1532 } 1533 #ifndef PRODUCT 1534 else if (do_print) { 1535 st->print("%-7s %s, [R1_SP + #%d+%d] \t// spill copy", 1536 op_str, 1537 Matcher::regName[reg], 1538 offset, 0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); 1539 } 1540 #endif 1541 return 4; // size 1542 } 1543 1544 uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 1545 Compile* C = ra_->C; 1546 1547 // Get registers to move. 1548 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 1549 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 1550 OptoReg::Name dst_hi = ra_->get_reg_second(this); 1551 OptoReg::Name dst_lo = ra_->get_reg_first(this); 1552 1553 enum RC src_hi_rc = rc_class(src_hi); 1554 enum RC src_lo_rc = rc_class(src_lo); 1555 enum RC dst_hi_rc = rc_class(dst_hi); 1556 enum RC dst_lo_rc = rc_class(dst_lo); 1557 1558 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 1559 if (src_hi != OptoReg::Bad) 1560 assert((src_lo&1)==0 && src_lo+1==src_hi && 1561 (dst_lo&1)==0 && dst_lo+1==dst_hi, 1562 "expected aligned-adjacent pairs"); 1563 // Generate spill code! 1564 int size = 0; 1565 1566 if (src_lo == dst_lo && src_hi == dst_hi) 1567 return size; // Self copy, no move. 1568 1569 // -------------------------------------- 1570 // Memory->Memory Spill. Use R0 to hold the value. 1571 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1572 int src_offset = ra_->reg2offset(src_lo); 1573 int dst_offset = ra_->reg2offset(dst_lo); 1574 if (src_hi != OptoReg::Bad) { 1575 assert(src_hi_rc==rc_stack && dst_hi_rc==rc_stack, 1576 "expected same type of move for high parts"); 1577 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, R0_num, src_offset, !do_size, C, st); 1578 if (!cbuf && !do_size) st->print("\n\t"); 1579 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, R0_num, dst_offset, !do_size, C, st); 1580 } else { 1581 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, R0_num, src_offset, !do_size, C, st); 1582 if (!cbuf && !do_size) st->print("\n\t"); 1583 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, R0_num, dst_offset, !do_size, C, st); 1584 } 1585 return size; 1586 } 1587 1588 // -------------------------------------- 1589 // Check for float->int copy; requires a trip through memory. 1590 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) { 1591 Unimplemented(); 1592 } 1593 1594 // -------------------------------------- 1595 // Check for integer reg-reg copy. 1596 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) { 1597 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]); 1598 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]); 1599 size = (Rsrc != Rdst) ? 4 : 0; 1600 1601 if (cbuf) { 1602 MacroAssembler _masm(cbuf); 1603 if (size) { 1604 __ mr(Rdst, Rsrc); 1605 } 1606 } 1607 #ifndef PRODUCT 1608 else if (!do_size) { 1609 if (size) { 1610 st->print("%-7s %s, %s \t// spill copy", "MR", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1611 } else { 1612 st->print("%-7s %s, %s \t// spill copy", "MR-NOP", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1613 } 1614 } 1615 #endif 1616 return size; 1617 } 1618 1619 // Check for integer store. 1620 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) { 1621 int dst_offset = ra_->reg2offset(dst_lo); 1622 if (src_hi != OptoReg::Bad) { 1623 assert(src_hi_rc==rc_int && dst_hi_rc==rc_stack, 1624 "expected same type of move for high parts"); 1625 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, src_lo, dst_offset, !do_size, C, st); 1626 } else { 1627 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, src_lo, dst_offset, !do_size, C, st); 1628 } 1629 return size; 1630 } 1631 1632 // Check for integer load. 1633 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) { 1634 int src_offset = ra_->reg2offset(src_lo); 1635 if (src_hi != OptoReg::Bad) { 1636 assert(dst_hi_rc==rc_int && src_hi_rc==rc_stack, 1637 "expected same type of move for high parts"); 1638 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, dst_lo, src_offset, !do_size, C, st); 1639 } else { 1640 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, dst_lo, src_offset, !do_size, C, st); 1641 } 1642 return size; 1643 } 1644 1645 // Check for float reg-reg copy. 1646 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1647 if (cbuf) { 1648 MacroAssembler _masm(cbuf); 1649 FloatRegister Rsrc = as_FloatRegister(Matcher::_regEncode[src_lo]); 1650 FloatRegister Rdst = as_FloatRegister(Matcher::_regEncode[dst_lo]); 1651 __ fmr(Rdst, Rsrc); 1652 } 1653 #ifndef PRODUCT 1654 else if (!do_size) { 1655 st->print("%-7s %s, %s \t// spill copy", "FMR", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1656 } 1657 #endif 1658 return 4; 1659 } 1660 1661 // Check for float store. 1662 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1663 int dst_offset = ra_->reg2offset(dst_lo); 1664 if (src_hi != OptoReg::Bad) { 1665 assert(src_hi_rc==rc_float && dst_hi_rc==rc_stack, 1666 "expected same type of move for high parts"); 1667 size += ld_st_helper(cbuf, "STFD", Assembler::STFD_OPCODE, src_lo, dst_offset, !do_size, C, st); 1668 } else { 1669 size += ld_st_helper(cbuf, "STFS", Assembler::STFS_OPCODE, src_lo, dst_offset, !do_size, C, st); 1670 } 1671 return size; 1672 } 1673 1674 // Check for float load. 1675 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) { 1676 int src_offset = ra_->reg2offset(src_lo); 1677 if (src_hi != OptoReg::Bad) { 1678 assert(dst_hi_rc==rc_float && src_hi_rc==rc_stack, 1679 "expected same type of move for high parts"); 1680 size += ld_st_helper(cbuf, "LFD ", Assembler::LFD_OPCODE, dst_lo, src_offset, !do_size, C, st); 1681 } else { 1682 size += ld_st_helper(cbuf, "LFS ", Assembler::LFS_OPCODE, dst_lo, src_offset, !do_size, C, st); 1683 } 1684 return size; 1685 } 1686 1687 // -------------------------------------------------------------------- 1688 // Check for hi bits still needing moving. Only happens for misaligned 1689 // arguments to native calls. 1690 if (src_hi == dst_hi) 1691 return size; // Self copy; no move. 1692 1693 assert(src_hi_rc != rc_bad && dst_hi_rc != rc_bad, "src_hi & dst_hi cannot be Bad"); 1694 ShouldNotReachHere(); // Unimplemented 1695 return 0; 1696 } 1697 1698 #ifndef PRODUCT 1699 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1700 if (!ra_) 1701 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 1702 else 1703 implementation(NULL, ra_, false, st); 1704 } 1705 #endif 1706 1707 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1708 implementation(&cbuf, ra_, false, NULL); 1709 } 1710 1711 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1712 return implementation(NULL, ra_, true, NULL); 1713 } 1714 1715 #if 0 // TODO: PPC port 1716 ArchOpcode MachSpillCopyNode_archOpcode(MachSpillCopyNode *n, PhaseRegAlloc *ra_) { 1717 #ifndef PRODUCT 1718 if (ra_->node_regs_max_index() == 0) return archOpcode_undefined; 1719 #endif 1720 assert(ra_->node_regs_max_index() != 0, ""); 1721 1722 // Get registers to move. 1723 OptoReg::Name src_hi = ra_->get_reg_second(n->in(1)); 1724 OptoReg::Name src_lo = ra_->get_reg_first(n->in(1)); 1725 OptoReg::Name dst_hi = ra_->get_reg_second(n); 1726 OptoReg::Name dst_lo = ra_->get_reg_first(n); 1727 1728 enum RC src_lo_rc = rc_class(src_lo); 1729 enum RC dst_lo_rc = rc_class(dst_lo); 1730 1731 if (src_lo == dst_lo && src_hi == dst_hi) 1732 return ppc64Opcode_none; // Self copy, no move. 1733 1734 // -------------------------------------- 1735 // Memory->Memory Spill. Use R0 to hold the value. 1736 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1737 return ppc64Opcode_compound; 1738 } 1739 1740 // -------------------------------------- 1741 // Check for float->int copy; requires a trip through memory. 1742 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) { 1743 Unimplemented(); 1744 } 1745 1746 // -------------------------------------- 1747 // Check for integer reg-reg copy. 1748 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) { 1749 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]); 1750 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]); 1751 if (Rsrc == Rdst) { 1752 return ppc64Opcode_none; 1753 } else { 1754 return ppc64Opcode_or; 1755 } 1756 } 1757 1758 // Check for integer store. 1759 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) { 1760 if (src_hi != OptoReg::Bad) { 1761 return ppc64Opcode_std; 1762 } else { 1763 return ppc64Opcode_stw; 1764 } 1765 } 1766 1767 // Check for integer load. 1768 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) { 1769 if (src_hi != OptoReg::Bad) { 1770 return ppc64Opcode_ld; 1771 } else { 1772 return ppc64Opcode_lwz; 1773 } 1774 } 1775 1776 // Check for float reg-reg copy. 1777 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1778 return ppc64Opcode_fmr; 1779 } 1780 1781 // Check for float store. 1782 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1783 if (src_hi != OptoReg::Bad) { 1784 return ppc64Opcode_stfd; 1785 } else { 1786 return ppc64Opcode_stfs; 1787 } 1788 } 1789 1790 // Check for float load. 1791 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) { 1792 if (src_hi != OptoReg::Bad) { 1793 return ppc64Opcode_lfd; 1794 } else { 1795 return ppc64Opcode_lfs; 1796 } 1797 } 1798 1799 // -------------------------------------------------------------------- 1800 // Check for hi bits still needing moving. Only happens for misaligned 1801 // arguments to native calls. 1802 if (src_hi == dst_hi) { 1803 return ppc64Opcode_none; // Self copy; no move. 1804 } 1805 1806 ShouldNotReachHere(); 1807 return ppc64Opcode_undefined; 1808 } 1809 #endif // PPC port 1810 1811 #ifndef PRODUCT 1812 void MachNopNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1813 st->print("NOP \t// %d nops to pad for loops.", _count); 1814 } 1815 #endif 1816 1817 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *) const { 1818 MacroAssembler _masm(&cbuf); 1819 // _count contains the number of nops needed for padding. 1820 for (int i = 0; i < _count; i++) { 1821 __ nop(); 1822 } 1823 } 1824 1825 uint MachNopNode::size(PhaseRegAlloc *ra_) const { 1826 return _count * 4; 1827 } 1828 1829 #ifndef PRODUCT 1830 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1831 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1832 char reg_str[128]; 1833 ra_->dump_register(this, reg_str); 1834 st->print("ADDI %s, SP, %d \t// box node", reg_str, offset); 1835 } 1836 #endif 1837 1838 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1839 MacroAssembler _masm(&cbuf); 1840 1841 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1842 int reg = ra_->get_encode(this); 1843 1844 if (Assembler::is_simm(offset, 16)) { 1845 __ addi(as_Register(reg), R1, offset); 1846 } else { 1847 ShouldNotReachHere(); 1848 } 1849 } 1850 1851 uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 1852 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 1853 return 4; 1854 } 1855 1856 #ifndef PRODUCT 1857 void MachUEPNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1858 st->print_cr("---- MachUEPNode ----"); 1859 st->print_cr("..."); 1860 } 1861 #endif 1862 1863 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1864 // This is the unverified entry point. 1865 MacroAssembler _masm(&cbuf); 1866 1867 // Inline_cache contains a klass. 1868 Register ic_klass = as_Register(Matcher::inline_cache_reg_encode()); 1869 Register receiver_klass = R12_scratch2; // tmp 1870 1871 assert_different_registers(ic_klass, receiver_klass, R11_scratch1, R3_ARG1); 1872 assert(R11_scratch1 == R11, "need prologue scratch register"); 1873 1874 // Check for NULL argument if we don't have implicit null checks. 1875 if (!ImplicitNullChecks || !os::zero_page_read_protected()) { 1876 if (TrapBasedNullChecks) { 1877 __ trap_null_check(R3_ARG1); 1878 } else { 1879 Label valid; 1880 __ cmpdi(CCR0, R3_ARG1, 0); 1881 __ bne_predict_taken(CCR0, valid); 1882 // We have a null argument, branch to ic_miss_stub. 1883 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), 1884 relocInfo::runtime_call_type); 1885 __ bind(valid); 1886 } 1887 } 1888 // Assume argument is not NULL, load klass from receiver. 1889 __ load_klass(receiver_klass, R3_ARG1); 1890 1891 if (TrapBasedICMissChecks) { 1892 __ trap_ic_miss_check(receiver_klass, ic_klass); 1893 } else { 1894 Label valid; 1895 __ cmpd(CCR0, receiver_klass, ic_klass); 1896 __ beq_predict_taken(CCR0, valid); 1897 // We have an unexpected klass, branch to ic_miss_stub. 1898 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), 1899 relocInfo::runtime_call_type); 1900 __ bind(valid); 1901 } 1902 1903 // Argument is valid and klass is as expected, continue. 1904 } 1905 1906 #if 0 // TODO: PPC port 1907 // Optimize UEP code on z (save a load_const() call in main path). 1908 int MachUEPNode::ep_offset() { 1909 return 0; 1910 } 1911 #endif 1912 1913 uint MachUEPNode::size(PhaseRegAlloc *ra_) const { 1914 // Variable size. Determine dynamically. 1915 return MachNode::size(ra_); 1916 } 1917 1918 //============================================================================= 1919 1920 %} // interrupt source 1921 1922 source_hpp %{ // Header information of the source block. 1923 1924 class HandlerImpl { 1925 1926 public: 1927 1928 static int emit_exception_handler(CodeBuffer &cbuf); 1929 static int emit_deopt_handler(CodeBuffer& cbuf); 1930 1931 static uint size_exception_handler() { 1932 // The exception_handler is a b64_patchable. 1933 return MacroAssembler::b64_patchable_size; 1934 } 1935 1936 static uint size_deopt_handler() { 1937 // The deopt_handler is a bl64_patchable. 1938 return MacroAssembler::bl64_patchable_size; 1939 } 1940 1941 }; 1942 1943 %} // end source_hpp 1944 1945 source %{ 1946 1947 int HandlerImpl::emit_exception_handler(CodeBuffer &cbuf) { 1948 MacroAssembler _masm(&cbuf); 1949 1950 address base = __ start_a_stub(size_exception_handler()); 1951 if (base == NULL) return 0; // CodeBuffer::expand failed 1952 1953 int offset = __ offset(); 1954 __ b64_patchable((address)OptoRuntime::exception_blob()->content_begin(), 1955 relocInfo::runtime_call_type); 1956 assert(__ offset() - offset == (int)size_exception_handler(), "must be fixed size"); 1957 __ end_a_stub(); 1958 1959 return offset; 1960 } 1961 1962 // The deopt_handler is like the exception handler, but it calls to 1963 // the deoptimization blob instead of jumping to the exception blob. 1964 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) { 1965 MacroAssembler _masm(&cbuf); 1966 1967 address base = __ start_a_stub(size_deopt_handler()); 1968 if (base == NULL) return 0; // CodeBuffer::expand failed 1969 1970 int offset = __ offset(); 1971 __ bl64_patchable((address)SharedRuntime::deopt_blob()->unpack(), 1972 relocInfo::runtime_call_type); 1973 assert(__ offset() - offset == (int) size_deopt_handler(), "must be fixed size"); 1974 __ end_a_stub(); 1975 1976 return offset; 1977 } 1978 1979 //============================================================================= 1980 1981 // Use a frame slots bias for frameless methods if accessing the stack. 1982 static int frame_slots_bias(int reg_enc, PhaseRegAlloc* ra_) { 1983 if (as_Register(reg_enc) == R1_SP) { 1984 return 0; // TODO: PPC port ra_->C->frame_slots_sp_bias_in_bytes(); 1985 } 1986 return 0; 1987 } 1988 1989 const bool Matcher::match_rule_supported(int opcode) { 1990 if (!has_match_rule(opcode)) 1991 return false; 1992 1993 switch (opcode) { 1994 case Op_SqrtD: 1995 return VM_Version::has_fsqrt(); 1996 case Op_CountLeadingZerosI: 1997 case Op_CountLeadingZerosL: 1998 case Op_CountTrailingZerosI: 1999 case Op_CountTrailingZerosL: 2000 if (!UseCountLeadingZerosInstructionsPPC64) 2001 return false; 2002 break; 2003 2004 case Op_PopCountI: 2005 case Op_PopCountL: 2006 return (UsePopCountInstruction && VM_Version::has_popcntw()); 2007 2008 case Op_StrComp: 2009 return SpecialStringCompareTo; 2010 case Op_StrEquals: 2011 return SpecialStringEquals; 2012 case Op_StrIndexOf: 2013 return SpecialStringIndexOf; 2014 case Op_StrIndexOfChar: 2015 return SpecialStringIndexOf; 2016 } 2017 2018 return true; // Per default match rules are supported. 2019 } 2020 2021 const bool Matcher::match_rule_supported_vector(int opcode, int vlen) { 2022 2023 // TODO 2024 // identify extra cases that we might want to provide match rules for 2025 // e.g. Op_ vector nodes and other intrinsics while guarding with vlen 2026 bool ret_value = match_rule_supported(opcode); 2027 // Add rules here. 2028 2029 return ret_value; // Per default match rules are supported. 2030 } 2031 2032 const bool Matcher::has_predicated_vectors(void) { 2033 return false; 2034 } 2035 2036 const int Matcher::float_pressure(int default_pressure_threshold) { 2037 return default_pressure_threshold; 2038 } 2039 2040 int Matcher::regnum_to_fpu_offset(int regnum) { 2041 // No user for this method? 2042 Unimplemented(); 2043 return 999; 2044 } 2045 2046 const bool Matcher::convL2FSupported(void) { 2047 // fcfids can do the conversion (>= Power7). 2048 // fcfid + frsp showed rounding problem when result should be 0x3f800001. 2049 return VM_Version::has_fcfids(); // False means that conversion is done by runtime call. 2050 } 2051 2052 // Vector width in bytes. 2053 const int Matcher::vector_width_in_bytes(BasicType bt) { 2054 assert(MaxVectorSize == 8, ""); 2055 return 8; 2056 } 2057 2058 // Vector ideal reg. 2059 const int Matcher::vector_ideal_reg(int size) { 2060 assert(MaxVectorSize == 8 && size == 8, ""); 2061 return Op_RegL; 2062 } 2063 2064 const int Matcher::vector_shift_count_ideal_reg(int size) { 2065 fatal("vector shift is not supported"); 2066 return Node::NotAMachineReg; 2067 } 2068 2069 // Limits on vector size (number of elements) loaded into vector. 2070 const int Matcher::max_vector_size(const BasicType bt) { 2071 assert(is_java_primitive(bt), "only primitive type vectors"); 2072 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2073 } 2074 2075 const int Matcher::min_vector_size(const BasicType bt) { 2076 return max_vector_size(bt); // Same as max. 2077 } 2078 2079 // PPC doesn't support misaligned vectors store/load. 2080 const bool Matcher::misaligned_vectors_ok() { 2081 return false; 2082 } 2083 2084 // PPC AES support not yet implemented 2085 const bool Matcher::pass_original_key_for_aes() { 2086 return false; 2087 } 2088 2089 // RETURNS: whether this branch offset is short enough that a short 2090 // branch can be used. 2091 // 2092 // If the platform does not provide any short branch variants, then 2093 // this method should return `false' for offset 0. 2094 // 2095 // `Compile::Fill_buffer' will decide on basis of this information 2096 // whether to do the pass `Compile::Shorten_branches' at all. 2097 // 2098 // And `Compile::Shorten_branches' will decide on basis of this 2099 // information whether to replace particular branch sites by short 2100 // ones. 2101 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 2102 // Is the offset within the range of a ppc64 pc relative branch? 2103 bool b; 2104 2105 const int safety_zone = 3 * BytesPerInstWord; 2106 b = Assembler::is_simm((offset<0 ? offset-safety_zone : offset+safety_zone), 2107 29 - 16 + 1 + 2); 2108 return b; 2109 } 2110 2111 const bool Matcher::isSimpleConstant64(jlong value) { 2112 // Probably always true, even if a temp register is required. 2113 return true; 2114 } 2115 /* TODO: PPC port 2116 // Make a new machine dependent decode node (with its operands). 2117 MachTypeNode *Matcher::make_decode_node() { 2118 assert(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0, 2119 "This method is only implemented for unscaled cOops mode so far"); 2120 MachTypeNode *decode = new decodeN_unscaledNode(); 2121 decode->set_opnd_array(0, new iRegPdstOper()); 2122 decode->set_opnd_array(1, new iRegNsrcOper()); 2123 return decode; 2124 } 2125 */ 2126 2127 // false => size gets scaled to BytesPerLong, ok. 2128 const bool Matcher::init_array_count_is_in_bytes = false; 2129 2130 // Use conditional move (CMOVL) on Power7. 2131 const int Matcher::long_cmove_cost() { return 0; } // this only makes long cmoves more expensive than int cmoves 2132 2133 // Suppress CMOVF. Conditional move available (sort of) on PPC64 only from P7 onwards. Not exploited yet. 2134 // fsel doesn't accept a condition register as input, so this would be slightly different. 2135 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 2136 2137 // Power6 requires postalloc expand (see block.cpp for description of postalloc expand). 2138 const bool Matcher::require_postalloc_expand = true; 2139 2140 // Do we need to mask the count passed to shift instructions or does 2141 // the cpu only look at the lower 5/6 bits anyway? 2142 // PowerPC requires masked shift counts. 2143 const bool Matcher::need_masked_shift_count = true; 2144 2145 // This affects two different things: 2146 // - how Decode nodes are matched 2147 // - how ImplicitNullCheck opportunities are recognized 2148 // If true, the matcher will try to remove all Decodes and match them 2149 // (as operands) into nodes. NullChecks are not prepared to deal with 2150 // Decodes by final_graph_reshaping(). 2151 // If false, final_graph_reshaping() forces the decode behind the Cmp 2152 // for a NullCheck. The matcher matches the Decode node into a register. 2153 // Implicit_null_check optimization moves the Decode along with the 2154 // memory operation back up before the NullCheck. 2155 bool Matcher::narrow_oop_use_complex_address() { 2156 // TODO: PPC port if (MatchDecodeNodes) return true; 2157 return false; 2158 } 2159 2160 bool Matcher::narrow_klass_use_complex_address() { 2161 NOT_LP64(ShouldNotCallThis()); 2162 assert(UseCompressedClassPointers, "only for compressed klass code"); 2163 // TODO: PPC port if (MatchDecodeNodes) return true; 2164 return false; 2165 } 2166 2167 // Is it better to copy float constants, or load them directly from memory? 2168 // Intel can load a float constant from a direct address, requiring no 2169 // extra registers. Most RISCs will have to materialize an address into a 2170 // register first, so they would do better to copy the constant from stack. 2171 const bool Matcher::rematerialize_float_constants = false; 2172 2173 // If CPU can load and store mis-aligned doubles directly then no fixup is 2174 // needed. Else we split the double into 2 integer pieces and move it 2175 // piece-by-piece. Only happens when passing doubles into C code as the 2176 // Java calling convention forces doubles to be aligned. 2177 const bool Matcher::misaligned_doubles_ok = true; 2178 2179 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) { 2180 Unimplemented(); 2181 } 2182 2183 // Advertise here if the CPU requires explicit rounding operations 2184 // to implement the UseStrictFP mode. 2185 const bool Matcher::strict_fp_requires_explicit_rounding = false; 2186 2187 // Do floats take an entire double register or just half? 2188 // 2189 // A float occupies a ppc64 double register. For the allocator, a 2190 // ppc64 double register appears as a pair of float registers. 2191 bool Matcher::float_in_double() { return true; } 2192 2193 // Do ints take an entire long register or just half? 2194 // The relevant question is how the int is callee-saved: 2195 // the whole long is written but de-opt'ing will have to extract 2196 // the relevant 32 bits. 2197 const bool Matcher::int_in_long = true; 2198 2199 // Constants for c2c and c calling conventions. 2200 2201 const MachRegisterNumbers iarg_reg[8] = { 2202 R3_num, R4_num, R5_num, R6_num, 2203 R7_num, R8_num, R9_num, R10_num 2204 }; 2205 2206 const MachRegisterNumbers farg_reg[13] = { 2207 F1_num, F2_num, F3_num, F4_num, 2208 F5_num, F6_num, F7_num, F8_num, 2209 F9_num, F10_num, F11_num, F12_num, 2210 F13_num 2211 }; 2212 2213 const int num_iarg_registers = sizeof(iarg_reg) / sizeof(iarg_reg[0]); 2214 2215 const int num_farg_registers = sizeof(farg_reg) / sizeof(farg_reg[0]); 2216 2217 // Return whether or not this register is ever used as an argument. This 2218 // function is used on startup to build the trampoline stubs in generateOptoStub. 2219 // Registers not mentioned will be killed by the VM call in the trampoline, and 2220 // arguments in those registers not be available to the callee. 2221 bool Matcher::can_be_java_arg(int reg) { 2222 // We return true for all registers contained in iarg_reg[] and 2223 // farg_reg[] and their virtual halves. 2224 // We must include the virtual halves in order to get STDs and LDs 2225 // instead of STWs and LWs in the trampoline stubs. 2226 2227 if ( reg == R3_num || reg == R3_H_num 2228 || reg == R4_num || reg == R4_H_num 2229 || reg == R5_num || reg == R5_H_num 2230 || reg == R6_num || reg == R6_H_num 2231 || reg == R7_num || reg == R7_H_num 2232 || reg == R8_num || reg == R8_H_num 2233 || reg == R9_num || reg == R9_H_num 2234 || reg == R10_num || reg == R10_H_num) 2235 return true; 2236 2237 if ( reg == F1_num || reg == F1_H_num 2238 || reg == F2_num || reg == F2_H_num 2239 || reg == F3_num || reg == F3_H_num 2240 || reg == F4_num || reg == F4_H_num 2241 || reg == F5_num || reg == F5_H_num 2242 || reg == F6_num || reg == F6_H_num 2243 || reg == F7_num || reg == F7_H_num 2244 || reg == F8_num || reg == F8_H_num 2245 || reg == F9_num || reg == F9_H_num 2246 || reg == F10_num || reg == F10_H_num 2247 || reg == F11_num || reg == F11_H_num 2248 || reg == F12_num || reg == F12_H_num 2249 || reg == F13_num || reg == F13_H_num) 2250 return true; 2251 2252 return false; 2253 } 2254 2255 bool Matcher::is_spillable_arg(int reg) { 2256 return can_be_java_arg(reg); 2257 } 2258 2259 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2260 return false; 2261 } 2262 2263 // Register for DIVI projection of divmodI. 2264 RegMask Matcher::divI_proj_mask() { 2265 ShouldNotReachHere(); 2266 return RegMask(); 2267 } 2268 2269 // Register for MODI projection of divmodI. 2270 RegMask Matcher::modI_proj_mask() { 2271 ShouldNotReachHere(); 2272 return RegMask(); 2273 } 2274 2275 // Register for DIVL projection of divmodL. 2276 RegMask Matcher::divL_proj_mask() { 2277 ShouldNotReachHere(); 2278 return RegMask(); 2279 } 2280 2281 // Register for MODL projection of divmodL. 2282 RegMask Matcher::modL_proj_mask() { 2283 ShouldNotReachHere(); 2284 return RegMask(); 2285 } 2286 2287 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2288 return RegMask(); 2289 } 2290 2291 const bool Matcher::convi2l_type_required = true; 2292 2293 %} 2294 2295 //----------ENCODING BLOCK----------------------------------------------------- 2296 // This block specifies the encoding classes used by the compiler to output 2297 // byte streams. Encoding classes are parameterized macros used by 2298 // Machine Instruction Nodes in order to generate the bit encoding of the 2299 // instruction. Operands specify their base encoding interface with the 2300 // interface keyword. There are currently supported four interfaces, 2301 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an 2302 // operand to generate a function which returns its register number when 2303 // queried. CONST_INTER causes an operand to generate a function which 2304 // returns the value of the constant when queried. MEMORY_INTER causes an 2305 // operand to generate four functions which return the Base Register, the 2306 // Index Register, the Scale Value, and the Offset Value of the operand when 2307 // queried. COND_INTER causes an operand to generate six functions which 2308 // return the encoding code (ie - encoding bits for the instruction) 2309 // associated with each basic boolean condition for a conditional instruction. 2310 // 2311 // Instructions specify two basic values for encoding. Again, a function 2312 // is available to check if the constant displacement is an oop. They use the 2313 // ins_encode keyword to specify their encoding classes (which must be 2314 // a sequence of enc_class names, and their parameters, specified in 2315 // the encoding block), and they use the 2316 // opcode keyword to specify, in order, their primary, secondary, and 2317 // tertiary opcode. Only the opcode sections which a particular instruction 2318 // needs for encoding need to be specified. 2319 encode %{ 2320 enc_class enc_unimplemented %{ 2321 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2322 MacroAssembler _masm(&cbuf); 2323 __ unimplemented("Unimplemented mach node encoding in AD file.", 13); 2324 %} 2325 2326 enc_class enc_untested %{ 2327 #ifdef ASSERT 2328 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2329 MacroAssembler _masm(&cbuf); 2330 __ untested("Untested mach node encoding in AD file."); 2331 #else 2332 // TODO: PPC port $archOpcode(ppc64Opcode_none); 2333 #endif 2334 %} 2335 2336 enc_class enc_lbz(iRegIdst dst, memory mem) %{ 2337 // TODO: PPC port $archOpcode(ppc64Opcode_lbz); 2338 MacroAssembler _masm(&cbuf); 2339 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2340 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2341 %} 2342 2343 // Load acquire. 2344 enc_class enc_lbz_ac(iRegIdst dst, memory mem) %{ 2345 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2346 MacroAssembler _masm(&cbuf); 2347 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2348 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2349 __ twi_0($dst$$Register); 2350 __ isync(); 2351 %} 2352 2353 enc_class enc_lhz(iRegIdst dst, memory mem) %{ 2354 // TODO: PPC port $archOpcode(ppc64Opcode_lhz); 2355 2356 MacroAssembler _masm(&cbuf); 2357 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2358 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2359 %} 2360 2361 // Load acquire. 2362 enc_class enc_lhz_ac(iRegIdst dst, memory mem) %{ 2363 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2364 2365 MacroAssembler _masm(&cbuf); 2366 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2367 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2368 __ twi_0($dst$$Register); 2369 __ isync(); 2370 %} 2371 2372 enc_class enc_lwz(iRegIdst dst, memory mem) %{ 2373 // TODO: PPC port $archOpcode(ppc64Opcode_lwz); 2374 2375 MacroAssembler _masm(&cbuf); 2376 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2377 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2378 %} 2379 2380 // Load acquire. 2381 enc_class enc_lwz_ac(iRegIdst dst, memory mem) %{ 2382 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2383 2384 MacroAssembler _masm(&cbuf); 2385 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2386 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2387 __ twi_0($dst$$Register); 2388 __ isync(); 2389 %} 2390 2391 enc_class enc_ld(iRegLdst dst, memoryAlg4 mem) %{ 2392 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2393 MacroAssembler _masm(&cbuf); 2394 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2395 // Operand 'ds' requires 4-alignment. 2396 assert((Idisp & 0x3) == 0, "unaligned offset"); 2397 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2398 %} 2399 2400 // Load acquire. 2401 enc_class enc_ld_ac(iRegLdst dst, memoryAlg4 mem) %{ 2402 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2403 MacroAssembler _masm(&cbuf); 2404 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2405 // Operand 'ds' requires 4-alignment. 2406 assert((Idisp & 0x3) == 0, "unaligned offset"); 2407 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2408 __ twi_0($dst$$Register); 2409 __ isync(); 2410 %} 2411 2412 enc_class enc_lfd(RegF dst, memory mem) %{ 2413 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 2414 MacroAssembler _masm(&cbuf); 2415 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2416 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 2417 %} 2418 2419 enc_class enc_load_long_constL(iRegLdst dst, immL src, iRegLdst toc) %{ 2420 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2421 2422 MacroAssembler _masm(&cbuf); 2423 int toc_offset = 0; 2424 2425 address const_toc_addr; 2426 // Create a non-oop constant, no relocation needed. 2427 // If it is an IC, it has a virtual_call_Relocation. 2428 const_toc_addr = __ long_constant((jlong)$src$$constant); 2429 if (const_toc_addr == NULL) { 2430 ciEnv::current()->record_out_of_memory_failure(); 2431 return; 2432 } 2433 2434 // Get the constant's TOC offset. 2435 toc_offset = __ offset_to_method_toc(const_toc_addr); 2436 2437 // Keep the current instruction offset in mind. 2438 ((loadConLNode*)this)->_cbuf_insts_offset = __ offset(); 2439 2440 __ ld($dst$$Register, toc_offset, $toc$$Register); 2441 %} 2442 2443 enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{ 2444 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 2445 2446 MacroAssembler _masm(&cbuf); 2447 2448 if (!ra_->C->in_scratch_emit_size()) { 2449 address const_toc_addr; 2450 // Create a non-oop constant, no relocation needed. 2451 // If it is an IC, it has a virtual_call_Relocation. 2452 const_toc_addr = __ long_constant((jlong)$src$$constant); 2453 if (const_toc_addr == NULL) { 2454 ciEnv::current()->record_out_of_memory_failure(); 2455 return; 2456 } 2457 2458 // Get the constant's TOC offset. 2459 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 2460 // Store the toc offset of the constant. 2461 ((loadConL_hiNode*)this)->_const_toc_offset = toc_offset; 2462 2463 // Also keep the current instruction offset in mind. 2464 ((loadConL_hiNode*)this)->_cbuf_insts_offset = __ offset(); 2465 } 2466 2467 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 2468 %} 2469 2470 %} // encode 2471 2472 source %{ 2473 2474 typedef struct { 2475 loadConL_hiNode *_large_hi; 2476 loadConL_loNode *_large_lo; 2477 loadConLNode *_small; 2478 MachNode *_last; 2479 } loadConLNodesTuple; 2480 2481 loadConLNodesTuple loadConLNodesTuple_create(PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2482 OptoReg::Name reg_second, OptoReg::Name reg_first) { 2483 loadConLNodesTuple nodes; 2484 2485 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2486 if (large_constant_pool) { 2487 // Create new nodes. 2488 loadConL_hiNode *m1 = new loadConL_hiNode(); 2489 loadConL_loNode *m2 = new loadConL_loNode(); 2490 2491 // inputs for new nodes 2492 m1->add_req(NULL, toc); 2493 m2->add_req(NULL, m1); 2494 2495 // operands for new nodes 2496 m1->_opnds[0] = new iRegLdstOper(); // dst 2497 m1->_opnds[1] = immSrc; // src 2498 m1->_opnds[2] = new iRegPdstOper(); // toc 2499 m2->_opnds[0] = new iRegLdstOper(); // dst 2500 m2->_opnds[1] = immSrc; // src 2501 m2->_opnds[2] = new iRegLdstOper(); // base 2502 2503 // Initialize ins_attrib TOC fields. 2504 m1->_const_toc_offset = -1; 2505 m2->_const_toc_offset_hi_node = m1; 2506 2507 // Initialize ins_attrib instruction offset. 2508 m1->_cbuf_insts_offset = -1; 2509 2510 // register allocation for new nodes 2511 ra_->set_pair(m1->_idx, reg_second, reg_first); 2512 ra_->set_pair(m2->_idx, reg_second, reg_first); 2513 2514 // Create result. 2515 nodes._large_hi = m1; 2516 nodes._large_lo = m2; 2517 nodes._small = NULL; 2518 nodes._last = nodes._large_lo; 2519 assert(m2->bottom_type()->isa_long(), "must be long"); 2520 } else { 2521 loadConLNode *m2 = new loadConLNode(); 2522 2523 // inputs for new nodes 2524 m2->add_req(NULL, toc); 2525 2526 // operands for new nodes 2527 m2->_opnds[0] = new iRegLdstOper(); // dst 2528 m2->_opnds[1] = immSrc; // src 2529 m2->_opnds[2] = new iRegPdstOper(); // toc 2530 2531 // Initialize ins_attrib instruction offset. 2532 m2->_cbuf_insts_offset = -1; 2533 2534 // register allocation for new nodes 2535 ra_->set_pair(m2->_idx, reg_second, reg_first); 2536 2537 // Create result. 2538 nodes._large_hi = NULL; 2539 nodes._large_lo = NULL; 2540 nodes._small = m2; 2541 nodes._last = nodes._small; 2542 assert(m2->bottom_type()->isa_long(), "must be long"); 2543 } 2544 2545 return nodes; 2546 } 2547 2548 %} // source 2549 2550 encode %{ 2551 // Postalloc expand emitter for loading a long constant from the method's TOC. 2552 // Enc_class needed as consttanttablebase is not supported by postalloc 2553 // expand. 2554 enc_class postalloc_expand_load_long_constant(iRegLdst dst, immL src, iRegLdst toc) %{ 2555 // Create new nodes. 2556 loadConLNodesTuple loadConLNodes = 2557 loadConLNodesTuple_create(ra_, n_toc, op_src, 2558 ra_->get_reg_second(this), ra_->get_reg_first(this)); 2559 2560 // Push new nodes. 2561 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 2562 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 2563 2564 // some asserts 2565 assert(nodes->length() >= 1, "must have created at least 1 node"); 2566 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 2567 %} 2568 2569 enc_class enc_load_long_constP(iRegLdst dst, immP src, iRegLdst toc) %{ 2570 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2571 2572 MacroAssembler _masm(&cbuf); 2573 int toc_offset = 0; 2574 2575 intptr_t val = $src$$constant; 2576 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 2577 address const_toc_addr; 2578 if (constant_reloc == relocInfo::oop_type) { 2579 // Create an oop constant and a corresponding relocation. 2580 AddressLiteral a = __ allocate_oop_address((jobject)val); 2581 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2582 __ relocate(a.rspec()); 2583 } else if (constant_reloc == relocInfo::metadata_type) { 2584 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 2585 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2586 __ relocate(a.rspec()); 2587 } else { 2588 // Create a non-oop constant, no relocation needed. 2589 const_toc_addr = __ long_constant((jlong)$src$$constant); 2590 } 2591 2592 if (const_toc_addr == NULL) { 2593 ciEnv::current()->record_out_of_memory_failure(); 2594 return; 2595 } 2596 // Get the constant's TOC offset. 2597 toc_offset = __ offset_to_method_toc(const_toc_addr); 2598 2599 __ ld($dst$$Register, toc_offset, $toc$$Register); 2600 %} 2601 2602 enc_class enc_load_long_constP_hi(iRegLdst dst, immP src, iRegLdst toc) %{ 2603 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 2604 2605 MacroAssembler _masm(&cbuf); 2606 if (!ra_->C->in_scratch_emit_size()) { 2607 intptr_t val = $src$$constant; 2608 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 2609 address const_toc_addr; 2610 if (constant_reloc == relocInfo::oop_type) { 2611 // Create an oop constant and a corresponding relocation. 2612 AddressLiteral a = __ allocate_oop_address((jobject)val); 2613 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2614 __ relocate(a.rspec()); 2615 } else if (constant_reloc == relocInfo::metadata_type) { 2616 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 2617 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2618 __ relocate(a.rspec()); 2619 } else { // non-oop pointers, e.g. card mark base, heap top 2620 // Create a non-oop constant, no relocation needed. 2621 const_toc_addr = __ long_constant((jlong)$src$$constant); 2622 } 2623 2624 if (const_toc_addr == NULL) { 2625 ciEnv::current()->record_out_of_memory_failure(); 2626 return; 2627 } 2628 // Get the constant's TOC offset. 2629 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 2630 // Store the toc offset of the constant. 2631 ((loadConP_hiNode*)this)->_const_toc_offset = toc_offset; 2632 } 2633 2634 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 2635 %} 2636 2637 // Postalloc expand emitter for loading a ptr constant from the method's TOC. 2638 // Enc_class needed as consttanttablebase is not supported by postalloc 2639 // expand. 2640 enc_class postalloc_expand_load_ptr_constant(iRegPdst dst, immP src, iRegLdst toc) %{ 2641 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2642 if (large_constant_pool) { 2643 // Create new nodes. 2644 loadConP_hiNode *m1 = new loadConP_hiNode(); 2645 loadConP_loNode *m2 = new loadConP_loNode(); 2646 2647 // inputs for new nodes 2648 m1->add_req(NULL, n_toc); 2649 m2->add_req(NULL, m1); 2650 2651 // operands for new nodes 2652 m1->_opnds[0] = new iRegPdstOper(); // dst 2653 m1->_opnds[1] = op_src; // src 2654 m1->_opnds[2] = new iRegPdstOper(); // toc 2655 m2->_opnds[0] = new iRegPdstOper(); // dst 2656 m2->_opnds[1] = op_src; // src 2657 m2->_opnds[2] = new iRegLdstOper(); // base 2658 2659 // Initialize ins_attrib TOC fields. 2660 m1->_const_toc_offset = -1; 2661 m2->_const_toc_offset_hi_node = m1; 2662 2663 // Register allocation for new nodes. 2664 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2665 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2666 2667 nodes->push(m1); 2668 nodes->push(m2); 2669 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 2670 } else { 2671 loadConPNode *m2 = new loadConPNode(); 2672 2673 // inputs for new nodes 2674 m2->add_req(NULL, n_toc); 2675 2676 // operands for new nodes 2677 m2->_opnds[0] = new iRegPdstOper(); // dst 2678 m2->_opnds[1] = op_src; // src 2679 m2->_opnds[2] = new iRegPdstOper(); // toc 2680 2681 // Register allocation for new nodes. 2682 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2683 2684 nodes->push(m2); 2685 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 2686 } 2687 %} 2688 2689 // Enc_class needed as consttanttablebase is not supported by postalloc 2690 // expand. 2691 enc_class postalloc_expand_load_float_constant(regF dst, immF src, iRegLdst toc) %{ 2692 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2693 2694 MachNode *m2; 2695 if (large_constant_pool) { 2696 m2 = new loadConFCompNode(); 2697 } else { 2698 m2 = new loadConFNode(); 2699 } 2700 // inputs for new nodes 2701 m2->add_req(NULL, n_toc); 2702 2703 // operands for new nodes 2704 m2->_opnds[0] = op_dst; 2705 m2->_opnds[1] = op_src; 2706 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 2707 2708 // register allocation for new nodes 2709 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2710 nodes->push(m2); 2711 %} 2712 2713 // Enc_class needed as consttanttablebase is not supported by postalloc 2714 // expand. 2715 enc_class postalloc_expand_load_double_constant(regD dst, immD src, iRegLdst toc) %{ 2716 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2717 2718 MachNode *m2; 2719 if (large_constant_pool) { 2720 m2 = new loadConDCompNode(); 2721 } else { 2722 m2 = new loadConDNode(); 2723 } 2724 // inputs for new nodes 2725 m2->add_req(NULL, n_toc); 2726 2727 // operands for new nodes 2728 m2->_opnds[0] = op_dst; 2729 m2->_opnds[1] = op_src; 2730 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 2731 2732 // register allocation for new nodes 2733 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2734 nodes->push(m2); 2735 %} 2736 2737 enc_class enc_stw(iRegIsrc src, memory mem) %{ 2738 // TODO: PPC port $archOpcode(ppc64Opcode_stw); 2739 MacroAssembler _masm(&cbuf); 2740 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2741 __ stw($src$$Register, Idisp, $mem$$base$$Register); 2742 %} 2743 2744 enc_class enc_std(iRegIsrc src, memoryAlg4 mem) %{ 2745 // TODO: PPC port $archOpcode(ppc64Opcode_std); 2746 MacroAssembler _masm(&cbuf); 2747 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2748 // Operand 'ds' requires 4-alignment. 2749 assert((Idisp & 0x3) == 0, "unaligned offset"); 2750 __ std($src$$Register, Idisp, $mem$$base$$Register); 2751 %} 2752 2753 enc_class enc_stfs(RegF src, memory mem) %{ 2754 // TODO: PPC port $archOpcode(ppc64Opcode_stfs); 2755 MacroAssembler _masm(&cbuf); 2756 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2757 __ stfs($src$$FloatRegister, Idisp, $mem$$base$$Register); 2758 %} 2759 2760 enc_class enc_stfd(RegF src, memory mem) %{ 2761 // TODO: PPC port $archOpcode(ppc64Opcode_stfd); 2762 MacroAssembler _masm(&cbuf); 2763 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2764 __ stfd($src$$FloatRegister, Idisp, $mem$$base$$Register); 2765 %} 2766 2767 // Use release_store for card-marking to ensure that previous 2768 // oop-stores are visible before the card-mark change. 2769 enc_class enc_cms_card_mark(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 2770 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2771 // FIXME: Implement this as a cmove and use a fixed condition code 2772 // register which is written on every transition to compiled code, 2773 // e.g. in call-stub and when returning from runtime stubs. 2774 // 2775 // Proposed code sequence for the cmove implementation: 2776 // 2777 // Label skip_release; 2778 // __ beq(CCRfixed, skip_release); 2779 // __ release(); 2780 // __ bind(skip_release); 2781 // __ stb(card mark); 2782 2783 MacroAssembler _masm(&cbuf); 2784 Label skip_storestore; 2785 2786 #if 0 // TODO: PPC port 2787 // Check CMSCollectorCardTableModRefBSExt::_requires_release and do the 2788 // StoreStore barrier conditionally. 2789 __ lwz(R0, 0, $releaseFieldAddr$$Register); 2790 __ cmpwi($crx$$CondRegister, R0, 0); 2791 __ beq_predict_taken($crx$$CondRegister, skip_storestore); 2792 #endif 2793 __ li(R0, 0); 2794 __ membar(Assembler::StoreStore); 2795 #if 0 // TODO: PPC port 2796 __ bind(skip_storestore); 2797 #endif 2798 2799 // Do the store. 2800 if ($mem$$index == 0) { 2801 __ stb(R0, $mem$$disp, $mem$$base$$Register); 2802 } else { 2803 assert(0 == $mem$$disp, "no displacement possible with indexed load/stores on ppc"); 2804 __ stbx(R0, $mem$$base$$Register, $mem$$index$$Register); 2805 } 2806 %} 2807 2808 enc_class postalloc_expand_encode_oop(iRegNdst dst, iRegPdst src, flagsReg crx) %{ 2809 2810 if (VM_Version::has_isel()) { 2811 // use isel instruction with Power 7 2812 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 2813 encodeP_subNode *n_sub_base = new encodeP_subNode(); 2814 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 2815 cond_set_0_oopNode *n_cond_set = new cond_set_0_oopNode(); 2816 2817 n_compare->add_req(n_region, n_src); 2818 n_compare->_opnds[0] = op_crx; 2819 n_compare->_opnds[1] = op_src; 2820 n_compare->_opnds[2] = new immL16Oper(0); 2821 2822 n_sub_base->add_req(n_region, n_src); 2823 n_sub_base->_opnds[0] = op_dst; 2824 n_sub_base->_opnds[1] = op_src; 2825 n_sub_base->_bottom_type = _bottom_type; 2826 2827 n_shift->add_req(n_region, n_sub_base); 2828 n_shift->_opnds[0] = op_dst; 2829 n_shift->_opnds[1] = op_dst; 2830 n_shift->_bottom_type = _bottom_type; 2831 2832 n_cond_set->add_req(n_region, n_compare, n_shift); 2833 n_cond_set->_opnds[0] = op_dst; 2834 n_cond_set->_opnds[1] = op_crx; 2835 n_cond_set->_opnds[2] = op_dst; 2836 n_cond_set->_bottom_type = _bottom_type; 2837 2838 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 2839 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2840 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2841 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2842 2843 nodes->push(n_compare); 2844 nodes->push(n_sub_base); 2845 nodes->push(n_shift); 2846 nodes->push(n_cond_set); 2847 2848 } else { 2849 // before Power 7 2850 moveRegNode *n_move = new moveRegNode(); 2851 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 2852 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 2853 cond_sub_baseNode *n_sub_base = new cond_sub_baseNode(); 2854 2855 n_move->add_req(n_region, n_src); 2856 n_move->_opnds[0] = op_dst; 2857 n_move->_opnds[1] = op_src; 2858 ra_->set_oop(n_move, true); // Until here, 'n_move' still produces an oop. 2859 2860 n_compare->add_req(n_region, n_src); 2861 n_compare->add_prec(n_move); 2862 2863 n_compare->_opnds[0] = op_crx; 2864 n_compare->_opnds[1] = op_src; 2865 n_compare->_opnds[2] = new immL16Oper(0); 2866 2867 n_sub_base->add_req(n_region, n_compare, n_src); 2868 n_sub_base->_opnds[0] = op_dst; 2869 n_sub_base->_opnds[1] = op_crx; 2870 n_sub_base->_opnds[2] = op_src; 2871 n_sub_base->_bottom_type = _bottom_type; 2872 2873 n_shift->add_req(n_region, n_sub_base); 2874 n_shift->_opnds[0] = op_dst; 2875 n_shift->_opnds[1] = op_dst; 2876 n_shift->_bottom_type = _bottom_type; 2877 2878 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2879 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 2880 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2881 ra_->set_pair(n_move->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2882 2883 nodes->push(n_move); 2884 nodes->push(n_compare); 2885 nodes->push(n_sub_base); 2886 nodes->push(n_shift); 2887 } 2888 2889 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 2890 %} 2891 2892 enc_class postalloc_expand_encode_oop_not_null(iRegNdst dst, iRegPdst src) %{ 2893 2894 encodeP_subNode *n1 = new encodeP_subNode(); 2895 n1->add_req(n_region, n_src); 2896 n1->_opnds[0] = op_dst; 2897 n1->_opnds[1] = op_src; 2898 n1->_bottom_type = _bottom_type; 2899 2900 encodeP_shiftNode *n2 = new encodeP_shiftNode(); 2901 n2->add_req(n_region, n1); 2902 n2->_opnds[0] = op_dst; 2903 n2->_opnds[1] = op_dst; 2904 n2->_bottom_type = _bottom_type; 2905 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2906 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2907 2908 nodes->push(n1); 2909 nodes->push(n2); 2910 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 2911 %} 2912 2913 enc_class postalloc_expand_decode_oop(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 2914 decodeN_shiftNode *n_shift = new decodeN_shiftNode(); 2915 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 2916 2917 n_compare->add_req(n_region, n_src); 2918 n_compare->_opnds[0] = op_crx; 2919 n_compare->_opnds[1] = op_src; 2920 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 2921 2922 n_shift->add_req(n_region, n_src); 2923 n_shift->_opnds[0] = op_dst; 2924 n_shift->_opnds[1] = op_src; 2925 n_shift->_bottom_type = _bottom_type; 2926 2927 if (VM_Version::has_isel()) { 2928 // use isel instruction with Power 7 2929 2930 decodeN_addNode *n_add_base = new decodeN_addNode(); 2931 n_add_base->add_req(n_region, n_shift); 2932 n_add_base->_opnds[0] = op_dst; 2933 n_add_base->_opnds[1] = op_dst; 2934 n_add_base->_bottom_type = _bottom_type; 2935 2936 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 2937 n_cond_set->add_req(n_region, n_compare, n_add_base); 2938 n_cond_set->_opnds[0] = op_dst; 2939 n_cond_set->_opnds[1] = op_crx; 2940 n_cond_set->_opnds[2] = op_dst; 2941 n_cond_set->_bottom_type = _bottom_type; 2942 2943 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 2944 ra_->set_oop(n_cond_set, true); 2945 2946 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2947 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 2948 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2949 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2950 2951 nodes->push(n_compare); 2952 nodes->push(n_shift); 2953 nodes->push(n_add_base); 2954 nodes->push(n_cond_set); 2955 2956 } else { 2957 // before Power 7 2958 cond_add_baseNode *n_add_base = new cond_add_baseNode(); 2959 2960 n_add_base->add_req(n_region, n_compare, n_shift); 2961 n_add_base->_opnds[0] = op_dst; 2962 n_add_base->_opnds[1] = op_crx; 2963 n_add_base->_opnds[2] = op_dst; 2964 n_add_base->_bottom_type = _bottom_type; 2965 2966 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 2967 ra_->set_oop(n_add_base, true); 2968 2969 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2970 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 2971 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2972 2973 nodes->push(n_compare); 2974 nodes->push(n_shift); 2975 nodes->push(n_add_base); 2976 } 2977 %} 2978 2979 enc_class postalloc_expand_decode_oop_not_null(iRegPdst dst, iRegNsrc src) %{ 2980 decodeN_shiftNode *n1 = new decodeN_shiftNode(); 2981 n1->add_req(n_region, n_src); 2982 n1->_opnds[0] = op_dst; 2983 n1->_opnds[1] = op_src; 2984 n1->_bottom_type = _bottom_type; 2985 2986 decodeN_addNode *n2 = new decodeN_addNode(); 2987 n2->add_req(n_region, n1); 2988 n2->_opnds[0] = op_dst; 2989 n2->_opnds[1] = op_dst; 2990 n2->_bottom_type = _bottom_type; 2991 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2992 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2993 2994 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 2995 ra_->set_oop(n2, true); 2996 2997 nodes->push(n1); 2998 nodes->push(n2); 2999 %} 3000 3001 enc_class enc_cmove_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src, cmpOp cmp) %{ 3002 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3003 3004 MacroAssembler _masm(&cbuf); 3005 int cc = $cmp$$cmpcode; 3006 int flags_reg = $crx$$reg; 3007 Label done; 3008 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3009 // Branch if not (cmp crx). 3010 __ bc(cc_to_inverse_boint(cc), cc_to_biint(cc, flags_reg), done); 3011 __ mr($dst$$Register, $src$$Register); 3012 // TODO PPC port __ endgroup_if_needed(_size == 12); 3013 __ bind(done); 3014 %} 3015 3016 enc_class enc_cmove_imm(iRegIdst dst, flagsRegSrc crx, immI16 src, cmpOp cmp) %{ 3017 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3018 3019 MacroAssembler _masm(&cbuf); 3020 Label done; 3021 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3022 // Branch if not (cmp crx). 3023 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 3024 __ li($dst$$Register, $src$$constant); 3025 // TODO PPC port __ endgroup_if_needed(_size == 12); 3026 __ bind(done); 3027 %} 3028 3029 // This enc_class is needed so that scheduler gets proper 3030 // input mapping for latency computation. 3031 enc_class enc_andc(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 3032 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 3033 MacroAssembler _masm(&cbuf); 3034 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 3035 %} 3036 3037 enc_class enc_convI2B_regI__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3038 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3039 3040 MacroAssembler _masm(&cbuf); 3041 3042 Label done; 3043 __ cmpwi($crx$$CondRegister, $src$$Register, 0); 3044 __ li($dst$$Register, $zero$$constant); 3045 __ beq($crx$$CondRegister, done); 3046 __ li($dst$$Register, $notzero$$constant); 3047 __ bind(done); 3048 %} 3049 3050 enc_class enc_convP2B_regP__cmove(iRegIdst dst, iRegPsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3051 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3052 3053 MacroAssembler _masm(&cbuf); 3054 3055 Label done; 3056 __ cmpdi($crx$$CondRegister, $src$$Register, 0); 3057 __ li($dst$$Register, $zero$$constant); 3058 __ beq($crx$$CondRegister, done); 3059 __ li($dst$$Register, $notzero$$constant); 3060 __ bind(done); 3061 %} 3062 3063 enc_class enc_cmove_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL mem ) %{ 3064 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3065 3066 MacroAssembler _masm(&cbuf); 3067 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3068 Label done; 3069 __ bso($crx$$CondRegister, done); 3070 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 3071 // TODO PPC port __ endgroup_if_needed(_size == 12); 3072 __ bind(done); 3073 %} 3074 3075 enc_class enc_bc(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3076 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3077 3078 MacroAssembler _masm(&cbuf); 3079 Label d; // dummy 3080 __ bind(d); 3081 Label* p = ($lbl$$label); 3082 // `p' is `NULL' when this encoding class is used only to 3083 // determine the size of the encoded instruction. 3084 Label& l = (NULL == p)? d : *(p); 3085 int cc = $cmp$$cmpcode; 3086 int flags_reg = $crx$$reg; 3087 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3088 int bhint = Assembler::bhintNoHint; 3089 3090 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3091 if (_prob <= PROB_NEVER) { 3092 bhint = Assembler::bhintIsNotTaken; 3093 } else if (_prob >= PROB_ALWAYS) { 3094 bhint = Assembler::bhintIsTaken; 3095 } 3096 } 3097 3098 __ bc(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3099 cc_to_biint(cc, flags_reg), 3100 l); 3101 %} 3102 3103 enc_class enc_bc_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3104 // The scheduler doesn't know about branch shortening, so we set the opcode 3105 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3106 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3107 3108 MacroAssembler _masm(&cbuf); 3109 Label d; // dummy 3110 __ bind(d); 3111 Label* p = ($lbl$$label); 3112 // `p' is `NULL' when this encoding class is used only to 3113 // determine the size of the encoded instruction. 3114 Label& l = (NULL == p)? d : *(p); 3115 int cc = $cmp$$cmpcode; 3116 int flags_reg = $crx$$reg; 3117 int bhint = Assembler::bhintNoHint; 3118 3119 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3120 if (_prob <= PROB_NEVER) { 3121 bhint = Assembler::bhintIsNotTaken; 3122 } else if (_prob >= PROB_ALWAYS) { 3123 bhint = Assembler::bhintIsTaken; 3124 } 3125 } 3126 3127 // Tell the conditional far branch to optimize itself when being relocated. 3128 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3129 cc_to_biint(cc, flags_reg), 3130 l, 3131 MacroAssembler::bc_far_optimize_on_relocate); 3132 %} 3133 3134 // Branch used with Power6 scheduling (can be shortened without changing the node). 3135 enc_class enc_bc_short_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3136 // The scheduler doesn't know about branch shortening, so we set the opcode 3137 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3138 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3139 3140 MacroAssembler _masm(&cbuf); 3141 Label d; // dummy 3142 __ bind(d); 3143 Label* p = ($lbl$$label); 3144 // `p' is `NULL' when this encoding class is used only to 3145 // determine the size of the encoded instruction. 3146 Label& l = (NULL == p)? d : *(p); 3147 int cc = $cmp$$cmpcode; 3148 int flags_reg = $crx$$reg; 3149 int bhint = Assembler::bhintNoHint; 3150 3151 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3152 if (_prob <= PROB_NEVER) { 3153 bhint = Assembler::bhintIsNotTaken; 3154 } else if (_prob >= PROB_ALWAYS) { 3155 bhint = Assembler::bhintIsTaken; 3156 } 3157 } 3158 3159 #if 0 // TODO: PPC port 3160 if (_size == 8) { 3161 // Tell the conditional far branch to optimize itself when being relocated. 3162 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3163 cc_to_biint(cc, flags_reg), 3164 l, 3165 MacroAssembler::bc_far_optimize_on_relocate); 3166 } else { 3167 __ bc (Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3168 cc_to_biint(cc, flags_reg), 3169 l); 3170 } 3171 #endif 3172 Unimplemented(); 3173 %} 3174 3175 // Postalloc expand emitter for loading a replicatef float constant from 3176 // the method's TOC. 3177 // Enc_class needed as consttanttablebase is not supported by postalloc 3178 // expand. 3179 enc_class postalloc_expand_load_replF_constant(iRegLdst dst, immF src, iRegLdst toc) %{ 3180 // Create new nodes. 3181 3182 // Make an operand with the bit pattern to load as float. 3183 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3184 3185 loadConLNodesTuple loadConLNodes = 3186 loadConLNodesTuple_create(ra_, n_toc, op_repl, 3187 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3188 3189 // Push new nodes. 3190 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 3191 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 3192 3193 assert(nodes->length() >= 1, "must have created at least 1 node"); 3194 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 3195 %} 3196 3197 // This enc_class is needed so that scheduler gets proper 3198 // input mapping for latency computation. 3199 enc_class enc_poll(immI dst, iRegLdst poll) %{ 3200 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 3201 // Fake operand dst needed for PPC scheduler. 3202 assert($dst$$constant == 0x0, "dst must be 0x0"); 3203 3204 MacroAssembler _masm(&cbuf); 3205 // Mark the code position where the load from the safepoint 3206 // polling page was emitted as relocInfo::poll_type. 3207 __ relocate(relocInfo::poll_type); 3208 __ load_from_polling_page($poll$$Register); 3209 %} 3210 3211 // A Java static call or a runtime call. 3212 // 3213 // Branch-and-link relative to a trampoline. 3214 // The trampoline loads the target address and does a long branch to there. 3215 // In case we call java, the trampoline branches to a interpreter_stub 3216 // which loads the inline cache and the real call target from the constant pool. 3217 // 3218 // This basically looks like this: 3219 // 3220 // >>>> consts -+ -+ 3221 // | |- offset1 3222 // [call target1] | <-+ 3223 // [IC cache] |- offset2 3224 // [call target2] <--+ 3225 // 3226 // <<<< consts 3227 // >>>> insts 3228 // 3229 // bl offset16 -+ -+ ??? // How many bits available? 3230 // | | 3231 // <<<< insts | | 3232 // >>>> stubs | | 3233 // | |- trampoline_stub_Reloc 3234 // trampoline stub: | <-+ 3235 // r2 = toc | 3236 // r2 = [r2 + offset1] | // Load call target1 from const section 3237 // mtctr r2 | 3238 // bctr |- static_stub_Reloc 3239 // comp_to_interp_stub: <---+ 3240 // r1 = toc 3241 // ICreg = [r1 + IC_offset] // Load IC from const section 3242 // r1 = [r1 + offset2] // Load call target2 from const section 3243 // mtctr r1 3244 // bctr 3245 // 3246 // <<<< stubs 3247 // 3248 // The call instruction in the code either 3249 // - Branches directly to a compiled method if the offset is encodable in instruction. 3250 // - Branches to the trampoline stub if the offset to the compiled method is not encodable. 3251 // - Branches to the compiled_to_interp stub if the target is interpreted. 3252 // 3253 // Further there are three relocations from the loads to the constants in 3254 // the constant section. 3255 // 3256 // Usage of r1 and r2 in the stubs allows to distinguish them. 3257 enc_class enc_java_static_call(method meth) %{ 3258 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3259 3260 MacroAssembler _masm(&cbuf); 3261 address entry_point = (address)$meth$$method; 3262 3263 if (!_method) { 3264 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3265 emit_call_with_trampoline_stub(_masm, entry_point, relocInfo::runtime_call_type); 3266 } else { 3267 // Remember the offset not the address. 3268 const int start_offset = __ offset(); 3269 3270 // The trampoline stub. 3271 // No entry point given, use the current pc. 3272 // Make sure branch fits into 3273 if (entry_point == 0) entry_point = __ pc(); 3274 3275 // Put the entry point as a constant into the constant pool. 3276 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 3277 if (entry_point_toc_addr == NULL) { 3278 ciEnv::current()->record_out_of_memory_failure(); 3279 return; 3280 } 3281 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 3282 3283 // Emit the trampoline stub which will be related to the branch-and-link below. 3284 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset); 3285 if (ciEnv::current()->failing()) { return; } // Code cache may be full. 3286 int method_index = resolved_method_index(cbuf); 3287 __ relocate(_optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 3288 : static_call_Relocation::spec(method_index)); 3289 3290 // The real call. 3291 // Note: At this point we do not have the address of the trampoline 3292 // stub, and the entry point might be too far away for bl, so __ pc() 3293 // serves as dummy and the bl will be patched later. 3294 cbuf.set_insts_mark(); 3295 __ bl(__ pc()); // Emits a relocation. 3296 3297 // The stub for call to interpreter. 3298 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); 3299 if (stub == NULL) { 3300 ciEnv::current()->record_failure("CodeCache is full"); 3301 return; 3302 } 3303 } 3304 %} 3305 3306 // Second node of expanded dynamic call - the call. 3307 enc_class enc_java_dynamic_call_sched(method meth) %{ 3308 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3309 3310 MacroAssembler _masm(&cbuf); 3311 3312 if (!ra_->C->in_scratch_emit_size()) { 3313 // Create a call trampoline stub for the given method. 3314 const address entry_point = !($meth$$method) ? 0 : (address)$meth$$method; 3315 const address entry_point_const = __ address_constant(entry_point, RelocationHolder::none); 3316 if (entry_point_const == NULL) { 3317 ciEnv::current()->record_out_of_memory_failure(); 3318 return; 3319 } 3320 const int entry_point_const_toc_offset = __ offset_to_method_toc(entry_point_const); 3321 CallStubImpl::emit_trampoline_stub(_masm, entry_point_const_toc_offset, __ offset()); 3322 if (ra_->C->env()->failing()) { return; } // Code cache may be full. 3323 3324 // Build relocation at call site with ic position as data. 3325 assert((_load_ic_hi_node != NULL && _load_ic_node == NULL) || 3326 (_load_ic_hi_node == NULL && _load_ic_node != NULL), 3327 "must have one, but can't have both"); 3328 assert((_load_ic_hi_node != NULL && _load_ic_hi_node->_cbuf_insts_offset != -1) || 3329 (_load_ic_node != NULL && _load_ic_node->_cbuf_insts_offset != -1), 3330 "must contain instruction offset"); 3331 const int virtual_call_oop_addr_offset = _load_ic_hi_node != NULL 3332 ? _load_ic_hi_node->_cbuf_insts_offset 3333 : _load_ic_node->_cbuf_insts_offset; 3334 const address virtual_call_oop_addr = __ addr_at(virtual_call_oop_addr_offset); 3335 assert(MacroAssembler::is_load_const_from_method_toc_at(virtual_call_oop_addr), 3336 "should be load from TOC"); 3337 int method_index = resolved_method_index(cbuf); 3338 __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr, method_index)); 3339 } 3340 3341 // At this point I do not have the address of the trampoline stub, 3342 // and the entry point might be too far away for bl. Pc() serves 3343 // as dummy and bl will be patched later. 3344 __ bl((address) __ pc()); 3345 %} 3346 3347 // postalloc expand emitter for virtual calls. 3348 enc_class postalloc_expand_java_dynamic_call_sched(method meth, iRegLdst toc) %{ 3349 3350 // Create the nodes for loading the IC from the TOC. 3351 loadConLNodesTuple loadConLNodes_IC = 3352 loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong)Universe::non_oop_word()), 3353 OptoReg::Name(R19_H_num), OptoReg::Name(R19_num)); 3354 3355 // Create the call node. 3356 CallDynamicJavaDirectSchedNode *call = new CallDynamicJavaDirectSchedNode(); 3357 call->_method_handle_invoke = _method_handle_invoke; 3358 call->_vtable_index = _vtable_index; 3359 call->_method = _method; 3360 call->_bci = _bci; 3361 call->_optimized_virtual = _optimized_virtual; 3362 call->_tf = _tf; 3363 call->_entry_point = _entry_point; 3364 call->_cnt = _cnt; 3365 call->_argsize = _argsize; 3366 call->_oop_map = _oop_map; 3367 call->_jvms = _jvms; 3368 call->_jvmadj = _jvmadj; 3369 call->_in_rms = _in_rms; 3370 call->_nesting = _nesting; 3371 call->_override_symbolic_info = _override_symbolic_info; 3372 3373 // New call needs all inputs of old call. 3374 // Req... 3375 for (uint i = 0; i < req(); ++i) { 3376 // The expanded node does not need toc any more. 3377 // Add the inline cache constant here instead. This expresses the 3378 // register of the inline cache must be live at the call. 3379 // Else we would have to adapt JVMState by -1. 3380 if (i == mach_constant_base_node_input()) { 3381 call->add_req(loadConLNodes_IC._last); 3382 } else { 3383 call->add_req(in(i)); 3384 } 3385 } 3386 // ...as well as prec 3387 for (uint i = req(); i < len(); ++i) { 3388 call->add_prec(in(i)); 3389 } 3390 3391 // Remember nodes loading the inline cache into r19. 3392 call->_load_ic_hi_node = loadConLNodes_IC._large_hi; 3393 call->_load_ic_node = loadConLNodes_IC._small; 3394 3395 // Operands for new nodes. 3396 call->_opnds[0] = _opnds[0]; 3397 call->_opnds[1] = _opnds[1]; 3398 3399 // Only the inline cache is associated with a register. 3400 assert(Matcher::inline_cache_reg() == OptoReg::Name(R19_num), "ic reg should be R19"); 3401 3402 // Push new nodes. 3403 if (loadConLNodes_IC._large_hi) nodes->push(loadConLNodes_IC._large_hi); 3404 if (loadConLNodes_IC._last) nodes->push(loadConLNodes_IC._last); 3405 nodes->push(call); 3406 %} 3407 3408 // Compound version of call dynamic 3409 // Toc is only passed so that it can be used in ins_encode statement. 3410 // In the code we have to use $constanttablebase. 3411 enc_class enc_java_dynamic_call(method meth, iRegLdst toc) %{ 3412 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3413 MacroAssembler _masm(&cbuf); 3414 int start_offset = __ offset(); 3415 3416 Register Rtoc = (ra_) ? $constanttablebase : R2_TOC; 3417 #if 0 3418 int vtable_index = this->_vtable_index; 3419 if (_vtable_index < 0) { 3420 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 3421 assert(_vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 3422 Register ic_reg = as_Register(Matcher::inline_cache_reg_encode()); 3423 3424 // Virtual call relocation will point to ic load. 3425 address virtual_call_meta_addr = __ pc(); 3426 // Load a clear inline cache. 3427 AddressLiteral empty_ic((address) Universe::non_oop_word()); 3428 bool success = __ load_const_from_method_toc(ic_reg, empty_ic, Rtoc, /*fixed_size*/ true); 3429 if (!success) { 3430 ciEnv::current()->record_out_of_memory_failure(); 3431 return; 3432 } 3433 // CALL to fixup routine. Fixup routine uses ScopeDesc info 3434 // to determine who we intended to call. 3435 __ relocate(virtual_call_Relocation::spec(virtual_call_meta_addr)); 3436 emit_call_with_trampoline_stub(_masm, (address)$meth$$method, relocInfo::none); 3437 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3438 "Fix constant in ret_addr_offset()"); 3439 } else { 3440 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 3441 // Go thru the vtable. Get receiver klass. Receiver already 3442 // checked for non-null. If we'll go thru a C2I adapter, the 3443 // interpreter expects method in R19_method. 3444 3445 __ load_klass(R11_scratch1, R3); 3446 3447 int entry_offset = in_bytes(Klass::vtable_start_offset()) + _vtable_index * vtableEntry::size_in_bytes(); 3448 int v_off = entry_offset + vtableEntry::method_offset_in_bytes(); 3449 __ li(R19_method, v_off); 3450 __ ldx(R19_method/*method oop*/, R19_method/*method offset*/, R11_scratch1/*class*/); 3451 // NOTE: for vtable dispatches, the vtable entry will never be 3452 // null. However it may very well end up in handle_wrong_method 3453 // if the method is abstract for the particular class. 3454 __ ld(R11_scratch1, in_bytes(Method::from_compiled_offset()), R19_method); 3455 // Call target. Either compiled code or C2I adapter. 3456 __ mtctr(R11_scratch1); 3457 __ bctrl(); 3458 if (((MachCallDynamicJavaNode*)this)->ret_addr_offset() != __ offset() - start_offset) { 3459 tty->print(" %d, %d\n", ((MachCallDynamicJavaNode*)this)->ret_addr_offset(),__ offset() - start_offset); 3460 } 3461 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3462 "Fix constant in ret_addr_offset()"); 3463 } 3464 #endif 3465 Unimplemented(); // ret_addr_offset not yet fixed. Depends on compressed oops (load klass!). 3466 %} 3467 3468 // a runtime call 3469 enc_class enc_java_to_runtime_call (method meth) %{ 3470 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3471 3472 MacroAssembler _masm(&cbuf); 3473 const address start_pc = __ pc(); 3474 3475 #if defined(ABI_ELFv2) 3476 address entry= !($meth$$method) ? NULL : (address)$meth$$method; 3477 __ call_c(entry, relocInfo::runtime_call_type); 3478 #else 3479 // The function we're going to call. 3480 FunctionDescriptor fdtemp; 3481 const FunctionDescriptor* fd = !($meth$$method) ? &fdtemp : (FunctionDescriptor*)$meth$$method; 3482 3483 Register Rtoc = R12_scratch2; 3484 // Calculate the method's TOC. 3485 __ calculate_address_from_global_toc(Rtoc, __ method_toc()); 3486 // Put entry, env, toc into the constant pool, this needs up to 3 constant 3487 // pool entries; call_c_using_toc will optimize the call. 3488 bool success = __ call_c_using_toc(fd, relocInfo::runtime_call_type, Rtoc); 3489 if (!success) { 3490 ciEnv::current()->record_out_of_memory_failure(); 3491 return; 3492 } 3493 #endif 3494 3495 // Check the ret_addr_offset. 3496 assert(((MachCallRuntimeNode*)this)->ret_addr_offset() == __ last_calls_return_pc() - start_pc, 3497 "Fix constant in ret_addr_offset()"); 3498 %} 3499 3500 // Move to ctr for leaf call. 3501 // This enc_class is needed so that scheduler gets proper 3502 // input mapping for latency computation. 3503 enc_class enc_leaf_call_mtctr(iRegLsrc src) %{ 3504 // TODO: PPC port $archOpcode(ppc64Opcode_mtctr); 3505 MacroAssembler _masm(&cbuf); 3506 __ mtctr($src$$Register); 3507 %} 3508 3509 // Postalloc expand emitter for runtime leaf calls. 3510 enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{ 3511 loadConLNodesTuple loadConLNodes_Entry; 3512 #if defined(ABI_ELFv2) 3513 jlong entry_address = (jlong) this->entry_point(); 3514 assert(entry_address, "need address here"); 3515 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3516 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3517 #else 3518 // Get the struct that describes the function we are about to call. 3519 FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point(); 3520 assert(fd, "need fd here"); 3521 jlong entry_address = (jlong) fd->entry(); 3522 // new nodes 3523 loadConLNodesTuple loadConLNodes_Env; 3524 loadConLNodesTuple loadConLNodes_Toc; 3525 3526 // Create nodes and operands for loading the entry point. 3527 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3528 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3529 3530 3531 // Create nodes and operands for loading the env pointer. 3532 if (fd->env() != NULL) { 3533 loadConLNodes_Env = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->env()), 3534 OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3535 } else { 3536 loadConLNodes_Env._large_hi = NULL; 3537 loadConLNodes_Env._large_lo = NULL; 3538 loadConLNodes_Env._small = NULL; 3539 loadConLNodes_Env._last = new loadConL16Node(); 3540 loadConLNodes_Env._last->_opnds[0] = new iRegLdstOper(); 3541 loadConLNodes_Env._last->_opnds[1] = new immL16Oper(0); 3542 ra_->set_pair(loadConLNodes_Env._last->_idx, OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3543 } 3544 3545 // Create nodes and operands for loading the Toc point. 3546 loadConLNodes_Toc = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->toc()), 3547 OptoReg::Name(R2_H_num), OptoReg::Name(R2_num)); 3548 #endif // ABI_ELFv2 3549 // mtctr node 3550 MachNode *mtctr = new CallLeafDirect_mtctrNode(); 3551 3552 assert(loadConLNodes_Entry._last != NULL, "entry must exist"); 3553 mtctr->add_req(0, loadConLNodes_Entry._last); 3554 3555 mtctr->_opnds[0] = new iRegLdstOper(); 3556 mtctr->_opnds[1] = new iRegLdstOper(); 3557 3558 // call node 3559 MachCallLeafNode *call = new CallLeafDirectNode(); 3560 3561 call->_opnds[0] = _opnds[0]; 3562 call->_opnds[1] = new methodOper((intptr_t) entry_address); // May get set later. 3563 3564 // Make the new call node look like the old one. 3565 call->_name = _name; 3566 call->_tf = _tf; 3567 call->_entry_point = _entry_point; 3568 call->_cnt = _cnt; 3569 call->_argsize = _argsize; 3570 call->_oop_map = _oop_map; 3571 guarantee(!_jvms, "You must clone the jvms and adapt the offsets by fix_jvms()."); 3572 call->_jvms = NULL; 3573 call->_jvmadj = _jvmadj; 3574 call->_in_rms = _in_rms; 3575 call->_nesting = _nesting; 3576 3577 3578 // New call needs all inputs of old call. 3579 // Req... 3580 for (uint i = 0; i < req(); ++i) { 3581 if (i != mach_constant_base_node_input()) { 3582 call->add_req(in(i)); 3583 } 3584 } 3585 3586 // These must be reqired edges, as the registers are live up to 3587 // the call. Else the constants are handled as kills. 3588 call->add_req(mtctr); 3589 #if !defined(ABI_ELFv2) 3590 call->add_req(loadConLNodes_Env._last); 3591 call->add_req(loadConLNodes_Toc._last); 3592 #endif 3593 3594 // ...as well as prec 3595 for (uint i = req(); i < len(); ++i) { 3596 call->add_prec(in(i)); 3597 } 3598 3599 // registers 3600 ra_->set1(mtctr->_idx, OptoReg::Name(SR_CTR_num)); 3601 3602 // Insert the new nodes. 3603 if (loadConLNodes_Entry._large_hi) nodes->push(loadConLNodes_Entry._large_hi); 3604 if (loadConLNodes_Entry._last) nodes->push(loadConLNodes_Entry._last); 3605 #if !defined(ABI_ELFv2) 3606 if (loadConLNodes_Env._large_hi) nodes->push(loadConLNodes_Env._large_hi); 3607 if (loadConLNodes_Env._last) nodes->push(loadConLNodes_Env._last); 3608 if (loadConLNodes_Toc._large_hi) nodes->push(loadConLNodes_Toc._large_hi); 3609 if (loadConLNodes_Toc._last) nodes->push(loadConLNodes_Toc._last); 3610 #endif 3611 nodes->push(mtctr); 3612 nodes->push(call); 3613 %} 3614 %} 3615 3616 //----------FRAME-------------------------------------------------------------- 3617 // Definition of frame structure and management information. 3618 3619 frame %{ 3620 // What direction does stack grow in (assumed to be same for native & Java). 3621 stack_direction(TOWARDS_LOW); 3622 3623 // These two registers define part of the calling convention between 3624 // compiled code and the interpreter. 3625 3626 // Inline Cache Register or method for I2C. 3627 inline_cache_reg(R19); // R19_method 3628 3629 // Method Oop Register when calling interpreter. 3630 interpreter_method_oop_reg(R19); // R19_method 3631 3632 // Optional: name the operand used by cisc-spilling to access 3633 // [stack_pointer + offset]. 3634 cisc_spilling_operand_name(indOffset); 3635 3636 // Number of stack slots consumed by a Monitor enter. 3637 sync_stack_slots((frame::jit_monitor_size / VMRegImpl::stack_slot_size)); 3638 3639 // Compiled code's Frame Pointer. 3640 frame_pointer(R1); // R1_SP 3641 3642 // Interpreter stores its frame pointer in a register which is 3643 // stored to the stack by I2CAdaptors. I2CAdaptors convert from 3644 // interpreted java to compiled java. 3645 // 3646 // R14_state holds pointer to caller's cInterpreter. 3647 interpreter_frame_pointer(R14); // R14_state 3648 3649 stack_alignment(frame::alignment_in_bytes); 3650 3651 in_preserve_stack_slots((frame::jit_in_preserve_size / VMRegImpl::stack_slot_size)); 3652 3653 // Number of outgoing stack slots killed above the 3654 // out_preserve_stack_slots for calls to C. Supports the var-args 3655 // backing area for register parms. 3656 // 3657 varargs_C_out_slots_killed(((frame::abi_reg_args_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size)); 3658 3659 // The after-PROLOG location of the return address. Location of 3660 // return address specifies a type (REG or STACK) and a number 3661 // representing the register number (i.e. - use a register name) or 3662 // stack slot. 3663 // 3664 // A: Link register is stored in stack slot ... 3665 // M: ... but it's in the caller's frame according to PPC-64 ABI. 3666 // J: Therefore, we make sure that the link register is also in R11_scratch1 3667 // at the end of the prolog. 3668 // B: We use R20, now. 3669 //return_addr(REG R20); 3670 3671 // G: After reading the comments made by all the luminaries on their 3672 // failure to tell the compiler where the return address really is, 3673 // I hardly dare to try myself. However, I'm convinced it's in slot 3674 // 4 what apparently works and saves us some spills. 3675 return_addr(STACK 4); 3676 3677 // This is the body of the function 3678 // 3679 // void Matcher::calling_convention(OptoRegPair* sig, // array of ideal regs 3680 // uint length, // length of array 3681 // bool is_outgoing) 3682 // 3683 // The `sig' array is to be updated. sig[j] represents the location 3684 // of the j-th argument, either a register or a stack slot. 3685 3686 // Comment taken from i486.ad: 3687 // Body of function which returns an integer array locating 3688 // arguments either in registers or in stack slots. Passed an array 3689 // of ideal registers called "sig" and a "length" count. Stack-slot 3690 // offsets are based on outgoing arguments, i.e. a CALLER setting up 3691 // arguments for a CALLEE. Incoming stack arguments are 3692 // automatically biased by the preserve_stack_slots field above. 3693 calling_convention %{ 3694 // No difference between ingoing/outgoing. Just pass false. 3695 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 3696 %} 3697 3698 // Comment taken from i486.ad: 3699 // Body of function which returns an integer array locating 3700 // arguments either in registers or in stack slots. Passed an array 3701 // of ideal registers called "sig" and a "length" count. Stack-slot 3702 // offsets are based on outgoing arguments, i.e. a CALLER setting up 3703 // arguments for a CALLEE. Incoming stack arguments are 3704 // automatically biased by the preserve_stack_slots field above. 3705 c_calling_convention %{ 3706 // This is obviously always outgoing. 3707 // C argument in register AND stack slot. 3708 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 3709 %} 3710 3711 // Location of native (C/C++) and interpreter return values. This 3712 // is specified to be the same as Java. In the 32-bit VM, long 3713 // values are actually returned from native calls in O0:O1 and 3714 // returned to the interpreter in I0:I1. The copying to and from 3715 // the register pairs is done by the appropriate call and epilog 3716 // opcodes. This simplifies the register allocator. 3717 c_return_value %{ 3718 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 3719 (ideal_reg == Op_RegN && Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0), 3720 "only return normal values"); 3721 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 3722 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 3723 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 3724 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 3725 %} 3726 3727 // Location of compiled Java return values. Same as C 3728 return_value %{ 3729 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 3730 (ideal_reg == Op_RegN && Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0), 3731 "only return normal values"); 3732 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 3733 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 3734 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 3735 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 3736 %} 3737 %} 3738 3739 3740 //----------ATTRIBUTES--------------------------------------------------------- 3741 3742 //----------Operand Attributes------------------------------------------------- 3743 op_attrib op_cost(1); // Required cost attribute. 3744 3745 //----------Instruction Attributes--------------------------------------------- 3746 3747 // Cost attribute. required. 3748 ins_attrib ins_cost(DEFAULT_COST); 3749 3750 // Is this instruction a non-matching short branch variant of some 3751 // long branch? Not required. 3752 ins_attrib ins_short_branch(0); 3753 3754 ins_attrib ins_is_TrapBasedCheckNode(true); 3755 3756 // Number of constants. 3757 // This instruction uses the given number of constants 3758 // (optional attribute). 3759 // This is needed to determine in time whether the constant pool will 3760 // exceed 4000 entries. Before postalloc_expand the overall number of constants 3761 // is determined. It's also used to compute the constant pool size 3762 // in Output(). 3763 ins_attrib ins_num_consts(0); 3764 3765 // Required alignment attribute (must be a power of 2) specifies the 3766 // alignment that some part of the instruction (not necessarily the 3767 // start) requires. If > 1, a compute_padding() function must be 3768 // provided for the instruction. 3769 ins_attrib ins_alignment(1); 3770 3771 // Enforce/prohibit rematerializations. 3772 // - If an instruction is attributed with 'ins_cannot_rematerialize(true)' 3773 // then rematerialization of that instruction is prohibited and the 3774 // instruction's value will be spilled if necessary. 3775 // Causes that MachNode::rematerialize() returns false. 3776 // - If an instruction is attributed with 'ins_should_rematerialize(true)' 3777 // then rematerialization should be enforced and a copy of the instruction 3778 // should be inserted if possible; rematerialization is not guaranteed. 3779 // Note: this may result in rematerializations in front of every use. 3780 // Causes that MachNode::rematerialize() can return true. 3781 // (optional attribute) 3782 ins_attrib ins_cannot_rematerialize(false); 3783 ins_attrib ins_should_rematerialize(false); 3784 3785 // Instruction has variable size depending on alignment. 3786 ins_attrib ins_variable_size_depending_on_alignment(false); 3787 3788 // Instruction is a nop. 3789 ins_attrib ins_is_nop(false); 3790 3791 // Instruction is mapped to a MachIfFastLock node (instead of MachFastLock). 3792 ins_attrib ins_use_mach_if_fast_lock_node(false); 3793 3794 // Field for the toc offset of a constant. 3795 // 3796 // This is needed if the toc offset is not encodable as an immediate in 3797 // the PPC load instruction. If so, the upper (hi) bits of the offset are 3798 // added to the toc, and from this a load with immediate is performed. 3799 // With postalloc expand, we get two nodes that require the same offset 3800 // but which don't know about each other. The offset is only known 3801 // when the constant is added to the constant pool during emitting. 3802 // It is generated in the 'hi'-node adding the upper bits, and saved 3803 // in this node. The 'lo'-node has a link to the 'hi'-node and reads 3804 // the offset from there when it gets encoded. 3805 ins_attrib ins_field_const_toc_offset(0); 3806 ins_attrib ins_field_const_toc_offset_hi_node(0); 3807 3808 // A field that can hold the instructions offset in the code buffer. 3809 // Set in the nodes emitter. 3810 ins_attrib ins_field_cbuf_insts_offset(-1); 3811 3812 // Fields for referencing a call's load-IC-node. 3813 // If the toc offset can not be encoded as an immediate in a load, we 3814 // use two nodes. 3815 ins_attrib ins_field_load_ic_hi_node(0); 3816 ins_attrib ins_field_load_ic_node(0); 3817 3818 //----------OPERANDS----------------------------------------------------------- 3819 // Operand definitions must precede instruction definitions for correct 3820 // parsing in the ADLC because operands constitute user defined types 3821 // which are used in instruction definitions. 3822 // 3823 // Formats are generated automatically for constants and base registers. 3824 3825 //----------Simple Operands---------------------------------------------------- 3826 // Immediate Operands 3827 3828 // Integer Immediate: 32-bit 3829 operand immI() %{ 3830 match(ConI); 3831 op_cost(40); 3832 format %{ %} 3833 interface(CONST_INTER); 3834 %} 3835 3836 operand immI8() %{ 3837 predicate(Assembler::is_simm(n->get_int(), 8)); 3838 op_cost(0); 3839 match(ConI); 3840 format %{ %} 3841 interface(CONST_INTER); 3842 %} 3843 3844 // Integer Immediate: 16-bit 3845 operand immI16() %{ 3846 predicate(Assembler::is_simm(n->get_int(), 16)); 3847 op_cost(0); 3848 match(ConI); 3849 format %{ %} 3850 interface(CONST_INTER); 3851 %} 3852 3853 // Integer Immediate: 32-bit, where lowest 16 bits are 0x0000. 3854 operand immIhi16() %{ 3855 predicate(((n->get_int() & 0xffff0000) != 0) && ((n->get_int() & 0xffff) == 0)); 3856 match(ConI); 3857 op_cost(0); 3858 format %{ %} 3859 interface(CONST_INTER); 3860 %} 3861 3862 operand immInegpow2() %{ 3863 predicate(is_power_of_2_long((jlong) (julong) (juint) (-(n->get_int())))); 3864 match(ConI); 3865 op_cost(0); 3866 format %{ %} 3867 interface(CONST_INTER); 3868 %} 3869 3870 operand immIpow2minus1() %{ 3871 predicate(is_power_of_2_long((((jlong) (n->get_int()))+1))); 3872 match(ConI); 3873 op_cost(0); 3874 format %{ %} 3875 interface(CONST_INTER); 3876 %} 3877 3878 operand immIpowerOf2() %{ 3879 predicate(is_power_of_2_long((((jlong) (julong) (juint) (n->get_int()))))); 3880 match(ConI); 3881 op_cost(0); 3882 format %{ %} 3883 interface(CONST_INTER); 3884 %} 3885 3886 // Unsigned Integer Immediate: the values 0-31 3887 operand uimmI5() %{ 3888 predicate(Assembler::is_uimm(n->get_int(), 5)); 3889 match(ConI); 3890 op_cost(0); 3891 format %{ %} 3892 interface(CONST_INTER); 3893 %} 3894 3895 // Unsigned Integer Immediate: 6-bit 3896 operand uimmI6() %{ 3897 predicate(Assembler::is_uimm(n->get_int(), 6)); 3898 match(ConI); 3899 op_cost(0); 3900 format %{ %} 3901 interface(CONST_INTER); 3902 %} 3903 3904 // Unsigned Integer Immediate: 6-bit int, greater than 32 3905 operand uimmI6_ge32() %{ 3906 predicate(Assembler::is_uimm(n->get_int(), 6) && n->get_int() >= 32); 3907 match(ConI); 3908 op_cost(0); 3909 format %{ %} 3910 interface(CONST_INTER); 3911 %} 3912 3913 // Unsigned Integer Immediate: 15-bit 3914 operand uimmI15() %{ 3915 predicate(Assembler::is_uimm(n->get_int(), 15)); 3916 match(ConI); 3917 op_cost(0); 3918 format %{ %} 3919 interface(CONST_INTER); 3920 %} 3921 3922 // Unsigned Integer Immediate: 16-bit 3923 operand uimmI16() %{ 3924 predicate(Assembler::is_uimm(n->get_int(), 16)); 3925 match(ConI); 3926 op_cost(0); 3927 format %{ %} 3928 interface(CONST_INTER); 3929 %} 3930 3931 // constant 'int 0'. 3932 operand immI_0() %{ 3933 predicate(n->get_int() == 0); 3934 match(ConI); 3935 op_cost(0); 3936 format %{ %} 3937 interface(CONST_INTER); 3938 %} 3939 3940 // constant 'int 1'. 3941 operand immI_1() %{ 3942 predicate(n->get_int() == 1); 3943 match(ConI); 3944 op_cost(0); 3945 format %{ %} 3946 interface(CONST_INTER); 3947 %} 3948 3949 // constant 'int -1'. 3950 operand immI_minus1() %{ 3951 predicate(n->get_int() == -1); 3952 match(ConI); 3953 op_cost(0); 3954 format %{ %} 3955 interface(CONST_INTER); 3956 %} 3957 3958 // int value 16. 3959 operand immI_16() %{ 3960 predicate(n->get_int() == 16); 3961 match(ConI); 3962 op_cost(0); 3963 format %{ %} 3964 interface(CONST_INTER); 3965 %} 3966 3967 // int value 24. 3968 operand immI_24() %{ 3969 predicate(n->get_int() == 24); 3970 match(ConI); 3971 op_cost(0); 3972 format %{ %} 3973 interface(CONST_INTER); 3974 %} 3975 3976 // Compressed oops constants 3977 // Pointer Immediate 3978 operand immN() %{ 3979 match(ConN); 3980 3981 op_cost(10); 3982 format %{ %} 3983 interface(CONST_INTER); 3984 %} 3985 3986 // NULL Pointer Immediate 3987 operand immN_0() %{ 3988 predicate(n->get_narrowcon() == 0); 3989 match(ConN); 3990 3991 op_cost(0); 3992 format %{ %} 3993 interface(CONST_INTER); 3994 %} 3995 3996 // Compressed klass constants 3997 operand immNKlass() %{ 3998 match(ConNKlass); 3999 4000 op_cost(0); 4001 format %{ %} 4002 interface(CONST_INTER); 4003 %} 4004 4005 // This operand can be used to avoid matching of an instruct 4006 // with chain rule. 4007 operand immNKlass_NM() %{ 4008 match(ConNKlass); 4009 predicate(false); 4010 op_cost(0); 4011 format %{ %} 4012 interface(CONST_INTER); 4013 %} 4014 4015 // Pointer Immediate: 64-bit 4016 operand immP() %{ 4017 match(ConP); 4018 op_cost(0); 4019 format %{ %} 4020 interface(CONST_INTER); 4021 %} 4022 4023 // Operand to avoid match of loadConP. 4024 // This operand can be used to avoid matching of an instruct 4025 // with chain rule. 4026 operand immP_NM() %{ 4027 match(ConP); 4028 predicate(false); 4029 op_cost(0); 4030 format %{ %} 4031 interface(CONST_INTER); 4032 %} 4033 4034 // costant 'pointer 0'. 4035 operand immP_0() %{ 4036 predicate(n->get_ptr() == 0); 4037 match(ConP); 4038 op_cost(0); 4039 format %{ %} 4040 interface(CONST_INTER); 4041 %} 4042 4043 // pointer 0x0 or 0x1 4044 operand immP_0or1() %{ 4045 predicate((n->get_ptr() == 0) || (n->get_ptr() == 1)); 4046 match(ConP); 4047 op_cost(0); 4048 format %{ %} 4049 interface(CONST_INTER); 4050 %} 4051 4052 operand immL() %{ 4053 match(ConL); 4054 op_cost(40); 4055 format %{ %} 4056 interface(CONST_INTER); 4057 %} 4058 4059 // Long Immediate: 16-bit 4060 operand immL16() %{ 4061 predicate(Assembler::is_simm(n->get_long(), 16)); 4062 match(ConL); 4063 op_cost(0); 4064 format %{ %} 4065 interface(CONST_INTER); 4066 %} 4067 4068 // Long Immediate: 16-bit, 4-aligned 4069 operand immL16Alg4() %{ 4070 predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0x3) == 0)); 4071 match(ConL); 4072 op_cost(0); 4073 format %{ %} 4074 interface(CONST_INTER); 4075 %} 4076 4077 // Long Immediate: 32-bit, where lowest 16 bits are 0x0000. 4078 operand immL32hi16() %{ 4079 predicate(Assembler::is_simm(n->get_long(), 32) && ((n->get_long() & 0xffffL) == 0L)); 4080 match(ConL); 4081 op_cost(0); 4082 format %{ %} 4083 interface(CONST_INTER); 4084 %} 4085 4086 // Long Immediate: 32-bit 4087 operand immL32() %{ 4088 predicate(Assembler::is_simm(n->get_long(), 32)); 4089 match(ConL); 4090 op_cost(0); 4091 format %{ %} 4092 interface(CONST_INTER); 4093 %} 4094 4095 // Long Immediate: 64-bit, where highest 16 bits are not 0x0000. 4096 operand immLhighest16() %{ 4097 predicate((n->get_long() & 0xffff000000000000L) != 0L && (n->get_long() & 0x0000ffffffffffffL) == 0L); 4098 match(ConL); 4099 op_cost(0); 4100 format %{ %} 4101 interface(CONST_INTER); 4102 %} 4103 4104 operand immLnegpow2() %{ 4105 predicate(is_power_of_2_long((jlong)-(n->get_long()))); 4106 match(ConL); 4107 op_cost(0); 4108 format %{ %} 4109 interface(CONST_INTER); 4110 %} 4111 4112 operand immLpow2minus1() %{ 4113 predicate(is_power_of_2_long((((jlong) (n->get_long()))+1)) && 4114 (n->get_long() != (jlong)0xffffffffffffffffL)); 4115 match(ConL); 4116 op_cost(0); 4117 format %{ %} 4118 interface(CONST_INTER); 4119 %} 4120 4121 // constant 'long 0'. 4122 operand immL_0() %{ 4123 predicate(n->get_long() == 0L); 4124 match(ConL); 4125 op_cost(0); 4126 format %{ %} 4127 interface(CONST_INTER); 4128 %} 4129 4130 // constat ' long -1'. 4131 operand immL_minus1() %{ 4132 predicate(n->get_long() == -1L); 4133 match(ConL); 4134 op_cost(0); 4135 format %{ %} 4136 interface(CONST_INTER); 4137 %} 4138 4139 // Long Immediate: low 32-bit mask 4140 operand immL_32bits() %{ 4141 predicate(n->get_long() == 0xFFFFFFFFL); 4142 match(ConL); 4143 op_cost(0); 4144 format %{ %} 4145 interface(CONST_INTER); 4146 %} 4147 4148 // Unsigned Long Immediate: 16-bit 4149 operand uimmL16() %{ 4150 predicate(Assembler::is_uimm(n->get_long(), 16)); 4151 match(ConL); 4152 op_cost(0); 4153 format %{ %} 4154 interface(CONST_INTER); 4155 %} 4156 4157 // Float Immediate 4158 operand immF() %{ 4159 match(ConF); 4160 op_cost(40); 4161 format %{ %} 4162 interface(CONST_INTER); 4163 %} 4164 4165 // Float Immediate: +0.0f. 4166 operand immF_0() %{ 4167 predicate(jint_cast(n->getf()) == 0); 4168 match(ConF); 4169 4170 op_cost(0); 4171 format %{ %} 4172 interface(CONST_INTER); 4173 %} 4174 4175 // Double Immediate 4176 operand immD() %{ 4177 match(ConD); 4178 op_cost(40); 4179 format %{ %} 4180 interface(CONST_INTER); 4181 %} 4182 4183 // Integer Register Operands 4184 // Integer Destination Register 4185 // See definition of reg_class bits32_reg_rw. 4186 operand iRegIdst() %{ 4187 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4188 match(RegI); 4189 match(rscratch1RegI); 4190 match(rscratch2RegI); 4191 match(rarg1RegI); 4192 match(rarg2RegI); 4193 match(rarg3RegI); 4194 match(rarg4RegI); 4195 format %{ %} 4196 interface(REG_INTER); 4197 %} 4198 4199 // Integer Source Register 4200 // See definition of reg_class bits32_reg_ro. 4201 operand iRegIsrc() %{ 4202 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4203 match(RegI); 4204 match(rscratch1RegI); 4205 match(rscratch2RegI); 4206 match(rarg1RegI); 4207 match(rarg2RegI); 4208 match(rarg3RegI); 4209 match(rarg4RegI); 4210 format %{ %} 4211 interface(REG_INTER); 4212 %} 4213 4214 operand rscratch1RegI() %{ 4215 constraint(ALLOC_IN_RC(rscratch1_bits32_reg)); 4216 match(iRegIdst); 4217 format %{ %} 4218 interface(REG_INTER); 4219 %} 4220 4221 operand rscratch2RegI() %{ 4222 constraint(ALLOC_IN_RC(rscratch2_bits32_reg)); 4223 match(iRegIdst); 4224 format %{ %} 4225 interface(REG_INTER); 4226 %} 4227 4228 operand rarg1RegI() %{ 4229 constraint(ALLOC_IN_RC(rarg1_bits32_reg)); 4230 match(iRegIdst); 4231 format %{ %} 4232 interface(REG_INTER); 4233 %} 4234 4235 operand rarg2RegI() %{ 4236 constraint(ALLOC_IN_RC(rarg2_bits32_reg)); 4237 match(iRegIdst); 4238 format %{ %} 4239 interface(REG_INTER); 4240 %} 4241 4242 operand rarg3RegI() %{ 4243 constraint(ALLOC_IN_RC(rarg3_bits32_reg)); 4244 match(iRegIdst); 4245 format %{ %} 4246 interface(REG_INTER); 4247 %} 4248 4249 operand rarg4RegI() %{ 4250 constraint(ALLOC_IN_RC(rarg4_bits32_reg)); 4251 match(iRegIdst); 4252 format %{ %} 4253 interface(REG_INTER); 4254 %} 4255 4256 operand rarg1RegL() %{ 4257 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4258 match(iRegLdst); 4259 format %{ %} 4260 interface(REG_INTER); 4261 %} 4262 4263 operand rarg2RegL() %{ 4264 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4265 match(iRegLdst); 4266 format %{ %} 4267 interface(REG_INTER); 4268 %} 4269 4270 operand rarg3RegL() %{ 4271 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4272 match(iRegLdst); 4273 format %{ %} 4274 interface(REG_INTER); 4275 %} 4276 4277 operand rarg4RegL() %{ 4278 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4279 match(iRegLdst); 4280 format %{ %} 4281 interface(REG_INTER); 4282 %} 4283 4284 // Pointer Destination Register 4285 // See definition of reg_class bits64_reg_rw. 4286 operand iRegPdst() %{ 4287 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4288 match(RegP); 4289 match(rscratch1RegP); 4290 match(rscratch2RegP); 4291 match(rarg1RegP); 4292 match(rarg2RegP); 4293 match(rarg3RegP); 4294 match(rarg4RegP); 4295 format %{ %} 4296 interface(REG_INTER); 4297 %} 4298 4299 // Pointer Destination Register 4300 // Operand not using r11 and r12 (killed in epilog). 4301 operand iRegPdstNoScratch() %{ 4302 constraint(ALLOC_IN_RC(bits64_reg_leaf_call)); 4303 match(RegP); 4304 match(rarg1RegP); 4305 match(rarg2RegP); 4306 match(rarg3RegP); 4307 match(rarg4RegP); 4308 format %{ %} 4309 interface(REG_INTER); 4310 %} 4311 4312 // Pointer Source Register 4313 // See definition of reg_class bits64_reg_ro. 4314 operand iRegPsrc() %{ 4315 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4316 match(RegP); 4317 match(iRegPdst); 4318 match(rscratch1RegP); 4319 match(rscratch2RegP); 4320 match(rarg1RegP); 4321 match(rarg2RegP); 4322 match(rarg3RegP); 4323 match(rarg4RegP); 4324 match(threadRegP); 4325 format %{ %} 4326 interface(REG_INTER); 4327 %} 4328 4329 // Thread operand. 4330 operand threadRegP() %{ 4331 constraint(ALLOC_IN_RC(thread_bits64_reg)); 4332 match(iRegPdst); 4333 format %{ "R16" %} 4334 interface(REG_INTER); 4335 %} 4336 4337 operand rscratch1RegP() %{ 4338 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4339 match(iRegPdst); 4340 format %{ "R11" %} 4341 interface(REG_INTER); 4342 %} 4343 4344 operand rscratch2RegP() %{ 4345 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4346 match(iRegPdst); 4347 format %{ %} 4348 interface(REG_INTER); 4349 %} 4350 4351 operand rarg1RegP() %{ 4352 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4353 match(iRegPdst); 4354 format %{ %} 4355 interface(REG_INTER); 4356 %} 4357 4358 operand rarg2RegP() %{ 4359 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4360 match(iRegPdst); 4361 format %{ %} 4362 interface(REG_INTER); 4363 %} 4364 4365 operand rarg3RegP() %{ 4366 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4367 match(iRegPdst); 4368 format %{ %} 4369 interface(REG_INTER); 4370 %} 4371 4372 operand rarg4RegP() %{ 4373 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4374 match(iRegPdst); 4375 format %{ %} 4376 interface(REG_INTER); 4377 %} 4378 4379 operand iRegNsrc() %{ 4380 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4381 match(RegN); 4382 match(iRegNdst); 4383 4384 format %{ %} 4385 interface(REG_INTER); 4386 %} 4387 4388 operand iRegNdst() %{ 4389 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4390 match(RegN); 4391 4392 format %{ %} 4393 interface(REG_INTER); 4394 %} 4395 4396 // Long Destination Register 4397 // See definition of reg_class bits64_reg_rw. 4398 operand iRegLdst() %{ 4399 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4400 match(RegL); 4401 match(rscratch1RegL); 4402 match(rscratch2RegL); 4403 format %{ %} 4404 interface(REG_INTER); 4405 %} 4406 4407 // Long Source Register 4408 // See definition of reg_class bits64_reg_ro. 4409 operand iRegLsrc() %{ 4410 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4411 match(RegL); 4412 match(iRegLdst); 4413 match(rscratch1RegL); 4414 match(rscratch2RegL); 4415 format %{ %} 4416 interface(REG_INTER); 4417 %} 4418 4419 // Special operand for ConvL2I. 4420 operand iRegL2Isrc(iRegLsrc reg) %{ 4421 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4422 match(ConvL2I reg); 4423 format %{ "ConvL2I($reg)" %} 4424 interface(REG_INTER) 4425 %} 4426 4427 operand rscratch1RegL() %{ 4428 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4429 match(RegL); 4430 format %{ %} 4431 interface(REG_INTER); 4432 %} 4433 4434 operand rscratch2RegL() %{ 4435 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4436 match(RegL); 4437 format %{ %} 4438 interface(REG_INTER); 4439 %} 4440 4441 // Condition Code Flag Registers 4442 operand flagsReg() %{ 4443 constraint(ALLOC_IN_RC(int_flags)); 4444 match(RegFlags); 4445 format %{ %} 4446 interface(REG_INTER); 4447 %} 4448 4449 operand flagsRegSrc() %{ 4450 constraint(ALLOC_IN_RC(int_flags_ro)); 4451 match(RegFlags); 4452 match(flagsReg); 4453 match(flagsRegCR0); 4454 format %{ %} 4455 interface(REG_INTER); 4456 %} 4457 4458 // Condition Code Flag Register CR0 4459 operand flagsRegCR0() %{ 4460 constraint(ALLOC_IN_RC(int_flags_CR0)); 4461 match(RegFlags); 4462 format %{ "CR0" %} 4463 interface(REG_INTER); 4464 %} 4465 4466 operand flagsRegCR1() %{ 4467 constraint(ALLOC_IN_RC(int_flags_CR1)); 4468 match(RegFlags); 4469 format %{ "CR1" %} 4470 interface(REG_INTER); 4471 %} 4472 4473 operand flagsRegCR6() %{ 4474 constraint(ALLOC_IN_RC(int_flags_CR6)); 4475 match(RegFlags); 4476 format %{ "CR6" %} 4477 interface(REG_INTER); 4478 %} 4479 4480 operand regCTR() %{ 4481 constraint(ALLOC_IN_RC(ctr_reg)); 4482 // RegFlags should work. Introducing a RegSpecial type would cause a 4483 // lot of changes. 4484 match(RegFlags); 4485 format %{"SR_CTR" %} 4486 interface(REG_INTER); 4487 %} 4488 4489 operand regD() %{ 4490 constraint(ALLOC_IN_RC(dbl_reg)); 4491 match(RegD); 4492 format %{ %} 4493 interface(REG_INTER); 4494 %} 4495 4496 operand regF() %{ 4497 constraint(ALLOC_IN_RC(flt_reg)); 4498 match(RegF); 4499 format %{ %} 4500 interface(REG_INTER); 4501 %} 4502 4503 // Special Registers 4504 4505 // Method Register 4506 operand inline_cache_regP(iRegPdst reg) %{ 4507 constraint(ALLOC_IN_RC(r19_bits64_reg)); // inline_cache_reg 4508 match(reg); 4509 format %{ %} 4510 interface(REG_INTER); 4511 %} 4512 4513 operand compiler_method_oop_regP(iRegPdst reg) %{ 4514 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); // compiler_method_oop_reg 4515 match(reg); 4516 format %{ %} 4517 interface(REG_INTER); 4518 %} 4519 4520 operand interpreter_method_oop_regP(iRegPdst reg) %{ 4521 constraint(ALLOC_IN_RC(r19_bits64_reg)); // interpreter_method_oop_reg 4522 match(reg); 4523 format %{ %} 4524 interface(REG_INTER); 4525 %} 4526 4527 // Operands to remove register moves in unscaled mode. 4528 // Match read/write registers with an EncodeP node if neither shift nor add are required. 4529 operand iRegP2N(iRegPsrc reg) %{ 4530 predicate(false /* TODO: PPC port MatchDecodeNodes*/&& Universe::narrow_oop_shift() == 0); 4531 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4532 match(EncodeP reg); 4533 format %{ "$reg" %} 4534 interface(REG_INTER) 4535 %} 4536 4537 operand iRegN2P(iRegNsrc reg) %{ 4538 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4539 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4540 match(DecodeN reg); 4541 format %{ "$reg" %} 4542 interface(REG_INTER) 4543 %} 4544 4545 operand iRegN2P_klass(iRegNsrc reg) %{ 4546 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 4547 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4548 match(DecodeNKlass reg); 4549 format %{ "$reg" %} 4550 interface(REG_INTER) 4551 %} 4552 4553 //----------Complex Operands--------------------------------------------------- 4554 // Indirect Memory Reference 4555 operand indirect(iRegPsrc reg) %{ 4556 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4557 match(reg); 4558 op_cost(100); 4559 format %{ "[$reg]" %} 4560 interface(MEMORY_INTER) %{ 4561 base($reg); 4562 index(0x0); 4563 scale(0x0); 4564 disp(0x0); 4565 %} 4566 %} 4567 4568 // Indirect with Offset 4569 operand indOffset16(iRegPsrc reg, immL16 offset) %{ 4570 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4571 match(AddP reg offset); 4572 op_cost(100); 4573 format %{ "[$reg + $offset]" %} 4574 interface(MEMORY_INTER) %{ 4575 base($reg); 4576 index(0x0); 4577 scale(0x0); 4578 disp($offset); 4579 %} 4580 %} 4581 4582 // Indirect with 4-aligned Offset 4583 operand indOffset16Alg4(iRegPsrc reg, immL16Alg4 offset) %{ 4584 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4585 match(AddP reg offset); 4586 op_cost(100); 4587 format %{ "[$reg + $offset]" %} 4588 interface(MEMORY_INTER) %{ 4589 base($reg); 4590 index(0x0); 4591 scale(0x0); 4592 disp($offset); 4593 %} 4594 %} 4595 4596 //----------Complex Operands for Compressed OOPs------------------------------- 4597 // Compressed OOPs with narrow_oop_shift == 0. 4598 4599 // Indirect Memory Reference, compressed OOP 4600 operand indirectNarrow(iRegNsrc reg) %{ 4601 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4602 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4603 match(DecodeN reg); 4604 op_cost(100); 4605 format %{ "[$reg]" %} 4606 interface(MEMORY_INTER) %{ 4607 base($reg); 4608 index(0x0); 4609 scale(0x0); 4610 disp(0x0); 4611 %} 4612 %} 4613 4614 operand indirectNarrow_klass(iRegNsrc reg) %{ 4615 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 4616 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4617 match(DecodeNKlass reg); 4618 op_cost(100); 4619 format %{ "[$reg]" %} 4620 interface(MEMORY_INTER) %{ 4621 base($reg); 4622 index(0x0); 4623 scale(0x0); 4624 disp(0x0); 4625 %} 4626 %} 4627 4628 // Indirect with Offset, compressed OOP 4629 operand indOffset16Narrow(iRegNsrc reg, immL16 offset) %{ 4630 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4631 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4632 match(AddP (DecodeN reg) offset); 4633 op_cost(100); 4634 format %{ "[$reg + $offset]" %} 4635 interface(MEMORY_INTER) %{ 4636 base($reg); 4637 index(0x0); 4638 scale(0x0); 4639 disp($offset); 4640 %} 4641 %} 4642 4643 operand indOffset16Narrow_klass(iRegNsrc reg, immL16 offset) %{ 4644 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 4645 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4646 match(AddP (DecodeNKlass reg) offset); 4647 op_cost(100); 4648 format %{ "[$reg + $offset]" %} 4649 interface(MEMORY_INTER) %{ 4650 base($reg); 4651 index(0x0); 4652 scale(0x0); 4653 disp($offset); 4654 %} 4655 %} 4656 4657 // Indirect with 4-aligned Offset, compressed OOP 4658 operand indOffset16NarrowAlg4(iRegNsrc reg, immL16Alg4 offset) %{ 4659 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4660 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4661 match(AddP (DecodeN reg) offset); 4662 op_cost(100); 4663 format %{ "[$reg + $offset]" %} 4664 interface(MEMORY_INTER) %{ 4665 base($reg); 4666 index(0x0); 4667 scale(0x0); 4668 disp($offset); 4669 %} 4670 %} 4671 4672 operand indOffset16NarrowAlg4_klass(iRegNsrc reg, immL16Alg4 offset) %{ 4673 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 4674 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4675 match(AddP (DecodeNKlass reg) offset); 4676 op_cost(100); 4677 format %{ "[$reg + $offset]" %} 4678 interface(MEMORY_INTER) %{ 4679 base($reg); 4680 index(0x0); 4681 scale(0x0); 4682 disp($offset); 4683 %} 4684 %} 4685 4686 //----------Special Memory Operands-------------------------------------------- 4687 // Stack Slot Operand 4688 // 4689 // This operand is used for loading and storing temporary values on 4690 // the stack where a match requires a value to flow through memory. 4691 operand stackSlotI(sRegI reg) %{ 4692 constraint(ALLOC_IN_RC(stack_slots)); 4693 op_cost(100); 4694 //match(RegI); 4695 format %{ "[sp+$reg]" %} 4696 interface(MEMORY_INTER) %{ 4697 base(0x1); // R1_SP 4698 index(0x0); 4699 scale(0x0); 4700 disp($reg); // Stack Offset 4701 %} 4702 %} 4703 4704 operand stackSlotL(sRegL reg) %{ 4705 constraint(ALLOC_IN_RC(stack_slots)); 4706 op_cost(100); 4707 //match(RegL); 4708 format %{ "[sp+$reg]" %} 4709 interface(MEMORY_INTER) %{ 4710 base(0x1); // R1_SP 4711 index(0x0); 4712 scale(0x0); 4713 disp($reg); // Stack Offset 4714 %} 4715 %} 4716 4717 operand stackSlotP(sRegP reg) %{ 4718 constraint(ALLOC_IN_RC(stack_slots)); 4719 op_cost(100); 4720 //match(RegP); 4721 format %{ "[sp+$reg]" %} 4722 interface(MEMORY_INTER) %{ 4723 base(0x1); // R1_SP 4724 index(0x0); 4725 scale(0x0); 4726 disp($reg); // Stack Offset 4727 %} 4728 %} 4729 4730 operand stackSlotF(sRegF reg) %{ 4731 constraint(ALLOC_IN_RC(stack_slots)); 4732 op_cost(100); 4733 //match(RegF); 4734 format %{ "[sp+$reg]" %} 4735 interface(MEMORY_INTER) %{ 4736 base(0x1); // R1_SP 4737 index(0x0); 4738 scale(0x0); 4739 disp($reg); // Stack Offset 4740 %} 4741 %} 4742 4743 operand stackSlotD(sRegD reg) %{ 4744 constraint(ALLOC_IN_RC(stack_slots)); 4745 op_cost(100); 4746 //match(RegD); 4747 format %{ "[sp+$reg]" %} 4748 interface(MEMORY_INTER) %{ 4749 base(0x1); // R1_SP 4750 index(0x0); 4751 scale(0x0); 4752 disp($reg); // Stack Offset 4753 %} 4754 %} 4755 4756 // Operands for expressing Control Flow 4757 // NOTE: Label is a predefined operand which should not be redefined in 4758 // the AD file. It is generically handled within the ADLC. 4759 4760 //----------Conditional Branch Operands---------------------------------------- 4761 // Comparison Op 4762 // 4763 // This is the operation of the comparison, and is limited to the 4764 // following set of codes: L (<), LE (<=), G (>), GE (>=), E (==), NE 4765 // (!=). 4766 // 4767 // Other attributes of the comparison, such as unsignedness, are specified 4768 // by the comparison instruction that sets a condition code flags register. 4769 // That result is represented by a flags operand whose subtype is appropriate 4770 // to the unsignedness (etc.) of the comparison. 4771 // 4772 // Later, the instruction which matches both the Comparison Op (a Bool) and 4773 // the flags (produced by the Cmp) specifies the coding of the comparison op 4774 // by matching a specific subtype of Bool operand below. 4775 4776 // When used for floating point comparisons: unordered same as less. 4777 operand cmpOp() %{ 4778 match(Bool); 4779 format %{ "" %} 4780 interface(COND_INTER) %{ 4781 // BO only encodes bit 4 of bcondCRbiIsX, as bits 1-3 are always '100'. 4782 // BO & BI 4783 equal(0xA); // 10 10: bcondCRbiIs1 & Condition::equal 4784 not_equal(0x2); // 00 10: bcondCRbiIs0 & Condition::equal 4785 less(0x8); // 10 00: bcondCRbiIs1 & Condition::less 4786 greater_equal(0x0); // 00 00: bcondCRbiIs0 & Condition::less 4787 less_equal(0x1); // 00 01: bcondCRbiIs0 & Condition::greater 4788 greater(0x9); // 10 01: bcondCRbiIs1 & Condition::greater 4789 overflow(0xB); // 10 11: bcondCRbiIs1 & Condition::summary_overflow 4790 no_overflow(0x3); // 00 11: bcondCRbiIs0 & Condition::summary_overflow 4791 %} 4792 %} 4793 4794 //----------OPERAND CLASSES---------------------------------------------------- 4795 // Operand Classes are groups of operands that are used to simplify 4796 // instruction definitions by not requiring the AD writer to specify 4797 // seperate instructions for every form of operand when the 4798 // instruction accepts multiple operand types with the same basic 4799 // encoding and format. The classic case of this is memory operands. 4800 // Indirect is not included since its use is limited to Compare & Swap. 4801 4802 opclass memory(indirect, indOffset16 /*, indIndex, tlsReference*/, indirectNarrow, indirectNarrow_klass, indOffset16Narrow, indOffset16Narrow_klass); 4803 // Memory operand where offsets are 4-aligned. Required for ld, std. 4804 opclass memoryAlg4(indirect, indOffset16Alg4, indirectNarrow, indOffset16NarrowAlg4, indOffset16NarrowAlg4_klass); 4805 opclass indirectMemory(indirect, indirectNarrow); 4806 4807 // Special opclass for I and ConvL2I. 4808 opclass iRegIsrc_iRegL2Isrc(iRegIsrc, iRegL2Isrc); 4809 4810 // Operand classes to match encode and decode. iRegN_P2N is only used 4811 // for storeN. I have never seen an encode node elsewhere. 4812 opclass iRegN_P2N(iRegNsrc, iRegP2N); 4813 opclass iRegP_N2P(iRegPsrc, iRegN2P, iRegN2P_klass); 4814 4815 //----------PIPELINE----------------------------------------------------------- 4816 4817 pipeline %{ 4818 4819 // See J.M.Tendler et al. "Power4 system microarchitecture", IBM 4820 // J. Res. & Dev., No. 1, Jan. 2002. 4821 4822 //----------ATTRIBUTES--------------------------------------------------------- 4823 attributes %{ 4824 4825 // Power4 instructions are of fixed length. 4826 fixed_size_instructions; 4827 4828 // TODO: if `bundle' means number of instructions fetched 4829 // per cycle, this is 8. If `bundle' means Power4 `group', that is 4830 // max instructions issued per cycle, this is 5. 4831 max_instructions_per_bundle = 8; 4832 4833 // A Power4 instruction is 4 bytes long. 4834 instruction_unit_size = 4; 4835 4836 // The Power4 processor fetches 64 bytes... 4837 instruction_fetch_unit_size = 64; 4838 4839 // ...in one line 4840 instruction_fetch_units = 1 4841 4842 // Unused, list one so that array generated by adlc is not empty. 4843 // Aix compiler chokes if _nop_count = 0. 4844 nops(fxNop); 4845 %} 4846 4847 //----------RESOURCES---------------------------------------------------------- 4848 // Resources are the functional units available to the machine 4849 resources( 4850 PPC_BR, // branch unit 4851 PPC_CR, // condition unit 4852 PPC_FX1, // integer arithmetic unit 1 4853 PPC_FX2, // integer arithmetic unit 2 4854 PPC_LDST1, // load/store unit 1 4855 PPC_LDST2, // load/store unit 2 4856 PPC_FP1, // float arithmetic unit 1 4857 PPC_FP2, // float arithmetic unit 2 4858 PPC_LDST = PPC_LDST1 | PPC_LDST2, 4859 PPC_FX = PPC_FX1 | PPC_FX2, 4860 PPC_FP = PPC_FP1 | PPC_FP2 4861 ); 4862 4863 //----------PIPELINE DESCRIPTION----------------------------------------------- 4864 // Pipeline Description specifies the stages in the machine's pipeline 4865 pipe_desc( 4866 // Power4 longest pipeline path 4867 PPC_IF, // instruction fetch 4868 PPC_IC, 4869 //PPC_BP, // branch prediction 4870 PPC_D0, // decode 4871 PPC_D1, // decode 4872 PPC_D2, // decode 4873 PPC_D3, // decode 4874 PPC_Xfer1, 4875 PPC_GD, // group definition 4876 PPC_MP, // map 4877 PPC_ISS, // issue 4878 PPC_RF, // resource fetch 4879 PPC_EX1, // execute (all units) 4880 PPC_EX2, // execute (FP, LDST) 4881 PPC_EX3, // execute (FP, LDST) 4882 PPC_EX4, // execute (FP) 4883 PPC_EX5, // execute (FP) 4884 PPC_EX6, // execute (FP) 4885 PPC_WB, // write back 4886 PPC_Xfer2, 4887 PPC_CP 4888 ); 4889 4890 //----------PIPELINE CLASSES--------------------------------------------------- 4891 // Pipeline Classes describe the stages in which input and output are 4892 // referenced by the hardware pipeline. 4893 4894 // Simple pipeline classes. 4895 4896 // Default pipeline class. 4897 pipe_class pipe_class_default() %{ 4898 single_instruction; 4899 fixed_latency(2); 4900 %} 4901 4902 // Pipeline class for empty instructions. 4903 pipe_class pipe_class_empty() %{ 4904 single_instruction; 4905 fixed_latency(0); 4906 %} 4907 4908 // Pipeline class for compares. 4909 pipe_class pipe_class_compare() %{ 4910 single_instruction; 4911 fixed_latency(16); 4912 %} 4913 4914 // Pipeline class for traps. 4915 pipe_class pipe_class_trap() %{ 4916 single_instruction; 4917 fixed_latency(100); 4918 %} 4919 4920 // Pipeline class for memory operations. 4921 pipe_class pipe_class_memory() %{ 4922 single_instruction; 4923 fixed_latency(16); 4924 %} 4925 4926 // Pipeline class for call. 4927 pipe_class pipe_class_call() %{ 4928 single_instruction; 4929 fixed_latency(100); 4930 %} 4931 4932 // Define the class for the Nop node. 4933 define %{ 4934 MachNop = pipe_class_default; 4935 %} 4936 4937 %} 4938 4939 //----------INSTRUCTIONS------------------------------------------------------- 4940 4941 // Naming of instructions: 4942 // opA_operB / opA_operB_operC: 4943 // Operation 'op' with one or two source operands 'oper'. Result 4944 // type is A, source operand types are B and C. 4945 // Iff A == B == C, B and C are left out. 4946 // 4947 // The instructions are ordered according to the following scheme: 4948 // - loads 4949 // - load constants 4950 // - prefetch 4951 // - store 4952 // - encode/decode 4953 // - membar 4954 // - conditional moves 4955 // - compare & swap 4956 // - arithmetic and logic operations 4957 // * int: Add, Sub, Mul, Div, Mod 4958 // * int: lShift, arShift, urShift, rot 4959 // * float: Add, Sub, Mul, Div 4960 // * and, or, xor ... 4961 // - register moves: float <-> int, reg <-> stack, repl 4962 // - cast (high level type cast, XtoP, castPP, castII, not_null etc. 4963 // - conv (low level type cast requiring bit changes (sign extend etc) 4964 // - compares, range & zero checks. 4965 // - branches 4966 // - complex operations, intrinsics, min, max, replicate 4967 // - lock 4968 // - Calls 4969 // 4970 // If there are similar instructions with different types they are sorted: 4971 // int before float 4972 // small before big 4973 // signed before unsigned 4974 // e.g., loadS before loadUS before loadI before loadF. 4975 4976 4977 //----------Load/Store Instructions-------------------------------------------- 4978 4979 //----------Load Instructions-------------------------------------------------- 4980 4981 // Converts byte to int. 4982 // As convB2I_reg, but without match rule. The match rule of convB2I_reg 4983 // reuses the 'amount' operand, but adlc expects that operand specification 4984 // and operands in match rule are equivalent. 4985 instruct convB2I_reg_2(iRegIdst dst, iRegIsrc src) %{ 4986 effect(DEF dst, USE src); 4987 format %{ "EXTSB $dst, $src \t// byte->int" %} 4988 size(4); 4989 ins_encode %{ 4990 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 4991 __ extsb($dst$$Register, $src$$Register); 4992 %} 4993 ins_pipe(pipe_class_default); 4994 %} 4995 4996 instruct loadUB_indirect(iRegIdst dst, indirectMemory mem) %{ 4997 // match-rule, false predicate 4998 match(Set dst (LoadB mem)); 4999 predicate(false); 5000 5001 format %{ "LBZ $dst, $mem" %} 5002 size(4); 5003 ins_encode( enc_lbz(dst, mem) ); 5004 ins_pipe(pipe_class_memory); 5005 %} 5006 5007 instruct loadUB_indirect_ac(iRegIdst dst, indirectMemory mem) %{ 5008 // match-rule, false predicate 5009 match(Set dst (LoadB mem)); 5010 predicate(false); 5011 5012 format %{ "LBZ $dst, $mem\n\t" 5013 "TWI $dst\n\t" 5014 "ISYNC" %} 5015 size(12); 5016 ins_encode( enc_lbz_ac(dst, mem) ); 5017 ins_pipe(pipe_class_memory); 5018 %} 5019 5020 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5021 instruct loadB_indirect_Ex(iRegIdst dst, indirectMemory mem) %{ 5022 match(Set dst (LoadB mem)); 5023 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5024 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5025 expand %{ 5026 iRegIdst tmp; 5027 loadUB_indirect(tmp, mem); 5028 convB2I_reg_2(dst, tmp); 5029 %} 5030 %} 5031 5032 instruct loadB_indirect_ac_Ex(iRegIdst dst, indirectMemory mem) %{ 5033 match(Set dst (LoadB mem)); 5034 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5035 expand %{ 5036 iRegIdst tmp; 5037 loadUB_indirect_ac(tmp, mem); 5038 convB2I_reg_2(dst, tmp); 5039 %} 5040 %} 5041 5042 instruct loadUB_indOffset16(iRegIdst dst, indOffset16 mem) %{ 5043 // match-rule, false predicate 5044 match(Set dst (LoadB mem)); 5045 predicate(false); 5046 5047 format %{ "LBZ $dst, $mem" %} 5048 size(4); 5049 ins_encode( enc_lbz(dst, mem) ); 5050 ins_pipe(pipe_class_memory); 5051 %} 5052 5053 instruct loadUB_indOffset16_ac(iRegIdst dst, indOffset16 mem) %{ 5054 // match-rule, false predicate 5055 match(Set dst (LoadB mem)); 5056 predicate(false); 5057 5058 format %{ "LBZ $dst, $mem\n\t" 5059 "TWI $dst\n\t" 5060 "ISYNC" %} 5061 size(12); 5062 ins_encode( enc_lbz_ac(dst, mem) ); 5063 ins_pipe(pipe_class_memory); 5064 %} 5065 5066 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5067 instruct loadB_indOffset16_Ex(iRegIdst dst, indOffset16 mem) %{ 5068 match(Set dst (LoadB mem)); 5069 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5070 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5071 5072 expand %{ 5073 iRegIdst tmp; 5074 loadUB_indOffset16(tmp, mem); 5075 convB2I_reg_2(dst, tmp); 5076 %} 5077 %} 5078 5079 instruct loadB_indOffset16_ac_Ex(iRegIdst dst, indOffset16 mem) %{ 5080 match(Set dst (LoadB mem)); 5081 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5082 5083 expand %{ 5084 iRegIdst tmp; 5085 loadUB_indOffset16_ac(tmp, mem); 5086 convB2I_reg_2(dst, tmp); 5087 %} 5088 %} 5089 5090 // Load Unsigned Byte (8bit UNsigned) into an int reg. 5091 instruct loadUB(iRegIdst dst, memory mem) %{ 5092 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5093 match(Set dst (LoadUB mem)); 5094 ins_cost(MEMORY_REF_COST); 5095 5096 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int" %} 5097 size(4); 5098 ins_encode( enc_lbz(dst, mem) ); 5099 ins_pipe(pipe_class_memory); 5100 %} 5101 5102 // Load Unsigned Byte (8bit UNsigned) acquire. 5103 instruct loadUB_ac(iRegIdst dst, memory mem) %{ 5104 match(Set dst (LoadUB mem)); 5105 ins_cost(3*MEMORY_REF_COST); 5106 5107 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int, acquire\n\t" 5108 "TWI $dst\n\t" 5109 "ISYNC" %} 5110 size(12); 5111 ins_encode( enc_lbz_ac(dst, mem) ); 5112 ins_pipe(pipe_class_memory); 5113 %} 5114 5115 // Load Unsigned Byte (8bit UNsigned) into a Long Register. 5116 instruct loadUB2L(iRegLdst dst, memory mem) %{ 5117 match(Set dst (ConvI2L (LoadUB mem))); 5118 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5119 ins_cost(MEMORY_REF_COST); 5120 5121 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long" %} 5122 size(4); 5123 ins_encode( enc_lbz(dst, mem) ); 5124 ins_pipe(pipe_class_memory); 5125 %} 5126 5127 instruct loadUB2L_ac(iRegLdst dst, memory mem) %{ 5128 match(Set dst (ConvI2L (LoadUB mem))); 5129 ins_cost(3*MEMORY_REF_COST); 5130 5131 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long, acquire\n\t" 5132 "TWI $dst\n\t" 5133 "ISYNC" %} 5134 size(12); 5135 ins_encode( enc_lbz_ac(dst, mem) ); 5136 ins_pipe(pipe_class_memory); 5137 %} 5138 5139 // Load Short (16bit signed) 5140 instruct loadS(iRegIdst dst, memory mem) %{ 5141 match(Set dst (LoadS mem)); 5142 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5143 ins_cost(MEMORY_REF_COST); 5144 5145 format %{ "LHA $dst, $mem" %} 5146 size(4); 5147 ins_encode %{ 5148 // TODO: PPC port $archOpcode(ppc64Opcode_lha); 5149 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5150 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5151 %} 5152 ins_pipe(pipe_class_memory); 5153 %} 5154 5155 // Load Short (16bit signed) acquire. 5156 instruct loadS_ac(iRegIdst dst, memory mem) %{ 5157 match(Set dst (LoadS mem)); 5158 ins_cost(3*MEMORY_REF_COST); 5159 5160 format %{ "LHA $dst, $mem\t acquire\n\t" 5161 "TWI $dst\n\t" 5162 "ISYNC" %} 5163 size(12); 5164 ins_encode %{ 5165 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5166 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5167 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5168 __ twi_0($dst$$Register); 5169 __ isync(); 5170 %} 5171 ins_pipe(pipe_class_memory); 5172 %} 5173 5174 // Load Char (16bit unsigned) 5175 instruct loadUS(iRegIdst dst, memory mem) %{ 5176 match(Set dst (LoadUS mem)); 5177 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5178 ins_cost(MEMORY_REF_COST); 5179 5180 format %{ "LHZ $dst, $mem" %} 5181 size(4); 5182 ins_encode( enc_lhz(dst, mem) ); 5183 ins_pipe(pipe_class_memory); 5184 %} 5185 5186 // Load Char (16bit unsigned) acquire. 5187 instruct loadUS_ac(iRegIdst dst, memory mem) %{ 5188 match(Set dst (LoadUS mem)); 5189 ins_cost(3*MEMORY_REF_COST); 5190 5191 format %{ "LHZ $dst, $mem \t// acquire\n\t" 5192 "TWI $dst\n\t" 5193 "ISYNC" %} 5194 size(12); 5195 ins_encode( enc_lhz_ac(dst, mem) ); 5196 ins_pipe(pipe_class_memory); 5197 %} 5198 5199 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register. 5200 instruct loadUS2L(iRegLdst dst, memory mem) %{ 5201 match(Set dst (ConvI2L (LoadUS mem))); 5202 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5203 ins_cost(MEMORY_REF_COST); 5204 5205 format %{ "LHZ $dst, $mem \t// short, zero-extend to long" %} 5206 size(4); 5207 ins_encode( enc_lhz(dst, mem) ); 5208 ins_pipe(pipe_class_memory); 5209 %} 5210 5211 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register acquire. 5212 instruct loadUS2L_ac(iRegLdst dst, memory mem) %{ 5213 match(Set dst (ConvI2L (LoadUS mem))); 5214 ins_cost(3*MEMORY_REF_COST); 5215 5216 format %{ "LHZ $dst, $mem \t// short, zero-extend to long, acquire\n\t" 5217 "TWI $dst\n\t" 5218 "ISYNC" %} 5219 size(12); 5220 ins_encode( enc_lhz_ac(dst, mem) ); 5221 ins_pipe(pipe_class_memory); 5222 %} 5223 5224 // Load Integer. 5225 instruct loadI(iRegIdst dst, memory mem) %{ 5226 match(Set dst (LoadI mem)); 5227 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5228 ins_cost(MEMORY_REF_COST); 5229 5230 format %{ "LWZ $dst, $mem" %} 5231 size(4); 5232 ins_encode( enc_lwz(dst, mem) ); 5233 ins_pipe(pipe_class_memory); 5234 %} 5235 5236 // Load Integer acquire. 5237 instruct loadI_ac(iRegIdst dst, memory mem) %{ 5238 match(Set dst (LoadI mem)); 5239 ins_cost(3*MEMORY_REF_COST); 5240 5241 format %{ "LWZ $dst, $mem \t// load acquire\n\t" 5242 "TWI $dst\n\t" 5243 "ISYNC" %} 5244 size(12); 5245 ins_encode( enc_lwz_ac(dst, mem) ); 5246 ins_pipe(pipe_class_memory); 5247 %} 5248 5249 // Match loading integer and casting it to unsigned int in 5250 // long register. 5251 // LoadI + ConvI2L + AndL 0xffffffff. 5252 instruct loadUI2L(iRegLdst dst, memory mem, immL_32bits mask) %{ 5253 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5254 predicate(_kids[0]->_kids[0]->_leaf->as_Load()->is_unordered()); 5255 ins_cost(MEMORY_REF_COST); 5256 5257 format %{ "LWZ $dst, $mem \t// zero-extend to long" %} 5258 size(4); 5259 ins_encode( enc_lwz(dst, mem) ); 5260 ins_pipe(pipe_class_memory); 5261 %} 5262 5263 // Match loading integer and casting it to long. 5264 instruct loadI2L(iRegLdst dst, memoryAlg4 mem) %{ 5265 match(Set dst (ConvI2L (LoadI mem))); 5266 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5267 ins_cost(MEMORY_REF_COST); 5268 5269 format %{ "LWA $dst, $mem \t// loadI2L" %} 5270 size(4); 5271 ins_encode %{ 5272 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5273 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5274 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5275 %} 5276 ins_pipe(pipe_class_memory); 5277 %} 5278 5279 // Match loading integer and casting it to long - acquire. 5280 instruct loadI2L_ac(iRegLdst dst, memoryAlg4 mem) %{ 5281 match(Set dst (ConvI2L (LoadI mem))); 5282 ins_cost(3*MEMORY_REF_COST); 5283 5284 format %{ "LWA $dst, $mem \t// loadI2L acquire" 5285 "TWI $dst\n\t" 5286 "ISYNC" %} 5287 size(12); 5288 ins_encode %{ 5289 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5290 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5291 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5292 __ twi_0($dst$$Register); 5293 __ isync(); 5294 %} 5295 ins_pipe(pipe_class_memory); 5296 %} 5297 5298 // Load Long - aligned 5299 instruct loadL(iRegLdst dst, memoryAlg4 mem) %{ 5300 match(Set dst (LoadL mem)); 5301 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5302 ins_cost(MEMORY_REF_COST); 5303 5304 format %{ "LD $dst, $mem \t// long" %} 5305 size(4); 5306 ins_encode( enc_ld(dst, mem) ); 5307 ins_pipe(pipe_class_memory); 5308 %} 5309 5310 // Load Long - aligned acquire. 5311 instruct loadL_ac(iRegLdst dst, memoryAlg4 mem) %{ 5312 match(Set dst (LoadL mem)); 5313 ins_cost(3*MEMORY_REF_COST); 5314 5315 format %{ "LD $dst, $mem \t// long acquire\n\t" 5316 "TWI $dst\n\t" 5317 "ISYNC" %} 5318 size(12); 5319 ins_encode( enc_ld_ac(dst, mem) ); 5320 ins_pipe(pipe_class_memory); 5321 %} 5322 5323 // Load Long - UNaligned 5324 instruct loadL_unaligned(iRegLdst dst, memoryAlg4 mem) %{ 5325 match(Set dst (LoadL_unaligned mem)); 5326 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 5327 ins_cost(MEMORY_REF_COST); 5328 5329 format %{ "LD $dst, $mem \t// unaligned long" %} 5330 size(4); 5331 ins_encode( enc_ld(dst, mem) ); 5332 ins_pipe(pipe_class_memory); 5333 %} 5334 5335 // Load nodes for superwords 5336 5337 // Load Aligned Packed Byte 5338 instruct loadV8(iRegLdst dst, memoryAlg4 mem) %{ 5339 predicate(n->as_LoadVector()->memory_size() == 8); 5340 match(Set dst (LoadVector mem)); 5341 ins_cost(MEMORY_REF_COST); 5342 5343 format %{ "LD $dst, $mem \t// load 8-byte Vector" %} 5344 size(4); 5345 ins_encode( enc_ld(dst, mem) ); 5346 ins_pipe(pipe_class_memory); 5347 %} 5348 5349 // Load Range, range = array length (=jint) 5350 instruct loadRange(iRegIdst dst, memory mem) %{ 5351 match(Set dst (LoadRange mem)); 5352 ins_cost(MEMORY_REF_COST); 5353 5354 format %{ "LWZ $dst, $mem \t// range" %} 5355 size(4); 5356 ins_encode( enc_lwz(dst, mem) ); 5357 ins_pipe(pipe_class_memory); 5358 %} 5359 5360 // Load Compressed Pointer 5361 instruct loadN(iRegNdst dst, memory mem) %{ 5362 match(Set dst (LoadN mem)); 5363 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5364 ins_cost(MEMORY_REF_COST); 5365 5366 format %{ "LWZ $dst, $mem \t// load compressed ptr" %} 5367 size(4); 5368 ins_encode( enc_lwz(dst, mem) ); 5369 ins_pipe(pipe_class_memory); 5370 %} 5371 5372 // Load Compressed Pointer acquire. 5373 instruct loadN_ac(iRegNdst dst, memory mem) %{ 5374 match(Set dst (LoadN mem)); 5375 ins_cost(3*MEMORY_REF_COST); 5376 5377 format %{ "LWZ $dst, $mem \t// load acquire compressed ptr\n\t" 5378 "TWI $dst\n\t" 5379 "ISYNC" %} 5380 size(12); 5381 ins_encode( enc_lwz_ac(dst, mem) ); 5382 ins_pipe(pipe_class_memory); 5383 %} 5384 5385 // Load Compressed Pointer and decode it if narrow_oop_shift == 0. 5386 instruct loadN2P_unscaled(iRegPdst dst, memory mem) %{ 5387 match(Set dst (DecodeN (LoadN mem))); 5388 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && Universe::narrow_oop_shift() == 0); 5389 ins_cost(MEMORY_REF_COST); 5390 5391 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5392 size(4); 5393 ins_encode( enc_lwz(dst, mem) ); 5394 ins_pipe(pipe_class_memory); 5395 %} 5396 5397 instruct loadN2P_klass_unscaled(iRegPdst dst, memory mem) %{ 5398 match(Set dst (DecodeNKlass (LoadNKlass mem))); 5399 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0 && 5400 _kids[0]->_leaf->as_Load()->is_unordered()); 5401 ins_cost(MEMORY_REF_COST); 5402 5403 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5404 size(4); 5405 ins_encode( enc_lwz(dst, mem) ); 5406 ins_pipe(pipe_class_memory); 5407 %} 5408 5409 // Load Pointer 5410 instruct loadP(iRegPdst dst, memoryAlg4 mem) %{ 5411 match(Set dst (LoadP mem)); 5412 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5413 ins_cost(MEMORY_REF_COST); 5414 5415 format %{ "LD $dst, $mem \t// ptr" %} 5416 size(4); 5417 ins_encode( enc_ld(dst, mem) ); 5418 ins_pipe(pipe_class_memory); 5419 %} 5420 5421 // Load Pointer acquire. 5422 instruct loadP_ac(iRegPdst dst, memoryAlg4 mem) %{ 5423 match(Set dst (LoadP mem)); 5424 ins_cost(3*MEMORY_REF_COST); 5425 5426 format %{ "LD $dst, $mem \t// ptr acquire\n\t" 5427 "TWI $dst\n\t" 5428 "ISYNC" %} 5429 size(12); 5430 ins_encode( enc_ld_ac(dst, mem) ); 5431 ins_pipe(pipe_class_memory); 5432 %} 5433 5434 // LoadP + CastP2L 5435 instruct loadP2X(iRegLdst dst, memoryAlg4 mem) %{ 5436 match(Set dst (CastP2X (LoadP mem))); 5437 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5438 ins_cost(MEMORY_REF_COST); 5439 5440 format %{ "LD $dst, $mem \t// ptr + p2x" %} 5441 size(4); 5442 ins_encode( enc_ld(dst, mem) ); 5443 ins_pipe(pipe_class_memory); 5444 %} 5445 5446 // Load compressed klass pointer. 5447 instruct loadNKlass(iRegNdst dst, memory mem) %{ 5448 match(Set dst (LoadNKlass mem)); 5449 ins_cost(MEMORY_REF_COST); 5450 5451 format %{ "LWZ $dst, $mem \t// compressed klass ptr" %} 5452 size(4); 5453 ins_encode( enc_lwz(dst, mem) ); 5454 ins_pipe(pipe_class_memory); 5455 %} 5456 5457 // Load Klass Pointer 5458 instruct loadKlass(iRegPdst dst, memoryAlg4 mem) %{ 5459 match(Set dst (LoadKlass mem)); 5460 ins_cost(MEMORY_REF_COST); 5461 5462 format %{ "LD $dst, $mem \t// klass ptr" %} 5463 size(4); 5464 ins_encode( enc_ld(dst, mem) ); 5465 ins_pipe(pipe_class_memory); 5466 %} 5467 5468 // Load Float 5469 instruct loadF(regF dst, memory mem) %{ 5470 match(Set dst (LoadF mem)); 5471 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5472 ins_cost(MEMORY_REF_COST); 5473 5474 format %{ "LFS $dst, $mem" %} 5475 size(4); 5476 ins_encode %{ 5477 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 5478 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5479 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5480 %} 5481 ins_pipe(pipe_class_memory); 5482 %} 5483 5484 // Load Float acquire. 5485 instruct loadF_ac(regF dst, memory mem, flagsRegCR0 cr0) %{ 5486 match(Set dst (LoadF mem)); 5487 effect(TEMP cr0); 5488 ins_cost(3*MEMORY_REF_COST); 5489 5490 format %{ "LFS $dst, $mem \t// acquire\n\t" 5491 "FCMPU cr0, $dst, $dst\n\t" 5492 "BNE cr0, next\n" 5493 "next:\n\t" 5494 "ISYNC" %} 5495 size(16); 5496 ins_encode %{ 5497 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5498 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5499 Label next; 5500 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5501 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 5502 __ bne(CCR0, next); 5503 __ bind(next); 5504 __ isync(); 5505 %} 5506 ins_pipe(pipe_class_memory); 5507 %} 5508 5509 // Load Double - aligned 5510 instruct loadD(regD dst, memory mem) %{ 5511 match(Set dst (LoadD mem)); 5512 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5513 ins_cost(MEMORY_REF_COST); 5514 5515 format %{ "LFD $dst, $mem" %} 5516 size(4); 5517 ins_encode( enc_lfd(dst, mem) ); 5518 ins_pipe(pipe_class_memory); 5519 %} 5520 5521 // Load Double - aligned acquire. 5522 instruct loadD_ac(regD dst, memory mem, flagsRegCR0 cr0) %{ 5523 match(Set dst (LoadD mem)); 5524 effect(TEMP cr0); 5525 ins_cost(3*MEMORY_REF_COST); 5526 5527 format %{ "LFD $dst, $mem \t// acquire\n\t" 5528 "FCMPU cr0, $dst, $dst\n\t" 5529 "BNE cr0, next\n" 5530 "next:\n\t" 5531 "ISYNC" %} 5532 size(16); 5533 ins_encode %{ 5534 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5535 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5536 Label next; 5537 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5538 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 5539 __ bne(CCR0, next); 5540 __ bind(next); 5541 __ isync(); 5542 %} 5543 ins_pipe(pipe_class_memory); 5544 %} 5545 5546 // Load Double - UNaligned 5547 instruct loadD_unaligned(regD dst, memory mem) %{ 5548 match(Set dst (LoadD_unaligned mem)); 5549 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 5550 ins_cost(MEMORY_REF_COST); 5551 5552 format %{ "LFD $dst, $mem" %} 5553 size(4); 5554 ins_encode( enc_lfd(dst, mem) ); 5555 ins_pipe(pipe_class_memory); 5556 %} 5557 5558 //----------Constants-------------------------------------------------------- 5559 5560 // Load MachConstantTableBase: add hi offset to global toc. 5561 // TODO: Handle hidden register r29 in bundler! 5562 instruct loadToc_hi(iRegLdst dst) %{ 5563 effect(DEF dst); 5564 ins_cost(DEFAULT_COST); 5565 5566 format %{ "ADDIS $dst, R29, DISP.hi \t// load TOC hi" %} 5567 size(4); 5568 ins_encode %{ 5569 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 5570 __ calculate_address_from_global_toc_hi16only($dst$$Register, __ method_toc()); 5571 %} 5572 ins_pipe(pipe_class_default); 5573 %} 5574 5575 // Load MachConstantTableBase: add lo offset to global toc. 5576 instruct loadToc_lo(iRegLdst dst, iRegLdst src) %{ 5577 effect(DEF dst, USE src); 5578 ins_cost(DEFAULT_COST); 5579 5580 format %{ "ADDI $dst, $src, DISP.lo \t// load TOC lo" %} 5581 size(4); 5582 ins_encode %{ 5583 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 5584 __ calculate_address_from_global_toc_lo16only($dst$$Register, __ method_toc()); 5585 %} 5586 ins_pipe(pipe_class_default); 5587 %} 5588 5589 // Load 16-bit integer constant 0xssss???? 5590 instruct loadConI16(iRegIdst dst, immI16 src) %{ 5591 match(Set dst src); 5592 5593 format %{ "LI $dst, $src" %} 5594 size(4); 5595 ins_encode %{ 5596 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 5597 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 5598 %} 5599 ins_pipe(pipe_class_default); 5600 %} 5601 5602 // Load integer constant 0x????0000 5603 instruct loadConIhi16(iRegIdst dst, immIhi16 src) %{ 5604 match(Set dst src); 5605 ins_cost(DEFAULT_COST); 5606 5607 format %{ "LIS $dst, $src.hi" %} 5608 size(4); 5609 ins_encode %{ 5610 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 5611 // Lis sign extends 16-bit src then shifts it 16 bit to the left. 5612 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 5613 %} 5614 ins_pipe(pipe_class_default); 5615 %} 5616 5617 // Part 2 of loading 32 bit constant: hi16 is is src1 (properly shifted 5618 // and sign extended), this adds the low 16 bits. 5619 instruct loadConI32_lo16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 5620 // no match-rule, false predicate 5621 effect(DEF dst, USE src1, USE src2); 5622 predicate(false); 5623 5624 format %{ "ORI $dst, $src1.hi, $src2.lo" %} 5625 size(4); 5626 ins_encode %{ 5627 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 5628 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 5629 %} 5630 ins_pipe(pipe_class_default); 5631 %} 5632 5633 instruct loadConI_Ex(iRegIdst dst, immI src) %{ 5634 match(Set dst src); 5635 ins_cost(DEFAULT_COST*2); 5636 5637 expand %{ 5638 // Would like to use $src$$constant. 5639 immI16 srcLo %{ _opnds[1]->constant() %} 5640 // srcHi can be 0000 if srcLo sign-extends to a negative number. 5641 immIhi16 srcHi %{ _opnds[1]->constant() %} 5642 iRegIdst tmpI; 5643 loadConIhi16(tmpI, srcHi); 5644 loadConI32_lo16(dst, tmpI, srcLo); 5645 %} 5646 %} 5647 5648 // No constant pool entries required. 5649 instruct loadConL16(iRegLdst dst, immL16 src) %{ 5650 match(Set dst src); 5651 5652 format %{ "LI $dst, $src \t// long" %} 5653 size(4); 5654 ins_encode %{ 5655 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 5656 __ li($dst$$Register, (int)((short) ($src$$constant & 0xFFFF))); 5657 %} 5658 ins_pipe(pipe_class_default); 5659 %} 5660 5661 // Load long constant 0xssssssss????0000 5662 instruct loadConL32hi16(iRegLdst dst, immL32hi16 src) %{ 5663 match(Set dst src); 5664 ins_cost(DEFAULT_COST); 5665 5666 format %{ "LIS $dst, $src.hi \t// long" %} 5667 size(4); 5668 ins_encode %{ 5669 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 5670 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 5671 %} 5672 ins_pipe(pipe_class_default); 5673 %} 5674 5675 // To load a 32 bit constant: merge lower 16 bits into already loaded 5676 // high 16 bits. 5677 instruct loadConL32_lo16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 5678 // no match-rule, false predicate 5679 effect(DEF dst, USE src1, USE src2); 5680 predicate(false); 5681 5682 format %{ "ORI $dst, $src1, $src2.lo" %} 5683 size(4); 5684 ins_encode %{ 5685 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 5686 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 5687 %} 5688 ins_pipe(pipe_class_default); 5689 %} 5690 5691 // Load 32-bit long constant 5692 instruct loadConL32_Ex(iRegLdst dst, immL32 src) %{ 5693 match(Set dst src); 5694 ins_cost(DEFAULT_COST*2); 5695 5696 expand %{ 5697 // Would like to use $src$$constant. 5698 immL16 srcLo %{ _opnds[1]->constant() /*& 0x0000FFFFL */%} 5699 // srcHi can be 0000 if srcLo sign-extends to a negative number. 5700 immL32hi16 srcHi %{ _opnds[1]->constant() /*& 0xFFFF0000L */%} 5701 iRegLdst tmpL; 5702 loadConL32hi16(tmpL, srcHi); 5703 loadConL32_lo16(dst, tmpL, srcLo); 5704 %} 5705 %} 5706 5707 // Load long constant 0x????000000000000. 5708 instruct loadConLhighest16_Ex(iRegLdst dst, immLhighest16 src) %{ 5709 match(Set dst src); 5710 ins_cost(DEFAULT_COST); 5711 5712 expand %{ 5713 immL32hi16 srcHi %{ _opnds[1]->constant() >> 32 /*& 0xFFFF0000L */%} 5714 immI shift32 %{ 32 %} 5715 iRegLdst tmpL; 5716 loadConL32hi16(tmpL, srcHi); 5717 lshiftL_regL_immI(dst, tmpL, shift32); 5718 %} 5719 %} 5720 5721 // Expand node for constant pool load: small offset. 5722 instruct loadConL(iRegLdst dst, immL src, iRegLdst toc) %{ 5723 effect(DEF dst, USE src, USE toc); 5724 ins_cost(MEMORY_REF_COST); 5725 5726 ins_num_consts(1); 5727 // Needed so that CallDynamicJavaDirect can compute the address of this 5728 // instruction for relocation. 5729 ins_field_cbuf_insts_offset(int); 5730 5731 format %{ "LD $dst, offset, $toc \t// load long $src from TOC" %} 5732 size(4); 5733 ins_encode( enc_load_long_constL(dst, src, toc) ); 5734 ins_pipe(pipe_class_memory); 5735 %} 5736 5737 // Expand node for constant pool load: large offset. 5738 instruct loadConL_hi(iRegLdst dst, immL src, iRegLdst toc) %{ 5739 effect(DEF dst, USE src, USE toc); 5740 predicate(false); 5741 5742 ins_num_consts(1); 5743 ins_field_const_toc_offset(int); 5744 // Needed so that CallDynamicJavaDirect can compute the address of this 5745 // instruction for relocation. 5746 ins_field_cbuf_insts_offset(int); 5747 5748 format %{ "ADDIS $dst, $toc, offset \t// load long $src from TOC (hi)" %} 5749 size(4); 5750 ins_encode( enc_load_long_constL_hi(dst, toc, src) ); 5751 ins_pipe(pipe_class_default); 5752 %} 5753 5754 // Expand node for constant pool load: large offset. 5755 // No constant pool entries required. 5756 instruct loadConL_lo(iRegLdst dst, immL src, iRegLdst base) %{ 5757 effect(DEF dst, USE src, USE base); 5758 predicate(false); 5759 5760 ins_field_const_toc_offset_hi_node(loadConL_hiNode*); 5761 5762 format %{ "LD $dst, offset, $base \t// load long $src from TOC (lo)" %} 5763 size(4); 5764 ins_encode %{ 5765 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 5766 int offset = ra_->C->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 5767 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 5768 %} 5769 ins_pipe(pipe_class_memory); 5770 %} 5771 5772 // Load long constant from constant table. Expand in case of 5773 // offset > 16 bit is needed. 5774 // Adlc adds toc node MachConstantTableBase. 5775 instruct loadConL_Ex(iRegLdst dst, immL src) %{ 5776 match(Set dst src); 5777 ins_cost(MEMORY_REF_COST); 5778 5779 format %{ "LD $dst, offset, $constanttablebase\t// load long $src from table, postalloc expanded" %} 5780 // We can not inline the enc_class for the expand as that does not support constanttablebase. 5781 postalloc_expand( postalloc_expand_load_long_constant(dst, src, constanttablebase) ); 5782 %} 5783 5784 // Load NULL as compressed oop. 5785 instruct loadConN0(iRegNdst dst, immN_0 src) %{ 5786 match(Set dst src); 5787 ins_cost(DEFAULT_COST); 5788 5789 format %{ "LI $dst, $src \t// compressed ptr" %} 5790 size(4); 5791 ins_encode %{ 5792 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 5793 __ li($dst$$Register, 0); 5794 %} 5795 ins_pipe(pipe_class_default); 5796 %} 5797 5798 // Load hi part of compressed oop constant. 5799 instruct loadConN_hi(iRegNdst dst, immN src) %{ 5800 effect(DEF dst, USE src); 5801 ins_cost(DEFAULT_COST); 5802 5803 format %{ "LIS $dst, $src \t// narrow oop hi" %} 5804 size(4); 5805 ins_encode %{ 5806 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 5807 __ lis($dst$$Register, (int)(short)(($src$$constant >> 16) & 0xffff)); 5808 %} 5809 ins_pipe(pipe_class_default); 5810 %} 5811 5812 // Add lo part of compressed oop constant to already loaded hi part. 5813 instruct loadConN_lo(iRegNdst dst, iRegNsrc src1, immN src2) %{ 5814 effect(DEF dst, USE src1, USE src2); 5815 ins_cost(DEFAULT_COST); 5816 5817 format %{ "ORI $dst, $src1, $src2 \t// narrow oop lo" %} 5818 size(4); 5819 ins_encode %{ 5820 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 5821 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 5822 int oop_index = __ oop_recorder()->find_index((jobject)$src2$$constant); 5823 RelocationHolder rspec = oop_Relocation::spec(oop_index); 5824 __ relocate(rspec, 1); 5825 __ ori($dst$$Register, $src1$$Register, $src2$$constant & 0xffff); 5826 %} 5827 ins_pipe(pipe_class_default); 5828 %} 5829 5830 // Needed to postalloc expand loadConN: ConN is loaded as ConI 5831 // leaving the upper 32 bits with sign-extension bits. 5832 // This clears these bits: dst = src & 0xFFFFFFFF. 5833 // TODO: Eventually call this maskN_regN_FFFFFFFF. 5834 instruct clearMs32b(iRegNdst dst, iRegNsrc src) %{ 5835 effect(DEF dst, USE src); 5836 predicate(false); 5837 5838 format %{ "MASK $dst, $src, 0xFFFFFFFF" %} // mask 5839 size(4); 5840 ins_encode %{ 5841 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 5842 __ clrldi($dst$$Register, $src$$Register, 0x20); 5843 %} 5844 ins_pipe(pipe_class_default); 5845 %} 5846 5847 // Optimize DecodeN for disjoint base. 5848 // Load base of compressed oops into a register 5849 instruct loadBase(iRegLdst dst) %{ 5850 effect(DEF dst); 5851 5852 format %{ "LoadConst $dst, heapbase" %} 5853 ins_encode %{ 5854 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5855 __ load_const_optimized($dst$$Register, Universe::narrow_oop_base(), R0); 5856 %} 5857 ins_pipe(pipe_class_default); 5858 %} 5859 5860 // Loading ConN must be postalloc expanded so that edges between 5861 // the nodes are safe. They may not interfere with a safepoint. 5862 // GL TODO: This needs three instructions: better put this into the constant pool. 5863 instruct loadConN_Ex(iRegNdst dst, immN src) %{ 5864 match(Set dst src); 5865 ins_cost(DEFAULT_COST*2); 5866 5867 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 5868 postalloc_expand %{ 5869 MachNode *m1 = new loadConN_hiNode(); 5870 MachNode *m2 = new loadConN_loNode(); 5871 MachNode *m3 = new clearMs32bNode(); 5872 m1->add_req(NULL); 5873 m2->add_req(NULL, m1); 5874 m3->add_req(NULL, m2); 5875 m1->_opnds[0] = op_dst; 5876 m1->_opnds[1] = op_src; 5877 m2->_opnds[0] = op_dst; 5878 m2->_opnds[1] = op_dst; 5879 m2->_opnds[2] = op_src; 5880 m3->_opnds[0] = op_dst; 5881 m3->_opnds[1] = op_dst; 5882 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5883 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5884 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5885 nodes->push(m1); 5886 nodes->push(m2); 5887 nodes->push(m3); 5888 %} 5889 %} 5890 5891 // We have seen a safepoint between the hi and lo parts, and this node was handled 5892 // as an oop. Therefore this needs a match rule so that build_oop_map knows this is 5893 // not a narrow oop. 5894 instruct loadConNKlass_hi(iRegNdst dst, immNKlass_NM src) %{ 5895 match(Set dst src); 5896 effect(DEF dst, USE src); 5897 ins_cost(DEFAULT_COST); 5898 5899 format %{ "LIS $dst, $src \t// narrow klass hi" %} 5900 size(4); 5901 ins_encode %{ 5902 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 5903 intptr_t Csrc = Klass::encode_klass((Klass *)$src$$constant); 5904 __ lis($dst$$Register, (int)(short)((Csrc >> 16) & 0xffff)); 5905 %} 5906 ins_pipe(pipe_class_default); 5907 %} 5908 5909 // As loadConNKlass_hi this must be recognized as narrow klass, not oop! 5910 instruct loadConNKlass_mask(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 5911 match(Set dst src1); 5912 effect(TEMP src2); 5913 ins_cost(DEFAULT_COST); 5914 5915 format %{ "MASK $dst, $src2, 0xFFFFFFFF" %} // mask 5916 size(4); 5917 ins_encode %{ 5918 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 5919 __ clrldi($dst$$Register, $src2$$Register, 0x20); 5920 %} 5921 ins_pipe(pipe_class_default); 5922 %} 5923 5924 // This needs a match rule so that build_oop_map knows this is 5925 // not a narrow oop. 5926 instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 5927 match(Set dst src1); 5928 effect(TEMP src2); 5929 ins_cost(DEFAULT_COST); 5930 5931 format %{ "ORI $dst, $src1, $src2 \t// narrow klass lo" %} 5932 size(4); 5933 ins_encode %{ 5934 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 5935 intptr_t Csrc = Klass::encode_klass((Klass *)$src1$$constant); 5936 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 5937 int klass_index = __ oop_recorder()->find_index((Klass *)$src1$$constant); 5938 RelocationHolder rspec = metadata_Relocation::spec(klass_index); 5939 5940 __ relocate(rspec, 1); 5941 __ ori($dst$$Register, $src2$$Register, Csrc & 0xffff); 5942 %} 5943 ins_pipe(pipe_class_default); 5944 %} 5945 5946 // Loading ConNKlass must be postalloc expanded so that edges between 5947 // the nodes are safe. They may not interfere with a safepoint. 5948 instruct loadConNKlass_Ex(iRegNdst dst, immNKlass src) %{ 5949 match(Set dst src); 5950 ins_cost(DEFAULT_COST*2); 5951 5952 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 5953 postalloc_expand %{ 5954 // Load high bits into register. Sign extended. 5955 MachNode *m1 = new loadConNKlass_hiNode(); 5956 m1->add_req(NULL); 5957 m1->_opnds[0] = op_dst; 5958 m1->_opnds[1] = op_src; 5959 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5960 nodes->push(m1); 5961 5962 MachNode *m2 = m1; 5963 if (!Assembler::is_uimm((jlong)Klass::encode_klass((Klass *)op_src->constant()), 31)) { 5964 // Value might be 1-extended. Mask out these bits. 5965 m2 = new loadConNKlass_maskNode(); 5966 m2->add_req(NULL, m1); 5967 m2->_opnds[0] = op_dst; 5968 m2->_opnds[1] = op_src; 5969 m2->_opnds[2] = op_dst; 5970 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5971 nodes->push(m2); 5972 } 5973 5974 MachNode *m3 = new loadConNKlass_loNode(); 5975 m3->add_req(NULL, m2); 5976 m3->_opnds[0] = op_dst; 5977 m3->_opnds[1] = op_src; 5978 m3->_opnds[2] = op_dst; 5979 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5980 nodes->push(m3); 5981 %} 5982 %} 5983 5984 // 0x1 is used in object initialization (initial object header). 5985 // No constant pool entries required. 5986 instruct loadConP0or1(iRegPdst dst, immP_0or1 src) %{ 5987 match(Set dst src); 5988 5989 format %{ "LI $dst, $src \t// ptr" %} 5990 size(4); 5991 ins_encode %{ 5992 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 5993 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 5994 %} 5995 ins_pipe(pipe_class_default); 5996 %} 5997 5998 // Expand node for constant pool load: small offset. 5999 // The match rule is needed to generate the correct bottom_type(), 6000 // however this node should never match. The use of predicate is not 6001 // possible since ADLC forbids predicates for chain rules. The higher 6002 // costs do not prevent matching in this case. For that reason the 6003 // operand immP_NM with predicate(false) is used. 6004 instruct loadConP(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6005 match(Set dst src); 6006 effect(TEMP toc); 6007 6008 ins_num_consts(1); 6009 6010 format %{ "LD $dst, offset, $toc \t// load ptr $src from TOC" %} 6011 size(4); 6012 ins_encode( enc_load_long_constP(dst, src, toc) ); 6013 ins_pipe(pipe_class_memory); 6014 %} 6015 6016 // Expand node for constant pool load: large offset. 6017 instruct loadConP_hi(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6018 effect(DEF dst, USE src, USE toc); 6019 predicate(false); 6020 6021 ins_num_consts(1); 6022 ins_field_const_toc_offset(int); 6023 6024 format %{ "ADDIS $dst, $toc, offset \t// load ptr $src from TOC (hi)" %} 6025 size(4); 6026 ins_encode( enc_load_long_constP_hi(dst, src, toc) ); 6027 ins_pipe(pipe_class_default); 6028 %} 6029 6030 // Expand node for constant pool load: large offset. 6031 instruct loadConP_lo(iRegPdst dst, immP_NM src, iRegLdst base) %{ 6032 match(Set dst src); 6033 effect(TEMP base); 6034 6035 ins_field_const_toc_offset_hi_node(loadConP_hiNode*); 6036 6037 format %{ "LD $dst, offset, $base \t// load ptr $src from TOC (lo)" %} 6038 size(4); 6039 ins_encode %{ 6040 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 6041 int offset = ra_->C->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 6042 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 6043 %} 6044 ins_pipe(pipe_class_memory); 6045 %} 6046 6047 // Load pointer constant from constant table. Expand in case an 6048 // offset > 16 bit is needed. 6049 // Adlc adds toc node MachConstantTableBase. 6050 instruct loadConP_Ex(iRegPdst dst, immP src) %{ 6051 match(Set dst src); 6052 ins_cost(MEMORY_REF_COST); 6053 6054 // This rule does not use "expand" because then 6055 // the result type is not known to be an Oop. An ADLC 6056 // enhancement will be needed to make that work - not worth it! 6057 6058 // If this instruction rematerializes, it prolongs the live range 6059 // of the toc node, causing illegal graphs. 6060 // assert(edge_from_to(_reg_node[reg_lo],def)) fails in verify_good_schedule(). 6061 ins_cannot_rematerialize(true); 6062 6063 format %{ "LD $dst, offset, $constanttablebase \t// load ptr $src from table, postalloc expanded" %} 6064 postalloc_expand( postalloc_expand_load_ptr_constant(dst, src, constanttablebase) ); 6065 %} 6066 6067 // Expand node for constant pool load: small offset. 6068 instruct loadConF(regF dst, immF src, iRegLdst toc) %{ 6069 effect(DEF dst, USE src, USE toc); 6070 ins_cost(MEMORY_REF_COST); 6071 6072 ins_num_consts(1); 6073 6074 format %{ "LFS $dst, offset, $toc \t// load float $src from TOC" %} 6075 size(4); 6076 ins_encode %{ 6077 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 6078 address float_address = __ float_constant($src$$constant); 6079 if (float_address == NULL) { 6080 ciEnv::current()->record_out_of_memory_failure(); 6081 return; 6082 } 6083 __ lfs($dst$$FloatRegister, __ offset_to_method_toc(float_address), $toc$$Register); 6084 %} 6085 ins_pipe(pipe_class_memory); 6086 %} 6087 6088 // Expand node for constant pool load: large offset. 6089 instruct loadConFComp(regF dst, immF src, iRegLdst toc) %{ 6090 effect(DEF dst, USE src, USE toc); 6091 ins_cost(MEMORY_REF_COST); 6092 6093 ins_num_consts(1); 6094 6095 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6096 "LFS $dst, offset_lo, $toc \t// load float $src from TOC (hi/lo)\n\t" 6097 "ADDIS $toc, $toc, -offset_hi"%} 6098 size(12); 6099 ins_encode %{ 6100 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6101 FloatRegister Rdst = $dst$$FloatRegister; 6102 Register Rtoc = $toc$$Register; 6103 address float_address = __ float_constant($src$$constant); 6104 if (float_address == NULL) { 6105 ciEnv::current()->record_out_of_memory_failure(); 6106 return; 6107 } 6108 int offset = __ offset_to_method_toc(float_address); 6109 int hi = (offset + (1<<15))>>16; 6110 int lo = offset - hi * (1<<16); 6111 6112 __ addis(Rtoc, Rtoc, hi); 6113 __ lfs(Rdst, lo, Rtoc); 6114 __ addis(Rtoc, Rtoc, -hi); 6115 %} 6116 ins_pipe(pipe_class_memory); 6117 %} 6118 6119 // Adlc adds toc node MachConstantTableBase. 6120 instruct loadConF_Ex(regF dst, immF src) %{ 6121 match(Set dst src); 6122 ins_cost(MEMORY_REF_COST); 6123 6124 // See loadConP. 6125 ins_cannot_rematerialize(true); 6126 6127 format %{ "LFS $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6128 postalloc_expand( postalloc_expand_load_float_constant(dst, src, constanttablebase) ); 6129 %} 6130 6131 // Expand node for constant pool load: small offset. 6132 instruct loadConD(regD dst, immD src, iRegLdst toc) %{ 6133 effect(DEF dst, USE src, USE toc); 6134 ins_cost(MEMORY_REF_COST); 6135 6136 ins_num_consts(1); 6137 6138 format %{ "LFD $dst, offset, $toc \t// load double $src from TOC" %} 6139 size(4); 6140 ins_encode %{ 6141 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 6142 address float_address = __ double_constant($src$$constant); 6143 if (float_address == NULL) { 6144 ciEnv::current()->record_out_of_memory_failure(); 6145 return; 6146 } 6147 int offset = __ offset_to_method_toc(float_address); 6148 __ lfd($dst$$FloatRegister, offset, $toc$$Register); 6149 %} 6150 ins_pipe(pipe_class_memory); 6151 %} 6152 6153 // Expand node for constant pool load: large offset. 6154 instruct loadConDComp(regD dst, immD src, iRegLdst toc) %{ 6155 effect(DEF dst, USE src, USE toc); 6156 ins_cost(MEMORY_REF_COST); 6157 6158 ins_num_consts(1); 6159 6160 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6161 "LFD $dst, offset_lo, $toc \t// load double $src from TOC (hi/lo)\n\t" 6162 "ADDIS $toc, $toc, -offset_hi" %} 6163 size(12); 6164 ins_encode %{ 6165 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6166 FloatRegister Rdst = $dst$$FloatRegister; 6167 Register Rtoc = $toc$$Register; 6168 address float_address = __ double_constant($src$$constant); 6169 if (float_address == NULL) { 6170 ciEnv::current()->record_out_of_memory_failure(); 6171 return; 6172 } 6173 int offset = __ offset_to_method_toc(float_address); 6174 int hi = (offset + (1<<15))>>16; 6175 int lo = offset - hi * (1<<16); 6176 6177 __ addis(Rtoc, Rtoc, hi); 6178 __ lfd(Rdst, lo, Rtoc); 6179 __ addis(Rtoc, Rtoc, -hi); 6180 %} 6181 ins_pipe(pipe_class_memory); 6182 %} 6183 6184 // Adlc adds toc node MachConstantTableBase. 6185 instruct loadConD_Ex(regD dst, immD src) %{ 6186 match(Set dst src); 6187 ins_cost(MEMORY_REF_COST); 6188 6189 // See loadConP. 6190 ins_cannot_rematerialize(true); 6191 6192 format %{ "ConD $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6193 postalloc_expand( postalloc_expand_load_double_constant(dst, src, constanttablebase) ); 6194 %} 6195 6196 // Prefetch instructions. 6197 // Must be safe to execute with invalid address (cannot fault). 6198 6199 // Special prefetch versions which use the dcbz instruction. 6200 instruct prefetch_alloc_zero(indirectMemory mem, iRegLsrc src) %{ 6201 match(PrefetchAllocation (AddP mem src)); 6202 predicate(AllocatePrefetchStyle == 3); 6203 ins_cost(MEMORY_REF_COST); 6204 6205 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many with zero" %} 6206 size(4); 6207 ins_encode %{ 6208 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6209 __ dcbz($src$$Register, $mem$$base$$Register); 6210 %} 6211 ins_pipe(pipe_class_memory); 6212 %} 6213 6214 instruct prefetch_alloc_zero_no_offset(indirectMemory mem) %{ 6215 match(PrefetchAllocation mem); 6216 predicate(AllocatePrefetchStyle == 3); 6217 ins_cost(MEMORY_REF_COST); 6218 6219 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many with zero" %} 6220 size(4); 6221 ins_encode %{ 6222 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6223 __ dcbz($mem$$base$$Register); 6224 %} 6225 ins_pipe(pipe_class_memory); 6226 %} 6227 6228 instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{ 6229 match(PrefetchAllocation (AddP mem src)); 6230 predicate(AllocatePrefetchStyle != 3); 6231 ins_cost(MEMORY_REF_COST); 6232 6233 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many" %} 6234 size(4); 6235 ins_encode %{ 6236 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6237 __ dcbtst($src$$Register, $mem$$base$$Register); 6238 %} 6239 ins_pipe(pipe_class_memory); 6240 %} 6241 6242 instruct prefetch_alloc_no_offset(indirectMemory mem) %{ 6243 match(PrefetchAllocation mem); 6244 predicate(AllocatePrefetchStyle != 3); 6245 ins_cost(MEMORY_REF_COST); 6246 6247 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many" %} 6248 size(4); 6249 ins_encode %{ 6250 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6251 __ dcbtst($mem$$base$$Register); 6252 %} 6253 ins_pipe(pipe_class_memory); 6254 %} 6255 6256 //----------Store Instructions------------------------------------------------- 6257 6258 // Store Byte 6259 instruct storeB(memory mem, iRegIsrc src) %{ 6260 match(Set mem (StoreB mem src)); 6261 ins_cost(MEMORY_REF_COST); 6262 6263 format %{ "STB $src, $mem \t// byte" %} 6264 size(4); 6265 ins_encode %{ 6266 // TODO: PPC port $archOpcode(ppc64Opcode_stb); 6267 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6268 __ stb($src$$Register, Idisp, $mem$$base$$Register); 6269 %} 6270 ins_pipe(pipe_class_memory); 6271 %} 6272 6273 // Store Char/Short 6274 instruct storeC(memory mem, iRegIsrc src) %{ 6275 match(Set mem (StoreC mem src)); 6276 ins_cost(MEMORY_REF_COST); 6277 6278 format %{ "STH $src, $mem \t// short" %} 6279 size(4); 6280 ins_encode %{ 6281 // TODO: PPC port $archOpcode(ppc64Opcode_sth); 6282 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6283 __ sth($src$$Register, Idisp, $mem$$base$$Register); 6284 %} 6285 ins_pipe(pipe_class_memory); 6286 %} 6287 6288 // Store Integer 6289 instruct storeI(memory mem, iRegIsrc src) %{ 6290 match(Set mem (StoreI mem src)); 6291 ins_cost(MEMORY_REF_COST); 6292 6293 format %{ "STW $src, $mem" %} 6294 size(4); 6295 ins_encode( enc_stw(src, mem) ); 6296 ins_pipe(pipe_class_memory); 6297 %} 6298 6299 // ConvL2I + StoreI. 6300 instruct storeI_convL2I(memory mem, iRegLsrc src) %{ 6301 match(Set mem (StoreI mem (ConvL2I src))); 6302 ins_cost(MEMORY_REF_COST); 6303 6304 format %{ "STW l2i($src), $mem" %} 6305 size(4); 6306 ins_encode( enc_stw(src, mem) ); 6307 ins_pipe(pipe_class_memory); 6308 %} 6309 6310 // Store Long 6311 instruct storeL(memoryAlg4 mem, iRegLsrc src) %{ 6312 match(Set mem (StoreL mem src)); 6313 ins_cost(MEMORY_REF_COST); 6314 6315 format %{ "STD $src, $mem \t// long" %} 6316 size(4); 6317 ins_encode( enc_std(src, mem) ); 6318 ins_pipe(pipe_class_memory); 6319 %} 6320 6321 // Store super word nodes. 6322 6323 // Store Aligned Packed Byte long register to memory 6324 instruct storeA8B(memoryAlg4 mem, iRegLsrc src) %{ 6325 predicate(n->as_StoreVector()->memory_size() == 8); 6326 match(Set mem (StoreVector mem src)); 6327 ins_cost(MEMORY_REF_COST); 6328 6329 format %{ "STD $mem, $src \t// packed8B" %} 6330 size(4); 6331 ins_encode( enc_std(src, mem) ); 6332 ins_pipe(pipe_class_memory); 6333 %} 6334 6335 // Store Compressed Oop 6336 instruct storeN(memory dst, iRegN_P2N src) %{ 6337 match(Set dst (StoreN dst src)); 6338 ins_cost(MEMORY_REF_COST); 6339 6340 format %{ "STW $src, $dst \t// compressed oop" %} 6341 size(4); 6342 ins_encode( enc_stw(src, dst) ); 6343 ins_pipe(pipe_class_memory); 6344 %} 6345 6346 // Store Compressed KLass 6347 instruct storeNKlass(memory dst, iRegN_P2N src) %{ 6348 match(Set dst (StoreNKlass dst src)); 6349 ins_cost(MEMORY_REF_COST); 6350 6351 format %{ "STW $src, $dst \t// compressed klass" %} 6352 size(4); 6353 ins_encode( enc_stw(src, dst) ); 6354 ins_pipe(pipe_class_memory); 6355 %} 6356 6357 // Store Pointer 6358 instruct storeP(memoryAlg4 dst, iRegPsrc src) %{ 6359 match(Set dst (StoreP dst src)); 6360 ins_cost(MEMORY_REF_COST); 6361 6362 format %{ "STD $src, $dst \t// ptr" %} 6363 size(4); 6364 ins_encode( enc_std(src, dst) ); 6365 ins_pipe(pipe_class_memory); 6366 %} 6367 6368 // Store Float 6369 instruct storeF(memory mem, regF src) %{ 6370 match(Set mem (StoreF mem src)); 6371 ins_cost(MEMORY_REF_COST); 6372 6373 format %{ "STFS $src, $mem" %} 6374 size(4); 6375 ins_encode( enc_stfs(src, mem) ); 6376 ins_pipe(pipe_class_memory); 6377 %} 6378 6379 // Store Double 6380 instruct storeD(memory mem, regD src) %{ 6381 match(Set mem (StoreD mem src)); 6382 ins_cost(MEMORY_REF_COST); 6383 6384 format %{ "STFD $src, $mem" %} 6385 size(4); 6386 ins_encode( enc_stfd(src, mem) ); 6387 ins_pipe(pipe_class_memory); 6388 %} 6389 6390 //----------Store Instructions With Zeros-------------------------------------- 6391 6392 // Card-mark for CMS garbage collection. 6393 // This cardmark does an optimization so that it must not always 6394 // do a releasing store. For this, it gets the address of 6395 // CMSCollectorCardTableModRefBSExt::_requires_release as input. 6396 // (Using releaseFieldAddr in the match rule is a hack.) 6397 instruct storeCM_CMS(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 6398 match(Set mem (StoreCM mem releaseFieldAddr)); 6399 effect(TEMP crx); 6400 predicate(false); 6401 ins_cost(MEMORY_REF_COST); 6402 6403 // See loadConP. 6404 ins_cannot_rematerialize(true); 6405 6406 format %{ "STB #0, $mem \t// CMS card-mark byte (must be 0!), checking requires_release in [$releaseFieldAddr]" %} 6407 ins_encode( enc_cms_card_mark(mem, releaseFieldAddr, crx) ); 6408 ins_pipe(pipe_class_memory); 6409 %} 6410 6411 // Card-mark for CMS garbage collection. 6412 // This cardmark does an optimization so that it must not always 6413 // do a releasing store. For this, it needs the constant address of 6414 // CMSCollectorCardTableModRefBSExt::_requires_release. 6415 // This constant address is split off here by expand so we can use 6416 // adlc / matcher functionality to load it from the constant section. 6417 instruct storeCM_CMS_ExEx(memory mem, immI_0 zero) %{ 6418 match(Set mem (StoreCM mem zero)); 6419 predicate(UseConcMarkSweepGC); 6420 6421 expand %{ 6422 immL baseImm %{ 0 /* TODO: PPC port (jlong)CMSCollectorCardTableModRefBSExt::requires_release_address() */ %} 6423 iRegLdst releaseFieldAddress; 6424 flagsReg crx; 6425 loadConL_Ex(releaseFieldAddress, baseImm); 6426 storeCM_CMS(mem, releaseFieldAddress, crx); 6427 %} 6428 %} 6429 6430 instruct storeCM_G1(memory mem, immI_0 zero) %{ 6431 match(Set mem (StoreCM mem zero)); 6432 predicate(UseG1GC); 6433 ins_cost(MEMORY_REF_COST); 6434 6435 ins_cannot_rematerialize(true); 6436 6437 format %{ "STB #0, $mem \t// CMS card-mark byte store (G1)" %} 6438 size(8); 6439 ins_encode %{ 6440 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6441 __ li(R0, 0); 6442 //__ release(); // G1: oops are allowed to get visible after dirty marking 6443 guarantee($mem$$base$$Register != R1_SP, "use frame_slots_bias"); 6444 __ stb(R0, $mem$$disp, $mem$$base$$Register); 6445 %} 6446 ins_pipe(pipe_class_memory); 6447 %} 6448 6449 // Convert oop pointer into compressed form. 6450 6451 // Nodes for postalloc expand. 6452 6453 // Shift node for expand. 6454 instruct encodeP_shift(iRegNdst dst, iRegNsrc src) %{ 6455 // The match rule is needed to make it a 'MachTypeNode'! 6456 match(Set dst (EncodeP src)); 6457 predicate(false); 6458 6459 format %{ "SRDI $dst, $src, 3 \t// encode" %} 6460 size(4); 6461 ins_encode %{ 6462 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6463 __ srdi($dst$$Register, $src$$Register, Universe::narrow_oop_shift() & 0x3f); 6464 %} 6465 ins_pipe(pipe_class_default); 6466 %} 6467 6468 // Add node for expand. 6469 instruct encodeP_sub(iRegPdst dst, iRegPdst src) %{ 6470 // The match rule is needed to make it a 'MachTypeNode'! 6471 match(Set dst (EncodeP src)); 6472 predicate(false); 6473 6474 format %{ "SUB $dst, $src, oop_base \t// encode" %} 6475 ins_encode %{ 6476 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6477 __ sub_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 6478 %} 6479 ins_pipe(pipe_class_default); 6480 %} 6481 6482 // Conditional sub base. 6483 instruct cond_sub_base(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6484 // The match rule is needed to make it a 'MachTypeNode'! 6485 match(Set dst (EncodeP (Binary crx src1))); 6486 predicate(false); 6487 6488 format %{ "BEQ $crx, done\n\t" 6489 "SUB $dst, $src1, heapbase \t// encode: subtract base if != NULL\n" 6490 "done:" %} 6491 ins_encode %{ 6492 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6493 Label done; 6494 __ beq($crx$$CondRegister, done); 6495 __ sub_const_optimized($dst$$Register, $src1$$Register, Universe::narrow_oop_base(), R0); 6496 __ bind(done); 6497 %} 6498 ins_pipe(pipe_class_default); 6499 %} 6500 6501 // Power 7 can use isel instruction 6502 instruct cond_set_0_oop(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6503 // The match rule is needed to make it a 'MachTypeNode'! 6504 match(Set dst (EncodeP (Binary crx src1))); 6505 predicate(false); 6506 6507 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// encode: preserve 0" %} 6508 size(4); 6509 ins_encode %{ 6510 // This is a Power7 instruction for which no machine description exists. 6511 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6512 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 6513 %} 6514 ins_pipe(pipe_class_default); 6515 %} 6516 6517 // Disjoint narrow oop base. 6518 instruct encodeP_Disjoint(iRegNdst dst, iRegPsrc src) %{ 6519 match(Set dst (EncodeP src)); 6520 predicate(Universe::narrow_oop_base_disjoint()); 6521 6522 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 6523 size(4); 6524 ins_encode %{ 6525 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6526 __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_oop_shift(), 32); 6527 %} 6528 ins_pipe(pipe_class_default); 6529 %} 6530 6531 // shift != 0, base != 0 6532 instruct encodeP_Ex(iRegNdst dst, flagsReg crx, iRegPsrc src) %{ 6533 match(Set dst (EncodeP src)); 6534 effect(TEMP crx); 6535 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull && 6536 Universe::narrow_oop_shift() != 0 && 6537 Universe::narrow_oop_base_overlaps()); 6538 6539 format %{ "EncodeP $dst, $crx, $src \t// postalloc expanded" %} 6540 postalloc_expand( postalloc_expand_encode_oop(dst, src, crx)); 6541 %} 6542 6543 // shift != 0, base != 0 6544 instruct encodeP_not_null_Ex(iRegNdst dst, iRegPsrc src) %{ 6545 match(Set dst (EncodeP src)); 6546 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull && 6547 Universe::narrow_oop_shift() != 0 && 6548 Universe::narrow_oop_base_overlaps()); 6549 6550 format %{ "EncodeP $dst, $src\t// $src != Null, postalloc expanded" %} 6551 postalloc_expand( postalloc_expand_encode_oop_not_null(dst, src) ); 6552 %} 6553 6554 // shift != 0, base == 0 6555 // TODO: This is the same as encodeP_shift. Merge! 6556 instruct encodeP_not_null_base_null(iRegNdst dst, iRegPsrc src) %{ 6557 match(Set dst (EncodeP src)); 6558 predicate(Universe::narrow_oop_shift() != 0 && 6559 Universe::narrow_oop_base() ==0); 6560 6561 format %{ "SRDI $dst, $src, #3 \t// encodeP, $src != NULL" %} 6562 size(4); 6563 ins_encode %{ 6564 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6565 __ srdi($dst$$Register, $src$$Register, Universe::narrow_oop_shift() & 0x3f); 6566 %} 6567 ins_pipe(pipe_class_default); 6568 %} 6569 6570 // Compressed OOPs with narrow_oop_shift == 0. 6571 // shift == 0, base == 0 6572 instruct encodeP_narrow_oop_shift_0(iRegNdst dst, iRegPsrc src) %{ 6573 match(Set dst (EncodeP src)); 6574 predicate(Universe::narrow_oop_shift() == 0); 6575 6576 format %{ "MR $dst, $src \t// Ptr->Narrow" %} 6577 // variable size, 0 or 4. 6578 ins_encode %{ 6579 // TODO: PPC port $archOpcode(ppc64Opcode_or); 6580 __ mr_if_needed($dst$$Register, $src$$Register); 6581 %} 6582 ins_pipe(pipe_class_default); 6583 %} 6584 6585 // Decode nodes. 6586 6587 // Shift node for expand. 6588 instruct decodeN_shift(iRegPdst dst, iRegPsrc src) %{ 6589 // The match rule is needed to make it a 'MachTypeNode'! 6590 match(Set dst (DecodeN src)); 6591 predicate(false); 6592 6593 format %{ "SLDI $dst, $src, #3 \t// DecodeN" %} 6594 size(4); 6595 ins_encode %{ 6596 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 6597 __ sldi($dst$$Register, $src$$Register, Universe::narrow_oop_shift()); 6598 %} 6599 ins_pipe(pipe_class_default); 6600 %} 6601 6602 // Add node for expand. 6603 instruct decodeN_add(iRegPdst dst, iRegPdst src) %{ 6604 // The match rule is needed to make it a 'MachTypeNode'! 6605 match(Set dst (DecodeN src)); 6606 predicate(false); 6607 6608 format %{ "ADD $dst, $src, heapbase \t// DecodeN, add oop base" %} 6609 ins_encode %{ 6610 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6611 __ add_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 6612 %} 6613 ins_pipe(pipe_class_default); 6614 %} 6615 6616 // conditianal add base for expand 6617 instruct cond_add_base(iRegPdst dst, flagsRegSrc crx, iRegPsrc src) %{ 6618 // The match rule is needed to make it a 'MachTypeNode'! 6619 // NOTICE that the rule is nonsense - we just have to make sure that: 6620 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 6621 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 6622 match(Set dst (DecodeN (Binary crx src))); 6623 predicate(false); 6624 6625 format %{ "BEQ $crx, done\n\t" 6626 "ADD $dst, $src, heapbase \t// DecodeN: add oop base if $src != NULL\n" 6627 "done:" %} 6628 ins_encode %{ 6629 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6630 Label done; 6631 __ beq($crx$$CondRegister, done); 6632 __ add_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 6633 __ bind(done); 6634 %} 6635 ins_pipe(pipe_class_default); 6636 %} 6637 6638 instruct cond_set_0_ptr(iRegPdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6639 // The match rule is needed to make it a 'MachTypeNode'! 6640 // NOTICE that the rule is nonsense - we just have to make sure that: 6641 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 6642 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 6643 match(Set dst (DecodeN (Binary crx src1))); 6644 predicate(false); 6645 6646 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// decode: preserve 0" %} 6647 size(4); 6648 ins_encode %{ 6649 // This is a Power7 instruction for which no machine description exists. 6650 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6651 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 6652 %} 6653 ins_pipe(pipe_class_default); 6654 %} 6655 6656 // shift != 0, base != 0 6657 instruct decodeN_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 6658 match(Set dst (DecodeN src)); 6659 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 6660 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 6661 Universe::narrow_oop_shift() != 0 && 6662 Universe::narrow_oop_base() != 0); 6663 ins_cost(4 * DEFAULT_COST); // Should be more expensive than decodeN_Disjoint_isel_Ex. 6664 effect(TEMP crx); 6665 6666 format %{ "DecodeN $dst, $src \t// Kills $crx, postalloc expanded" %} 6667 postalloc_expand( postalloc_expand_decode_oop(dst, src, crx) ); 6668 %} 6669 6670 // shift != 0, base == 0 6671 instruct decodeN_nullBase(iRegPdst dst, iRegNsrc src) %{ 6672 match(Set dst (DecodeN src)); 6673 predicate(Universe::narrow_oop_shift() != 0 && 6674 Universe::narrow_oop_base() == 0); 6675 6676 format %{ "SLDI $dst, $src, #3 \t// DecodeN (zerobased)" %} 6677 size(4); 6678 ins_encode %{ 6679 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 6680 __ sldi($dst$$Register, $src$$Register, Universe::narrow_oop_shift()); 6681 %} 6682 ins_pipe(pipe_class_default); 6683 %} 6684 6685 // Optimize DecodeN for disjoint base. 6686 // Shift narrow oop and or it into register that already contains the heap base. 6687 // Base == dst must hold, and is assured by construction in postaloc_expand. 6688 instruct decodeN_mergeDisjoint(iRegPdst dst, iRegNsrc src, iRegLsrc base) %{ 6689 match(Set dst (DecodeN src)); 6690 effect(TEMP base); 6691 predicate(false); 6692 6693 format %{ "RLDIMI $dst, $src, shift, 32-shift \t// DecodeN (disjoint base)" %} 6694 size(4); 6695 ins_encode %{ 6696 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 6697 __ rldimi($dst$$Register, $src$$Register, Universe::narrow_oop_shift(), 32-Universe::narrow_oop_shift()); 6698 %} 6699 ins_pipe(pipe_class_default); 6700 %} 6701 6702 // Optimize DecodeN for disjoint base. 6703 // This node requires only one cycle on the critical path. 6704 // We must postalloc_expand as we can not express use_def effects where 6705 // the used register is L and the def'ed register P. 6706 instruct decodeN_Disjoint_notNull_Ex(iRegPdst dst, iRegNsrc src) %{ 6707 match(Set dst (DecodeN src)); 6708 effect(TEMP_DEF dst); 6709 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 6710 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 6711 Universe::narrow_oop_base_disjoint()); 6712 ins_cost(DEFAULT_COST); 6713 6714 format %{ "MOV $dst, heapbase \t\n" 6715 "RLDIMI $dst, $src, shift, 32-shift \t// decode with disjoint base" %} 6716 postalloc_expand %{ 6717 loadBaseNode *n1 = new loadBaseNode(); 6718 n1->add_req(NULL); 6719 n1->_opnds[0] = op_dst; 6720 6721 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 6722 n2->add_req(n_region, n_src, n1); 6723 n2->_opnds[0] = op_dst; 6724 n2->_opnds[1] = op_src; 6725 n2->_opnds[2] = op_dst; 6726 n2->_bottom_type = _bottom_type; 6727 6728 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6729 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6730 6731 nodes->push(n1); 6732 nodes->push(n2); 6733 %} 6734 %} 6735 6736 instruct decodeN_Disjoint_isel_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 6737 match(Set dst (DecodeN src)); 6738 effect(TEMP_DEF dst, TEMP crx); 6739 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 6740 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 6741 Universe::narrow_oop_base_disjoint() && VM_Version::has_isel()); 6742 ins_cost(3 * DEFAULT_COST); 6743 6744 format %{ "DecodeN $dst, $src \t// decode with disjoint base using isel" %} 6745 postalloc_expand %{ 6746 loadBaseNode *n1 = new loadBaseNode(); 6747 n1->add_req(NULL); 6748 n1->_opnds[0] = op_dst; 6749 6750 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 6751 n_compare->add_req(n_region, n_src); 6752 n_compare->_opnds[0] = op_crx; 6753 n_compare->_opnds[1] = op_src; 6754 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 6755 6756 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 6757 n2->add_req(n_region, n_src, n1); 6758 n2->_opnds[0] = op_dst; 6759 n2->_opnds[1] = op_src; 6760 n2->_opnds[2] = op_dst; 6761 n2->_bottom_type = _bottom_type; 6762 6763 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 6764 n_cond_set->add_req(n_region, n_compare, n2); 6765 n_cond_set->_opnds[0] = op_dst; 6766 n_cond_set->_opnds[1] = op_crx; 6767 n_cond_set->_opnds[2] = op_dst; 6768 n_cond_set->_bottom_type = _bottom_type; 6769 6770 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 6771 ra_->set_oop(n_cond_set, true); 6772 6773 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6774 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 6775 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6776 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6777 6778 nodes->push(n1); 6779 nodes->push(n_compare); 6780 nodes->push(n2); 6781 nodes->push(n_cond_set); 6782 %} 6783 %} 6784 6785 // src != 0, shift != 0, base != 0 6786 instruct decodeN_notNull_addBase_Ex(iRegPdst dst, iRegNsrc src) %{ 6787 match(Set dst (DecodeN src)); 6788 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 6789 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 6790 Universe::narrow_oop_shift() != 0 && 6791 Universe::narrow_oop_base() != 0); 6792 ins_cost(2 * DEFAULT_COST); 6793 6794 format %{ "DecodeN $dst, $src \t// $src != NULL, postalloc expanded" %} 6795 postalloc_expand( postalloc_expand_decode_oop_not_null(dst, src)); 6796 %} 6797 6798 // Compressed OOPs with narrow_oop_shift == 0. 6799 instruct decodeN_unscaled(iRegPdst dst, iRegNsrc src) %{ 6800 match(Set dst (DecodeN src)); 6801 predicate(Universe::narrow_oop_shift() == 0); 6802 ins_cost(DEFAULT_COST); 6803 6804 format %{ "MR $dst, $src \t// DecodeN (unscaled)" %} 6805 // variable size, 0 or 4. 6806 ins_encode %{ 6807 // TODO: PPC port $archOpcode(ppc64Opcode_or); 6808 __ mr_if_needed($dst$$Register, $src$$Register); 6809 %} 6810 ins_pipe(pipe_class_default); 6811 %} 6812 6813 // Convert compressed oop into int for vectors alignment masking. 6814 instruct decodeN2I_unscaled(iRegIdst dst, iRegNsrc src) %{ 6815 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6816 predicate(Universe::narrow_oop_shift() == 0); 6817 ins_cost(DEFAULT_COST); 6818 6819 format %{ "MR $dst, $src \t// (int)DecodeN (unscaled)" %} 6820 // variable size, 0 or 4. 6821 ins_encode %{ 6822 // TODO: PPC port $archOpcode(ppc64Opcode_or); 6823 __ mr_if_needed($dst$$Register, $src$$Register); 6824 %} 6825 ins_pipe(pipe_class_default); 6826 %} 6827 6828 // Convert klass pointer into compressed form. 6829 6830 // Nodes for postalloc expand. 6831 6832 // Shift node for expand. 6833 instruct encodePKlass_shift(iRegNdst dst, iRegNsrc src) %{ 6834 // The match rule is needed to make it a 'MachTypeNode'! 6835 match(Set dst (EncodePKlass src)); 6836 predicate(false); 6837 6838 format %{ "SRDI $dst, $src, 3 \t// encode" %} 6839 size(4); 6840 ins_encode %{ 6841 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6842 __ srdi($dst$$Register, $src$$Register, Universe::narrow_klass_shift()); 6843 %} 6844 ins_pipe(pipe_class_default); 6845 %} 6846 6847 // Add node for expand. 6848 instruct encodePKlass_sub_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 6849 // The match rule is needed to make it a 'MachTypeNode'! 6850 match(Set dst (EncodePKlass (Binary base src))); 6851 predicate(false); 6852 6853 format %{ "SUB $dst, $base, $src \t// encode" %} 6854 size(4); 6855 ins_encode %{ 6856 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 6857 __ subf($dst$$Register, $base$$Register, $src$$Register); 6858 %} 6859 ins_pipe(pipe_class_default); 6860 %} 6861 6862 // Disjoint narrow oop base. 6863 instruct encodePKlass_Disjoint(iRegNdst dst, iRegPsrc src) %{ 6864 match(Set dst (EncodePKlass src)); 6865 predicate(false /* TODO: PPC port Universe::narrow_klass_base_disjoint()*/); 6866 6867 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 6868 size(4); 6869 ins_encode %{ 6870 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6871 __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_klass_shift(), 32); 6872 %} 6873 ins_pipe(pipe_class_default); 6874 %} 6875 6876 // shift != 0, base != 0 6877 instruct encodePKlass_not_null_Ex(iRegNdst dst, iRegLsrc base, iRegPsrc src) %{ 6878 match(Set dst (EncodePKlass (Binary base src))); 6879 predicate(false); 6880 6881 format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 6882 postalloc_expand %{ 6883 encodePKlass_sub_baseNode *n1 = new encodePKlass_sub_baseNode(); 6884 n1->add_req(n_region, n_base, n_src); 6885 n1->_opnds[0] = op_dst; 6886 n1->_opnds[1] = op_base; 6887 n1->_opnds[2] = op_src; 6888 n1->_bottom_type = _bottom_type; 6889 6890 encodePKlass_shiftNode *n2 = new encodePKlass_shiftNode(); 6891 n2->add_req(n_region, n1); 6892 n2->_opnds[0] = op_dst; 6893 n2->_opnds[1] = op_dst; 6894 n2->_bottom_type = _bottom_type; 6895 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6896 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6897 6898 nodes->push(n1); 6899 nodes->push(n2); 6900 %} 6901 %} 6902 6903 // shift != 0, base != 0 6904 instruct encodePKlass_not_null_ExEx(iRegNdst dst, iRegPsrc src) %{ 6905 match(Set dst (EncodePKlass src)); 6906 //predicate(Universe::narrow_klass_shift() != 0 && 6907 // true /* TODO: PPC port Universe::narrow_klass_base_overlaps()*/); 6908 6909 //format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 6910 ins_cost(DEFAULT_COST*2); // Don't count constant. 6911 expand %{ 6912 immL baseImm %{ (jlong)(intptr_t)Universe::narrow_klass_base() %} 6913 iRegLdst base; 6914 loadConL_Ex(base, baseImm); 6915 encodePKlass_not_null_Ex(dst, base, src); 6916 %} 6917 %} 6918 6919 // Decode nodes. 6920 6921 // Shift node for expand. 6922 instruct decodeNKlass_shift(iRegPdst dst, iRegPsrc src) %{ 6923 // The match rule is needed to make it a 'MachTypeNode'! 6924 match(Set dst (DecodeNKlass src)); 6925 predicate(false); 6926 6927 format %{ "SLDI $dst, $src, #3 \t// DecodeNKlass" %} 6928 size(4); 6929 ins_encode %{ 6930 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 6931 __ sldi($dst$$Register, $src$$Register, Universe::narrow_klass_shift()); 6932 %} 6933 ins_pipe(pipe_class_default); 6934 %} 6935 6936 // Add node for expand. 6937 6938 instruct decodeNKlass_add_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 6939 // The match rule is needed to make it a 'MachTypeNode'! 6940 match(Set dst (DecodeNKlass (Binary base src))); 6941 predicate(false); 6942 6943 format %{ "ADD $dst, $base, $src \t// DecodeNKlass, add klass base" %} 6944 size(4); 6945 ins_encode %{ 6946 // TODO: PPC port $archOpcode(ppc64Opcode_add); 6947 __ add($dst$$Register, $base$$Register, $src$$Register); 6948 %} 6949 ins_pipe(pipe_class_default); 6950 %} 6951 6952 // src != 0, shift != 0, base != 0 6953 instruct decodeNKlass_notNull_addBase_Ex(iRegPdst dst, iRegLsrc base, iRegNsrc src) %{ 6954 match(Set dst (DecodeNKlass (Binary base src))); 6955 //effect(kill src); // We need a register for the immediate result after shifting. 6956 predicate(false); 6957 6958 format %{ "DecodeNKlass $dst = $base + ($src << 3) \t// $src != NULL, postalloc expanded" %} 6959 postalloc_expand %{ 6960 decodeNKlass_add_baseNode *n1 = new decodeNKlass_add_baseNode(); 6961 n1->add_req(n_region, n_base, n_src); 6962 n1->_opnds[0] = op_dst; 6963 n1->_opnds[1] = op_base; 6964 n1->_opnds[2] = op_src; 6965 n1->_bottom_type = _bottom_type; 6966 6967 decodeNKlass_shiftNode *n2 = new decodeNKlass_shiftNode(); 6968 n2->add_req(n_region, n1); 6969 n2->_opnds[0] = op_dst; 6970 n2->_opnds[1] = op_dst; 6971 n2->_bottom_type = _bottom_type; 6972 6973 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6974 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6975 6976 nodes->push(n1); 6977 nodes->push(n2); 6978 %} 6979 %} 6980 6981 // src != 0, shift != 0, base != 0 6982 instruct decodeNKlass_notNull_addBase_ExEx(iRegPdst dst, iRegNsrc src) %{ 6983 match(Set dst (DecodeNKlass src)); 6984 // predicate(Universe::narrow_klass_shift() != 0 && 6985 // Universe::narrow_klass_base() != 0); 6986 6987 //format %{ "DecodeNKlass $dst, $src \t// $src != NULL, expanded" %} 6988 6989 ins_cost(DEFAULT_COST*2); // Don't count constant. 6990 expand %{ 6991 // We add first, then we shift. Like this, we can get along with one register less. 6992 // But we have to load the base pre-shifted. 6993 immL baseImm %{ (jlong)((intptr_t)Universe::narrow_klass_base() >> Universe::narrow_klass_shift()) %} 6994 iRegLdst base; 6995 loadConL_Ex(base, baseImm); 6996 decodeNKlass_notNull_addBase_Ex(dst, base, src); 6997 %} 6998 %} 6999 7000 //----------MemBar Instructions----------------------------------------------- 7001 // Memory barrier flavors 7002 7003 instruct membar_acquire() %{ 7004 match(LoadFence); 7005 ins_cost(4*MEMORY_REF_COST); 7006 7007 format %{ "MEMBAR-acquire" %} 7008 size(4); 7009 ins_encode %{ 7010 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7011 __ acquire(); 7012 %} 7013 ins_pipe(pipe_class_default); 7014 %} 7015 7016 instruct unnecessary_membar_acquire() %{ 7017 match(MemBarAcquire); 7018 ins_cost(0); 7019 7020 format %{ " -- \t// redundant MEMBAR-acquire - empty" %} 7021 size(0); 7022 ins_encode( /*empty*/ ); 7023 ins_pipe(pipe_class_default); 7024 %} 7025 7026 instruct membar_acquire_lock() %{ 7027 match(MemBarAcquireLock); 7028 ins_cost(0); 7029 7030 format %{ " -- \t// redundant MEMBAR-acquire - empty (acquire as part of CAS in prior FastLock)" %} 7031 size(0); 7032 ins_encode( /*empty*/ ); 7033 ins_pipe(pipe_class_default); 7034 %} 7035 7036 instruct membar_release() %{ 7037 match(MemBarRelease); 7038 match(StoreFence); 7039 ins_cost(4*MEMORY_REF_COST); 7040 7041 format %{ "MEMBAR-release" %} 7042 size(4); 7043 ins_encode %{ 7044 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7045 __ release(); 7046 %} 7047 ins_pipe(pipe_class_default); 7048 %} 7049 7050 instruct membar_storestore() %{ 7051 match(MemBarStoreStore); 7052 ins_cost(4*MEMORY_REF_COST); 7053 7054 format %{ "MEMBAR-store-store" %} 7055 size(4); 7056 ins_encode %{ 7057 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7058 __ membar(Assembler::StoreStore); 7059 %} 7060 ins_pipe(pipe_class_default); 7061 %} 7062 7063 instruct membar_release_lock() %{ 7064 match(MemBarReleaseLock); 7065 ins_cost(0); 7066 7067 format %{ " -- \t// redundant MEMBAR-release - empty (release in FastUnlock)" %} 7068 size(0); 7069 ins_encode( /*empty*/ ); 7070 ins_pipe(pipe_class_default); 7071 %} 7072 7073 instruct membar_volatile() %{ 7074 match(MemBarVolatile); 7075 ins_cost(4*MEMORY_REF_COST); 7076 7077 format %{ "MEMBAR-volatile" %} 7078 size(4); 7079 ins_encode %{ 7080 // TODO: PPC port $archOpcode(ppc64Opcode_sync); 7081 __ fence(); 7082 %} 7083 ins_pipe(pipe_class_default); 7084 %} 7085 7086 // This optimization is wrong on PPC. The following pattern is not supported: 7087 // MemBarVolatile 7088 // ^ ^ 7089 // | | 7090 // CtrlProj MemProj 7091 // ^ ^ 7092 // | | 7093 // | Load 7094 // | 7095 // MemBarVolatile 7096 // 7097 // The first MemBarVolatile could get optimized out! According to 7098 // Vladimir, this pattern can not occur on Oracle platforms. 7099 // However, it does occur on PPC64 (because of membars in 7100 // inline_unsafe_load_store). 7101 // 7102 // Add this node again if we found a good solution for inline_unsafe_load_store(). 7103 // Don't forget to look at the implementation of post_store_load_barrier again, 7104 // we did other fixes in that method. 7105 //instruct unnecessary_membar_volatile() %{ 7106 // match(MemBarVolatile); 7107 // predicate(Matcher::post_store_load_barrier(n)); 7108 // ins_cost(0); 7109 // 7110 // format %{ " -- \t// redundant MEMBAR-volatile - empty" %} 7111 // size(0); 7112 // ins_encode( /*empty*/ ); 7113 // ins_pipe(pipe_class_default); 7114 //%} 7115 7116 instruct membar_CPUOrder() %{ 7117 match(MemBarCPUOrder); 7118 ins_cost(0); 7119 7120 format %{ " -- \t// MEMBAR-CPUOrder - empty: PPC64 processors are self-consistent." %} 7121 size(0); 7122 ins_encode( /*empty*/ ); 7123 ins_pipe(pipe_class_default); 7124 %} 7125 7126 //----------Conditional Move--------------------------------------------------- 7127 7128 // Cmove using isel. 7129 instruct cmovI_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7130 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7131 predicate(VM_Version::has_isel()); 7132 ins_cost(DEFAULT_COST); 7133 7134 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7135 size(4); 7136 ins_encode %{ 7137 // This is a Power7 instruction for which no machine description 7138 // exists. Anyways, the scheduler should be off on Power7. 7139 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7140 int cc = $cmp$$cmpcode; 7141 __ isel($dst$$Register, $crx$$CondRegister, 7142 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7143 %} 7144 ins_pipe(pipe_class_default); 7145 %} 7146 7147 instruct cmovI_reg(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7148 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7149 predicate(!VM_Version::has_isel()); 7150 ins_cost(DEFAULT_COST+BRANCH_COST); 7151 7152 ins_variable_size_depending_on_alignment(true); 7153 7154 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7155 // Worst case is branch + move + stop, no stop without scheduler 7156 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7157 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7158 ins_pipe(pipe_class_default); 7159 %} 7160 7161 instruct cmovI_imm(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, immI16 src) %{ 7162 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7163 ins_cost(DEFAULT_COST+BRANCH_COST); 7164 7165 ins_variable_size_depending_on_alignment(true); 7166 7167 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7168 // Worst case is branch + move + stop, no stop without scheduler 7169 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7170 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7171 ins_pipe(pipe_class_default); 7172 %} 7173 7174 // Cmove using isel. 7175 instruct cmovL_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7176 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7177 predicate(VM_Version::has_isel()); 7178 ins_cost(DEFAULT_COST); 7179 7180 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7181 size(4); 7182 ins_encode %{ 7183 // This is a Power7 instruction for which no machine description 7184 // exists. Anyways, the scheduler should be off on Power7. 7185 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7186 int cc = $cmp$$cmpcode; 7187 __ isel($dst$$Register, $crx$$CondRegister, 7188 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7189 %} 7190 ins_pipe(pipe_class_default); 7191 %} 7192 7193 instruct cmovL_reg(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7194 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7195 predicate(!VM_Version::has_isel()); 7196 ins_cost(DEFAULT_COST+BRANCH_COST); 7197 7198 ins_variable_size_depending_on_alignment(true); 7199 7200 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7201 // Worst case is branch + move + stop, no stop without scheduler. 7202 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7203 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7204 ins_pipe(pipe_class_default); 7205 %} 7206 7207 instruct cmovL_imm(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, immL16 src) %{ 7208 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7209 ins_cost(DEFAULT_COST+BRANCH_COST); 7210 7211 ins_variable_size_depending_on_alignment(true); 7212 7213 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7214 // Worst case is branch + move + stop, no stop without scheduler. 7215 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7216 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7217 ins_pipe(pipe_class_default); 7218 %} 7219 7220 // Cmove using isel. 7221 instruct cmovN_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7222 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7223 predicate(VM_Version::has_isel()); 7224 ins_cost(DEFAULT_COST); 7225 7226 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7227 size(4); 7228 ins_encode %{ 7229 // This is a Power7 instruction for which no machine description 7230 // exists. Anyways, the scheduler should be off on Power7. 7231 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7232 int cc = $cmp$$cmpcode; 7233 __ isel($dst$$Register, $crx$$CondRegister, 7234 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7235 %} 7236 ins_pipe(pipe_class_default); 7237 %} 7238 7239 // Conditional move for RegN. Only cmov(reg, reg). 7240 instruct cmovN_reg(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7241 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7242 predicate(!VM_Version::has_isel()); 7243 ins_cost(DEFAULT_COST+BRANCH_COST); 7244 7245 ins_variable_size_depending_on_alignment(true); 7246 7247 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7248 // Worst case is branch + move + stop, no stop without scheduler. 7249 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7250 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7251 ins_pipe(pipe_class_default); 7252 %} 7253 7254 instruct cmovN_imm(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, immN_0 src) %{ 7255 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7256 ins_cost(DEFAULT_COST+BRANCH_COST); 7257 7258 ins_variable_size_depending_on_alignment(true); 7259 7260 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7261 // Worst case is branch + move + stop, no stop without scheduler. 7262 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7263 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7264 ins_pipe(pipe_class_default); 7265 %} 7266 7267 // Cmove using isel. 7268 instruct cmovP_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegPsrc src) %{ 7269 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7270 predicate(VM_Version::has_isel()); 7271 ins_cost(DEFAULT_COST); 7272 7273 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7274 size(4); 7275 ins_encode %{ 7276 // This is a Power7 instruction for which no machine description 7277 // exists. Anyways, the scheduler should be off on Power7. 7278 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7279 int cc = $cmp$$cmpcode; 7280 __ isel($dst$$Register, $crx$$CondRegister, 7281 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7282 %} 7283 ins_pipe(pipe_class_default); 7284 %} 7285 7286 instruct cmovP_reg(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegP_N2P src) %{ 7287 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7288 predicate(!VM_Version::has_isel()); 7289 ins_cost(DEFAULT_COST+BRANCH_COST); 7290 7291 ins_variable_size_depending_on_alignment(true); 7292 7293 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7294 // Worst case is branch + move + stop, no stop without scheduler. 7295 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7296 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7297 ins_pipe(pipe_class_default); 7298 %} 7299 7300 instruct cmovP_imm(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, immP_0 src) %{ 7301 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7302 ins_cost(DEFAULT_COST+BRANCH_COST); 7303 7304 ins_variable_size_depending_on_alignment(true); 7305 7306 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7307 // Worst case is branch + move + stop, no stop without scheduler. 7308 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7309 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7310 ins_pipe(pipe_class_default); 7311 %} 7312 7313 instruct cmovF_reg(cmpOp cmp, flagsRegSrc crx, regF dst, regF src) %{ 7314 match(Set dst (CMoveF (Binary cmp crx) (Binary dst src))); 7315 ins_cost(DEFAULT_COST+BRANCH_COST); 7316 7317 ins_variable_size_depending_on_alignment(true); 7318 7319 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7320 // Worst case is branch + move + stop, no stop without scheduler. 7321 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 7322 ins_encode %{ 7323 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7324 Label done; 7325 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7326 // Branch if not (cmp crx). 7327 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7328 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7329 // TODO PPC port __ endgroup_if_needed(_size == 12); 7330 __ bind(done); 7331 %} 7332 ins_pipe(pipe_class_default); 7333 %} 7334 7335 instruct cmovD_reg(cmpOp cmp, flagsRegSrc crx, regD dst, regD src) %{ 7336 match(Set dst (CMoveD (Binary cmp crx) (Binary dst src))); 7337 ins_cost(DEFAULT_COST+BRANCH_COST); 7338 7339 ins_variable_size_depending_on_alignment(true); 7340 7341 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7342 // Worst case is branch + move + stop, no stop without scheduler. 7343 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 7344 ins_encode %{ 7345 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7346 Label done; 7347 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7348 // Branch if not (cmp crx). 7349 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7350 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7351 // TODO PPC port __ endgroup_if_needed(_size == 12); 7352 __ bind(done); 7353 %} 7354 ins_pipe(pipe_class_default); 7355 %} 7356 7357 //----------Conditional_store-------------------------------------------------- 7358 // Conditional-store of the updated heap-top. 7359 // Used during allocation of the shared heap. 7360 // Sets flags (EQ) on success. Implemented with a CASA on Sparc. 7361 7362 // As compareAndSwapL, but return flag register instead of boolean value in 7363 // int register. 7364 // Used by sun/misc/AtomicLongCSImpl.java. 7365 // Mem_ptr must be a memory operand, else this node does not get 7366 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7367 // can be rematerialized which leads to errors. 7368 instruct storeLConditional_regP_regL_regL(flagsReg crx, indirect mem_ptr, iRegLsrc oldVal, iRegLsrc newVal, flagsRegCR0 cr0) %{ 7369 match(Set crx (StoreLConditional mem_ptr (Binary oldVal newVal))); 7370 effect(TEMP cr0); 7371 format %{ "CMPXCHGD if ($crx = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7372 ins_encode %{ 7373 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7374 __ cmpxchgd($crx$$CondRegister, R0, $oldVal$$Register, $newVal$$Register, $mem_ptr$$Register, 7375 MacroAssembler::MemBarAcq, MacroAssembler::cmpxchgx_hint_atomic_update(), 7376 noreg, NULL, true); 7377 %} 7378 ins_pipe(pipe_class_default); 7379 %} 7380 7381 // As compareAndSwapP, but return flag register instead of boolean value in 7382 // int register. 7383 // This instruction is matched if UseTLAB is off. 7384 // Mem_ptr must be a memory operand, else this node does not get 7385 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7386 // can be rematerialized which leads to errors. 7387 instruct storePConditional_regP_regP_regP(flagsRegCR0 cr0, indirect mem_ptr, iRegPsrc oldVal, iRegPsrc newVal) %{ 7388 match(Set cr0 (StorePConditional mem_ptr (Binary oldVal newVal))); 7389 ins_cost(2*MEMORY_REF_COST); 7390 7391 format %{ "STDCX_ if ($cr0 = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7392 ins_encode %{ 7393 // TODO: PPC port $archOpcode(ppc64Opcode_stdcx_); 7394 __ stdcx_($newVal$$Register, $mem_ptr$$Register); 7395 %} 7396 ins_pipe(pipe_class_memory); 7397 %} 7398 7399 // Implement LoadPLocked. Must be ordered against changes of the memory location 7400 // by storePConditional. 7401 // Don't know whether this is ever used. 7402 instruct loadPLocked(iRegPdst dst, memory mem) %{ 7403 match(Set dst (LoadPLocked mem)); 7404 ins_cost(2*MEMORY_REF_COST); 7405 7406 format %{ "LDARX $dst, $mem \t// loadPLocked\n\t" %} 7407 size(4); 7408 ins_encode %{ 7409 // TODO: PPC port $archOpcode(ppc64Opcode_ldarx); 7410 __ ldarx($dst$$Register, $mem$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 7411 %} 7412 ins_pipe(pipe_class_memory); 7413 %} 7414 7415 //----------Compare-And-Swap--------------------------------------------------- 7416 7417 // CompareAndSwap{P,I,L} have more than one output, therefore "CmpI 7418 // (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be 7419 // matched. 7420 7421 // Strong versions: 7422 7423 instruct compareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7424 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7425 predicate(VM_Version::has_lqarx()); 7426 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7427 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7428 ins_encode %{ 7429 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7430 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7431 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7432 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7433 $res$$Register, true); 7434 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7435 __ isync(); 7436 } else { 7437 __ sync(); 7438 } 7439 %} 7440 ins_pipe(pipe_class_default); 7441 %} 7442 7443 instruct compareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7444 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7445 predicate(!VM_Version::has_lqarx()); 7446 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7447 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7448 ins_encode %{ 7449 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7450 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7451 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7452 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7453 $res$$Register, true); 7454 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7455 __ isync(); 7456 } else { 7457 __ sync(); 7458 } 7459 %} 7460 ins_pipe(pipe_class_default); 7461 %} 7462 7463 instruct compareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7464 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7465 predicate(VM_Version::has_lqarx()); 7466 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7467 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7468 ins_encode %{ 7469 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7470 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7471 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7472 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7473 $res$$Register, true); 7474 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7475 __ isync(); 7476 } else { 7477 __ sync(); 7478 } 7479 %} 7480 ins_pipe(pipe_class_default); 7481 %} 7482 7483 instruct compareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7484 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7485 predicate(!VM_Version::has_lqarx()); 7486 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7487 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7488 ins_encode %{ 7489 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7490 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7491 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7492 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7493 $res$$Register, true); 7494 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7495 __ isync(); 7496 } else { 7497 __ sync(); 7498 } 7499 %} 7500 ins_pipe(pipe_class_default); 7501 %} 7502 7503 instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7504 match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2))); 7505 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7506 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7507 ins_encode %{ 7508 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7509 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7510 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7511 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7512 $res$$Register, true); 7513 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7514 __ isync(); 7515 } else { 7516 __ sync(); 7517 } 7518 %} 7519 ins_pipe(pipe_class_default); 7520 %} 7521 7522 instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 7523 match(Set res (CompareAndSwapN mem_ptr (Binary src1 src2))); 7524 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7525 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7526 ins_encode %{ 7527 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7528 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7529 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7530 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7531 $res$$Register, true); 7532 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7533 __ isync(); 7534 } else { 7535 __ sync(); 7536 } 7537 %} 7538 ins_pipe(pipe_class_default); 7539 %} 7540 7541 instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 7542 match(Set res (CompareAndSwapL mem_ptr (Binary src1 src2))); 7543 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7544 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 7545 ins_encode %{ 7546 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7547 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7548 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7549 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7550 $res$$Register, NULL, true); 7551 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7552 __ isync(); 7553 } else { 7554 __ sync(); 7555 } 7556 %} 7557 ins_pipe(pipe_class_default); 7558 %} 7559 7560 instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 7561 match(Set res (CompareAndSwapP mem_ptr (Binary src1 src2))); 7562 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7563 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 7564 ins_encode %{ 7565 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7566 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7567 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7568 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7569 $res$$Register, NULL, true); 7570 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7571 __ isync(); 7572 } else { 7573 __ sync(); 7574 } 7575 %} 7576 ins_pipe(pipe_class_default); 7577 %} 7578 7579 // Weak versions: 7580 7581 instruct weakCompareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7582 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7583 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7584 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7585 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7586 ins_encode %{ 7587 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7588 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7589 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7590 MacroAssembler::MemBarNone, 7591 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7592 %} 7593 ins_pipe(pipe_class_default); 7594 %} 7595 7596 instruct weakCompareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7597 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7598 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 7599 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7600 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7601 ins_encode %{ 7602 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7603 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7604 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7605 MacroAssembler::MemBarNone, 7606 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7607 %} 7608 ins_pipe(pipe_class_default); 7609 %} 7610 7611 instruct weakCompareAndSwapB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7612 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7613 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 7614 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7615 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 7616 ins_encode %{ 7617 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7618 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7619 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7620 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7621 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7622 %} 7623 ins_pipe(pipe_class_default); 7624 %} 7625 7626 instruct weakCompareAndSwapB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7627 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7628 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 7629 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7630 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 7631 ins_encode %{ 7632 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7633 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7634 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7635 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7636 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7637 %} 7638 ins_pipe(pipe_class_default); 7639 %} 7640 7641 instruct weakCompareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7642 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 7643 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7644 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7645 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7646 ins_encode %{ 7647 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7648 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7649 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7650 MacroAssembler::MemBarNone, 7651 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7652 %} 7653 ins_pipe(pipe_class_default); 7654 %} 7655 7656 instruct weakCompareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7657 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 7658 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 7659 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7660 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7661 ins_encode %{ 7662 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7663 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7664 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7665 MacroAssembler::MemBarNone, 7666 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7667 %} 7668 ins_pipe(pipe_class_default); 7669 %} 7670 7671 instruct weakCompareAndSwapS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7672 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 7673 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 7674 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7675 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 7676 ins_encode %{ 7677 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7678 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7679 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7680 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7681 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7682 %} 7683 ins_pipe(pipe_class_default); 7684 %} 7685 7686 instruct weakCompareAndSwapS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7687 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 7688 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 7689 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7690 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 7691 ins_encode %{ 7692 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7693 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7694 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7695 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7696 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7697 %} 7698 ins_pipe(pipe_class_default); 7699 %} 7700 7701 instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7702 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 7703 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7704 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7705 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7706 ins_encode %{ 7707 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7708 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7709 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7710 MacroAssembler::MemBarNone, 7711 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7712 %} 7713 ins_pipe(pipe_class_default); 7714 %} 7715 7716 instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7717 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 7718 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 7719 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7720 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 7721 ins_encode %{ 7722 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7723 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7724 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 7725 // value is never passed to caller. 7726 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7727 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7728 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7729 %} 7730 ins_pipe(pipe_class_default); 7731 %} 7732 7733 instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 7734 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 7735 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7736 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7737 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7738 ins_encode %{ 7739 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7740 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7741 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7742 MacroAssembler::MemBarNone, 7743 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7744 %} 7745 ins_pipe(pipe_class_default); 7746 %} 7747 7748 instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 7749 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 7750 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 7751 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7752 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 7753 ins_encode %{ 7754 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7755 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7756 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 7757 // value is never passed to caller. 7758 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7759 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7760 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7761 %} 7762 ins_pipe(pipe_class_default); 7763 %} 7764 7765 instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 7766 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 7767 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7768 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7769 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 7770 ins_encode %{ 7771 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7772 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7773 // value is never passed to caller. 7774 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7775 MacroAssembler::MemBarNone, 7776 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 7777 %} 7778 ins_pipe(pipe_class_default); 7779 %} 7780 7781 instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 7782 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 7783 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 7784 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7785 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %} 7786 ins_encode %{ 7787 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7788 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7789 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 7790 // value is never passed to caller. 7791 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7792 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7793 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 7794 %} 7795 ins_pipe(pipe_class_default); 7796 %} 7797 7798 instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 7799 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 7800 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7801 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7802 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 7803 ins_encode %{ 7804 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7805 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7806 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7807 MacroAssembler::MemBarNone, 7808 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 7809 %} 7810 ins_pipe(pipe_class_default); 7811 %} 7812 7813 instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 7814 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 7815 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 7816 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7817 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 7818 ins_encode %{ 7819 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7820 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7821 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 7822 // value is never passed to caller. 7823 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7824 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7825 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 7826 %} 7827 ins_pipe(pipe_class_default); 7828 %} 7829 7830 // CompareAndExchange 7831 7832 instruct compareAndExchangeB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7833 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 7834 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7835 effect(TEMP_DEF res, TEMP cr0); 7836 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 7837 ins_encode %{ 7838 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7839 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7840 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7841 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7842 noreg, true); 7843 %} 7844 ins_pipe(pipe_class_default); 7845 %} 7846 7847 instruct compareAndExchangeB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 7848 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 7849 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 7850 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 7851 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 7852 ins_encode %{ 7853 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7854 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7855 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 7856 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7857 noreg, true); 7858 %} 7859 ins_pipe(pipe_class_default); 7860 %} 7861 7862 instruct compareAndExchangeB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7863 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 7864 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 7865 effect(TEMP_DEF res, TEMP cr0); 7866 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 7867 ins_encode %{ 7868 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7869 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7870 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7871 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7872 noreg, true); 7873 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7874 __ isync(); 7875 } else { 7876 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 7877 __ sync(); 7878 } 7879 %} 7880 ins_pipe(pipe_class_default); 7881 %} 7882 7883 instruct compareAndExchangeB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 7884 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 7885 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 7886 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 7887 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 7888 ins_encode %{ 7889 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7890 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7891 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 7892 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7893 noreg, true); 7894 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7895 __ isync(); 7896 } else { 7897 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 7898 __ sync(); 7899 } 7900 %} 7901 ins_pipe(pipe_class_default); 7902 %} 7903 7904 instruct compareAndExchangeS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7905 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 7906 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7907 effect(TEMP_DEF res, TEMP cr0); 7908 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 7909 ins_encode %{ 7910 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7911 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7912 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7913 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7914 noreg, true); 7915 %} 7916 ins_pipe(pipe_class_default); 7917 %} 7918 7919 instruct compareAndExchangeS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 7920 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 7921 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 7922 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 7923 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 7924 ins_encode %{ 7925 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7926 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7927 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 7928 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7929 noreg, true); 7930 %} 7931 ins_pipe(pipe_class_default); 7932 %} 7933 7934 instruct compareAndExchangeS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7935 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 7936 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 7937 effect(TEMP_DEF res, TEMP cr0); 7938 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 7939 ins_encode %{ 7940 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7941 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7942 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7943 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7944 noreg, true); 7945 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7946 __ isync(); 7947 } else { 7948 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 7949 __ sync(); 7950 } 7951 %} 7952 ins_pipe(pipe_class_default); 7953 %} 7954 7955 instruct compareAndExchangeS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 7956 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 7957 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 7958 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 7959 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 7960 ins_encode %{ 7961 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7962 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7963 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 7964 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7965 noreg, true); 7966 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7967 __ isync(); 7968 } else { 7969 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 7970 __ sync(); 7971 } 7972 %} 7973 ins_pipe(pipe_class_default); 7974 %} 7975 7976 instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7977 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 7978 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7979 effect(TEMP_DEF res, TEMP cr0); 7980 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %} 7981 ins_encode %{ 7982 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7983 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7984 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7985 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7986 noreg, true); 7987 %} 7988 ins_pipe(pipe_class_default); 7989 %} 7990 7991 instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7992 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 7993 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 7994 effect(TEMP_DEF res, TEMP cr0); 7995 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %} 7996 ins_encode %{ 7997 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7998 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7999 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8000 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8001 noreg, true); 8002 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8003 __ isync(); 8004 } else { 8005 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8006 __ sync(); 8007 } 8008 %} 8009 ins_pipe(pipe_class_default); 8010 %} 8011 8012 instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8013 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8014 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8015 effect(TEMP_DEF res, TEMP cr0); 8016 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8017 ins_encode %{ 8018 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8019 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8020 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8021 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8022 noreg, true); 8023 %} 8024 ins_pipe(pipe_class_default); 8025 %} 8026 8027 instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8028 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8029 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8030 effect(TEMP_DEF res, TEMP cr0); 8031 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8032 ins_encode %{ 8033 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8034 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8035 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8036 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8037 noreg, true); 8038 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8039 __ isync(); 8040 } else { 8041 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8042 __ sync(); 8043 } 8044 %} 8045 ins_pipe(pipe_class_default); 8046 %} 8047 8048 instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8049 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8050 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8051 effect(TEMP_DEF res, TEMP cr0); 8052 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %} 8053 ins_encode %{ 8054 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8055 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8056 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8057 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8058 noreg, NULL, true); 8059 %} 8060 ins_pipe(pipe_class_default); 8061 %} 8062 8063 instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8064 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8065 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8066 effect(TEMP_DEF res, TEMP cr0); 8067 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %} 8068 ins_encode %{ 8069 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8070 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8071 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8072 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8073 noreg, NULL, true); 8074 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8075 __ isync(); 8076 } else { 8077 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8078 __ sync(); 8079 } 8080 %} 8081 ins_pipe(pipe_class_default); 8082 %} 8083 8084 instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8085 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8086 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8087 effect(TEMP_DEF res, TEMP cr0); 8088 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8089 ins_encode %{ 8090 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8091 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8092 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8093 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8094 noreg, NULL, true); 8095 %} 8096 ins_pipe(pipe_class_default); 8097 %} 8098 8099 instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8100 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8101 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8102 effect(TEMP_DEF res, TEMP cr0); 8103 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8104 ins_encode %{ 8105 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8106 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8107 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8108 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8109 noreg, NULL, true); 8110 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8111 __ isync(); 8112 } else { 8113 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8114 __ sync(); 8115 } 8116 %} 8117 ins_pipe(pipe_class_default); 8118 %} 8119 8120 // Special RMW 8121 8122 instruct getAndAddB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8123 match(Set res (GetAndAddB mem_ptr src)); 8124 predicate(VM_Version::has_lqarx()); 8125 effect(TEMP_DEF res, TEMP cr0); 8126 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8127 ins_encode %{ 8128 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8129 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8130 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8131 __ isync(); 8132 } else { 8133 __ sync(); 8134 } 8135 %} 8136 ins_pipe(pipe_class_default); 8137 %} 8138 8139 instruct getAndAddB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8140 match(Set res (GetAndAddB mem_ptr src)); 8141 predicate(!VM_Version::has_lqarx()); 8142 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8143 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8144 ins_encode %{ 8145 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8146 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8147 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8148 __ isync(); 8149 } else { 8150 __ sync(); 8151 } 8152 %} 8153 ins_pipe(pipe_class_default); 8154 %} 8155 8156 instruct getAndAddS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8157 match(Set res (GetAndAddS mem_ptr src)); 8158 predicate(VM_Version::has_lqarx()); 8159 effect(TEMP_DEF res, TEMP cr0); 8160 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8161 ins_encode %{ 8162 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8163 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8164 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8165 __ isync(); 8166 } else { 8167 __ sync(); 8168 } 8169 %} 8170 ins_pipe(pipe_class_default); 8171 %} 8172 8173 instruct getAndAddS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8174 match(Set res (GetAndAddS mem_ptr src)); 8175 predicate(!VM_Version::has_lqarx()); 8176 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8177 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8178 ins_encode %{ 8179 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8180 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8181 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8182 __ isync(); 8183 } else { 8184 __ sync(); 8185 } 8186 %} 8187 ins_pipe(pipe_class_default); 8188 %} 8189 8190 instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8191 match(Set res (GetAndAddI mem_ptr src)); 8192 effect(TEMP_DEF res, TEMP cr0); 8193 format %{ "GetAndAddI $res, $mem_ptr, $src" %} 8194 ins_encode %{ 8195 __ getandaddw($res$$Register, $src$$Register, $mem_ptr$$Register, 8196 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8197 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8198 __ isync(); 8199 } else { 8200 __ sync(); 8201 } 8202 %} 8203 ins_pipe(pipe_class_default); 8204 %} 8205 8206 instruct getAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8207 match(Set res (GetAndAddL mem_ptr src)); 8208 effect(TEMP_DEF res, TEMP cr0); 8209 format %{ "GetAndAddL $res, $mem_ptr, $src" %} 8210 ins_encode %{ 8211 __ getandaddd($res$$Register, $src$$Register, $mem_ptr$$Register, 8212 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8213 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8214 __ isync(); 8215 } else { 8216 __ sync(); 8217 } 8218 %} 8219 ins_pipe(pipe_class_default); 8220 %} 8221 8222 instruct getAndSetB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8223 match(Set res (GetAndSetB mem_ptr src)); 8224 predicate(VM_Version::has_lqarx()); 8225 effect(TEMP_DEF res, TEMP cr0); 8226 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8227 ins_encode %{ 8228 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8229 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8230 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8231 __ isync(); 8232 } else { 8233 __ sync(); 8234 } 8235 %} 8236 ins_pipe(pipe_class_default); 8237 %} 8238 8239 instruct getAndSetB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8240 match(Set res (GetAndSetB mem_ptr src)); 8241 predicate(!VM_Version::has_lqarx()); 8242 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8243 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8244 ins_encode %{ 8245 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8246 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8247 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8248 __ isync(); 8249 } else { 8250 __ sync(); 8251 } 8252 %} 8253 ins_pipe(pipe_class_default); 8254 %} 8255 8256 instruct getAndSetS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8257 match(Set res (GetAndSetS mem_ptr src)); 8258 predicate(VM_Version::has_lqarx()); 8259 effect(TEMP_DEF res, TEMP cr0); 8260 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8261 ins_encode %{ 8262 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8263 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8264 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8265 __ isync(); 8266 } else { 8267 __ sync(); 8268 } 8269 %} 8270 ins_pipe(pipe_class_default); 8271 %} 8272 8273 instruct getAndSetS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8274 match(Set res (GetAndSetS mem_ptr src)); 8275 predicate(!VM_Version::has_lqarx()); 8276 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8277 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8278 ins_encode %{ 8279 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8280 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8281 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8282 __ isync(); 8283 } else { 8284 __ sync(); 8285 } 8286 %} 8287 ins_pipe(pipe_class_default); 8288 %} 8289 8290 instruct getAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8291 match(Set res (GetAndSetI mem_ptr src)); 8292 effect(TEMP_DEF res, TEMP cr0); 8293 format %{ "GetAndSetI $res, $mem_ptr, $src" %} 8294 ins_encode %{ 8295 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8296 MacroAssembler::cmpxchgx_hint_atomic_update()); 8297 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8298 __ isync(); 8299 } else { 8300 __ sync(); 8301 } 8302 %} 8303 ins_pipe(pipe_class_default); 8304 %} 8305 8306 instruct getAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8307 match(Set res (GetAndSetL mem_ptr src)); 8308 effect(TEMP_DEF res, TEMP cr0); 8309 format %{ "GetAndSetL $res, $mem_ptr, $src" %} 8310 ins_encode %{ 8311 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8312 MacroAssembler::cmpxchgx_hint_atomic_update()); 8313 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8314 __ isync(); 8315 } else { 8316 __ sync(); 8317 } 8318 %} 8319 ins_pipe(pipe_class_default); 8320 %} 8321 8322 instruct getAndSetP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src, flagsRegCR0 cr0) %{ 8323 match(Set res (GetAndSetP mem_ptr src)); 8324 effect(TEMP_DEF res, TEMP cr0); 8325 format %{ "GetAndSetP $res, $mem_ptr, $src" %} 8326 ins_encode %{ 8327 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8328 MacroAssembler::cmpxchgx_hint_atomic_update()); 8329 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8330 __ isync(); 8331 } else { 8332 __ sync(); 8333 } 8334 %} 8335 ins_pipe(pipe_class_default); 8336 %} 8337 8338 instruct getAndSetN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src, flagsRegCR0 cr0) %{ 8339 match(Set res (GetAndSetN mem_ptr src)); 8340 effect(TEMP_DEF res, TEMP cr0); 8341 format %{ "GetAndSetN $res, $mem_ptr, $src" %} 8342 ins_encode %{ 8343 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8344 MacroAssembler::cmpxchgx_hint_atomic_update()); 8345 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8346 __ isync(); 8347 } else { 8348 __ sync(); 8349 } 8350 %} 8351 ins_pipe(pipe_class_default); 8352 %} 8353 8354 //----------Arithmetic Instructions-------------------------------------------- 8355 // Addition Instructions 8356 8357 // Register Addition 8358 instruct addI_reg_reg(iRegIdst dst, iRegIsrc_iRegL2Isrc src1, iRegIsrc_iRegL2Isrc src2) %{ 8359 match(Set dst (AddI src1 src2)); 8360 format %{ "ADD $dst, $src1, $src2" %} 8361 size(4); 8362 ins_encode %{ 8363 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8364 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8365 %} 8366 ins_pipe(pipe_class_default); 8367 %} 8368 8369 // Expand does not work with above instruct. (??) 8370 instruct addI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8371 // no match-rule 8372 effect(DEF dst, USE src1, USE src2); 8373 format %{ "ADD $dst, $src1, $src2" %} 8374 size(4); 8375 ins_encode %{ 8376 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8377 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8378 %} 8379 ins_pipe(pipe_class_default); 8380 %} 8381 8382 instruct tree_addI_addI_addI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 8383 match(Set dst (AddI (AddI (AddI src1 src2) src3) src4)); 8384 ins_cost(DEFAULT_COST*3); 8385 8386 expand %{ 8387 // FIXME: we should do this in the ideal world. 8388 iRegIdst tmp1; 8389 iRegIdst tmp2; 8390 addI_reg_reg(tmp1, src1, src2); 8391 addI_reg_reg_2(tmp2, src3, src4); // Adlc complains about addI_reg_reg. 8392 addI_reg_reg(dst, tmp1, tmp2); 8393 %} 8394 %} 8395 8396 // Immediate Addition 8397 instruct addI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 8398 match(Set dst (AddI src1 src2)); 8399 format %{ "ADDI $dst, $src1, $src2" %} 8400 size(4); 8401 ins_encode %{ 8402 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8403 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8404 %} 8405 ins_pipe(pipe_class_default); 8406 %} 8407 8408 // Immediate Addition with 16-bit shifted operand 8409 instruct addI_reg_immhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2) %{ 8410 match(Set dst (AddI src1 src2)); 8411 format %{ "ADDIS $dst, $src1, $src2" %} 8412 size(4); 8413 ins_encode %{ 8414 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8415 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8416 %} 8417 ins_pipe(pipe_class_default); 8418 %} 8419 8420 // Long Addition 8421 instruct addL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8422 match(Set dst (AddL src1 src2)); 8423 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8424 size(4); 8425 ins_encode %{ 8426 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8427 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8428 %} 8429 ins_pipe(pipe_class_default); 8430 %} 8431 8432 // Expand does not work with above instruct. (??) 8433 instruct addL_reg_reg_2(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8434 // no match-rule 8435 effect(DEF dst, USE src1, USE src2); 8436 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8437 size(4); 8438 ins_encode %{ 8439 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8440 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8441 %} 8442 ins_pipe(pipe_class_default); 8443 %} 8444 8445 instruct tree_addL_addL_addL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2, iRegLsrc src3, iRegLsrc src4) %{ 8446 match(Set dst (AddL (AddL (AddL src1 src2) src3) src4)); 8447 ins_cost(DEFAULT_COST*3); 8448 8449 expand %{ 8450 // FIXME: we should do this in the ideal world. 8451 iRegLdst tmp1; 8452 iRegLdst tmp2; 8453 addL_reg_reg(tmp1, src1, src2); 8454 addL_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 8455 addL_reg_reg(dst, tmp1, tmp2); 8456 %} 8457 %} 8458 8459 // AddL + ConvL2I. 8460 instruct addI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8461 match(Set dst (ConvL2I (AddL src1 src2))); 8462 8463 format %{ "ADD $dst, $src1, $src2 \t// long + l2i" %} 8464 size(4); 8465 ins_encode %{ 8466 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8467 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8468 %} 8469 ins_pipe(pipe_class_default); 8470 %} 8471 8472 // No constant pool entries required. 8473 instruct addL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 8474 match(Set dst (AddL src1 src2)); 8475 8476 format %{ "ADDI $dst, $src1, $src2" %} 8477 size(4); 8478 ins_encode %{ 8479 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8480 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8481 %} 8482 ins_pipe(pipe_class_default); 8483 %} 8484 8485 // Long Immediate Addition with 16-bit shifted operand. 8486 // No constant pool entries required. 8487 instruct addL_reg_immhi16(iRegLdst dst, iRegLsrc src1, immL32hi16 src2) %{ 8488 match(Set dst (AddL src1 src2)); 8489 8490 format %{ "ADDIS $dst, $src1, $src2" %} 8491 size(4); 8492 ins_encode %{ 8493 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8494 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8495 %} 8496 ins_pipe(pipe_class_default); 8497 %} 8498 8499 // Pointer Register Addition 8500 instruct addP_reg_reg(iRegPdst dst, iRegP_N2P src1, iRegLsrc src2) %{ 8501 match(Set dst (AddP src1 src2)); 8502 format %{ "ADD $dst, $src1, $src2" %} 8503 size(4); 8504 ins_encode %{ 8505 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8506 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8507 %} 8508 ins_pipe(pipe_class_default); 8509 %} 8510 8511 // Pointer Immediate Addition 8512 // No constant pool entries required. 8513 instruct addP_reg_imm16(iRegPdst dst, iRegP_N2P src1, immL16 src2) %{ 8514 match(Set dst (AddP src1 src2)); 8515 8516 format %{ "ADDI $dst, $src1, $src2" %} 8517 size(4); 8518 ins_encode %{ 8519 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8520 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8521 %} 8522 ins_pipe(pipe_class_default); 8523 %} 8524 8525 // Pointer Immediate Addition with 16-bit shifted operand. 8526 // No constant pool entries required. 8527 instruct addP_reg_immhi16(iRegPdst dst, iRegP_N2P src1, immL32hi16 src2) %{ 8528 match(Set dst (AddP src1 src2)); 8529 8530 format %{ "ADDIS $dst, $src1, $src2" %} 8531 size(4); 8532 ins_encode %{ 8533 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8534 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8535 %} 8536 ins_pipe(pipe_class_default); 8537 %} 8538 8539 //--------------------- 8540 // Subtraction Instructions 8541 8542 // Register Subtraction 8543 instruct subI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8544 match(Set dst (SubI src1 src2)); 8545 format %{ "SUBF $dst, $src2, $src1" %} 8546 size(4); 8547 ins_encode %{ 8548 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 8549 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 8550 %} 8551 ins_pipe(pipe_class_default); 8552 %} 8553 8554 // Immediate Subtraction 8555 // Immediate Subtraction: The compiler converts "x-c0" into "x+ -c0" (see SubLNode::Ideal), 8556 // Don't try to use addi with - $src2$$constant since it can overflow when $src2$$constant == minI16. 8557 8558 // SubI from constant (using subfic). 8559 instruct subI_imm16_reg(iRegIdst dst, immI16 src1, iRegIsrc src2) %{ 8560 match(Set dst (SubI src1 src2)); 8561 format %{ "SUBI $dst, $src1, $src2" %} 8562 8563 size(4); 8564 ins_encode %{ 8565 // TODO: PPC port $archOpcode(ppc64Opcode_subfic); 8566 __ subfic($dst$$Register, $src2$$Register, $src1$$constant); 8567 %} 8568 ins_pipe(pipe_class_default); 8569 %} 8570 8571 // Turn the sign-bit of an integer into a 32-bit mask, 0x0...0 for 8572 // positive integers and 0xF...F for negative ones. 8573 instruct signmask32I_regI(iRegIdst dst, iRegIsrc src) %{ 8574 // no match-rule, false predicate 8575 effect(DEF dst, USE src); 8576 predicate(false); 8577 8578 format %{ "SRAWI $dst, $src, #31" %} 8579 size(4); 8580 ins_encode %{ 8581 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 8582 __ srawi($dst$$Register, $src$$Register, 0x1f); 8583 %} 8584 ins_pipe(pipe_class_default); 8585 %} 8586 8587 instruct absI_reg_Ex(iRegIdst dst, iRegIsrc src) %{ 8588 match(Set dst (AbsI src)); 8589 ins_cost(DEFAULT_COST*3); 8590 8591 expand %{ 8592 iRegIdst tmp1; 8593 iRegIdst tmp2; 8594 signmask32I_regI(tmp1, src); 8595 xorI_reg_reg(tmp2, tmp1, src); 8596 subI_reg_reg(dst, tmp2, tmp1); 8597 %} 8598 %} 8599 8600 instruct negI_regI(iRegIdst dst, immI_0 zero, iRegIsrc src2) %{ 8601 match(Set dst (SubI zero src2)); 8602 format %{ "NEG $dst, $src2" %} 8603 size(4); 8604 ins_encode %{ 8605 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 8606 __ neg($dst$$Register, $src2$$Register); 8607 %} 8608 ins_pipe(pipe_class_default); 8609 %} 8610 8611 // Long subtraction 8612 instruct subL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8613 match(Set dst (SubL src1 src2)); 8614 format %{ "SUBF $dst, $src2, $src1 \t// long" %} 8615 size(4); 8616 ins_encode %{ 8617 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 8618 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 8619 %} 8620 ins_pipe(pipe_class_default); 8621 %} 8622 8623 // SubL + convL2I. 8624 instruct subI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8625 match(Set dst (ConvL2I (SubL src1 src2))); 8626 8627 format %{ "SUBF $dst, $src2, $src1 \t// long + l2i" %} 8628 size(4); 8629 ins_encode %{ 8630 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 8631 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 8632 %} 8633 ins_pipe(pipe_class_default); 8634 %} 8635 8636 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 8637 // positive longs and 0xF...F for negative ones. 8638 instruct signmask64I_regL(iRegIdst dst, iRegLsrc src) %{ 8639 // no match-rule, false predicate 8640 effect(DEF dst, USE src); 8641 predicate(false); 8642 8643 format %{ "SRADI $dst, $src, #63" %} 8644 size(4); 8645 ins_encode %{ 8646 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 8647 __ sradi($dst$$Register, $src$$Register, 0x3f); 8648 %} 8649 ins_pipe(pipe_class_default); 8650 %} 8651 8652 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 8653 // positive longs and 0xF...F for negative ones. 8654 instruct signmask64L_regL(iRegLdst dst, iRegLsrc src) %{ 8655 // no match-rule, false predicate 8656 effect(DEF dst, USE src); 8657 predicate(false); 8658 8659 format %{ "SRADI $dst, $src, #63" %} 8660 size(4); 8661 ins_encode %{ 8662 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 8663 __ sradi($dst$$Register, $src$$Register, 0x3f); 8664 %} 8665 ins_pipe(pipe_class_default); 8666 %} 8667 8668 // Long negation 8669 instruct negL_reg_reg(iRegLdst dst, immL_0 zero, iRegLsrc src2) %{ 8670 match(Set dst (SubL zero src2)); 8671 format %{ "NEG $dst, $src2 \t// long" %} 8672 size(4); 8673 ins_encode %{ 8674 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 8675 __ neg($dst$$Register, $src2$$Register); 8676 %} 8677 ins_pipe(pipe_class_default); 8678 %} 8679 8680 // NegL + ConvL2I. 8681 instruct negI_con0_regL(iRegIdst dst, immL_0 zero, iRegLsrc src2) %{ 8682 match(Set dst (ConvL2I (SubL zero src2))); 8683 8684 format %{ "NEG $dst, $src2 \t// long + l2i" %} 8685 size(4); 8686 ins_encode %{ 8687 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 8688 __ neg($dst$$Register, $src2$$Register); 8689 %} 8690 ins_pipe(pipe_class_default); 8691 %} 8692 8693 // Multiplication Instructions 8694 // Integer Multiplication 8695 8696 // Register Multiplication 8697 instruct mulI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8698 match(Set dst (MulI src1 src2)); 8699 ins_cost(DEFAULT_COST); 8700 8701 format %{ "MULLW $dst, $src1, $src2" %} 8702 size(4); 8703 ins_encode %{ 8704 // TODO: PPC port $archOpcode(ppc64Opcode_mullw); 8705 __ mullw($dst$$Register, $src1$$Register, $src2$$Register); 8706 %} 8707 ins_pipe(pipe_class_default); 8708 %} 8709 8710 // Immediate Multiplication 8711 instruct mulI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 8712 match(Set dst (MulI src1 src2)); 8713 ins_cost(DEFAULT_COST); 8714 8715 format %{ "MULLI $dst, $src1, $src2" %} 8716 size(4); 8717 ins_encode %{ 8718 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 8719 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 8720 %} 8721 ins_pipe(pipe_class_default); 8722 %} 8723 8724 instruct mulL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8725 match(Set dst (MulL src1 src2)); 8726 ins_cost(DEFAULT_COST); 8727 8728 format %{ "MULLD $dst $src1, $src2 \t// long" %} 8729 size(4); 8730 ins_encode %{ 8731 // TODO: PPC port $archOpcode(ppc64Opcode_mulld); 8732 __ mulld($dst$$Register, $src1$$Register, $src2$$Register); 8733 %} 8734 ins_pipe(pipe_class_default); 8735 %} 8736 8737 // Multiply high for optimized long division by constant. 8738 instruct mulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8739 match(Set dst (MulHiL src1 src2)); 8740 ins_cost(DEFAULT_COST); 8741 8742 format %{ "MULHD $dst $src1, $src2 \t// long" %} 8743 size(4); 8744 ins_encode %{ 8745 // TODO: PPC port $archOpcode(ppc64Opcode_mulhd); 8746 __ mulhd($dst$$Register, $src1$$Register, $src2$$Register); 8747 %} 8748 ins_pipe(pipe_class_default); 8749 %} 8750 8751 // Immediate Multiplication 8752 instruct mulL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 8753 match(Set dst (MulL src1 src2)); 8754 ins_cost(DEFAULT_COST); 8755 8756 format %{ "MULLI $dst, $src1, $src2" %} 8757 size(4); 8758 ins_encode %{ 8759 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 8760 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 8761 %} 8762 ins_pipe(pipe_class_default); 8763 %} 8764 8765 // Integer Division with Immediate -1: Negate. 8766 instruct divI_reg_immIvalueMinus1(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 8767 match(Set dst (DivI src1 src2)); 8768 ins_cost(DEFAULT_COST); 8769 8770 format %{ "NEG $dst, $src1 \t// /-1" %} 8771 size(4); 8772 ins_encode %{ 8773 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 8774 __ neg($dst$$Register, $src1$$Register); 8775 %} 8776 ins_pipe(pipe_class_default); 8777 %} 8778 8779 // Integer Division with constant, but not -1. 8780 // We should be able to improve this by checking the type of src2. 8781 // It might well be that src2 is known to be positive. 8782 instruct divI_reg_regnotMinus1(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8783 match(Set dst (DivI src1 src2)); 8784 predicate(n->in(2)->find_int_con(-1) != -1); // src2 is a constant, but not -1 8785 ins_cost(2*DEFAULT_COST); 8786 8787 format %{ "DIVW $dst, $src1, $src2 \t// /not-1" %} 8788 size(4); 8789 ins_encode %{ 8790 // TODO: PPC port $archOpcode(ppc64Opcode_divw); 8791 __ divw($dst$$Register, $src1$$Register, $src2$$Register); 8792 %} 8793 ins_pipe(pipe_class_default); 8794 %} 8795 8796 instruct cmovI_bne_negI_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src1) %{ 8797 effect(USE_DEF dst, USE src1, USE crx); 8798 predicate(false); 8799 8800 ins_variable_size_depending_on_alignment(true); 8801 8802 format %{ "CMOVE $dst, neg($src1), $crx" %} 8803 // Worst case is branch + move + stop, no stop without scheduler. 8804 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 8805 ins_encode %{ 8806 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 8807 Label done; 8808 __ bne($crx$$CondRegister, done); 8809 __ neg($dst$$Register, $src1$$Register); 8810 // TODO PPC port __ endgroup_if_needed(_size == 12); 8811 __ bind(done); 8812 %} 8813 ins_pipe(pipe_class_default); 8814 %} 8815 8816 // Integer Division with Registers not containing constants. 8817 instruct divI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8818 match(Set dst (DivI src1 src2)); 8819 ins_cost(10*DEFAULT_COST); 8820 8821 expand %{ 8822 immI16 imm %{ (int)-1 %} 8823 flagsReg tmp1; 8824 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 8825 divI_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 8826 cmovI_bne_negI_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 8827 %} 8828 %} 8829 8830 // Long Division with Immediate -1: Negate. 8831 instruct divL_reg_immLvalueMinus1(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 8832 match(Set dst (DivL src1 src2)); 8833 ins_cost(DEFAULT_COST); 8834 8835 format %{ "NEG $dst, $src1 \t// /-1, long" %} 8836 size(4); 8837 ins_encode %{ 8838 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 8839 __ neg($dst$$Register, $src1$$Register); 8840 %} 8841 ins_pipe(pipe_class_default); 8842 %} 8843 8844 // Long Division with constant, but not -1. 8845 instruct divL_reg_regnotMinus1(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8846 match(Set dst (DivL src1 src2)); 8847 predicate(n->in(2)->find_long_con(-1L) != -1L); // Src2 is a constant, but not -1. 8848 ins_cost(2*DEFAULT_COST); 8849 8850 format %{ "DIVD $dst, $src1, $src2 \t// /not-1, long" %} 8851 size(4); 8852 ins_encode %{ 8853 // TODO: PPC port $archOpcode(ppc64Opcode_divd); 8854 __ divd($dst$$Register, $src1$$Register, $src2$$Register); 8855 %} 8856 ins_pipe(pipe_class_default); 8857 %} 8858 8859 instruct cmovL_bne_negL_reg(iRegLdst dst, flagsRegSrc crx, iRegLsrc src1) %{ 8860 effect(USE_DEF dst, USE src1, USE crx); 8861 predicate(false); 8862 8863 ins_variable_size_depending_on_alignment(true); 8864 8865 format %{ "CMOVE $dst, neg($src1), $crx" %} 8866 // Worst case is branch + move + stop, no stop without scheduler. 8867 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 8868 ins_encode %{ 8869 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 8870 Label done; 8871 __ bne($crx$$CondRegister, done); 8872 __ neg($dst$$Register, $src1$$Register); 8873 // TODO PPC port __ endgroup_if_needed(_size == 12); 8874 __ bind(done); 8875 %} 8876 ins_pipe(pipe_class_default); 8877 %} 8878 8879 // Long Division with Registers not containing constants. 8880 instruct divL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8881 match(Set dst (DivL src1 src2)); 8882 ins_cost(10*DEFAULT_COST); 8883 8884 expand %{ 8885 immL16 imm %{ (int)-1 %} 8886 flagsReg tmp1; 8887 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 8888 divL_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 8889 cmovL_bne_negL_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 8890 %} 8891 %} 8892 8893 // Integer Remainder with registers. 8894 instruct modI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8895 match(Set dst (ModI src1 src2)); 8896 ins_cost(10*DEFAULT_COST); 8897 8898 expand %{ 8899 immI16 imm %{ (int)-1 %} 8900 flagsReg tmp1; 8901 iRegIdst tmp2; 8902 iRegIdst tmp3; 8903 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 8904 divI_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 8905 cmovI_bne_negI_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 8906 mulI_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 8907 subI_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 8908 %} 8909 %} 8910 8911 // Long Remainder with registers 8912 instruct modL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8913 match(Set dst (ModL src1 src2)); 8914 ins_cost(10*DEFAULT_COST); 8915 8916 expand %{ 8917 immL16 imm %{ (int)-1 %} 8918 flagsReg tmp1; 8919 iRegLdst tmp2; 8920 iRegLdst tmp3; 8921 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 8922 divL_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 8923 cmovL_bne_negL_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 8924 mulL_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 8925 subL_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 8926 %} 8927 %} 8928 8929 // Integer Shift Instructions 8930 8931 // Register Shift Left 8932 8933 // Clear all but the lowest #mask bits. 8934 // Used to normalize shift amounts in registers. 8935 instruct maskI_reg_imm(iRegIdst dst, iRegIsrc src, uimmI6 mask) %{ 8936 // no match-rule, false predicate 8937 effect(DEF dst, USE src, USE mask); 8938 predicate(false); 8939 8940 format %{ "MASK $dst, $src, $mask \t// clear $mask upper bits" %} 8941 size(4); 8942 ins_encode %{ 8943 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 8944 __ clrldi($dst$$Register, $src$$Register, $mask$$constant); 8945 %} 8946 ins_pipe(pipe_class_default); 8947 %} 8948 8949 instruct lShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8950 // no match-rule, false predicate 8951 effect(DEF dst, USE src1, USE src2); 8952 predicate(false); 8953 8954 format %{ "SLW $dst, $src1, $src2" %} 8955 size(4); 8956 ins_encode %{ 8957 // TODO: PPC port $archOpcode(ppc64Opcode_slw); 8958 __ slw($dst$$Register, $src1$$Register, $src2$$Register); 8959 %} 8960 ins_pipe(pipe_class_default); 8961 %} 8962 8963 instruct lShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8964 match(Set dst (LShiftI src1 src2)); 8965 ins_cost(DEFAULT_COST*2); 8966 expand %{ 8967 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 8968 iRegIdst tmpI; 8969 maskI_reg_imm(tmpI, src2, mask); 8970 lShiftI_reg_reg(dst, src1, tmpI); 8971 %} 8972 %} 8973 8974 // Register Shift Left Immediate 8975 instruct lShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 8976 match(Set dst (LShiftI src1 src2)); 8977 8978 format %{ "SLWI $dst, $src1, ($src2 & 0x1f)" %} 8979 size(4); 8980 ins_encode %{ 8981 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 8982 __ slwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 8983 %} 8984 ins_pipe(pipe_class_default); 8985 %} 8986 8987 // AndI with negpow2-constant + LShiftI 8988 instruct lShiftI_andI_immInegpow2_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 8989 match(Set dst (LShiftI (AndI src1 src2) src3)); 8990 predicate(UseRotateAndMaskInstructionsPPC64); 8991 8992 format %{ "RLWINM $dst, lShiftI(AndI($src1, $src2), $src3)" %} 8993 size(4); 8994 ins_encode %{ 8995 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 8996 long src2 = $src2$$constant; 8997 long src3 = $src3$$constant; 8998 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 8999 if (maskbits >= 32) { 9000 __ li($dst$$Register, 0); // addi 9001 } else { 9002 __ rlwinm($dst$$Register, $src1$$Register, src3 & 0x1f, 0, (31-maskbits) & 0x1f); 9003 } 9004 %} 9005 ins_pipe(pipe_class_default); 9006 %} 9007 9008 // RShiftI + AndI with negpow2-constant + LShiftI 9009 instruct lShiftI_andI_immInegpow2_rShiftI_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9010 match(Set dst (LShiftI (AndI (RShiftI src1 src3) src2) src3)); 9011 predicate(UseRotateAndMaskInstructionsPPC64); 9012 9013 format %{ "RLWINM $dst, lShiftI(AndI(RShiftI($src1, $src3), $src2), $src3)" %} 9014 size(4); 9015 ins_encode %{ 9016 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9017 long src2 = $src2$$constant; 9018 long src3 = $src3$$constant; 9019 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9020 if (maskbits >= 32) { 9021 __ li($dst$$Register, 0); // addi 9022 } else { 9023 __ rlwinm($dst$$Register, $src1$$Register, 0, 0, (31-maskbits) & 0x1f); 9024 } 9025 %} 9026 ins_pipe(pipe_class_default); 9027 %} 9028 9029 instruct lShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9030 // no match-rule, false predicate 9031 effect(DEF dst, USE src1, USE src2); 9032 predicate(false); 9033 9034 format %{ "SLD $dst, $src1, $src2" %} 9035 size(4); 9036 ins_encode %{ 9037 // TODO: PPC port $archOpcode(ppc64Opcode_sld); 9038 __ sld($dst$$Register, $src1$$Register, $src2$$Register); 9039 %} 9040 ins_pipe(pipe_class_default); 9041 %} 9042 9043 // Register Shift Left 9044 instruct lShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9045 match(Set dst (LShiftL src1 src2)); 9046 ins_cost(DEFAULT_COST*2); 9047 expand %{ 9048 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9049 iRegIdst tmpI; 9050 maskI_reg_imm(tmpI, src2, mask); 9051 lShiftL_regL_regI(dst, src1, tmpI); 9052 %} 9053 %} 9054 9055 // Register Shift Left Immediate 9056 instruct lshiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9057 match(Set dst (LShiftL src1 src2)); 9058 format %{ "SLDI $dst, $src1, ($src2 & 0x3f)" %} 9059 size(4); 9060 ins_encode %{ 9061 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9062 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9063 %} 9064 ins_pipe(pipe_class_default); 9065 %} 9066 9067 // If we shift more than 32 bits, we need not convert I2L. 9068 instruct lShiftL_regI_immGE32(iRegLdst dst, iRegIsrc src1, uimmI6_ge32 src2) %{ 9069 match(Set dst (LShiftL (ConvI2L src1) src2)); 9070 ins_cost(DEFAULT_COST); 9071 9072 size(4); 9073 format %{ "SLDI $dst, i2l($src1), $src2" %} 9074 ins_encode %{ 9075 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9076 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9077 %} 9078 ins_pipe(pipe_class_default); 9079 %} 9080 9081 // Shift a postivie int to the left. 9082 // Clrlsldi clears the upper 32 bits and shifts. 9083 instruct scaledPositiveI2L_lShiftL_convI2L_reg_imm6(iRegLdst dst, iRegIsrc src1, uimmI6 src2) %{ 9084 match(Set dst (LShiftL (ConvI2L src1) src2)); 9085 predicate(((ConvI2LNode*)(_kids[0]->_leaf))->type()->is_long()->is_positive_int()); 9086 9087 format %{ "SLDI $dst, i2l(positive_int($src1)), $src2" %} 9088 size(4); 9089 ins_encode %{ 9090 // TODO: PPC port $archOpcode(ppc64Opcode_rldic); 9091 __ clrlsldi($dst$$Register, $src1$$Register, 0x20, $src2$$constant); 9092 %} 9093 ins_pipe(pipe_class_default); 9094 %} 9095 9096 instruct arShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9097 // no match-rule, false predicate 9098 effect(DEF dst, USE src1, USE src2); 9099 predicate(false); 9100 9101 format %{ "SRAW $dst, $src1, $src2" %} 9102 size(4); 9103 ins_encode %{ 9104 // TODO: PPC port $archOpcode(ppc64Opcode_sraw); 9105 __ sraw($dst$$Register, $src1$$Register, $src2$$Register); 9106 %} 9107 ins_pipe(pipe_class_default); 9108 %} 9109 9110 // Register Arithmetic Shift Right 9111 instruct arShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9112 match(Set dst (RShiftI src1 src2)); 9113 ins_cost(DEFAULT_COST*2); 9114 expand %{ 9115 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9116 iRegIdst tmpI; 9117 maskI_reg_imm(tmpI, src2, mask); 9118 arShiftI_reg_reg(dst, src1, tmpI); 9119 %} 9120 %} 9121 9122 // Register Arithmetic Shift Right Immediate 9123 instruct arShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9124 match(Set dst (RShiftI src1 src2)); 9125 9126 format %{ "SRAWI $dst, $src1, ($src2 & 0x1f)" %} 9127 size(4); 9128 ins_encode %{ 9129 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 9130 __ srawi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9131 %} 9132 ins_pipe(pipe_class_default); 9133 %} 9134 9135 instruct arShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9136 // no match-rule, false predicate 9137 effect(DEF dst, USE src1, USE src2); 9138 predicate(false); 9139 9140 format %{ "SRAD $dst, $src1, $src2" %} 9141 size(4); 9142 ins_encode %{ 9143 // TODO: PPC port $archOpcode(ppc64Opcode_srad); 9144 __ srad($dst$$Register, $src1$$Register, $src2$$Register); 9145 %} 9146 ins_pipe(pipe_class_default); 9147 %} 9148 9149 // Register Shift Right Arithmetic Long 9150 instruct arShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9151 match(Set dst (RShiftL src1 src2)); 9152 ins_cost(DEFAULT_COST*2); 9153 9154 expand %{ 9155 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9156 iRegIdst tmpI; 9157 maskI_reg_imm(tmpI, src2, mask); 9158 arShiftL_regL_regI(dst, src1, tmpI); 9159 %} 9160 %} 9161 9162 // Register Shift Right Immediate 9163 instruct arShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9164 match(Set dst (RShiftL src1 src2)); 9165 9166 format %{ "SRADI $dst, $src1, ($src2 & 0x3f)" %} 9167 size(4); 9168 ins_encode %{ 9169 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9170 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9171 %} 9172 ins_pipe(pipe_class_default); 9173 %} 9174 9175 // RShiftL + ConvL2I 9176 instruct convL2I_arShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9177 match(Set dst (ConvL2I (RShiftL src1 src2))); 9178 9179 format %{ "SRADI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9180 size(4); 9181 ins_encode %{ 9182 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9183 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9184 %} 9185 ins_pipe(pipe_class_default); 9186 %} 9187 9188 instruct urShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9189 // no match-rule, false predicate 9190 effect(DEF dst, USE src1, USE src2); 9191 predicate(false); 9192 9193 format %{ "SRW $dst, $src1, $src2" %} 9194 size(4); 9195 ins_encode %{ 9196 // TODO: PPC port $archOpcode(ppc64Opcode_srw); 9197 __ srw($dst$$Register, $src1$$Register, $src2$$Register); 9198 %} 9199 ins_pipe(pipe_class_default); 9200 %} 9201 9202 // Register Shift Right 9203 instruct urShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9204 match(Set dst (URShiftI src1 src2)); 9205 ins_cost(DEFAULT_COST*2); 9206 9207 expand %{ 9208 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9209 iRegIdst tmpI; 9210 maskI_reg_imm(tmpI, src2, mask); 9211 urShiftI_reg_reg(dst, src1, tmpI); 9212 %} 9213 %} 9214 9215 // Register Shift Right Immediate 9216 instruct urShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9217 match(Set dst (URShiftI src1 src2)); 9218 9219 format %{ "SRWI $dst, $src1, ($src2 & 0x1f)" %} 9220 size(4); 9221 ins_encode %{ 9222 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9223 __ srwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9224 %} 9225 ins_pipe(pipe_class_default); 9226 %} 9227 9228 instruct urShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9229 // no match-rule, false predicate 9230 effect(DEF dst, USE src1, USE src2); 9231 predicate(false); 9232 9233 format %{ "SRD $dst, $src1, $src2" %} 9234 size(4); 9235 ins_encode %{ 9236 // TODO: PPC port $archOpcode(ppc64Opcode_srd); 9237 __ srd($dst$$Register, $src1$$Register, $src2$$Register); 9238 %} 9239 ins_pipe(pipe_class_default); 9240 %} 9241 9242 // Register Shift Right 9243 instruct urShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9244 match(Set dst (URShiftL src1 src2)); 9245 ins_cost(DEFAULT_COST*2); 9246 9247 expand %{ 9248 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9249 iRegIdst tmpI; 9250 maskI_reg_imm(tmpI, src2, mask); 9251 urShiftL_regL_regI(dst, src1, tmpI); 9252 %} 9253 %} 9254 9255 // Register Shift Right Immediate 9256 instruct urShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9257 match(Set dst (URShiftL src1 src2)); 9258 9259 format %{ "SRDI $dst, $src1, ($src2 & 0x3f)" %} 9260 size(4); 9261 ins_encode %{ 9262 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9263 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9264 %} 9265 ins_pipe(pipe_class_default); 9266 %} 9267 9268 // URShiftL + ConvL2I. 9269 instruct convL2I_urShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9270 match(Set dst (ConvL2I (URShiftL src1 src2))); 9271 9272 format %{ "SRDI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9273 size(4); 9274 ins_encode %{ 9275 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9276 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9277 %} 9278 ins_pipe(pipe_class_default); 9279 %} 9280 9281 // Register Shift Right Immediate with a CastP2X 9282 instruct shrP_convP2X_reg_imm6(iRegLdst dst, iRegP_N2P src1, uimmI6 src2) %{ 9283 match(Set dst (URShiftL (CastP2X src1) src2)); 9284 9285 format %{ "SRDI $dst, $src1, $src2 \t// Cast ptr $src1 to long and shift" %} 9286 size(4); 9287 ins_encode %{ 9288 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9289 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9290 %} 9291 ins_pipe(pipe_class_default); 9292 %} 9293 9294 instruct sxtI_reg(iRegIdst dst, iRegIsrc src) %{ 9295 match(Set dst (ConvL2I (ConvI2L src))); 9296 9297 format %{ "EXTSW $dst, $src \t// int->int" %} 9298 size(4); 9299 ins_encode %{ 9300 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 9301 __ extsw($dst$$Register, $src$$Register); 9302 %} 9303 ins_pipe(pipe_class_default); 9304 %} 9305 9306 //----------Rotate Instructions------------------------------------------------ 9307 9308 // Rotate Left by 8-bit immediate 9309 instruct rotlI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 lshift, immI8 rshift) %{ 9310 match(Set dst (OrI (LShiftI src lshift) (URShiftI src rshift))); 9311 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9312 9313 format %{ "ROTLWI $dst, $src, $lshift" %} 9314 size(4); 9315 ins_encode %{ 9316 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9317 __ rotlwi($dst$$Register, $src$$Register, $lshift$$constant); 9318 %} 9319 ins_pipe(pipe_class_default); 9320 %} 9321 9322 // Rotate Right by 8-bit immediate 9323 instruct rotrI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 rshift, immI8 lshift) %{ 9324 match(Set dst (OrI (URShiftI src rshift) (LShiftI src lshift))); 9325 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9326 9327 format %{ "ROTRWI $dst, $rshift" %} 9328 size(4); 9329 ins_encode %{ 9330 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9331 __ rotrwi($dst$$Register, $src$$Register, $rshift$$constant); 9332 %} 9333 ins_pipe(pipe_class_default); 9334 %} 9335 9336 //----------Floating Point Arithmetic Instructions----------------------------- 9337 9338 // Add float single precision 9339 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{ 9340 match(Set dst (AddF src1 src2)); 9341 9342 format %{ "FADDS $dst, $src1, $src2" %} 9343 size(4); 9344 ins_encode %{ 9345 // TODO: PPC port $archOpcode(ppc64Opcode_fadds); 9346 __ fadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9347 %} 9348 ins_pipe(pipe_class_default); 9349 %} 9350 9351 // Add float double precision 9352 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{ 9353 match(Set dst (AddD src1 src2)); 9354 9355 format %{ "FADD $dst, $src1, $src2" %} 9356 size(4); 9357 ins_encode %{ 9358 // TODO: PPC port $archOpcode(ppc64Opcode_fadd); 9359 __ fadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9360 %} 9361 ins_pipe(pipe_class_default); 9362 %} 9363 9364 // Sub float single precision 9365 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{ 9366 match(Set dst (SubF src1 src2)); 9367 9368 format %{ "FSUBS $dst, $src1, $src2" %} 9369 size(4); 9370 ins_encode %{ 9371 // TODO: PPC port $archOpcode(ppc64Opcode_fsubs); 9372 __ fsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9373 %} 9374 ins_pipe(pipe_class_default); 9375 %} 9376 9377 // Sub float double precision 9378 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{ 9379 match(Set dst (SubD src1 src2)); 9380 format %{ "FSUB $dst, $src1, $src2" %} 9381 size(4); 9382 ins_encode %{ 9383 // TODO: PPC port $archOpcode(ppc64Opcode_fsub); 9384 __ fsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9385 %} 9386 ins_pipe(pipe_class_default); 9387 %} 9388 9389 // Mul float single precision 9390 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{ 9391 match(Set dst (MulF src1 src2)); 9392 format %{ "FMULS $dst, $src1, $src2" %} 9393 size(4); 9394 ins_encode %{ 9395 // TODO: PPC port $archOpcode(ppc64Opcode_fmuls); 9396 __ fmuls($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9397 %} 9398 ins_pipe(pipe_class_default); 9399 %} 9400 9401 // Mul float double precision 9402 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{ 9403 match(Set dst (MulD src1 src2)); 9404 format %{ "FMUL $dst, $src1, $src2" %} 9405 size(4); 9406 ins_encode %{ 9407 // TODO: PPC port $archOpcode(ppc64Opcode_fmul); 9408 __ fmul($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9409 %} 9410 ins_pipe(pipe_class_default); 9411 %} 9412 9413 // Div float single precision 9414 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{ 9415 match(Set dst (DivF src1 src2)); 9416 format %{ "FDIVS $dst, $src1, $src2" %} 9417 size(4); 9418 ins_encode %{ 9419 // TODO: PPC port $archOpcode(ppc64Opcode_fdivs); 9420 __ fdivs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9421 %} 9422 ins_pipe(pipe_class_default); 9423 %} 9424 9425 // Div float double precision 9426 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{ 9427 match(Set dst (DivD src1 src2)); 9428 format %{ "FDIV $dst, $src1, $src2" %} 9429 size(4); 9430 ins_encode %{ 9431 // TODO: PPC port $archOpcode(ppc64Opcode_fdiv); 9432 __ fdiv($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9433 %} 9434 ins_pipe(pipe_class_default); 9435 %} 9436 9437 // Absolute float single precision 9438 instruct absF_reg(regF dst, regF src) %{ 9439 match(Set dst (AbsF src)); 9440 format %{ "FABS $dst, $src \t// float" %} 9441 size(4); 9442 ins_encode %{ 9443 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 9444 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9445 %} 9446 ins_pipe(pipe_class_default); 9447 %} 9448 9449 // Absolute float double precision 9450 instruct absD_reg(regD dst, regD src) %{ 9451 match(Set dst (AbsD src)); 9452 format %{ "FABS $dst, $src \t// double" %} 9453 size(4); 9454 ins_encode %{ 9455 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 9456 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9457 %} 9458 ins_pipe(pipe_class_default); 9459 %} 9460 9461 instruct negF_reg(regF dst, regF src) %{ 9462 match(Set dst (NegF src)); 9463 format %{ "FNEG $dst, $src \t// float" %} 9464 size(4); 9465 ins_encode %{ 9466 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 9467 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 9468 %} 9469 ins_pipe(pipe_class_default); 9470 %} 9471 9472 instruct negD_reg(regD dst, regD src) %{ 9473 match(Set dst (NegD src)); 9474 format %{ "FNEG $dst, $src \t// double" %} 9475 size(4); 9476 ins_encode %{ 9477 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 9478 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 9479 %} 9480 ins_pipe(pipe_class_default); 9481 %} 9482 9483 // AbsF + NegF. 9484 instruct negF_absF_reg(regF dst, regF src) %{ 9485 match(Set dst (NegF (AbsF src))); 9486 format %{ "FNABS $dst, $src \t// float" %} 9487 size(4); 9488 ins_encode %{ 9489 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 9490 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 9491 %} 9492 ins_pipe(pipe_class_default); 9493 %} 9494 9495 // AbsD + NegD. 9496 instruct negD_absD_reg(regD dst, regD src) %{ 9497 match(Set dst (NegD (AbsD src))); 9498 format %{ "FNABS $dst, $src \t// double" %} 9499 size(4); 9500 ins_encode %{ 9501 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 9502 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 9503 %} 9504 ins_pipe(pipe_class_default); 9505 %} 9506 9507 // VM_Version::has_fsqrt() decides if this node will be used. 9508 // Sqrt float double precision 9509 instruct sqrtD_reg(regD dst, regD src) %{ 9510 match(Set dst (SqrtD src)); 9511 format %{ "FSQRT $dst, $src" %} 9512 size(4); 9513 ins_encode %{ 9514 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrt); 9515 __ fsqrt($dst$$FloatRegister, $src$$FloatRegister); 9516 %} 9517 ins_pipe(pipe_class_default); 9518 %} 9519 9520 // Single-precision sqrt. 9521 instruct sqrtF_reg(regF dst, regF src) %{ 9522 match(Set dst (ConvD2F (SqrtD (ConvF2D src)))); 9523 predicate(VM_Version::has_fsqrts()); 9524 ins_cost(DEFAULT_COST); 9525 9526 format %{ "FSQRTS $dst, $src" %} 9527 size(4); 9528 ins_encode %{ 9529 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrts); 9530 __ fsqrts($dst$$FloatRegister, $src$$FloatRegister); 9531 %} 9532 ins_pipe(pipe_class_default); 9533 %} 9534 9535 instruct roundDouble_nop(regD dst) %{ 9536 match(Set dst (RoundDouble dst)); 9537 ins_cost(0); 9538 9539 format %{ " -- \t// RoundDouble not needed - empty" %} 9540 size(0); 9541 // PPC results are already "rounded" (i.e., normal-format IEEE). 9542 ins_encode( /*empty*/ ); 9543 ins_pipe(pipe_class_default); 9544 %} 9545 9546 instruct roundFloat_nop(regF dst) %{ 9547 match(Set dst (RoundFloat dst)); 9548 ins_cost(0); 9549 9550 format %{ " -- \t// RoundFloat not needed - empty" %} 9551 size(0); 9552 // PPC results are already "rounded" (i.e., normal-format IEEE). 9553 ins_encode( /*empty*/ ); 9554 ins_pipe(pipe_class_default); 9555 %} 9556 9557 //----------Logical Instructions----------------------------------------------- 9558 9559 // And Instructions 9560 9561 // Register And 9562 instruct andI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9563 match(Set dst (AndI src1 src2)); 9564 format %{ "AND $dst, $src1, $src2" %} 9565 size(4); 9566 ins_encode %{ 9567 // TODO: PPC port $archOpcode(ppc64Opcode_and); 9568 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 9569 %} 9570 ins_pipe(pipe_class_default); 9571 %} 9572 9573 // Immediate And 9574 instruct andI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2, flagsRegCR0 cr0) %{ 9575 match(Set dst (AndI src1 src2)); 9576 effect(KILL cr0); 9577 9578 format %{ "ANDI $dst, $src1, $src2" %} 9579 size(4); 9580 ins_encode %{ 9581 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 9582 // FIXME: avoid andi_ ? 9583 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 9584 %} 9585 ins_pipe(pipe_class_default); 9586 %} 9587 9588 // Immediate And where the immediate is a negative power of 2. 9589 instruct andI_reg_immInegpow2(iRegIdst dst, iRegIsrc src1, immInegpow2 src2) %{ 9590 match(Set dst (AndI src1 src2)); 9591 format %{ "ANDWI $dst, $src1, $src2" %} 9592 size(4); 9593 ins_encode %{ 9594 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9595 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)(julong)(juint)-($src2$$constant))); 9596 %} 9597 ins_pipe(pipe_class_default); 9598 %} 9599 9600 instruct andI_reg_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immIpow2minus1 src2) %{ 9601 match(Set dst (AndI src1 src2)); 9602 format %{ "ANDWI $dst, $src1, $src2" %} 9603 size(4); 9604 ins_encode %{ 9605 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9606 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 9607 %} 9608 ins_pipe(pipe_class_default); 9609 %} 9610 9611 instruct andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src1, immIpowerOf2 src2) %{ 9612 match(Set dst (AndI src1 src2)); 9613 predicate(UseRotateAndMaskInstructionsPPC64); 9614 format %{ "ANDWI $dst, $src1, $src2" %} 9615 size(4); 9616 ins_encode %{ 9617 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9618 __ rlwinm($dst$$Register, $src1$$Register, 0, 9619 (31-log2_long((jlong) $src2$$constant)) & 0x1f, (31-log2_long((jlong) $src2$$constant)) & 0x1f); 9620 %} 9621 ins_pipe(pipe_class_default); 9622 %} 9623 9624 // Register And Long 9625 instruct andL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9626 match(Set dst (AndL src1 src2)); 9627 ins_cost(DEFAULT_COST); 9628 9629 format %{ "AND $dst, $src1, $src2 \t// long" %} 9630 size(4); 9631 ins_encode %{ 9632 // TODO: PPC port $archOpcode(ppc64Opcode_and); 9633 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 9634 %} 9635 ins_pipe(pipe_class_default); 9636 %} 9637 9638 // Immediate And long 9639 instruct andL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2, flagsRegCR0 cr0) %{ 9640 match(Set dst (AndL src1 src2)); 9641 effect(KILL cr0); 9642 9643 format %{ "ANDI $dst, $src1, $src2 \t// long" %} 9644 size(4); 9645 ins_encode %{ 9646 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 9647 // FIXME: avoid andi_ ? 9648 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 9649 %} 9650 ins_pipe(pipe_class_default); 9651 %} 9652 9653 // Immediate And Long where the immediate is a negative power of 2. 9654 instruct andL_reg_immLnegpow2(iRegLdst dst, iRegLsrc src1, immLnegpow2 src2) %{ 9655 match(Set dst (AndL src1 src2)); 9656 format %{ "ANDDI $dst, $src1, $src2" %} 9657 size(4); 9658 ins_encode %{ 9659 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9660 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)-$src2$$constant)); 9661 %} 9662 ins_pipe(pipe_class_default); 9663 %} 9664 9665 instruct andL_reg_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 9666 match(Set dst (AndL src1 src2)); 9667 format %{ "ANDDI $dst, $src1, $src2" %} 9668 size(4); 9669 ins_encode %{ 9670 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9671 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 9672 %} 9673 ins_pipe(pipe_class_default); 9674 %} 9675 9676 // AndL + ConvL2I. 9677 instruct convL2I_andL_reg_immLpow2minus1(iRegIdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 9678 match(Set dst (ConvL2I (AndL src1 src2))); 9679 ins_cost(DEFAULT_COST); 9680 9681 format %{ "ANDDI $dst, $src1, $src2 \t// long + l2i" %} 9682 size(4); 9683 ins_encode %{ 9684 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9685 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 9686 %} 9687 ins_pipe(pipe_class_default); 9688 %} 9689 9690 // Or Instructions 9691 9692 // Register Or 9693 instruct orI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9694 match(Set dst (OrI src1 src2)); 9695 format %{ "OR $dst, $src1, $src2" %} 9696 size(4); 9697 ins_encode %{ 9698 // TODO: PPC port $archOpcode(ppc64Opcode_or); 9699 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 9700 %} 9701 ins_pipe(pipe_class_default); 9702 %} 9703 9704 // Expand does not work with above instruct. (??) 9705 instruct orI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9706 // no match-rule 9707 effect(DEF dst, USE src1, USE src2); 9708 format %{ "OR $dst, $src1, $src2" %} 9709 size(4); 9710 ins_encode %{ 9711 // TODO: PPC port $archOpcode(ppc64Opcode_or); 9712 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 9713 %} 9714 ins_pipe(pipe_class_default); 9715 %} 9716 9717 instruct tree_orI_orI_orI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 9718 match(Set dst (OrI (OrI (OrI src1 src2) src3) src4)); 9719 ins_cost(DEFAULT_COST*3); 9720 9721 expand %{ 9722 // FIXME: we should do this in the ideal world. 9723 iRegIdst tmp1; 9724 iRegIdst tmp2; 9725 orI_reg_reg(tmp1, src1, src2); 9726 orI_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 9727 orI_reg_reg(dst, tmp1, tmp2); 9728 %} 9729 %} 9730 9731 // Immediate Or 9732 instruct orI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 9733 match(Set dst (OrI src1 src2)); 9734 format %{ "ORI $dst, $src1, $src2" %} 9735 size(4); 9736 ins_encode %{ 9737 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 9738 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 9739 %} 9740 ins_pipe(pipe_class_default); 9741 %} 9742 9743 // Register Or Long 9744 instruct orL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9745 match(Set dst (OrL src1 src2)); 9746 ins_cost(DEFAULT_COST); 9747 9748 size(4); 9749 format %{ "OR $dst, $src1, $src2 \t// long" %} 9750 ins_encode %{ 9751 // TODO: PPC port $archOpcode(ppc64Opcode_or); 9752 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 9753 %} 9754 ins_pipe(pipe_class_default); 9755 %} 9756 9757 // OrL + ConvL2I. 9758 instruct orI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9759 match(Set dst (ConvL2I (OrL src1 src2))); 9760 ins_cost(DEFAULT_COST); 9761 9762 format %{ "OR $dst, $src1, $src2 \t// long + l2i" %} 9763 size(4); 9764 ins_encode %{ 9765 // TODO: PPC port $archOpcode(ppc64Opcode_or); 9766 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 9767 %} 9768 ins_pipe(pipe_class_default); 9769 %} 9770 9771 // Immediate Or long 9772 instruct orL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 con) %{ 9773 match(Set dst (OrL src1 con)); 9774 ins_cost(DEFAULT_COST); 9775 9776 format %{ "ORI $dst, $src1, $con \t// long" %} 9777 size(4); 9778 ins_encode %{ 9779 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 9780 __ ori($dst$$Register, $src1$$Register, ($con$$constant) & 0xFFFF); 9781 %} 9782 ins_pipe(pipe_class_default); 9783 %} 9784 9785 // Xor Instructions 9786 9787 // Register Xor 9788 instruct xorI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9789 match(Set dst (XorI src1 src2)); 9790 format %{ "XOR $dst, $src1, $src2" %} 9791 size(4); 9792 ins_encode %{ 9793 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 9794 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 9795 %} 9796 ins_pipe(pipe_class_default); 9797 %} 9798 9799 // Expand does not work with above instruct. (??) 9800 instruct xorI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9801 // no match-rule 9802 effect(DEF dst, USE src1, USE src2); 9803 format %{ "XOR $dst, $src1, $src2" %} 9804 size(4); 9805 ins_encode %{ 9806 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 9807 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 9808 %} 9809 ins_pipe(pipe_class_default); 9810 %} 9811 9812 instruct tree_xorI_xorI_xorI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 9813 match(Set dst (XorI (XorI (XorI src1 src2) src3) src4)); 9814 ins_cost(DEFAULT_COST*3); 9815 9816 expand %{ 9817 // FIXME: we should do this in the ideal world. 9818 iRegIdst tmp1; 9819 iRegIdst tmp2; 9820 xorI_reg_reg(tmp1, src1, src2); 9821 xorI_reg_reg_2(tmp2, src3, src4); // Adlc complains about xorI_reg_reg. 9822 xorI_reg_reg(dst, tmp1, tmp2); 9823 %} 9824 %} 9825 9826 // Immediate Xor 9827 instruct xorI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 9828 match(Set dst (XorI src1 src2)); 9829 format %{ "XORI $dst, $src1, $src2" %} 9830 size(4); 9831 ins_encode %{ 9832 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 9833 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 9834 %} 9835 ins_pipe(pipe_class_default); 9836 %} 9837 9838 // Register Xor Long 9839 instruct xorL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9840 match(Set dst (XorL src1 src2)); 9841 ins_cost(DEFAULT_COST); 9842 9843 format %{ "XOR $dst, $src1, $src2 \t// long" %} 9844 size(4); 9845 ins_encode %{ 9846 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 9847 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 9848 %} 9849 ins_pipe(pipe_class_default); 9850 %} 9851 9852 // XorL + ConvL2I. 9853 instruct xorI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9854 match(Set dst (ConvL2I (XorL src1 src2))); 9855 ins_cost(DEFAULT_COST); 9856 9857 format %{ "XOR $dst, $src1, $src2 \t// long + l2i" %} 9858 size(4); 9859 ins_encode %{ 9860 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 9861 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 9862 %} 9863 ins_pipe(pipe_class_default); 9864 %} 9865 9866 // Immediate Xor Long 9867 instruct xorL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2) %{ 9868 match(Set dst (XorL src1 src2)); 9869 ins_cost(DEFAULT_COST); 9870 9871 format %{ "XORI $dst, $src1, $src2 \t// long" %} 9872 size(4); 9873 ins_encode %{ 9874 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 9875 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 9876 %} 9877 ins_pipe(pipe_class_default); 9878 %} 9879 9880 instruct notI_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 9881 match(Set dst (XorI src1 src2)); 9882 ins_cost(DEFAULT_COST); 9883 9884 format %{ "NOT $dst, $src1 ($src2)" %} 9885 size(4); 9886 ins_encode %{ 9887 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 9888 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 9889 %} 9890 ins_pipe(pipe_class_default); 9891 %} 9892 9893 instruct notL_reg(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 9894 match(Set dst (XorL src1 src2)); 9895 ins_cost(DEFAULT_COST); 9896 9897 format %{ "NOT $dst, $src1 ($src2) \t// long" %} 9898 size(4); 9899 ins_encode %{ 9900 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 9901 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 9902 %} 9903 ins_pipe(pipe_class_default); 9904 %} 9905 9906 // And-complement 9907 instruct andcI_reg_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2, iRegIsrc src3) %{ 9908 match(Set dst (AndI (XorI src1 src2) src3)); 9909 ins_cost(DEFAULT_COST); 9910 9911 format %{ "ANDW $dst, xori($src1, $src2), $src3" %} 9912 size(4); 9913 ins_encode( enc_andc(dst, src3, src1) ); 9914 ins_pipe(pipe_class_default); 9915 %} 9916 9917 // And-complement 9918 instruct andcL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9919 // no match-rule, false predicate 9920 effect(DEF dst, USE src1, USE src2); 9921 predicate(false); 9922 9923 format %{ "ANDC $dst, $src1, $src2" %} 9924 size(4); 9925 ins_encode %{ 9926 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 9927 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 9928 %} 9929 ins_pipe(pipe_class_default); 9930 %} 9931 9932 //----------Moves between int/long and float/double---------------------------- 9933 // 9934 // The following rules move values from int/long registers/stack-locations 9935 // to float/double registers/stack-locations and vice versa, without doing any 9936 // conversions. These rules are used to implement the bit-conversion methods 9937 // of java.lang.Float etc., e.g. 9938 // int floatToIntBits(float value) 9939 // float intBitsToFloat(int bits) 9940 // 9941 // Notes on the implementation on ppc64: 9942 // We only provide rules which move between a register and a stack-location, 9943 // because we always have to go through memory when moving between a float 9944 // register and an integer register. 9945 9946 //---------- Chain stack slots between similar types -------- 9947 9948 // These are needed so that the rules below can match. 9949 9950 // Load integer from stack slot 9951 instruct stkI_to_regI(iRegIdst dst, stackSlotI src) %{ 9952 match(Set dst src); 9953 ins_cost(MEMORY_REF_COST); 9954 9955 format %{ "LWZ $dst, $src" %} 9956 size(4); 9957 ins_encode( enc_lwz(dst, src) ); 9958 ins_pipe(pipe_class_memory); 9959 %} 9960 9961 // Store integer to stack slot 9962 instruct regI_to_stkI(stackSlotI dst, iRegIsrc src) %{ 9963 match(Set dst src); 9964 ins_cost(MEMORY_REF_COST); 9965 9966 format %{ "STW $src, $dst \t// stk" %} 9967 size(4); 9968 ins_encode( enc_stw(src, dst) ); // rs=rt 9969 ins_pipe(pipe_class_memory); 9970 %} 9971 9972 // Load long from stack slot 9973 instruct stkL_to_regL(iRegLdst dst, stackSlotL src) %{ 9974 match(Set dst src); 9975 ins_cost(MEMORY_REF_COST); 9976 9977 format %{ "LD $dst, $src \t// long" %} 9978 size(4); 9979 ins_encode( enc_ld(dst, src) ); 9980 ins_pipe(pipe_class_memory); 9981 %} 9982 9983 // Store long to stack slot 9984 instruct regL_to_stkL(stackSlotL dst, iRegLsrc src) %{ 9985 match(Set dst src); 9986 ins_cost(MEMORY_REF_COST); 9987 9988 format %{ "STD $src, $dst \t// long" %} 9989 size(4); 9990 ins_encode( enc_std(src, dst) ); // rs=rt 9991 ins_pipe(pipe_class_memory); 9992 %} 9993 9994 //----------Moves between int and float 9995 9996 // Move float value from float stack-location to integer register. 9997 instruct moveF2I_stack_reg(iRegIdst dst, stackSlotF src) %{ 9998 match(Set dst (MoveF2I src)); 9999 ins_cost(MEMORY_REF_COST); 10000 10001 format %{ "LWZ $dst, $src \t// MoveF2I" %} 10002 size(4); 10003 ins_encode( enc_lwz(dst, src) ); 10004 ins_pipe(pipe_class_memory); 10005 %} 10006 10007 // Move float value from float register to integer stack-location. 10008 instruct moveF2I_reg_stack(stackSlotI dst, regF src) %{ 10009 match(Set dst (MoveF2I src)); 10010 ins_cost(MEMORY_REF_COST); 10011 10012 format %{ "STFS $src, $dst \t// MoveF2I" %} 10013 size(4); 10014 ins_encode( enc_stfs(src, dst) ); 10015 ins_pipe(pipe_class_memory); 10016 %} 10017 10018 // Move integer value from integer stack-location to float register. 10019 instruct moveI2F_stack_reg(regF dst, stackSlotI src) %{ 10020 match(Set dst (MoveI2F src)); 10021 ins_cost(MEMORY_REF_COST); 10022 10023 format %{ "LFS $dst, $src \t// MoveI2F" %} 10024 size(4); 10025 ins_encode %{ 10026 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 10027 int Idisp = $src$$disp + frame_slots_bias($src$$base, ra_); 10028 __ lfs($dst$$FloatRegister, Idisp, $src$$base$$Register); 10029 %} 10030 ins_pipe(pipe_class_memory); 10031 %} 10032 10033 // Move integer value from integer register to float stack-location. 10034 instruct moveI2F_reg_stack(stackSlotF dst, iRegIsrc src) %{ 10035 match(Set dst (MoveI2F src)); 10036 ins_cost(MEMORY_REF_COST); 10037 10038 format %{ "STW $src, $dst \t// MoveI2F" %} 10039 size(4); 10040 ins_encode( enc_stw(src, dst) ); 10041 ins_pipe(pipe_class_memory); 10042 %} 10043 10044 //----------Moves between long and float 10045 10046 instruct moveF2L_reg_stack(stackSlotL dst, regF src) %{ 10047 // no match-rule, false predicate 10048 effect(DEF dst, USE src); 10049 predicate(false); 10050 10051 format %{ "storeD $src, $dst \t// STACK" %} 10052 size(4); 10053 ins_encode( enc_stfd(src, dst) ); 10054 ins_pipe(pipe_class_default); 10055 %} 10056 10057 //----------Moves between long and double 10058 10059 // Move double value from double stack-location to long register. 10060 instruct moveD2L_stack_reg(iRegLdst dst, stackSlotD src) %{ 10061 match(Set dst (MoveD2L src)); 10062 ins_cost(MEMORY_REF_COST); 10063 size(4); 10064 format %{ "LD $dst, $src \t// MoveD2L" %} 10065 ins_encode( enc_ld(dst, src) ); 10066 ins_pipe(pipe_class_memory); 10067 %} 10068 10069 // Move double value from double register to long stack-location. 10070 instruct moveD2L_reg_stack(stackSlotL dst, regD src) %{ 10071 match(Set dst (MoveD2L src)); 10072 effect(DEF dst, USE src); 10073 ins_cost(MEMORY_REF_COST); 10074 10075 format %{ "STFD $src, $dst \t// MoveD2L" %} 10076 size(4); 10077 ins_encode( enc_stfd(src, dst) ); 10078 ins_pipe(pipe_class_memory); 10079 %} 10080 10081 // Move long value from long stack-location to double register. 10082 instruct moveL2D_stack_reg(regD dst, stackSlotL src) %{ 10083 match(Set dst (MoveL2D src)); 10084 ins_cost(MEMORY_REF_COST); 10085 10086 format %{ "LFD $dst, $src \t// MoveL2D" %} 10087 size(4); 10088 ins_encode( enc_lfd(dst, src) ); 10089 ins_pipe(pipe_class_memory); 10090 %} 10091 10092 // Move long value from long register to double stack-location. 10093 instruct moveL2D_reg_stack(stackSlotD dst, iRegLsrc src) %{ 10094 match(Set dst (MoveL2D src)); 10095 ins_cost(MEMORY_REF_COST); 10096 10097 format %{ "STD $src, $dst \t// MoveL2D" %} 10098 size(4); 10099 ins_encode( enc_std(src, dst) ); 10100 ins_pipe(pipe_class_memory); 10101 %} 10102 10103 //----------Register Move Instructions----------------------------------------- 10104 10105 // Replicate for Superword 10106 10107 instruct moveReg(iRegLdst dst, iRegIsrc src) %{ 10108 predicate(false); 10109 effect(DEF dst, USE src); 10110 10111 format %{ "MR $dst, $src \t// replicate " %} 10112 // variable size, 0 or 4. 10113 ins_encode %{ 10114 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10115 __ mr_if_needed($dst$$Register, $src$$Register); 10116 %} 10117 ins_pipe(pipe_class_default); 10118 %} 10119 10120 //----------Cast instructions (Java-level type cast)--------------------------- 10121 10122 // Cast Long to Pointer for unsafe natives. 10123 instruct castX2P(iRegPdst dst, iRegLsrc src) %{ 10124 match(Set dst (CastX2P src)); 10125 10126 format %{ "MR $dst, $src \t// Long->Ptr" %} 10127 // variable size, 0 or 4. 10128 ins_encode %{ 10129 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10130 __ mr_if_needed($dst$$Register, $src$$Register); 10131 %} 10132 ins_pipe(pipe_class_default); 10133 %} 10134 10135 // Cast Pointer to Long for unsafe natives. 10136 instruct castP2X(iRegLdst dst, iRegP_N2P src) %{ 10137 match(Set dst (CastP2X src)); 10138 10139 format %{ "MR $dst, $src \t// Ptr->Long" %} 10140 // variable size, 0 or 4. 10141 ins_encode %{ 10142 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10143 __ mr_if_needed($dst$$Register, $src$$Register); 10144 %} 10145 ins_pipe(pipe_class_default); 10146 %} 10147 10148 instruct castPP(iRegPdst dst) %{ 10149 match(Set dst (CastPP dst)); 10150 format %{ " -- \t// castPP of $dst" %} 10151 size(0); 10152 ins_encode( /*empty*/ ); 10153 ins_pipe(pipe_class_default); 10154 %} 10155 10156 instruct castII(iRegIdst dst) %{ 10157 match(Set dst (CastII dst)); 10158 format %{ " -- \t// castII of $dst" %} 10159 size(0); 10160 ins_encode( /*empty*/ ); 10161 ins_pipe(pipe_class_default); 10162 %} 10163 10164 instruct checkCastPP(iRegPdst dst) %{ 10165 match(Set dst (CheckCastPP dst)); 10166 format %{ " -- \t// checkcastPP of $dst" %} 10167 size(0); 10168 ins_encode( /*empty*/ ); 10169 ins_pipe(pipe_class_default); 10170 %} 10171 10172 //----------Convert instructions----------------------------------------------- 10173 10174 // Convert to boolean. 10175 10176 // int_to_bool(src) : { 1 if src != 0 10177 // { 0 else 10178 // 10179 // strategy: 10180 // 1) Count leading zeros of 32 bit-value src, 10181 // this returns 32 (0b10.0000) iff src == 0 and <32 otherwise. 10182 // 2) Shift 5 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10183 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10184 10185 // convI2Bool 10186 instruct convI2Bool_reg__cntlz_Ex(iRegIdst dst, iRegIsrc src) %{ 10187 match(Set dst (Conv2B src)); 10188 predicate(UseCountLeadingZerosInstructionsPPC64); 10189 ins_cost(DEFAULT_COST); 10190 10191 expand %{ 10192 immI shiftAmount %{ 0x5 %} 10193 uimmI16 mask %{ 0x1 %} 10194 iRegIdst tmp1; 10195 iRegIdst tmp2; 10196 countLeadingZerosI(tmp1, src); 10197 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10198 xorI_reg_uimm16(dst, tmp2, mask); 10199 %} 10200 %} 10201 10202 instruct convI2Bool_reg__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx) %{ 10203 match(Set dst (Conv2B src)); 10204 effect(TEMP crx); 10205 predicate(!UseCountLeadingZerosInstructionsPPC64); 10206 ins_cost(DEFAULT_COST); 10207 10208 format %{ "CMPWI $crx, $src, #0 \t// convI2B" 10209 "LI $dst, #0\n\t" 10210 "BEQ $crx, done\n\t" 10211 "LI $dst, #1\n" 10212 "done:" %} 10213 size(16); 10214 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x0, 0x1) ); 10215 ins_pipe(pipe_class_compare); 10216 %} 10217 10218 // ConvI2B + XorI 10219 instruct xorI_convI2Bool_reg_immIvalue1__cntlz_Ex(iRegIdst dst, iRegIsrc src, immI_1 mask) %{ 10220 match(Set dst (XorI (Conv2B src) mask)); 10221 predicate(UseCountLeadingZerosInstructionsPPC64); 10222 ins_cost(DEFAULT_COST); 10223 10224 expand %{ 10225 immI shiftAmount %{ 0x5 %} 10226 iRegIdst tmp1; 10227 countLeadingZerosI(tmp1, src); 10228 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10229 %} 10230 %} 10231 10232 instruct xorI_convI2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI_1 mask) %{ 10233 match(Set dst (XorI (Conv2B src) mask)); 10234 effect(TEMP crx); 10235 predicate(!UseCountLeadingZerosInstructionsPPC64); 10236 ins_cost(DEFAULT_COST); 10237 10238 format %{ "CMPWI $crx, $src, #0 \t// Xor(convI2B($src), $mask)" 10239 "LI $dst, #1\n\t" 10240 "BEQ $crx, done\n\t" 10241 "LI $dst, #0\n" 10242 "done:" %} 10243 size(16); 10244 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x1, 0x0) ); 10245 ins_pipe(pipe_class_compare); 10246 %} 10247 10248 // AndI 0b0..010..0 + ConvI2B 10249 instruct convI2Bool_andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src, immIpowerOf2 mask) %{ 10250 match(Set dst (Conv2B (AndI src mask))); 10251 predicate(UseRotateAndMaskInstructionsPPC64); 10252 ins_cost(DEFAULT_COST); 10253 10254 format %{ "RLWINM $dst, $src, $mask \t// convI2B(AndI($src, $mask))" %} 10255 size(4); 10256 ins_encode %{ 10257 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 10258 __ rlwinm($dst$$Register, $src$$Register, (32-log2_long((jlong)$mask$$constant)) & 0x1f, 31, 31); 10259 %} 10260 ins_pipe(pipe_class_default); 10261 %} 10262 10263 // Convert pointer to boolean. 10264 // 10265 // ptr_to_bool(src) : { 1 if src != 0 10266 // { 0 else 10267 // 10268 // strategy: 10269 // 1) Count leading zeros of 64 bit-value src, 10270 // this returns 64 (0b100.0000) iff src == 0 and <64 otherwise. 10271 // 2) Shift 6 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10272 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10273 10274 // ConvP2B 10275 instruct convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src) %{ 10276 match(Set dst (Conv2B src)); 10277 predicate(UseCountLeadingZerosInstructionsPPC64); 10278 ins_cost(DEFAULT_COST); 10279 10280 expand %{ 10281 immI shiftAmount %{ 0x6 %} 10282 uimmI16 mask %{ 0x1 %} 10283 iRegIdst tmp1; 10284 iRegIdst tmp2; 10285 countLeadingZerosP(tmp1, src); 10286 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10287 xorI_reg_uimm16(dst, tmp2, mask); 10288 %} 10289 %} 10290 10291 instruct convP2Bool_reg__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx) %{ 10292 match(Set dst (Conv2B src)); 10293 effect(TEMP crx); 10294 predicate(!UseCountLeadingZerosInstructionsPPC64); 10295 ins_cost(DEFAULT_COST); 10296 10297 format %{ "CMPDI $crx, $src, #0 \t// convP2B" 10298 "LI $dst, #0\n\t" 10299 "BEQ $crx, done\n\t" 10300 "LI $dst, #1\n" 10301 "done:" %} 10302 size(16); 10303 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x0, 0x1) ); 10304 ins_pipe(pipe_class_compare); 10305 %} 10306 10307 // ConvP2B + XorI 10308 instruct xorI_convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src, immI_1 mask) %{ 10309 match(Set dst (XorI (Conv2B src) mask)); 10310 predicate(UseCountLeadingZerosInstructionsPPC64); 10311 ins_cost(DEFAULT_COST); 10312 10313 expand %{ 10314 immI shiftAmount %{ 0x6 %} 10315 iRegIdst tmp1; 10316 countLeadingZerosP(tmp1, src); 10317 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10318 %} 10319 %} 10320 10321 instruct xorI_convP2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx, immI_1 mask) %{ 10322 match(Set dst (XorI (Conv2B src) mask)); 10323 effect(TEMP crx); 10324 predicate(!UseCountLeadingZerosInstructionsPPC64); 10325 ins_cost(DEFAULT_COST); 10326 10327 format %{ "CMPDI $crx, $src, #0 \t// XorI(convP2B($src), $mask)" 10328 "LI $dst, #1\n\t" 10329 "BEQ $crx, done\n\t" 10330 "LI $dst, #0\n" 10331 "done:" %} 10332 size(16); 10333 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x1, 0x0) ); 10334 ins_pipe(pipe_class_compare); 10335 %} 10336 10337 // if src1 < src2, return -1 else return 0 10338 instruct cmpLTMask_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10339 match(Set dst (CmpLTMask src1 src2)); 10340 ins_cost(DEFAULT_COST*4); 10341 10342 expand %{ 10343 iRegLdst src1s; 10344 iRegLdst src2s; 10345 iRegLdst diff; 10346 convI2L_reg(src1s, src1); // Ensure proper sign extension. 10347 convI2L_reg(src2s, src2); // Ensure proper sign extension. 10348 subL_reg_reg(diff, src1s, src2s); 10349 // Need to consider >=33 bit result, therefore we need signmaskL. 10350 signmask64I_regL(dst, diff); 10351 %} 10352 %} 10353 10354 instruct cmpLTMask_reg_immI0(iRegIdst dst, iRegIsrc src1, immI_0 src2) %{ 10355 match(Set dst (CmpLTMask src1 src2)); // if src1 < src2, return -1 else return 0 10356 format %{ "SRAWI $dst, $src1, $src2 \t// CmpLTMask" %} 10357 size(4); 10358 ins_encode %{ 10359 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 10360 __ srawi($dst$$Register, $src1$$Register, 0x1f); 10361 %} 10362 ins_pipe(pipe_class_default); 10363 %} 10364 10365 //----------Arithmetic Conversion Instructions--------------------------------- 10366 10367 // Convert to Byte -- nop 10368 // Convert to Short -- nop 10369 10370 // Convert to Int 10371 10372 instruct convB2I_reg(iRegIdst dst, iRegIsrc src, immI_24 amount) %{ 10373 match(Set dst (RShiftI (LShiftI src amount) amount)); 10374 format %{ "EXTSB $dst, $src \t// byte->int" %} 10375 size(4); 10376 ins_encode %{ 10377 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 10378 __ extsb($dst$$Register, $src$$Register); 10379 %} 10380 ins_pipe(pipe_class_default); 10381 %} 10382 10383 // LShiftI 16 + RShiftI 16 converts short to int. 10384 instruct convS2I_reg(iRegIdst dst, iRegIsrc src, immI_16 amount) %{ 10385 match(Set dst (RShiftI (LShiftI src amount) amount)); 10386 format %{ "EXTSH $dst, $src \t// short->int" %} 10387 size(4); 10388 ins_encode %{ 10389 // TODO: PPC port $archOpcode(ppc64Opcode_extsh); 10390 __ extsh($dst$$Register, $src$$Register); 10391 %} 10392 ins_pipe(pipe_class_default); 10393 %} 10394 10395 // ConvL2I + ConvI2L: Sign extend int in long register. 10396 instruct sxtI_L2L_reg(iRegLdst dst, iRegLsrc src) %{ 10397 match(Set dst (ConvI2L (ConvL2I src))); 10398 10399 format %{ "EXTSW $dst, $src \t// long->long" %} 10400 size(4); 10401 ins_encode %{ 10402 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 10403 __ extsw($dst$$Register, $src$$Register); 10404 %} 10405 ins_pipe(pipe_class_default); 10406 %} 10407 10408 instruct convL2I_reg(iRegIdst dst, iRegLsrc src) %{ 10409 match(Set dst (ConvL2I src)); 10410 format %{ "MR $dst, $src \t// long->int" %} 10411 // variable size, 0 or 4 10412 ins_encode %{ 10413 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10414 __ mr_if_needed($dst$$Register, $src$$Register); 10415 %} 10416 ins_pipe(pipe_class_default); 10417 %} 10418 10419 instruct convD2IRaw_regD(regD dst, regD src) %{ 10420 // no match-rule, false predicate 10421 effect(DEF dst, USE src); 10422 predicate(false); 10423 10424 format %{ "FCTIWZ $dst, $src \t// convD2I, $src != NaN" %} 10425 size(4); 10426 ins_encode %{ 10427 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz);; 10428 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 10429 %} 10430 ins_pipe(pipe_class_default); 10431 %} 10432 10433 instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL src) %{ 10434 // no match-rule, false predicate 10435 effect(DEF dst, USE crx, USE src); 10436 predicate(false); 10437 10438 ins_variable_size_depending_on_alignment(true); 10439 10440 format %{ "cmovI $crx, $dst, $src" %} 10441 // Worst case is branch + move + stop, no stop without scheduler. 10442 size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 10443 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 10444 ins_pipe(pipe_class_default); 10445 %} 10446 10447 instruct cmovI_bso_stackSlotL_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, stackSlotL mem) %{ 10448 // no match-rule, false predicate 10449 effect(DEF dst, USE crx, USE mem); 10450 predicate(false); 10451 10452 format %{ "CmovI $dst, $crx, $mem \t// postalloc expanded" %} 10453 postalloc_expand %{ 10454 // 10455 // replaces 10456 // 10457 // region dst crx mem 10458 // \ | | / 10459 // dst=cmovI_bso_stackSlotL_conLvalue0 10460 // 10461 // with 10462 // 10463 // region dst 10464 // \ / 10465 // dst=loadConI16(0) 10466 // | 10467 // ^ region dst crx mem 10468 // | \ | | / 10469 // dst=cmovI_bso_stackSlotL 10470 // 10471 10472 // Create new nodes. 10473 MachNode *m1 = new loadConI16Node(); 10474 MachNode *m2 = new cmovI_bso_stackSlotLNode(); 10475 10476 // inputs for new nodes 10477 m1->add_req(n_region); 10478 m2->add_req(n_region, n_crx, n_mem); 10479 10480 // precedences for new nodes 10481 m2->add_prec(m1); 10482 10483 // operands for new nodes 10484 m1->_opnds[0] = op_dst; 10485 m1->_opnds[1] = new immI16Oper(0); 10486 10487 m2->_opnds[0] = op_dst; 10488 m2->_opnds[1] = op_crx; 10489 m2->_opnds[2] = op_mem; 10490 10491 // registers for new nodes 10492 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10493 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10494 10495 // Insert new nodes. 10496 nodes->push(m1); 10497 nodes->push(m2); 10498 %} 10499 %} 10500 10501 // Double to Int conversion, NaN is mapped to 0. 10502 instruct convD2I_reg_ExEx(iRegIdst dst, regD src) %{ 10503 match(Set dst (ConvD2I src)); 10504 ins_cost(DEFAULT_COST); 10505 10506 expand %{ 10507 regD tmpD; 10508 stackSlotL tmpS; 10509 flagsReg crx; 10510 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10511 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 10512 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 10513 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 10514 %} 10515 %} 10516 10517 instruct convF2IRaw_regF(regF dst, regF src) %{ 10518 // no match-rule, false predicate 10519 effect(DEF dst, USE src); 10520 predicate(false); 10521 10522 format %{ "FCTIWZ $dst, $src \t// convF2I, $src != NaN" %} 10523 size(4); 10524 ins_encode %{ 10525 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 10526 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 10527 %} 10528 ins_pipe(pipe_class_default); 10529 %} 10530 10531 // Float to Int conversion, NaN is mapped to 0. 10532 instruct convF2I_regF_ExEx(iRegIdst dst, regF src) %{ 10533 match(Set dst (ConvF2I src)); 10534 ins_cost(DEFAULT_COST); 10535 10536 expand %{ 10537 regF tmpF; 10538 stackSlotL tmpS; 10539 flagsReg crx; 10540 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10541 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 10542 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 10543 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 10544 %} 10545 %} 10546 10547 // Convert to Long 10548 10549 instruct convI2L_reg(iRegLdst dst, iRegIsrc src) %{ 10550 match(Set dst (ConvI2L src)); 10551 format %{ "EXTSW $dst, $src \t// int->long" %} 10552 size(4); 10553 ins_encode %{ 10554 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 10555 __ extsw($dst$$Register, $src$$Register); 10556 %} 10557 ins_pipe(pipe_class_default); 10558 %} 10559 10560 // Zero-extend: convert unsigned int to long (convUI2L). 10561 instruct zeroExtendL_regI(iRegLdst dst, iRegIsrc src, immL_32bits mask) %{ 10562 match(Set dst (AndL (ConvI2L src) mask)); 10563 ins_cost(DEFAULT_COST); 10564 10565 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 10566 size(4); 10567 ins_encode %{ 10568 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10569 __ clrldi($dst$$Register, $src$$Register, 32); 10570 %} 10571 ins_pipe(pipe_class_default); 10572 %} 10573 10574 // Zero-extend: convert unsigned int to long in long register. 10575 instruct zeroExtendL_regL(iRegLdst dst, iRegLsrc src, immL_32bits mask) %{ 10576 match(Set dst (AndL src mask)); 10577 ins_cost(DEFAULT_COST); 10578 10579 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 10580 size(4); 10581 ins_encode %{ 10582 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10583 __ clrldi($dst$$Register, $src$$Register, 32); 10584 %} 10585 ins_pipe(pipe_class_default); 10586 %} 10587 10588 instruct convF2LRaw_regF(regF dst, regF src) %{ 10589 // no match-rule, false predicate 10590 effect(DEF dst, USE src); 10591 predicate(false); 10592 10593 format %{ "FCTIDZ $dst, $src \t// convF2L, $src != NaN" %} 10594 size(4); 10595 ins_encode %{ 10596 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 10597 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 10598 %} 10599 ins_pipe(pipe_class_default); 10600 %} 10601 10602 instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL src) %{ 10603 // no match-rule, false predicate 10604 effect(DEF dst, USE crx, USE src); 10605 predicate(false); 10606 10607 ins_variable_size_depending_on_alignment(true); 10608 10609 format %{ "cmovL $crx, $dst, $src" %} 10610 // Worst case is branch + move + stop, no stop without scheduler. 10611 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 10612 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 10613 ins_pipe(pipe_class_default); 10614 %} 10615 10616 instruct cmovL_bso_stackSlotL_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, stackSlotL mem) %{ 10617 // no match-rule, false predicate 10618 effect(DEF dst, USE crx, USE mem); 10619 predicate(false); 10620 10621 format %{ "CmovL $dst, $crx, $mem \t// postalloc expanded" %} 10622 postalloc_expand %{ 10623 // 10624 // replaces 10625 // 10626 // region dst crx mem 10627 // \ | | / 10628 // dst=cmovL_bso_stackSlotL_conLvalue0 10629 // 10630 // with 10631 // 10632 // region dst 10633 // \ / 10634 // dst=loadConL16(0) 10635 // | 10636 // ^ region dst crx mem 10637 // | \ | | / 10638 // dst=cmovL_bso_stackSlotL 10639 // 10640 10641 // Create new nodes. 10642 MachNode *m1 = new loadConL16Node(); 10643 MachNode *m2 = new cmovL_bso_stackSlotLNode(); 10644 10645 // inputs for new nodes 10646 m1->add_req(n_region); 10647 m2->add_req(n_region, n_crx, n_mem); 10648 m2->add_prec(m1); 10649 10650 // operands for new nodes 10651 m1->_opnds[0] = op_dst; 10652 m1->_opnds[1] = new immL16Oper(0); 10653 m2->_opnds[0] = op_dst; 10654 m2->_opnds[1] = op_crx; 10655 m2->_opnds[2] = op_mem; 10656 10657 // registers for new nodes 10658 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10659 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10660 10661 // Insert new nodes. 10662 nodes->push(m1); 10663 nodes->push(m2); 10664 %} 10665 %} 10666 10667 // Float to Long conversion, NaN is mapped to 0. 10668 instruct convF2L_reg_ExEx(iRegLdst dst, regF src) %{ 10669 match(Set dst (ConvF2L src)); 10670 ins_cost(DEFAULT_COST); 10671 10672 expand %{ 10673 regF tmpF; 10674 stackSlotL tmpS; 10675 flagsReg crx; 10676 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10677 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 10678 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 10679 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 10680 %} 10681 %} 10682 10683 instruct convD2LRaw_regD(regD dst, regD src) %{ 10684 // no match-rule, false predicate 10685 effect(DEF dst, USE src); 10686 predicate(false); 10687 10688 format %{ "FCTIDZ $dst, $src \t// convD2L $src != NaN" %} 10689 size(4); 10690 ins_encode %{ 10691 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 10692 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 10693 %} 10694 ins_pipe(pipe_class_default); 10695 %} 10696 10697 // Double to Long conversion, NaN is mapped to 0. 10698 instruct convD2L_reg_ExEx(iRegLdst dst, regD src) %{ 10699 match(Set dst (ConvD2L src)); 10700 ins_cost(DEFAULT_COST); 10701 10702 expand %{ 10703 regD tmpD; 10704 stackSlotL tmpS; 10705 flagsReg crx; 10706 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10707 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 10708 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 10709 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 10710 %} 10711 %} 10712 10713 // Convert to Float 10714 10715 // Placed here as needed in expand. 10716 instruct convL2DRaw_regD(regD dst, regD src) %{ 10717 // no match-rule, false predicate 10718 effect(DEF dst, USE src); 10719 predicate(false); 10720 10721 format %{ "FCFID $dst, $src \t// convL2D" %} 10722 size(4); 10723 ins_encode %{ 10724 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 10725 __ fcfid($dst$$FloatRegister, $src$$FloatRegister); 10726 %} 10727 ins_pipe(pipe_class_default); 10728 %} 10729 10730 // Placed here as needed in expand. 10731 instruct convD2F_reg(regF dst, regD src) %{ 10732 match(Set dst (ConvD2F src)); 10733 format %{ "FRSP $dst, $src \t// convD2F" %} 10734 size(4); 10735 ins_encode %{ 10736 // TODO: PPC port $archOpcode(ppc64Opcode_frsp); 10737 __ frsp($dst$$FloatRegister, $src$$FloatRegister); 10738 %} 10739 ins_pipe(pipe_class_default); 10740 %} 10741 10742 // Integer to Float conversion. 10743 instruct convI2F_ireg_Ex(regF dst, iRegIsrc src) %{ 10744 match(Set dst (ConvI2F src)); 10745 predicate(!VM_Version::has_fcfids()); 10746 ins_cost(DEFAULT_COST); 10747 10748 expand %{ 10749 iRegLdst tmpL; 10750 stackSlotL tmpS; 10751 regD tmpD; 10752 regD tmpD2; 10753 convI2L_reg(tmpL, src); // Sign-extension int to long. 10754 regL_to_stkL(tmpS, tmpL); // Store long to stack. 10755 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 10756 convL2DRaw_regD(tmpD2, tmpD); // Convert to double. 10757 convD2F_reg(dst, tmpD2); // Convert double to float. 10758 %} 10759 %} 10760 10761 instruct convL2FRaw_regF(regF dst, regD src) %{ 10762 // no match-rule, false predicate 10763 effect(DEF dst, USE src); 10764 predicate(false); 10765 10766 format %{ "FCFIDS $dst, $src \t// convL2F" %} 10767 size(4); 10768 ins_encode %{ 10769 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 10770 __ fcfids($dst$$FloatRegister, $src$$FloatRegister); 10771 %} 10772 ins_pipe(pipe_class_default); 10773 %} 10774 10775 // Integer to Float conversion. Special version for Power7. 10776 instruct convI2F_ireg_fcfids_Ex(regF dst, iRegIsrc src) %{ 10777 match(Set dst (ConvI2F src)); 10778 predicate(VM_Version::has_fcfids()); 10779 ins_cost(DEFAULT_COST); 10780 10781 expand %{ 10782 iRegLdst tmpL; 10783 stackSlotL tmpS; 10784 regD tmpD; 10785 convI2L_reg(tmpL, src); // Sign-extension int to long. 10786 regL_to_stkL(tmpS, tmpL); // Store long to stack. 10787 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 10788 convL2FRaw_regF(dst, tmpD); // Convert to float. 10789 %} 10790 %} 10791 10792 // L2F to avoid runtime call. 10793 instruct convL2F_ireg_fcfids_Ex(regF dst, iRegLsrc src) %{ 10794 match(Set dst (ConvL2F src)); 10795 predicate(VM_Version::has_fcfids()); 10796 ins_cost(DEFAULT_COST); 10797 10798 expand %{ 10799 stackSlotL tmpS; 10800 regD tmpD; 10801 regL_to_stkL(tmpS, src); // Store long to stack. 10802 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 10803 convL2FRaw_regF(dst, tmpD); // Convert to float. 10804 %} 10805 %} 10806 10807 // Moved up as used in expand. 10808 //instruct convD2F_reg(regF dst, regD src) %{%} 10809 10810 // Convert to Double 10811 10812 // Integer to Double conversion. 10813 instruct convI2D_reg_Ex(regD dst, iRegIsrc src) %{ 10814 match(Set dst (ConvI2D src)); 10815 ins_cost(DEFAULT_COST); 10816 10817 expand %{ 10818 iRegLdst tmpL; 10819 stackSlotL tmpS; 10820 regD tmpD; 10821 convI2L_reg(tmpL, src); // Sign-extension int to long. 10822 regL_to_stkL(tmpS, tmpL); // Store long to stack. 10823 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 10824 convL2DRaw_regD(dst, tmpD); // Convert to double. 10825 %} 10826 %} 10827 10828 // Long to Double conversion 10829 instruct convL2D_reg_Ex(regD dst, stackSlotL src) %{ 10830 match(Set dst (ConvL2D src)); 10831 ins_cost(DEFAULT_COST + MEMORY_REF_COST); 10832 10833 expand %{ 10834 regD tmpD; 10835 moveL2D_stack_reg(tmpD, src); 10836 convL2DRaw_regD(dst, tmpD); 10837 %} 10838 %} 10839 10840 instruct convF2D_reg(regD dst, regF src) %{ 10841 match(Set dst (ConvF2D src)); 10842 format %{ "FMR $dst, $src \t// float->double" %} 10843 // variable size, 0 or 4 10844 ins_encode %{ 10845 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 10846 __ fmr_if_needed($dst$$FloatRegister, $src$$FloatRegister); 10847 %} 10848 ins_pipe(pipe_class_default); 10849 %} 10850 10851 //----------Control Flow Instructions------------------------------------------ 10852 // Compare Instructions 10853 10854 // Compare Integers 10855 instruct cmpI_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 10856 match(Set crx (CmpI src1 src2)); 10857 size(4); 10858 format %{ "CMPW $crx, $src1, $src2" %} 10859 ins_encode %{ 10860 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 10861 __ cmpw($crx$$CondRegister, $src1$$Register, $src2$$Register); 10862 %} 10863 ins_pipe(pipe_class_compare); 10864 %} 10865 10866 instruct cmpI_reg_imm16(flagsReg crx, iRegIsrc src1, immI16 src2) %{ 10867 match(Set crx (CmpI src1 src2)); 10868 format %{ "CMPWI $crx, $src1, $src2" %} 10869 size(4); 10870 ins_encode %{ 10871 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 10872 __ cmpwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 10873 %} 10874 ins_pipe(pipe_class_compare); 10875 %} 10876 10877 // (src1 & src2) == 0? 10878 instruct testI_reg_imm(flagsRegCR0 cr0, iRegIsrc src1, uimmI16 src2, immI_0 zero) %{ 10879 match(Set cr0 (CmpI (AndI src1 src2) zero)); 10880 // r0 is killed 10881 format %{ "ANDI R0, $src1, $src2 \t// BTST int" %} 10882 size(4); 10883 ins_encode %{ 10884 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 10885 __ andi_(R0, $src1$$Register, $src2$$constant); 10886 %} 10887 ins_pipe(pipe_class_compare); 10888 %} 10889 10890 instruct cmpL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 10891 match(Set crx (CmpL src1 src2)); 10892 format %{ "CMPD $crx, $src1, $src2" %} 10893 size(4); 10894 ins_encode %{ 10895 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 10896 __ cmpd($crx$$CondRegister, $src1$$Register, $src2$$Register); 10897 %} 10898 ins_pipe(pipe_class_compare); 10899 %} 10900 10901 instruct cmpL_reg_imm16(flagsReg crx, iRegLsrc src1, immL16 src2) %{ 10902 match(Set crx (CmpL src1 src2)); 10903 format %{ "CMPDI $crx, $src1, $src2" %} 10904 size(4); 10905 ins_encode %{ 10906 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 10907 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 10908 %} 10909 ins_pipe(pipe_class_compare); 10910 %} 10911 10912 instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zero) %{ 10913 match(Set cr0 (CmpL (AndL src1 src2) zero)); 10914 // r0 is killed 10915 format %{ "AND R0, $src1, $src2 \t// BTST long" %} 10916 size(4); 10917 ins_encode %{ 10918 // TODO: PPC port $archOpcode(ppc64Opcode_and_); 10919 __ and_(R0, $src1$$Register, $src2$$Register); 10920 %} 10921 ins_pipe(pipe_class_compare); 10922 %} 10923 10924 instruct testL_reg_imm(flagsRegCR0 cr0, iRegLsrc src1, uimmL16 src2, immL_0 zero) %{ 10925 match(Set cr0 (CmpL (AndL src1 src2) zero)); 10926 // r0 is killed 10927 format %{ "ANDI R0, $src1, $src2 \t// BTST long" %} 10928 size(4); 10929 ins_encode %{ 10930 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 10931 __ andi_(R0, $src1$$Register, $src2$$constant); 10932 %} 10933 ins_pipe(pipe_class_compare); 10934 %} 10935 10936 instruct cmovI_conIvalueMinus1_conIvalue1(iRegIdst dst, flagsRegSrc crx) %{ 10937 // no match-rule, false predicate 10938 effect(DEF dst, USE crx); 10939 predicate(false); 10940 10941 ins_variable_size_depending_on_alignment(true); 10942 10943 format %{ "cmovI $crx, $dst, -1, 0, +1" %} 10944 // Worst case is branch + move + branch + move + stop, no stop without scheduler. 10945 size(false /* TODO: PPC PORTInsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 20 : 16); 10946 ins_encode %{ 10947 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 10948 Label done; 10949 // li(Rdst, 0); // equal -> 0 10950 __ beq($crx$$CondRegister, done); 10951 __ li($dst$$Register, 1); // greater -> +1 10952 __ bgt($crx$$CondRegister, done); 10953 __ li($dst$$Register, -1); // unordered or less -> -1 10954 // TODO: PPC port__ endgroup_if_needed(_size == 20); 10955 __ bind(done); 10956 %} 10957 ins_pipe(pipe_class_compare); 10958 %} 10959 10960 instruct cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(iRegIdst dst, flagsRegSrc crx) %{ 10961 // no match-rule, false predicate 10962 effect(DEF dst, USE crx); 10963 predicate(false); 10964 10965 format %{ "CmovI $crx, $dst, -1, 0, +1 \t// postalloc expanded" %} 10966 postalloc_expand %{ 10967 // 10968 // replaces 10969 // 10970 // region crx 10971 // \ | 10972 // dst=cmovI_conIvalueMinus1_conIvalue0_conIvalue1 10973 // 10974 // with 10975 // 10976 // region 10977 // \ 10978 // dst=loadConI16(0) 10979 // | 10980 // ^ region crx 10981 // | \ | 10982 // dst=cmovI_conIvalueMinus1_conIvalue1 10983 // 10984 10985 // Create new nodes. 10986 MachNode *m1 = new loadConI16Node(); 10987 MachNode *m2 = new cmovI_conIvalueMinus1_conIvalue1Node(); 10988 10989 // inputs for new nodes 10990 m1->add_req(n_region); 10991 m2->add_req(n_region, n_crx); 10992 m2->add_prec(m1); 10993 10994 // operands for new nodes 10995 m1->_opnds[0] = op_dst; 10996 m1->_opnds[1] = new immI16Oper(0); 10997 m2->_opnds[0] = op_dst; 10998 m2->_opnds[1] = op_crx; 10999 11000 // registers for new nodes 11001 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11002 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11003 11004 // Insert new nodes. 11005 nodes->push(m1); 11006 nodes->push(m2); 11007 %} 11008 %} 11009 11010 // Manifest a CmpL3 result in an integer register. Very painful. 11011 // This is the test to avoid. 11012 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 11013 instruct cmpL3_reg_reg_ExEx(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 11014 match(Set dst (CmpL3 src1 src2)); 11015 ins_cost(DEFAULT_COST*5+BRANCH_COST); 11016 11017 expand %{ 11018 flagsReg tmp1; 11019 cmpL_reg_reg(tmp1, src1, src2); 11020 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 11021 %} 11022 %} 11023 11024 // Implicit range checks. 11025 // A range check in the ideal world has one of the following shapes: 11026 // - (If le (CmpU length index)), (IfTrue throw exception) 11027 // - (If lt (CmpU index length)), (IfFalse throw exception) 11028 // 11029 // Match range check 'If le (CmpU length index)'. 11030 instruct rangeCheck_iReg_uimm15(cmpOp cmp, iRegIsrc src_length, uimmI15 index, label labl) %{ 11031 match(If cmp (CmpU src_length index)); 11032 effect(USE labl); 11033 predicate(TrapBasedRangeChecks && 11034 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le && 11035 PROB_UNLIKELY(_leaf->as_If()->_prob) >= PROB_ALWAYS && 11036 (Matcher::branches_to_uncommon_trap(_leaf))); 11037 11038 ins_is_TrapBasedCheckNode(true); 11039 11040 format %{ "TWI $index $cmp $src_length \t// RangeCheck => trap $labl" %} 11041 size(4); 11042 ins_encode %{ 11043 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 11044 if ($cmp$$cmpcode == 0x1 /* less_equal */) { 11045 __ trap_range_check_le($src_length$$Register, $index$$constant); 11046 } else { 11047 // Both successors are uncommon traps, probability is 0. 11048 // Node got flipped during fixup flow. 11049 assert($cmp$$cmpcode == 0x9, "must be greater"); 11050 __ trap_range_check_g($src_length$$Register, $index$$constant); 11051 } 11052 %} 11053 ins_pipe(pipe_class_trap); 11054 %} 11055 11056 // Match range check 'If lt (CmpU index length)'. 11057 instruct rangeCheck_iReg_iReg(cmpOp cmp, iRegIsrc src_index, iRegIsrc src_length, label labl) %{ 11058 match(If cmp (CmpU src_index src_length)); 11059 effect(USE labl); 11060 predicate(TrapBasedRangeChecks && 11061 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 11062 _leaf->as_If()->_prob >= PROB_ALWAYS && 11063 (Matcher::branches_to_uncommon_trap(_leaf))); 11064 11065 ins_is_TrapBasedCheckNode(true); 11066 11067 format %{ "TW $src_index $cmp $src_length \t// RangeCheck => trap $labl" %} 11068 size(4); 11069 ins_encode %{ 11070 // TODO: PPC port $archOpcode(ppc64Opcode_tw); 11071 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 11072 __ trap_range_check_ge($src_index$$Register, $src_length$$Register); 11073 } else { 11074 // Both successors are uncommon traps, probability is 0. 11075 // Node got flipped during fixup flow. 11076 assert($cmp$$cmpcode == 0x8, "must be less"); 11077 __ trap_range_check_l($src_index$$Register, $src_length$$Register); 11078 } 11079 %} 11080 ins_pipe(pipe_class_trap); 11081 %} 11082 11083 // Match range check 'If lt (CmpU index length)'. 11084 instruct rangeCheck_uimm15_iReg(cmpOp cmp, iRegIsrc src_index, uimmI15 length, label labl) %{ 11085 match(If cmp (CmpU src_index length)); 11086 effect(USE labl); 11087 predicate(TrapBasedRangeChecks && 11088 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 11089 _leaf->as_If()->_prob >= PROB_ALWAYS && 11090 (Matcher::branches_to_uncommon_trap(_leaf))); 11091 11092 ins_is_TrapBasedCheckNode(true); 11093 11094 format %{ "TWI $src_index $cmp $length \t// RangeCheck => trap $labl" %} 11095 size(4); 11096 ins_encode %{ 11097 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 11098 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 11099 __ trap_range_check_ge($src_index$$Register, $length$$constant); 11100 } else { 11101 // Both successors are uncommon traps, probability is 0. 11102 // Node got flipped during fixup flow. 11103 assert($cmp$$cmpcode == 0x8, "must be less"); 11104 __ trap_range_check_l($src_index$$Register, $length$$constant); 11105 } 11106 %} 11107 ins_pipe(pipe_class_trap); 11108 %} 11109 11110 instruct compU_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 11111 match(Set crx (CmpU src1 src2)); 11112 format %{ "CMPLW $crx, $src1, $src2 \t// unsigned" %} 11113 size(4); 11114 ins_encode %{ 11115 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11116 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11117 %} 11118 ins_pipe(pipe_class_compare); 11119 %} 11120 11121 instruct compU_reg_uimm16(flagsReg crx, iRegIsrc src1, uimmI16 src2) %{ 11122 match(Set crx (CmpU src1 src2)); 11123 size(4); 11124 format %{ "CMPLWI $crx, $src1, $src2" %} 11125 ins_encode %{ 11126 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 11127 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11128 %} 11129 ins_pipe(pipe_class_compare); 11130 %} 11131 11132 // Implicit zero checks (more implicit null checks). 11133 // No constant pool entries required. 11134 instruct zeroCheckN_iReg_imm0(cmpOp cmp, iRegNsrc value, immN_0 zero, label labl) %{ 11135 match(If cmp (CmpN value zero)); 11136 effect(USE labl); 11137 predicate(TrapBasedNullChecks && 11138 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 11139 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 11140 Matcher::branches_to_uncommon_trap(_leaf)); 11141 ins_cost(1); 11142 11143 ins_is_TrapBasedCheckNode(true); 11144 11145 format %{ "TDI $value $cmp $zero \t// ZeroCheckN => trap $labl" %} 11146 size(4); 11147 ins_encode %{ 11148 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 11149 if ($cmp$$cmpcode == 0xA) { 11150 __ trap_null_check($value$$Register); 11151 } else { 11152 // Both successors are uncommon traps, probability is 0. 11153 // Node got flipped during fixup flow. 11154 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 11155 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 11156 } 11157 %} 11158 ins_pipe(pipe_class_trap); 11159 %} 11160 11161 // Compare narrow oops. 11162 instruct cmpN_reg_reg(flagsReg crx, iRegNsrc src1, iRegNsrc src2) %{ 11163 match(Set crx (CmpN src1 src2)); 11164 11165 size(4); 11166 ins_cost(2); 11167 format %{ "CMPLW $crx, $src1, $src2 \t// compressed ptr" %} 11168 ins_encode %{ 11169 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11170 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11171 %} 11172 ins_pipe(pipe_class_compare); 11173 %} 11174 11175 instruct cmpN_reg_imm0(flagsReg crx, iRegNsrc src1, immN_0 src2) %{ 11176 match(Set crx (CmpN src1 src2)); 11177 // Make this more expensive than zeroCheckN_iReg_imm0. 11178 ins_cost(2); 11179 11180 format %{ "CMPLWI $crx, $src1, $src2 \t// compressed ptr" %} 11181 size(4); 11182 ins_encode %{ 11183 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 11184 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11185 %} 11186 ins_pipe(pipe_class_compare); 11187 %} 11188 11189 // Implicit zero checks (more implicit null checks). 11190 // No constant pool entries required. 11191 instruct zeroCheckP_reg_imm0(cmpOp cmp, iRegP_N2P value, immP_0 zero, label labl) %{ 11192 match(If cmp (CmpP value zero)); 11193 effect(USE labl); 11194 predicate(TrapBasedNullChecks && 11195 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 11196 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 11197 Matcher::branches_to_uncommon_trap(_leaf)); 11198 ins_cost(1); // Should not be cheaper than zeroCheckN. 11199 11200 ins_is_TrapBasedCheckNode(true); 11201 11202 format %{ "TDI $value $cmp $zero \t// ZeroCheckP => trap $labl" %} 11203 size(4); 11204 ins_encode %{ 11205 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 11206 if ($cmp$$cmpcode == 0xA) { 11207 __ trap_null_check($value$$Register); 11208 } else { 11209 // Both successors are uncommon traps, probability is 0. 11210 // Node got flipped during fixup flow. 11211 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 11212 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 11213 } 11214 %} 11215 ins_pipe(pipe_class_trap); 11216 %} 11217 11218 // Compare Pointers 11219 instruct cmpP_reg_reg(flagsReg crx, iRegP_N2P src1, iRegP_N2P src2) %{ 11220 match(Set crx (CmpP src1 src2)); 11221 format %{ "CMPLD $crx, $src1, $src2 \t// ptr" %} 11222 size(4); 11223 ins_encode %{ 11224 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11225 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 11226 %} 11227 ins_pipe(pipe_class_compare); 11228 %} 11229 11230 // Used in postalloc expand. 11231 instruct cmpP_reg_imm16(flagsReg crx, iRegPsrc src1, immL16 src2) %{ 11232 // This match rule prevents reordering of node before a safepoint. 11233 // This only makes sense if this instructions is used exclusively 11234 // for the expansion of EncodeP! 11235 match(Set crx (CmpP src1 src2)); 11236 predicate(false); 11237 11238 format %{ "CMPDI $crx, $src1, $src2" %} 11239 size(4); 11240 ins_encode %{ 11241 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11242 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11243 %} 11244 ins_pipe(pipe_class_compare); 11245 %} 11246 11247 //----------Float Compares---------------------------------------------------- 11248 11249 instruct cmpFUnordered_reg_reg(flagsReg crx, regF src1, regF src2) %{ 11250 // Needs matchrule, see cmpDUnordered. 11251 match(Set crx (CmpF src1 src2)); 11252 // no match-rule, false predicate 11253 predicate(false); 11254 11255 format %{ "cmpFUrd $crx, $src1, $src2" %} 11256 size(4); 11257 ins_encode %{ 11258 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 11259 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 11260 %} 11261 ins_pipe(pipe_class_default); 11262 %} 11263 11264 instruct cmov_bns_less(flagsReg crx) %{ 11265 // no match-rule, false predicate 11266 effect(DEF crx); 11267 predicate(false); 11268 11269 ins_variable_size_depending_on_alignment(true); 11270 11271 format %{ "cmov $crx" %} 11272 // Worst case is branch + move + stop, no stop without scheduler. 11273 size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 16 : 12); 11274 ins_encode %{ 11275 // TODO: PPC port $archOpcode(ppc64Opcode_cmovecr); 11276 Label done; 11277 __ bns($crx$$CondRegister, done); // not unordered -> keep crx 11278 __ li(R0, 0); 11279 __ cmpwi($crx$$CondRegister, R0, 1); // unordered -> set crx to 'less' 11280 // TODO PPC port __ endgroup_if_needed(_size == 16); 11281 __ bind(done); 11282 %} 11283 ins_pipe(pipe_class_default); 11284 %} 11285 11286 // Compare floating, generate condition code. 11287 instruct cmpF_reg_reg_Ex(flagsReg crx, regF src1, regF src2) %{ 11288 // FIXME: should we match 'If cmp (CmpF src1 src2))' ?? 11289 // 11290 // The following code sequence occurs a lot in mpegaudio: 11291 // 11292 // block BXX: 11293 // 0: instruct cmpFUnordered_reg_reg (cmpF_reg_reg-0): 11294 // cmpFUrd CCR6, F11, F9 11295 // 4: instruct cmov_bns_less (cmpF_reg_reg-1): 11296 // cmov CCR6 11297 // 8: instruct branchConSched: 11298 // B_FARle CCR6, B56 P=0.500000 C=-1.000000 11299 match(Set crx (CmpF src1 src2)); 11300 ins_cost(DEFAULT_COST+BRANCH_COST); 11301 11302 format %{ "CmpF $crx, $src1, $src2 \t// postalloc expanded" %} 11303 postalloc_expand %{ 11304 // 11305 // replaces 11306 // 11307 // region src1 src2 11308 // \ | | 11309 // crx=cmpF_reg_reg 11310 // 11311 // with 11312 // 11313 // region src1 src2 11314 // \ | | 11315 // crx=cmpFUnordered_reg_reg 11316 // | 11317 // ^ region 11318 // | \ 11319 // crx=cmov_bns_less 11320 // 11321 11322 // Create new nodes. 11323 MachNode *m1 = new cmpFUnordered_reg_regNode(); 11324 MachNode *m2 = new cmov_bns_lessNode(); 11325 11326 // inputs for new nodes 11327 m1->add_req(n_region, n_src1, n_src2); 11328 m2->add_req(n_region); 11329 m2->add_prec(m1); 11330 11331 // operands for new nodes 11332 m1->_opnds[0] = op_crx; 11333 m1->_opnds[1] = op_src1; 11334 m1->_opnds[2] = op_src2; 11335 m2->_opnds[0] = op_crx; 11336 11337 // registers for new nodes 11338 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 11339 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 11340 11341 // Insert new nodes. 11342 nodes->push(m1); 11343 nodes->push(m2); 11344 %} 11345 %} 11346 11347 // Compare float, generate -1,0,1 11348 instruct cmpF3_reg_reg_ExEx(iRegIdst dst, regF src1, regF src2) %{ 11349 match(Set dst (CmpF3 src1 src2)); 11350 ins_cost(DEFAULT_COST*5+BRANCH_COST); 11351 11352 expand %{ 11353 flagsReg tmp1; 11354 cmpFUnordered_reg_reg(tmp1, src1, src2); 11355 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 11356 %} 11357 %} 11358 11359 instruct cmpDUnordered_reg_reg(flagsReg crx, regD src1, regD src2) %{ 11360 // Needs matchrule so that ideal opcode is Cmp. This causes that gcm places the 11361 // node right before the conditional move using it. 11362 // In jck test api/java_awt/geom/QuadCurve2DFloat/index.html#SetCurveTesttestCase7, 11363 // compilation of java.awt.geom.RectangularShape::getBounds()Ljava/awt/Rectangle 11364 // crashed in register allocation where the flags Reg between cmpDUnoredered and a 11365 // conditional move was supposed to be spilled. 11366 match(Set crx (CmpD src1 src2)); 11367 // False predicate, shall not be matched. 11368 predicate(false); 11369 11370 format %{ "cmpFUrd $crx, $src1, $src2" %} 11371 size(4); 11372 ins_encode %{ 11373 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 11374 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 11375 %} 11376 ins_pipe(pipe_class_default); 11377 %} 11378 11379 instruct cmpD_reg_reg_Ex(flagsReg crx, regD src1, regD src2) %{ 11380 match(Set crx (CmpD src1 src2)); 11381 ins_cost(DEFAULT_COST+BRANCH_COST); 11382 11383 format %{ "CmpD $crx, $src1, $src2 \t// postalloc expanded" %} 11384 postalloc_expand %{ 11385 // 11386 // replaces 11387 // 11388 // region src1 src2 11389 // \ | | 11390 // crx=cmpD_reg_reg 11391 // 11392 // with 11393 // 11394 // region src1 src2 11395 // \ | | 11396 // crx=cmpDUnordered_reg_reg 11397 // | 11398 // ^ region 11399 // | \ 11400 // crx=cmov_bns_less 11401 // 11402 11403 // create new nodes 11404 MachNode *m1 = new cmpDUnordered_reg_regNode(); 11405 MachNode *m2 = new cmov_bns_lessNode(); 11406 11407 // inputs for new nodes 11408 m1->add_req(n_region, n_src1, n_src2); 11409 m2->add_req(n_region); 11410 m2->add_prec(m1); 11411 11412 // operands for new nodes 11413 m1->_opnds[0] = op_crx; 11414 m1->_opnds[1] = op_src1; 11415 m1->_opnds[2] = op_src2; 11416 m2->_opnds[0] = op_crx; 11417 11418 // registers for new nodes 11419 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 11420 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 11421 11422 // Insert new nodes. 11423 nodes->push(m1); 11424 nodes->push(m2); 11425 %} 11426 %} 11427 11428 // Compare double, generate -1,0,1 11429 instruct cmpD3_reg_reg_ExEx(iRegIdst dst, regD src1, regD src2) %{ 11430 match(Set dst (CmpD3 src1 src2)); 11431 ins_cost(DEFAULT_COST*5+BRANCH_COST); 11432 11433 expand %{ 11434 flagsReg tmp1; 11435 cmpDUnordered_reg_reg(tmp1, src1, src2); 11436 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 11437 %} 11438 %} 11439 11440 //----------Branches--------------------------------------------------------- 11441 // Jump 11442 11443 // Direct Branch. 11444 instruct branch(label labl) %{ 11445 match(Goto); 11446 effect(USE labl); 11447 ins_cost(BRANCH_COST); 11448 11449 format %{ "B $labl" %} 11450 size(4); 11451 ins_encode %{ 11452 // TODO: PPC port $archOpcode(ppc64Opcode_b); 11453 Label d; // dummy 11454 __ bind(d); 11455 Label* p = $labl$$label; 11456 // `p' is `NULL' when this encoding class is used only to 11457 // determine the size of the encoded instruction. 11458 Label& l = (NULL == p)? d : *(p); 11459 __ b(l); 11460 %} 11461 ins_pipe(pipe_class_default); 11462 %} 11463 11464 // Conditional Near Branch 11465 instruct branchCon(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 11466 // Same match rule as `branchConFar'. 11467 match(If cmp crx); 11468 effect(USE lbl); 11469 ins_cost(BRANCH_COST); 11470 11471 // If set to 1 this indicates that the current instruction is a 11472 // short variant of a long branch. This avoids using this 11473 // instruction in first-pass matching. It will then only be used in 11474 // the `Shorten_branches' pass. 11475 ins_short_branch(1); 11476 11477 format %{ "B$cmp $crx, $lbl" %} 11478 size(4); 11479 ins_encode( enc_bc(crx, cmp, lbl) ); 11480 ins_pipe(pipe_class_default); 11481 %} 11482 11483 // This is for cases when the ppc64 `bc' instruction does not 11484 // reach far enough. So we emit a far branch here, which is more 11485 // expensive. 11486 // 11487 // Conditional Far Branch 11488 instruct branchConFar(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 11489 // Same match rule as `branchCon'. 11490 match(If cmp crx); 11491 effect(USE crx, USE lbl); 11492 predicate(!false /* TODO: PPC port HB_Schedule*/); 11493 // Higher cost than `branchCon'. 11494 ins_cost(5*BRANCH_COST); 11495 11496 // This is not a short variant of a branch, but the long variant. 11497 ins_short_branch(0); 11498 11499 format %{ "B_FAR$cmp $crx, $lbl" %} 11500 size(8); 11501 ins_encode( enc_bc_far(crx, cmp, lbl) ); 11502 ins_pipe(pipe_class_default); 11503 %} 11504 11505 // Conditional Branch used with Power6 scheduler (can be far or short). 11506 instruct branchConSched(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 11507 // Same match rule as `branchCon'. 11508 match(If cmp crx); 11509 effect(USE crx, USE lbl); 11510 predicate(false /* TODO: PPC port HB_Schedule*/); 11511 // Higher cost than `branchCon'. 11512 ins_cost(5*BRANCH_COST); 11513 11514 // Actually size doesn't depend on alignment but on shortening. 11515 ins_variable_size_depending_on_alignment(true); 11516 // long variant. 11517 ins_short_branch(0); 11518 11519 format %{ "B_FAR$cmp $crx, $lbl" %} 11520 size(8); // worst case 11521 ins_encode( enc_bc_short_far(crx, cmp, lbl) ); 11522 ins_pipe(pipe_class_default); 11523 %} 11524 11525 instruct branchLoopEnd(cmpOp cmp, flagsRegSrc crx, label labl) %{ 11526 match(CountedLoopEnd cmp crx); 11527 effect(USE labl); 11528 ins_cost(BRANCH_COST); 11529 11530 // short variant. 11531 ins_short_branch(1); 11532 11533 format %{ "B$cmp $crx, $labl \t// counted loop end" %} 11534 size(4); 11535 ins_encode( enc_bc(crx, cmp, labl) ); 11536 ins_pipe(pipe_class_default); 11537 %} 11538 11539 instruct branchLoopEndFar(cmpOp cmp, flagsRegSrc crx, label labl) %{ 11540 match(CountedLoopEnd cmp crx); 11541 effect(USE labl); 11542 predicate(!false /* TODO: PPC port HB_Schedule */); 11543 ins_cost(BRANCH_COST); 11544 11545 // Long variant. 11546 ins_short_branch(0); 11547 11548 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 11549 size(8); 11550 ins_encode( enc_bc_far(crx, cmp, labl) ); 11551 ins_pipe(pipe_class_default); 11552 %} 11553 11554 // Conditional Branch used with Power6 scheduler (can be far or short). 11555 instruct branchLoopEndSched(cmpOp cmp, flagsRegSrc crx, label labl) %{ 11556 match(CountedLoopEnd cmp crx); 11557 effect(USE labl); 11558 predicate(false /* TODO: PPC port HB_Schedule */); 11559 // Higher cost than `branchCon'. 11560 ins_cost(5*BRANCH_COST); 11561 11562 // Actually size doesn't depend on alignment but on shortening. 11563 ins_variable_size_depending_on_alignment(true); 11564 // Long variant. 11565 ins_short_branch(0); 11566 11567 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 11568 size(8); // worst case 11569 ins_encode( enc_bc_short_far(crx, cmp, labl) ); 11570 ins_pipe(pipe_class_default); 11571 %} 11572 11573 // ============================================================================ 11574 // Java runtime operations, intrinsics and other complex operations. 11575 11576 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass 11577 // array for an instance of the superklass. Set a hidden internal cache on a 11578 // hit (cache is checked with exposed code in gen_subtype_check()). Return 11579 // not zero for a miss or zero for a hit. The encoding ALSO sets flags. 11580 // 11581 // GL TODO: Improve this. 11582 // - result should not be a TEMP 11583 // - Add match rule as on sparc avoiding additional Cmp. 11584 instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass, 11585 iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{ 11586 match(Set result (PartialSubtypeCheck subklass superklass)); 11587 effect(TEMP_DEF result, TEMP tmp_klass, TEMP tmp_arrayptr); 11588 ins_cost(DEFAULT_COST*10); 11589 11590 format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %} 11591 ins_encode %{ 11592 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11593 __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register, 11594 $tmp_klass$$Register, NULL, $result$$Register); 11595 %} 11596 ins_pipe(pipe_class_default); 11597 %} 11598 11599 // inlined locking and unlocking 11600 11601 instruct cmpFastLock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2) %{ 11602 match(Set crx (FastLock oop box)); 11603 effect(TEMP tmp1, TEMP tmp2); 11604 predicate(!Compile::current()->use_rtm()); 11605 11606 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2" %} 11607 ins_encode %{ 11608 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11609 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 11610 $tmp1$$Register, $tmp2$$Register, /*tmp3*/ R0, 11611 UseBiasedLocking && !UseOptoBiasInlining); 11612 // If locking was successfull, crx should indicate 'EQ'. 11613 // The compiler generates a branch to the runtime call to 11614 // _complete_monitor_locking_Java for the case where crx is 'NE'. 11615 %} 11616 ins_pipe(pipe_class_compare); 11617 %} 11618 11619 // Separate version for TM. Use bound register for box to enable USE_KILL. 11620 instruct cmpFastLock_tm(flagsReg crx, iRegPdst oop, rarg2RegP box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 11621 match(Set crx (FastLock oop box)); 11622 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL box); 11623 predicate(Compile::current()->use_rtm()); 11624 11625 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2, $tmp3 (TM)" %} 11626 ins_encode %{ 11627 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11628 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 11629 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 11630 /*Biased Locking*/ false, 11631 _rtm_counters, _stack_rtm_counters, 11632 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 11633 /*TM*/ true, ra_->C->profile_rtm()); 11634 // If locking was successfull, crx should indicate 'EQ'. 11635 // The compiler generates a branch to the runtime call to 11636 // _complete_monitor_locking_Java for the case where crx is 'NE'. 11637 %} 11638 ins_pipe(pipe_class_compare); 11639 %} 11640 11641 instruct cmpFastUnlock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 11642 match(Set crx (FastUnlock oop box)); 11643 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 11644 predicate(!Compile::current()->use_rtm()); 11645 11646 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2" %} 11647 ins_encode %{ 11648 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11649 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 11650 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 11651 UseBiasedLocking && !UseOptoBiasInlining, 11652 false); 11653 // If unlocking was successfull, crx should indicate 'EQ'. 11654 // The compiler generates a branch to the runtime call to 11655 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 11656 %} 11657 ins_pipe(pipe_class_compare); 11658 %} 11659 11660 instruct cmpFastUnlock_tm(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 11661 match(Set crx (FastUnlock oop box)); 11662 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 11663 predicate(Compile::current()->use_rtm()); 11664 11665 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2 (TM)" %} 11666 ins_encode %{ 11667 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11668 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 11669 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 11670 /*Biased Locking*/ false, /*TM*/ true); 11671 // If unlocking was successfull, crx should indicate 'EQ'. 11672 // The compiler generates a branch to the runtime call to 11673 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 11674 %} 11675 ins_pipe(pipe_class_compare); 11676 %} 11677 11678 // Align address. 11679 instruct align_addr(iRegPdst dst, iRegPsrc src, immLnegpow2 mask) %{ 11680 match(Set dst (CastX2P (AndL (CastP2X src) mask))); 11681 11682 format %{ "ANDDI $dst, $src, $mask \t// next aligned address" %} 11683 size(4); 11684 ins_encode %{ 11685 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 11686 __ clrrdi($dst$$Register, $src$$Register, log2_long((jlong)-$mask$$constant)); 11687 %} 11688 ins_pipe(pipe_class_default); 11689 %} 11690 11691 // Array size computation. 11692 instruct array_size(iRegLdst dst, iRegPsrc end, iRegPsrc start) %{ 11693 match(Set dst (SubL (CastP2X end) (CastP2X start))); 11694 11695 format %{ "SUB $dst, $end, $start \t// array size in bytes" %} 11696 size(4); 11697 ins_encode %{ 11698 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 11699 __ subf($dst$$Register, $start$$Register, $end$$Register); 11700 %} 11701 ins_pipe(pipe_class_default); 11702 %} 11703 11704 // Clear-array with dynamic array-size. 11705 instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 11706 match(Set dummy (ClearArray cnt base)); 11707 effect(USE_KILL cnt, USE_KILL base, KILL ctr); 11708 ins_cost(MEMORY_REF_COST); 11709 11710 ins_alignment(4); // 'compute_padding()' gets called, up to this number-1 nops will get inserted. 11711 11712 format %{ "ClearArray $cnt, $base" %} 11713 ins_encode %{ 11714 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11715 __ clear_memory_doubleword($base$$Register, $cnt$$Register); // kills cnt, base, R0 11716 %} 11717 ins_pipe(pipe_class_default); 11718 %} 11719 11720 instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 11721 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 11722 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 11723 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11724 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 11725 ins_cost(300); 11726 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 11727 ins_encode %{ 11728 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11729 __ string_compare($str1$$Register, $str2$$Register, 11730 $cnt1$$Register, $cnt2$$Register, 11731 $tmp$$Register, 11732 $result$$Register, StrIntrinsicNode::LL); 11733 %} 11734 ins_pipe(pipe_class_default); 11735 %} 11736 11737 instruct string_compareU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 11738 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 11739 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 11740 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11741 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 11742 ins_cost(300); 11743 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 11744 ins_encode %{ 11745 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11746 __ string_compare($str1$$Register, $str2$$Register, 11747 $cnt1$$Register, $cnt2$$Register, 11748 $tmp$$Register, 11749 $result$$Register, StrIntrinsicNode::UU); 11750 %} 11751 ins_pipe(pipe_class_default); 11752 %} 11753 11754 instruct string_compareLU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 11755 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 11756 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 11757 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11758 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 11759 ins_cost(300); 11760 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 11761 ins_encode %{ 11762 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11763 __ string_compare($str1$$Register, $str2$$Register, 11764 $cnt1$$Register, $cnt2$$Register, 11765 $tmp$$Register, 11766 $result$$Register, StrIntrinsicNode::LU); 11767 %} 11768 ins_pipe(pipe_class_default); 11769 %} 11770 11771 instruct string_compareUL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 11772 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 11773 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 11774 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11775 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 11776 ins_cost(300); 11777 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 11778 ins_encode %{ 11779 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11780 __ string_compare($str2$$Register, $str1$$Register, 11781 $cnt2$$Register, $cnt1$$Register, 11782 $tmp$$Register, 11783 $result$$Register, StrIntrinsicNode::UL); 11784 %} 11785 ins_pipe(pipe_class_default); 11786 %} 11787 11788 instruct string_equalsL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 11789 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 11790 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 11791 match(Set result (StrEquals (Binary str1 str2) cnt)); 11792 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 11793 ins_cost(300); 11794 format %{ "String Equals byte[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 11795 ins_encode %{ 11796 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11797 __ array_equals(false, $str1$$Register, $str2$$Register, 11798 $cnt$$Register, $tmp$$Register, 11799 $result$$Register, true /* byte */); 11800 %} 11801 ins_pipe(pipe_class_default); 11802 %} 11803 11804 instruct string_equalsU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 11805 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 11806 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 11807 match(Set result (StrEquals (Binary str1 str2) cnt)); 11808 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 11809 ins_cost(300); 11810 format %{ "String Equals char[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 11811 ins_encode %{ 11812 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11813 __ array_equals(false, $str1$$Register, $str2$$Register, 11814 $cnt$$Register, $tmp$$Register, 11815 $result$$Register, false /* byte */); 11816 %} 11817 ins_pipe(pipe_class_default); 11818 %} 11819 11820 instruct array_equalsB(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 11821 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 11822 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11823 match(Set result (AryEq ary1 ary2)); 11824 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 11825 ins_cost(300); 11826 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 11827 ins_encode %{ 11828 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11829 __ array_equals(true, $ary1$$Register, $ary2$$Register, 11830 $tmp1$$Register, $tmp2$$Register, 11831 $result$$Register, true /* byte */); 11832 %} 11833 ins_pipe(pipe_class_default); 11834 %} 11835 11836 instruct array_equalsC(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 11837 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 11838 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11839 match(Set result (AryEq ary1 ary2)); 11840 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 11841 ins_cost(300); 11842 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 11843 ins_encode %{ 11844 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11845 __ array_equals(true, $ary1$$Register, $ary2$$Register, 11846 $tmp1$$Register, $tmp2$$Register, 11847 $result$$Register, false /* byte */); 11848 %} 11849 ins_pipe(pipe_class_default); 11850 %} 11851 11852 instruct indexOf_imm1_char_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 11853 immP needleImm, immL offsetImm, immI_1 needlecntImm, 11854 iRegIdst tmp1, iRegIdst tmp2, 11855 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 11856 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 11857 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 11858 // Required for EA: check if it is still a type_array. 11859 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 11860 ins_cost(150); 11861 11862 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 11863 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 11864 11865 ins_encode %{ 11866 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11867 immPOper *needleOper = (immPOper *)$needleImm; 11868 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 11869 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 11870 jchar chr; 11871 #ifdef VM_LITTLE_ENDIAN 11872 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 11873 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 11874 #else 11875 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 11876 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 11877 #endif 11878 __ string_indexof_char($result$$Register, 11879 $haystack$$Register, $haycnt$$Register, 11880 R0, chr, 11881 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 11882 %} 11883 ins_pipe(pipe_class_compare); 11884 %} 11885 11886 instruct indexOf_imm1_char_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 11887 immP needleImm, immL offsetImm, immI_1 needlecntImm, 11888 iRegIdst tmp1, iRegIdst tmp2, 11889 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 11890 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 11891 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 11892 // Required for EA: check if it is still a type_array. 11893 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 11894 ins_cost(150); 11895 11896 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 11897 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 11898 11899 ins_encode %{ 11900 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11901 immPOper *needleOper = (immPOper *)$needleImm; 11902 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 11903 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 11904 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 11905 __ string_indexof_char($result$$Register, 11906 $haystack$$Register, $haycnt$$Register, 11907 R0, chr, 11908 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 11909 %} 11910 ins_pipe(pipe_class_compare); 11911 %} 11912 11913 instruct indexOf_imm1_char_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 11914 immP needleImm, immL offsetImm, immI_1 needlecntImm, 11915 iRegIdst tmp1, iRegIdst tmp2, 11916 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 11917 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 11918 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 11919 // Required for EA: check if it is still a type_array. 11920 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 11921 ins_cost(150); 11922 11923 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 11924 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 11925 11926 ins_encode %{ 11927 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11928 immPOper *needleOper = (immPOper *)$needleImm; 11929 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 11930 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 11931 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 11932 __ string_indexof_char($result$$Register, 11933 $haystack$$Register, $haycnt$$Register, 11934 R0, chr, 11935 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 11936 %} 11937 ins_pipe(pipe_class_compare); 11938 %} 11939 11940 instruct indexOf_imm1_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 11941 rscratch2RegP needle, immI_1 needlecntImm, 11942 iRegIdst tmp1, iRegIdst tmp2, 11943 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 11944 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 11945 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 11946 // Required for EA: check if it is still a type_array. 11947 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 11948 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 11949 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 11950 ins_cost(180); 11951 11952 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 11953 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 11954 ins_encode %{ 11955 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11956 Node *ndl = in(operand_index($needle)); // The node that defines needle. 11957 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 11958 guarantee(needle_values, "sanity"); 11959 jchar chr; 11960 #ifdef VM_LITTLE_ENDIAN 11961 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 11962 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 11963 #else 11964 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 11965 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 11966 #endif 11967 __ string_indexof_char($result$$Register, 11968 $haystack$$Register, $haycnt$$Register, 11969 R0, chr, 11970 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 11971 %} 11972 ins_pipe(pipe_class_compare); 11973 %} 11974 11975 instruct indexOf_imm1_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 11976 rscratch2RegP needle, immI_1 needlecntImm, 11977 iRegIdst tmp1, iRegIdst tmp2, 11978 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 11979 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 11980 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 11981 // Required for EA: check if it is still a type_array. 11982 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 11983 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 11984 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 11985 ins_cost(180); 11986 11987 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 11988 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 11989 ins_encode %{ 11990 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11991 Node *ndl = in(operand_index($needle)); // The node that defines needle. 11992 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 11993 guarantee(needle_values, "sanity"); 11994 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 11995 __ string_indexof_char($result$$Register, 11996 $haystack$$Register, $haycnt$$Register, 11997 R0, chr, 11998 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 11999 %} 12000 ins_pipe(pipe_class_compare); 12001 %} 12002 12003 instruct indexOf_imm1_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12004 rscratch2RegP needle, immI_1 needlecntImm, 12005 iRegIdst tmp1, iRegIdst tmp2, 12006 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12007 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12008 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12009 // Required for EA: check if it is still a type_array. 12010 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 12011 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12012 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12013 ins_cost(180); 12014 12015 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12016 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12017 ins_encode %{ 12018 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12019 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12020 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12021 guarantee(needle_values, "sanity"); 12022 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12023 __ string_indexof_char($result$$Register, 12024 $haystack$$Register, $haycnt$$Register, 12025 R0, chr, 12026 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12027 %} 12028 ins_pipe(pipe_class_compare); 12029 %} 12030 12031 instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12032 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2, 12033 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12034 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch)); 12035 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12036 ins_cost(180); 12037 12038 format %{ "String IndexOfChar $haystack[0..$haycnt], $ch" 12039 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12040 ins_encode %{ 12041 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12042 __ string_indexof_char($result$$Register, 12043 $haystack$$Register, $haycnt$$Register, 12044 $ch$$Register, 0 /* this is not used if the character is already in a register */, 12045 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12046 %} 12047 ins_pipe(pipe_class_compare); 12048 %} 12049 12050 instruct indexOf_imm_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 12051 iRegPsrc needle, uimmI15 needlecntImm, 12052 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 12053 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12054 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12055 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 12056 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12057 // Required for EA: check if it is still a type_array. 12058 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 12059 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12060 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12061 ins_cost(250); 12062 12063 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12064 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 12065 ins_encode %{ 12066 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12067 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12068 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12069 12070 __ string_indexof($result$$Register, 12071 $haystack$$Register, $haycnt$$Register, 12072 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 12073 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 12074 %} 12075 ins_pipe(pipe_class_compare); 12076 %} 12077 12078 instruct indexOf_imm_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 12079 iRegPsrc needle, uimmI15 needlecntImm, 12080 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 12081 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12082 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12083 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 12084 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12085 // Required for EA: check if it is still a type_array. 12086 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 12087 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12088 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12089 ins_cost(250); 12090 12091 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12092 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 12093 ins_encode %{ 12094 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12095 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12096 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12097 12098 __ string_indexof($result$$Register, 12099 $haystack$$Register, $haycnt$$Register, 12100 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 12101 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 12102 %} 12103 ins_pipe(pipe_class_compare); 12104 %} 12105 12106 instruct indexOf_imm_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 12107 iRegPsrc needle, uimmI15 needlecntImm, 12108 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 12109 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12110 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12111 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 12112 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12113 // Required for EA: check if it is still a type_array. 12114 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 12115 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12116 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12117 ins_cost(250); 12118 12119 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12120 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 12121 ins_encode %{ 12122 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12123 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12124 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12125 12126 __ string_indexof($result$$Register, 12127 $haystack$$Register, $haycnt$$Register, 12128 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 12129 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 12130 %} 12131 ins_pipe(pipe_class_compare); 12132 %} 12133 12134 instruct indexOf_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 12135 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 12136 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12137 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 12138 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 12139 TEMP_DEF result, 12140 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12141 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 12142 ins_cost(300); 12143 12144 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 12145 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 12146 ins_encode %{ 12147 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12148 __ string_indexof($result$$Register, 12149 $haystack$$Register, $haycnt$$Register, 12150 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 12151 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 12152 %} 12153 ins_pipe(pipe_class_compare); 12154 %} 12155 12156 instruct indexOf_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 12157 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 12158 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12159 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 12160 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 12161 TEMP_DEF result, 12162 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12163 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 12164 ins_cost(300); 12165 12166 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 12167 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 12168 ins_encode %{ 12169 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12170 __ string_indexof($result$$Register, 12171 $haystack$$Register, $haycnt$$Register, 12172 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 12173 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 12174 %} 12175 ins_pipe(pipe_class_compare); 12176 %} 12177 12178 instruct indexOf_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 12179 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 12180 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12181 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 12182 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 12183 TEMP_DEF result, 12184 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12185 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 12186 ins_cost(300); 12187 12188 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 12189 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 12190 ins_encode %{ 12191 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12192 __ string_indexof($result$$Register, 12193 $haystack$$Register, $haycnt$$Register, 12194 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 12195 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 12196 %} 12197 ins_pipe(pipe_class_compare); 12198 %} 12199 12200 // char[] to byte[] compression 12201 instruct string_compress(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 12202 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 12203 match(Set result (StrCompressedCopy src (Binary dst len))); 12204 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 12205 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 12206 ins_cost(300); 12207 format %{ "String Compress $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 12208 ins_encode %{ 12209 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12210 Label Lskip, Ldone; 12211 __ li($result$$Register, 0); 12212 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 12213 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Ldone); 12214 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 12215 __ beq(CCR0, Lskip); 12216 __ string_compress($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register, Ldone); 12217 __ bind(Lskip); 12218 __ mr($result$$Register, $len$$Register); 12219 __ bind(Ldone); 12220 %} 12221 ins_pipe(pipe_class_default); 12222 %} 12223 12224 // byte[] to char[] inflation 12225 instruct string_inflate(Universe dummy, rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegLdst tmp1, 12226 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 12227 match(Set dummy (StrInflatedCopy src (Binary dst len))); 12228 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 12229 ins_cost(300); 12230 format %{ "String Inflate $src,$dst,$len \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 12231 ins_encode %{ 12232 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12233 Label Ldone; 12234 __ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 12235 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register); 12236 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 12237 __ beq(CCR0, Ldone); 12238 __ string_inflate($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register); 12239 __ bind(Ldone); 12240 %} 12241 ins_pipe(pipe_class_default); 12242 %} 12243 12244 // StringCoding.java intrinsics 12245 instruct has_negatives(rarg1RegP ary1, iRegIsrc len, iRegIdst result, iRegLdst tmp1, iRegLdst tmp2, 12246 regCTR ctr, flagsRegCR0 cr0) 12247 %{ 12248 match(Set result (HasNegatives ary1 len)); 12249 effect(TEMP_DEF result, USE_KILL ary1, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0); 12250 ins_cost(300); 12251 format %{ "has negatives byte[] $ary1,$len -> $result \t// KILL $tmp1, $tmp2" %} 12252 ins_encode %{ 12253 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12254 __ has_negatives($ary1$$Register, $len$$Register, $result$$Register, 12255 $tmp1$$Register, $tmp2$$Register); 12256 %} 12257 ins_pipe(pipe_class_default); 12258 %} 12259 12260 // encode char[] to byte[] in ISO_8859_1 12261 instruct encode_iso_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 12262 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 12263 match(Set result (EncodeISOArray src (Binary dst len))); 12264 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 12265 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 12266 ins_cost(300); 12267 format %{ "Encode array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 12268 ins_encode %{ 12269 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12270 Label Lslow, Lfailure1, Lfailure2, Ldone; 12271 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 12272 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Lfailure1); 12273 __ rldicl_($result$$Register, $len$$Register, 0, 64-3); // Remaining characters. 12274 __ beq(CCR0, Ldone); 12275 __ bind(Lslow); 12276 __ string_compress($src$$Register, $dst$$Register, $result$$Register, $tmp2$$Register, Lfailure2); 12277 __ li($result$$Register, 0); 12278 __ b(Ldone); 12279 12280 __ bind(Lfailure1); 12281 __ mr($result$$Register, $len$$Register); 12282 __ mfctr($tmp1$$Register); 12283 __ rldimi_($result$$Register, $tmp1$$Register, 3, 0); // Remaining characters. 12284 __ beq(CCR0, Ldone); 12285 __ b(Lslow); 12286 12287 __ bind(Lfailure2); 12288 __ mfctr($result$$Register); // Remaining characters. 12289 12290 __ bind(Ldone); 12291 __ subf($result$$Register, $result$$Register, $len$$Register); 12292 %} 12293 ins_pipe(pipe_class_default); 12294 %} 12295 12296 12297 //---------- Min/Max Instructions --------------------------------------------- 12298 12299 instruct minI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 12300 match(Set dst (MinI src1 src2)); 12301 ins_cost(DEFAULT_COST*6); 12302 12303 expand %{ 12304 iRegLdst src1s; 12305 iRegLdst src2s; 12306 iRegLdst diff; 12307 iRegLdst sm; 12308 iRegLdst doz; // difference or zero 12309 convI2L_reg(src1s, src1); // Ensure proper sign extension. 12310 convI2L_reg(src2s, src2); // Ensure proper sign extension. 12311 subL_reg_reg(diff, src2s, src1s); 12312 // Need to consider >=33 bit result, therefore we need signmaskL. 12313 signmask64L_regL(sm, diff); 12314 andL_reg_reg(doz, diff, sm); // <=0 12315 addI_regL_regL(dst, doz, src1s); 12316 %} 12317 %} 12318 12319 instruct minI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 12320 match(Set dst (MinI src1 src2)); 12321 effect(KILL cr0); 12322 predicate(VM_Version::has_isel()); 12323 ins_cost(DEFAULT_COST*2); 12324 12325 ins_encode %{ 12326 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12327 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 12328 __ isel($dst$$Register, CCR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register); 12329 %} 12330 ins_pipe(pipe_class_default); 12331 %} 12332 12333 instruct maxI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 12334 match(Set dst (MaxI src1 src2)); 12335 ins_cost(DEFAULT_COST*6); 12336 12337 expand %{ 12338 iRegLdst src1s; 12339 iRegLdst src2s; 12340 iRegLdst diff; 12341 iRegLdst sm; 12342 iRegLdst doz; // difference or zero 12343 convI2L_reg(src1s, src1); // Ensure proper sign extension. 12344 convI2L_reg(src2s, src2); // Ensure proper sign extension. 12345 subL_reg_reg(diff, src2s, src1s); 12346 // Need to consider >=33 bit result, therefore we need signmaskL. 12347 signmask64L_regL(sm, diff); 12348 andcL_reg_reg(doz, diff, sm); // >=0 12349 addI_regL_regL(dst, doz, src1s); 12350 %} 12351 %} 12352 12353 instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 12354 match(Set dst (MaxI src1 src2)); 12355 effect(KILL cr0); 12356 predicate(VM_Version::has_isel()); 12357 ins_cost(DEFAULT_COST*2); 12358 12359 ins_encode %{ 12360 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12361 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 12362 __ isel($dst$$Register, CCR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register); 12363 %} 12364 ins_pipe(pipe_class_default); 12365 %} 12366 12367 //---------- Population Count Instructions ------------------------------------ 12368 12369 // Popcnt for Power7. 12370 instruct popCountI(iRegIdst dst, iRegIsrc src) %{ 12371 match(Set dst (PopCountI src)); 12372 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 12373 ins_cost(DEFAULT_COST); 12374 12375 format %{ "POPCNTW $dst, $src" %} 12376 size(4); 12377 ins_encode %{ 12378 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 12379 __ popcntw($dst$$Register, $src$$Register); 12380 %} 12381 ins_pipe(pipe_class_default); 12382 %} 12383 12384 // Popcnt for Power7. 12385 instruct popCountL(iRegIdst dst, iRegLsrc src) %{ 12386 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 12387 match(Set dst (PopCountL src)); 12388 ins_cost(DEFAULT_COST); 12389 12390 format %{ "POPCNTD $dst, $src" %} 12391 size(4); 12392 ins_encode %{ 12393 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 12394 __ popcntd($dst$$Register, $src$$Register); 12395 %} 12396 ins_pipe(pipe_class_default); 12397 %} 12398 12399 instruct countLeadingZerosI(iRegIdst dst, iRegIsrc src) %{ 12400 match(Set dst (CountLeadingZerosI src)); 12401 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 12402 ins_cost(DEFAULT_COST); 12403 12404 format %{ "CNTLZW $dst, $src" %} 12405 size(4); 12406 ins_encode %{ 12407 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzw); 12408 __ cntlzw($dst$$Register, $src$$Register); 12409 %} 12410 ins_pipe(pipe_class_default); 12411 %} 12412 12413 instruct countLeadingZerosL(iRegIdst dst, iRegLsrc src) %{ 12414 match(Set dst (CountLeadingZerosL src)); 12415 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 12416 ins_cost(DEFAULT_COST); 12417 12418 format %{ "CNTLZD $dst, $src" %} 12419 size(4); 12420 ins_encode %{ 12421 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 12422 __ cntlzd($dst$$Register, $src$$Register); 12423 %} 12424 ins_pipe(pipe_class_default); 12425 %} 12426 12427 instruct countLeadingZerosP(iRegIdst dst, iRegPsrc src) %{ 12428 // no match-rule, false predicate 12429 effect(DEF dst, USE src); 12430 predicate(false); 12431 12432 format %{ "CNTLZD $dst, $src" %} 12433 size(4); 12434 ins_encode %{ 12435 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 12436 __ cntlzd($dst$$Register, $src$$Register); 12437 %} 12438 ins_pipe(pipe_class_default); 12439 %} 12440 12441 instruct countTrailingZerosI_Ex(iRegIdst dst, iRegIsrc src) %{ 12442 match(Set dst (CountTrailingZerosI src)); 12443 predicate(UseCountLeadingZerosInstructionsPPC64); 12444 ins_cost(DEFAULT_COST); 12445 12446 expand %{ 12447 immI16 imm1 %{ (int)-1 %} 12448 immI16 imm2 %{ (int)32 %} 12449 immI_minus1 m1 %{ -1 %} 12450 iRegIdst tmpI1; 12451 iRegIdst tmpI2; 12452 iRegIdst tmpI3; 12453 addI_reg_imm16(tmpI1, src, imm1); 12454 andcI_reg_reg(tmpI2, src, m1, tmpI1); 12455 countLeadingZerosI(tmpI3, tmpI2); 12456 subI_imm16_reg(dst, imm2, tmpI3); 12457 %} 12458 %} 12459 12460 instruct countTrailingZerosL_Ex(iRegIdst dst, iRegLsrc src) %{ 12461 match(Set dst (CountTrailingZerosL src)); 12462 predicate(UseCountLeadingZerosInstructionsPPC64); 12463 ins_cost(DEFAULT_COST); 12464 12465 expand %{ 12466 immL16 imm1 %{ (long)-1 %} 12467 immI16 imm2 %{ (int)64 %} 12468 iRegLdst tmpL1; 12469 iRegLdst tmpL2; 12470 iRegIdst tmpL3; 12471 addL_reg_imm16(tmpL1, src, imm1); 12472 andcL_reg_reg(tmpL2, tmpL1, src); 12473 countLeadingZerosL(tmpL3, tmpL2); 12474 subI_imm16_reg(dst, imm2, tmpL3); 12475 %} 12476 %} 12477 12478 // Expand nodes for byte_reverse_int. 12479 instruct insrwi_a(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 12480 effect(DEF dst, USE src, USE pos, USE shift); 12481 predicate(false); 12482 12483 format %{ "INSRWI $dst, $src, $pos, $shift" %} 12484 size(4); 12485 ins_encode %{ 12486 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 12487 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 12488 %} 12489 ins_pipe(pipe_class_default); 12490 %} 12491 12492 // As insrwi_a, but with USE_DEF. 12493 instruct insrwi(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 12494 effect(USE_DEF dst, USE src, USE pos, USE shift); 12495 predicate(false); 12496 12497 format %{ "INSRWI $dst, $src, $pos, $shift" %} 12498 size(4); 12499 ins_encode %{ 12500 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 12501 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 12502 %} 12503 ins_pipe(pipe_class_default); 12504 %} 12505 12506 // Just slightly faster than java implementation. 12507 instruct bytes_reverse_int_Ex(iRegIdst dst, iRegIsrc src) %{ 12508 match(Set dst (ReverseBytesI src)); 12509 predicate(UseCountLeadingZerosInstructionsPPC64); 12510 ins_cost(DEFAULT_COST); 12511 12512 expand %{ 12513 immI16 imm24 %{ (int) 24 %} 12514 immI16 imm16 %{ (int) 16 %} 12515 immI16 imm8 %{ (int) 8 %} 12516 immI16 imm4 %{ (int) 4 %} 12517 immI16 imm0 %{ (int) 0 %} 12518 iRegLdst tmpI1; 12519 iRegLdst tmpI2; 12520 iRegLdst tmpI3; 12521 12522 urShiftI_reg_imm(tmpI1, src, imm24); 12523 insrwi_a(dst, tmpI1, imm24, imm8); 12524 urShiftI_reg_imm(tmpI2, src, imm16); 12525 insrwi(dst, tmpI2, imm8, imm16); 12526 urShiftI_reg_imm(tmpI3, src, imm8); 12527 insrwi(dst, tmpI3, imm8, imm8); 12528 insrwi(dst, src, imm0, imm8); 12529 %} 12530 %} 12531 12532 //---------- Replicate Vector Instructions ------------------------------------ 12533 12534 // Insrdi does replicate if src == dst. 12535 instruct repl32(iRegLdst dst) %{ 12536 predicate(false); 12537 effect(USE_DEF dst); 12538 12539 format %{ "INSRDI $dst, #0, $dst, #32 \t// replicate" %} 12540 size(4); 12541 ins_encode %{ 12542 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 12543 __ insrdi($dst$$Register, $dst$$Register, 32, 0); 12544 %} 12545 ins_pipe(pipe_class_default); 12546 %} 12547 12548 // Insrdi does replicate if src == dst. 12549 instruct repl48(iRegLdst dst) %{ 12550 predicate(false); 12551 effect(USE_DEF dst); 12552 12553 format %{ "INSRDI $dst, #0, $dst, #48 \t// replicate" %} 12554 size(4); 12555 ins_encode %{ 12556 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 12557 __ insrdi($dst$$Register, $dst$$Register, 48, 0); 12558 %} 12559 ins_pipe(pipe_class_default); 12560 %} 12561 12562 // Insrdi does replicate if src == dst. 12563 instruct repl56(iRegLdst dst) %{ 12564 predicate(false); 12565 effect(USE_DEF dst); 12566 12567 format %{ "INSRDI $dst, #0, $dst, #56 \t// replicate" %} 12568 size(4); 12569 ins_encode %{ 12570 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 12571 __ insrdi($dst$$Register, $dst$$Register, 56, 0); 12572 %} 12573 ins_pipe(pipe_class_default); 12574 %} 12575 12576 instruct repl8B_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 12577 match(Set dst (ReplicateB src)); 12578 predicate(n->as_Vector()->length() == 8); 12579 expand %{ 12580 moveReg(dst, src); 12581 repl56(dst); 12582 repl48(dst); 12583 repl32(dst); 12584 %} 12585 %} 12586 12587 instruct repl8B_immI0(iRegLdst dst, immI_0 zero) %{ 12588 match(Set dst (ReplicateB zero)); 12589 predicate(n->as_Vector()->length() == 8); 12590 format %{ "LI $dst, #0 \t// replicate8B" %} 12591 size(4); 12592 ins_encode %{ 12593 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12594 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 12595 %} 12596 ins_pipe(pipe_class_default); 12597 %} 12598 12599 instruct repl8B_immIminus1(iRegLdst dst, immI_minus1 src) %{ 12600 match(Set dst (ReplicateB src)); 12601 predicate(n->as_Vector()->length() == 8); 12602 format %{ "LI $dst, #-1 \t// replicate8B" %} 12603 size(4); 12604 ins_encode %{ 12605 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12606 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 12607 %} 12608 ins_pipe(pipe_class_default); 12609 %} 12610 12611 instruct repl4S_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 12612 match(Set dst (ReplicateS src)); 12613 predicate(n->as_Vector()->length() == 4); 12614 expand %{ 12615 moveReg(dst, src); 12616 repl48(dst); 12617 repl32(dst); 12618 %} 12619 %} 12620 12621 instruct repl4S_immI0(iRegLdst dst, immI_0 zero) %{ 12622 match(Set dst (ReplicateS zero)); 12623 predicate(n->as_Vector()->length() == 4); 12624 format %{ "LI $dst, #0 \t// replicate4C" %} 12625 size(4); 12626 ins_encode %{ 12627 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12628 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 12629 %} 12630 ins_pipe(pipe_class_default); 12631 %} 12632 12633 instruct repl4S_immIminus1(iRegLdst dst, immI_minus1 src) %{ 12634 match(Set dst (ReplicateS src)); 12635 predicate(n->as_Vector()->length() == 4); 12636 format %{ "LI $dst, -1 \t// replicate4C" %} 12637 size(4); 12638 ins_encode %{ 12639 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12640 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 12641 %} 12642 ins_pipe(pipe_class_default); 12643 %} 12644 12645 instruct repl2I_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 12646 match(Set dst (ReplicateI src)); 12647 predicate(n->as_Vector()->length() == 2); 12648 ins_cost(2 * DEFAULT_COST); 12649 expand %{ 12650 moveReg(dst, src); 12651 repl32(dst); 12652 %} 12653 %} 12654 12655 instruct repl2I_immI0(iRegLdst dst, immI_0 zero) %{ 12656 match(Set dst (ReplicateI zero)); 12657 predicate(n->as_Vector()->length() == 2); 12658 format %{ "LI $dst, #0 \t// replicate4C" %} 12659 size(4); 12660 ins_encode %{ 12661 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12662 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 12663 %} 12664 ins_pipe(pipe_class_default); 12665 %} 12666 12667 instruct repl2I_immIminus1(iRegLdst dst, immI_minus1 src) %{ 12668 match(Set dst (ReplicateI src)); 12669 predicate(n->as_Vector()->length() == 2); 12670 format %{ "LI $dst, -1 \t// replicate4C" %} 12671 size(4); 12672 ins_encode %{ 12673 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12674 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 12675 %} 12676 ins_pipe(pipe_class_default); 12677 %} 12678 12679 // Move float to int register via stack, replicate. 12680 instruct repl2F_reg_Ex(iRegLdst dst, regF src) %{ 12681 match(Set dst (ReplicateF src)); 12682 predicate(n->as_Vector()->length() == 2); 12683 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST); 12684 expand %{ 12685 stackSlotL tmpS; 12686 iRegIdst tmpI; 12687 moveF2I_reg_stack(tmpS, src); // Move float to stack. 12688 moveF2I_stack_reg(tmpI, tmpS); // Move stack to int reg. 12689 moveReg(dst, tmpI); // Move int to long reg. 12690 repl32(dst); // Replicate bitpattern. 12691 %} 12692 %} 12693 12694 // Replicate scalar constant to packed float values in Double register 12695 instruct repl2F_immF_Ex(iRegLdst dst, immF src) %{ 12696 match(Set dst (ReplicateF src)); 12697 predicate(n->as_Vector()->length() == 2); 12698 ins_cost(5 * DEFAULT_COST); 12699 12700 format %{ "LD $dst, offset, $constanttablebase\t// load replicated float $src $src from table, postalloc expanded" %} 12701 postalloc_expand( postalloc_expand_load_replF_constant(dst, src, constanttablebase) ); 12702 %} 12703 12704 // Replicate scalar zero constant to packed float values in Double register 12705 instruct repl2F_immF0(iRegLdst dst, immF_0 zero) %{ 12706 match(Set dst (ReplicateF zero)); 12707 predicate(n->as_Vector()->length() == 2); 12708 12709 format %{ "LI $dst, #0 \t// replicate2F" %} 12710 ins_encode %{ 12711 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12712 __ li($dst$$Register, 0x0); 12713 %} 12714 ins_pipe(pipe_class_default); 12715 %} 12716 12717 12718 //----------Overflow Math Instructions----------------------------------------- 12719 12720 // Note that we have to make sure that XER.SO is reset before using overflow instructions. 12721 // Simple Overflow operations can be matched by very few instructions (e.g. addExact: xor, and_, bc). 12722 // Seems like only Long intrinsincs have an advantage. (The only expensive one is OverflowMulL.) 12723 12724 instruct overflowAddL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 12725 match(Set cr0 (OverflowAddL op1 op2)); 12726 12727 format %{ "add_ $op1, $op2\t# overflow check long" %} 12728 ins_encode %{ 12729 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12730 __ li(R0, 0); 12731 __ mtxer(R0); // clear XER.SO 12732 __ addo_(R0, $op1$$Register, $op2$$Register); 12733 %} 12734 ins_pipe(pipe_class_default); 12735 %} 12736 12737 instruct overflowSubL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 12738 match(Set cr0 (OverflowSubL op1 op2)); 12739 12740 format %{ "subfo_ R0, $op2, $op1\t# overflow check long" %} 12741 ins_encode %{ 12742 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12743 __ li(R0, 0); 12744 __ mtxer(R0); // clear XER.SO 12745 __ subfo_(R0, $op2$$Register, $op1$$Register); 12746 %} 12747 ins_pipe(pipe_class_default); 12748 %} 12749 12750 instruct overflowNegL_reg(flagsRegCR0 cr0, immL_0 zero, iRegLsrc op2) %{ 12751 match(Set cr0 (OverflowSubL zero op2)); 12752 12753 format %{ "nego_ R0, $op2\t# overflow check long" %} 12754 ins_encode %{ 12755 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12756 __ li(R0, 0); 12757 __ mtxer(R0); // clear XER.SO 12758 __ nego_(R0, $op2$$Register); 12759 %} 12760 ins_pipe(pipe_class_default); 12761 %} 12762 12763 instruct overflowMulL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 12764 match(Set cr0 (OverflowMulL op1 op2)); 12765 12766 format %{ "mulldo_ R0, $op1, $op2\t# overflow check long" %} 12767 ins_encode %{ 12768 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12769 __ li(R0, 0); 12770 __ mtxer(R0); // clear XER.SO 12771 __ mulldo_(R0, $op1$$Register, $op2$$Register); 12772 %} 12773 ins_pipe(pipe_class_default); 12774 %} 12775 12776 12777 // ============================================================================ 12778 // Safepoint Instruction 12779 12780 instruct safePoint_poll(iRegPdst poll) %{ 12781 match(SafePoint poll); 12782 predicate(LoadPollAddressFromThread); 12783 12784 // It caused problems to add the effect that r0 is killed, but this 12785 // effect no longer needs to be mentioned, since r0 is not contained 12786 // in a reg_class. 12787 12788 format %{ "LD R0, #0, $poll \t// Safepoint poll for GC" %} 12789 size(4); 12790 ins_encode( enc_poll(0x0, poll) ); 12791 ins_pipe(pipe_class_default); 12792 %} 12793 12794 // Safepoint without per-thread support. Load address of page to poll 12795 // as constant. 12796 // Rscratch2RegP is R12. 12797 // LoadConPollAddr node is added in pd_post_matching_hook(). It must be 12798 // a seperate node so that the oop map is at the right location. 12799 instruct safePoint_poll_conPollAddr(rscratch2RegP poll) %{ 12800 match(SafePoint poll); 12801 predicate(!LoadPollAddressFromThread); 12802 12803 // It caused problems to add the effect that r0 is killed, but this 12804 // effect no longer needs to be mentioned, since r0 is not contained 12805 // in a reg_class. 12806 12807 format %{ "LD R0, #0, R12 \t// Safepoint poll for GC" %} 12808 ins_encode( enc_poll(0x0, poll) ); 12809 ins_pipe(pipe_class_default); 12810 %} 12811 12812 // ============================================================================ 12813 // Call Instructions 12814 12815 // Call Java Static Instruction 12816 12817 // Schedulable version of call static node. 12818 instruct CallStaticJavaDirect(method meth) %{ 12819 match(CallStaticJava); 12820 effect(USE meth); 12821 ins_cost(CALL_COST); 12822 12823 ins_num_consts(3 /* up to 3 patchable constants: inline cache, 2 call targets. */); 12824 12825 format %{ "CALL,static $meth \t// ==> " %} 12826 size(4); 12827 ins_encode( enc_java_static_call(meth) ); 12828 ins_pipe(pipe_class_call); 12829 %} 12830 12831 // Call Java Dynamic Instruction 12832 12833 // Used by postalloc expand of CallDynamicJavaDirectSchedEx (actual call). 12834 // Loading of IC was postalloc expanded. The nodes loading the IC are reachable 12835 // via fields ins_field_load_ic_hi_node and ins_field_load_ic_node. 12836 // The call destination must still be placed in the constant pool. 12837 instruct CallDynamicJavaDirectSched(method meth) %{ 12838 match(CallDynamicJava); // To get all the data fields we need ... 12839 effect(USE meth); 12840 predicate(false); // ... but never match. 12841 12842 ins_field_load_ic_hi_node(loadConL_hiNode*); 12843 ins_field_load_ic_node(loadConLNode*); 12844 ins_num_consts(1 /* 1 patchable constant: call destination */); 12845 12846 format %{ "BL \t// dynamic $meth ==> " %} 12847 size(4); 12848 ins_encode( enc_java_dynamic_call_sched(meth) ); 12849 ins_pipe(pipe_class_call); 12850 %} 12851 12852 // Schedulable (i.e. postalloc expanded) version of call dynamic java. 12853 // We use postalloc expanded calls if we use inline caches 12854 // and do not update method data. 12855 // 12856 // This instruction has two constants: inline cache (IC) and call destination. 12857 // Loading the inline cache will be postalloc expanded, thus leaving a call with 12858 // one constant. 12859 instruct CallDynamicJavaDirectSched_Ex(method meth) %{ 12860 match(CallDynamicJava); 12861 effect(USE meth); 12862 predicate(UseInlineCaches); 12863 ins_cost(CALL_COST); 12864 12865 ins_num_consts(2 /* 2 patchable constants: inline cache, call destination. */); 12866 12867 format %{ "CALL,dynamic $meth \t// postalloc expanded" %} 12868 postalloc_expand( postalloc_expand_java_dynamic_call_sched(meth, constanttablebase) ); 12869 %} 12870 12871 // Compound version of call dynamic java 12872 // We use postalloc expanded calls if we use inline caches 12873 // and do not update method data. 12874 instruct CallDynamicJavaDirect(method meth) %{ 12875 match(CallDynamicJava); 12876 effect(USE meth); 12877 predicate(!UseInlineCaches); 12878 ins_cost(CALL_COST); 12879 12880 // Enc_java_to_runtime_call needs up to 4 constants (method data oop). 12881 ins_num_consts(4); 12882 12883 format %{ "CALL,dynamic $meth \t// ==> " %} 12884 ins_encode( enc_java_dynamic_call(meth, constanttablebase) ); 12885 ins_pipe(pipe_class_call); 12886 %} 12887 12888 // Call Runtime Instruction 12889 12890 instruct CallRuntimeDirect(method meth) %{ 12891 match(CallRuntime); 12892 effect(USE meth); 12893 ins_cost(CALL_COST); 12894 12895 // Enc_java_to_runtime_call needs up to 3 constants: call target, 12896 // env for callee, C-toc. 12897 ins_num_consts(3); 12898 12899 format %{ "CALL,runtime" %} 12900 ins_encode( enc_java_to_runtime_call(meth) ); 12901 ins_pipe(pipe_class_call); 12902 %} 12903 12904 // Call Leaf 12905 12906 // Used by postalloc expand of CallLeafDirect_Ex (mtctr). 12907 instruct CallLeafDirect_mtctr(iRegLdst dst, iRegLsrc src) %{ 12908 effect(DEF dst, USE src); 12909 12910 ins_num_consts(1); 12911 12912 format %{ "MTCTR $src" %} 12913 size(4); 12914 ins_encode( enc_leaf_call_mtctr(src) ); 12915 ins_pipe(pipe_class_default); 12916 %} 12917 12918 // Used by postalloc expand of CallLeafDirect_Ex (actual call). 12919 instruct CallLeafDirect(method meth) %{ 12920 match(CallLeaf); // To get the data all the data fields we need ... 12921 effect(USE meth); 12922 predicate(false); // but never match. 12923 12924 format %{ "BCTRL \t// leaf call $meth ==> " %} 12925 size(4); 12926 ins_encode %{ 12927 // TODO: PPC port $archOpcode(ppc64Opcode_bctrl); 12928 __ bctrl(); 12929 %} 12930 ins_pipe(pipe_class_call); 12931 %} 12932 12933 // postalloc expand of CallLeafDirect. 12934 // Load adress to call from TOC, then bl to it. 12935 instruct CallLeafDirect_Ex(method meth) %{ 12936 match(CallLeaf); 12937 effect(USE meth); 12938 ins_cost(CALL_COST); 12939 12940 // Postalloc_expand_java_to_runtime_call needs up to 3 constants: call target, 12941 // env for callee, C-toc. 12942 ins_num_consts(3); 12943 12944 format %{ "CALL,runtime leaf $meth \t// postalloc expanded" %} 12945 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 12946 %} 12947 12948 // Call runtime without safepoint - same as CallLeaf. 12949 // postalloc expand of CallLeafNoFPDirect. 12950 // Load adress to call from TOC, then bl to it. 12951 instruct CallLeafNoFPDirect_Ex(method meth) %{ 12952 match(CallLeafNoFP); 12953 effect(USE meth); 12954 ins_cost(CALL_COST); 12955 12956 // Enc_java_to_runtime_call needs up to 3 constants: call target, 12957 // env for callee, C-toc. 12958 ins_num_consts(3); 12959 12960 format %{ "CALL,runtime leaf nofp $meth \t// postalloc expanded" %} 12961 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 12962 %} 12963 12964 // Tail Call; Jump from runtime stub to Java code. 12965 // Also known as an 'interprocedural jump'. 12966 // Target of jump will eventually return to caller. 12967 // TailJump below removes the return address. 12968 instruct TailCalljmpInd(iRegPdstNoScratch jump_target, inline_cache_regP method_oop) %{ 12969 match(TailCall jump_target method_oop); 12970 ins_cost(CALL_COST); 12971 12972 format %{ "MTCTR $jump_target \t// $method_oop holds method oop\n\t" 12973 "BCTR \t// tail call" %} 12974 size(8); 12975 ins_encode %{ 12976 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12977 __ mtctr($jump_target$$Register); 12978 __ bctr(); 12979 %} 12980 ins_pipe(pipe_class_call); 12981 %} 12982 12983 // Return Instruction 12984 instruct Ret() %{ 12985 match(Return); 12986 format %{ "BLR \t// branch to link register" %} 12987 size(4); 12988 ins_encode %{ 12989 // TODO: PPC port $archOpcode(ppc64Opcode_blr); 12990 // LR is restored in MachEpilogNode. Just do the RET here. 12991 __ blr(); 12992 %} 12993 ins_pipe(pipe_class_default); 12994 %} 12995 12996 // Tail Jump; remove the return address; jump to target. 12997 // TailCall above leaves the return address around. 12998 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2). 12999 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a 13000 // "restore" before this instruction (in Epilogue), we need to materialize it 13001 // in %i0. 13002 instruct tailjmpInd(iRegPdstNoScratch jump_target, rarg1RegP ex_oop) %{ 13003 match(TailJump jump_target ex_oop); 13004 ins_cost(CALL_COST); 13005 13006 format %{ "LD R4_ARG2 = LR\n\t" 13007 "MTCTR $jump_target\n\t" 13008 "BCTR \t// TailJump, exception oop: $ex_oop" %} 13009 size(12); 13010 ins_encode %{ 13011 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13012 __ ld(R4_ARG2/* issuing pc */, _abi(lr), R1_SP); 13013 __ mtctr($jump_target$$Register); 13014 __ bctr(); 13015 %} 13016 ins_pipe(pipe_class_call); 13017 %} 13018 13019 // Create exception oop: created by stack-crawling runtime code. 13020 // Created exception is now available to this handler, and is setup 13021 // just prior to jumping to this handler. No code emitted. 13022 instruct CreateException(rarg1RegP ex_oop) %{ 13023 match(Set ex_oop (CreateEx)); 13024 ins_cost(0); 13025 13026 format %{ " -- \t// exception oop; no code emitted" %} 13027 size(0); 13028 ins_encode( /*empty*/ ); 13029 ins_pipe(pipe_class_default); 13030 %} 13031 13032 // Rethrow exception: The exception oop will come in the first 13033 // argument position. Then JUMP (not call) to the rethrow stub code. 13034 instruct RethrowException() %{ 13035 match(Rethrow); 13036 ins_cost(CALL_COST); 13037 13038 format %{ "Jmp rethrow_stub" %} 13039 ins_encode %{ 13040 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13041 cbuf.set_insts_mark(); 13042 __ b64_patchable((address)OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type); 13043 %} 13044 ins_pipe(pipe_class_call); 13045 %} 13046 13047 // Die now. 13048 instruct ShouldNotReachHere() %{ 13049 match(Halt); 13050 ins_cost(CALL_COST); 13051 13052 format %{ "ShouldNotReachHere" %} 13053 size(4); 13054 ins_encode %{ 13055 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 13056 __ trap_should_not_reach_here(); 13057 %} 13058 ins_pipe(pipe_class_default); 13059 %} 13060 13061 // This name is KNOWN by the ADLC and cannot be changed. The ADLC 13062 // forces a 'TypeRawPtr::BOTTOM' output type for this guy. 13063 // Get a DEF on threadRegP, no costs, no encoding, use 13064 // 'ins_should_rematerialize(true)' to avoid spilling. 13065 instruct tlsLoadP(threadRegP dst) %{ 13066 match(Set dst (ThreadLocal)); 13067 ins_cost(0); 13068 13069 ins_should_rematerialize(true); 13070 13071 format %{ " -- \t// $dst=Thread::current(), empty" %} 13072 size(0); 13073 ins_encode( /*empty*/ ); 13074 ins_pipe(pipe_class_empty); 13075 %} 13076 13077 //---Some PPC specific nodes--------------------------------------------------- 13078 13079 // Stop a group. 13080 instruct endGroup() %{ 13081 ins_cost(0); 13082 13083 ins_is_nop(true); 13084 13085 format %{ "End Bundle (ori r1, r1, 0)" %} 13086 size(4); 13087 ins_encode %{ 13088 // TODO: PPC port $archOpcode(ppc64Opcode_endgroup); 13089 __ endgroup(); 13090 %} 13091 ins_pipe(pipe_class_default); 13092 %} 13093 13094 // Nop instructions 13095 13096 instruct fxNop() %{ 13097 ins_cost(0); 13098 13099 ins_is_nop(true); 13100 13101 format %{ "fxNop" %} 13102 size(4); 13103 ins_encode %{ 13104 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 13105 __ nop(); 13106 %} 13107 ins_pipe(pipe_class_default); 13108 %} 13109 13110 instruct fpNop0() %{ 13111 ins_cost(0); 13112 13113 ins_is_nop(true); 13114 13115 format %{ "fpNop0" %} 13116 size(4); 13117 ins_encode %{ 13118 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 13119 __ fpnop0(); 13120 %} 13121 ins_pipe(pipe_class_default); 13122 %} 13123 13124 instruct fpNop1() %{ 13125 ins_cost(0); 13126 13127 ins_is_nop(true); 13128 13129 format %{ "fpNop1" %} 13130 size(4); 13131 ins_encode %{ 13132 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 13133 __ fpnop1(); 13134 %} 13135 ins_pipe(pipe_class_default); 13136 %} 13137 13138 instruct brNop0() %{ 13139 ins_cost(0); 13140 size(4); 13141 format %{ "brNop0" %} 13142 ins_encode %{ 13143 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 13144 __ brnop0(); 13145 %} 13146 ins_is_nop(true); 13147 ins_pipe(pipe_class_default); 13148 %} 13149 13150 instruct brNop1() %{ 13151 ins_cost(0); 13152 13153 ins_is_nop(true); 13154 13155 format %{ "brNop1" %} 13156 size(4); 13157 ins_encode %{ 13158 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 13159 __ brnop1(); 13160 %} 13161 ins_pipe(pipe_class_default); 13162 %} 13163 13164 instruct brNop2() %{ 13165 ins_cost(0); 13166 13167 ins_is_nop(true); 13168 13169 format %{ "brNop2" %} 13170 size(4); 13171 ins_encode %{ 13172 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 13173 __ brnop2(); 13174 %} 13175 ins_pipe(pipe_class_default); 13176 %} 13177 13178 //----------PEEPHOLE RULES----------------------------------------------------- 13179 // These must follow all instruction definitions as they use the names 13180 // defined in the instructions definitions. 13181 // 13182 // peepmatch ( root_instr_name [preceeding_instruction]* ); 13183 // 13184 // peepconstraint %{ 13185 // (instruction_number.operand_name relational_op instruction_number.operand_name 13186 // [, ...] ); 13187 // // instruction numbers are zero-based using left to right order in peepmatch 13188 // 13189 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 13190 // // provide an instruction_number.operand_name for each operand that appears 13191 // // in the replacement instruction's match rule 13192 // 13193 // ---------VM FLAGS--------------------------------------------------------- 13194 // 13195 // All peephole optimizations can be turned off using -XX:-OptoPeephole 13196 // 13197 // Each peephole rule is given an identifying number starting with zero and 13198 // increasing by one in the order seen by the parser. An individual peephole 13199 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 13200 // on the command-line. 13201 // 13202 // ---------CURRENT LIMITATIONS---------------------------------------------- 13203 // 13204 // Only match adjacent instructions in same basic block 13205 // Only equality constraints 13206 // Only constraints between operands, not (0.dest_reg == EAX_enc) 13207 // Only one replacement instruction 13208 // 13209 // ---------EXAMPLE---------------------------------------------------------- 13210 // 13211 // // pertinent parts of existing instructions in architecture description 13212 // instruct movI(eRegI dst, eRegI src) %{ 13213 // match(Set dst (CopyI src)); 13214 // %} 13215 // 13216 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{ 13217 // match(Set dst (AddI dst src)); 13218 // effect(KILL cr); 13219 // %} 13220 // 13221 // // Change (inc mov) to lea 13222 // peephole %{ 13223 // // increment preceeded by register-register move 13224 // peepmatch ( incI_eReg movI ); 13225 // // require that the destination register of the increment 13226 // // match the destination register of the move 13227 // peepconstraint ( 0.dst == 1.dst ); 13228 // // construct a replacement instruction that sets 13229 // // the destination to ( move's source register + one ) 13230 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 13231 // %} 13232 // 13233 // Implementation no longer uses movX instructions since 13234 // machine-independent system no longer uses CopyX nodes. 13235 // 13236 // peephole %{ 13237 // peepmatch ( incI_eReg movI ); 13238 // peepconstraint ( 0.dst == 1.dst ); 13239 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 13240 // %} 13241 // 13242 // peephole %{ 13243 // peepmatch ( decI_eReg movI ); 13244 // peepconstraint ( 0.dst == 1.dst ); 13245 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 13246 // %} 13247 // 13248 // peephole %{ 13249 // peepmatch ( addI_eReg_imm movI ); 13250 // peepconstraint ( 0.dst == 1.dst ); 13251 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 13252 // %} 13253 // 13254 // peephole %{ 13255 // peepmatch ( addP_eReg_imm movP ); 13256 // peepconstraint ( 0.dst == 1.dst ); 13257 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) ); 13258 // %} 13259 13260 // // Change load of spilled value to only a spill 13261 // instruct storeI(memory mem, eRegI src) %{ 13262 // match(Set mem (StoreI mem src)); 13263 // %} 13264 // 13265 // instruct loadI(eRegI dst, memory mem) %{ 13266 // match(Set dst (LoadI mem)); 13267 // %} 13268 // 13269 peephole %{ 13270 peepmatch ( loadI storeI ); 13271 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 13272 peepreplace ( storeI( 1.mem 1.mem 1.src ) ); 13273 %} 13274 13275 peephole %{ 13276 peepmatch ( loadL storeL ); 13277 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 13278 peepreplace ( storeL( 1.mem 1.mem 1.src ) ); 13279 %} 13280 13281 peephole %{ 13282 peepmatch ( loadP storeP ); 13283 peepconstraint ( 1.src == 0.dst, 1.dst == 0.mem ); 13284 peepreplace ( storeP( 1.dst 1.dst 1.src ) ); 13285 %} 13286 13287 //----------SMARTSPILL RULES--------------------------------------------------- 13288 // These must follow all instruction definitions as they use the names 13289 // defined in the instructions definitions.