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 R31, R31_H, 304 305 // scratch/special registers 306 R11, R11_H, 307 R12, R12_H, 308 309 // argument registers 310 R10, R10_H, 311 R9, R9_H, 312 R8, R8_H, 313 R7, R7_H, 314 R6, R6_H, 315 R5, R5_H, 316 R4, R4_H, 317 R3, R3_H, 318 319 // special registers, not available for allocation 320 R30, R30_H, // R30_zero 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,*/ // R30_zero 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,*/ // R30_zero 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,*/ // R30_zero 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,*/ // R30_zero 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,*/ // R30_zero 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,*/ // R30_zero 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 bool Matcher::const_oop_prefer_decode() { 2168 // Prefer ConN+DecodeN over ConP in simple compressed oops mode. 2169 return Universe::narrow_oop_base() == NULL; 2170 } 2171 2172 bool Matcher::const_klass_prefer_decode() { 2173 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 2174 return Universe::narrow_klass_base() == NULL; 2175 } 2176 2177 // Is it better to copy float constants, or load them directly from memory? 2178 // Intel can load a float constant from a direct address, requiring no 2179 // extra registers. Most RISCs will have to materialize an address into a 2180 // register first, so they would do better to copy the constant from stack. 2181 const bool Matcher::rematerialize_float_constants = false; 2182 2183 // If CPU can load and store mis-aligned doubles directly then no fixup is 2184 // needed. Else we split the double into 2 integer pieces and move it 2185 // piece-by-piece. Only happens when passing doubles into C code as the 2186 // Java calling convention forces doubles to be aligned. 2187 const bool Matcher::misaligned_doubles_ok = true; 2188 2189 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) { 2190 Unimplemented(); 2191 } 2192 2193 // Advertise here if the CPU requires explicit rounding operations 2194 // to implement the UseStrictFP mode. 2195 const bool Matcher::strict_fp_requires_explicit_rounding = false; 2196 2197 // Do floats take an entire double register or just half? 2198 // 2199 // A float occupies a ppc64 double register. For the allocator, a 2200 // ppc64 double register appears as a pair of float registers. 2201 bool Matcher::float_in_double() { return true; } 2202 2203 // Do ints take an entire long register or just half? 2204 // The relevant question is how the int is callee-saved: 2205 // the whole long is written but de-opt'ing will have to extract 2206 // the relevant 32 bits. 2207 const bool Matcher::int_in_long = true; 2208 2209 // Constants for c2c and c calling conventions. 2210 2211 const MachRegisterNumbers iarg_reg[8] = { 2212 R3_num, R4_num, R5_num, R6_num, 2213 R7_num, R8_num, R9_num, R10_num 2214 }; 2215 2216 const MachRegisterNumbers farg_reg[13] = { 2217 F1_num, F2_num, F3_num, F4_num, 2218 F5_num, F6_num, F7_num, F8_num, 2219 F9_num, F10_num, F11_num, F12_num, 2220 F13_num 2221 }; 2222 2223 const int num_iarg_registers = sizeof(iarg_reg) / sizeof(iarg_reg[0]); 2224 2225 const int num_farg_registers = sizeof(farg_reg) / sizeof(farg_reg[0]); 2226 2227 // Return whether or not this register is ever used as an argument. This 2228 // function is used on startup to build the trampoline stubs in generateOptoStub. 2229 // Registers not mentioned will be killed by the VM call in the trampoline, and 2230 // arguments in those registers not be available to the callee. 2231 bool Matcher::can_be_java_arg(int reg) { 2232 // We return true for all registers contained in iarg_reg[] and 2233 // farg_reg[] and their virtual halves. 2234 // We must include the virtual halves in order to get STDs and LDs 2235 // instead of STWs and LWs in the trampoline stubs. 2236 2237 if ( reg == R3_num || reg == R3_H_num 2238 || reg == R4_num || reg == R4_H_num 2239 || reg == R5_num || reg == R5_H_num 2240 || reg == R6_num || reg == R6_H_num 2241 || reg == R7_num || reg == R7_H_num 2242 || reg == R8_num || reg == R8_H_num 2243 || reg == R9_num || reg == R9_H_num 2244 || reg == R10_num || reg == R10_H_num) 2245 return true; 2246 2247 if ( reg == F1_num || reg == F1_H_num 2248 || reg == F2_num || reg == F2_H_num 2249 || reg == F3_num || reg == F3_H_num 2250 || reg == F4_num || reg == F4_H_num 2251 || reg == F5_num || reg == F5_H_num 2252 || reg == F6_num || reg == F6_H_num 2253 || reg == F7_num || reg == F7_H_num 2254 || reg == F8_num || reg == F8_H_num 2255 || reg == F9_num || reg == F9_H_num 2256 || reg == F10_num || reg == F10_H_num 2257 || reg == F11_num || reg == F11_H_num 2258 || reg == F12_num || reg == F12_H_num 2259 || reg == F13_num || reg == F13_H_num) 2260 return true; 2261 2262 return false; 2263 } 2264 2265 bool Matcher::is_spillable_arg(int reg) { 2266 return can_be_java_arg(reg); 2267 } 2268 2269 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2270 return false; 2271 } 2272 2273 // Register for DIVI projection of divmodI. 2274 RegMask Matcher::divI_proj_mask() { 2275 ShouldNotReachHere(); 2276 return RegMask(); 2277 } 2278 2279 // Register for MODI projection of divmodI. 2280 RegMask Matcher::modI_proj_mask() { 2281 ShouldNotReachHere(); 2282 return RegMask(); 2283 } 2284 2285 // Register for DIVL projection of divmodL. 2286 RegMask Matcher::divL_proj_mask() { 2287 ShouldNotReachHere(); 2288 return RegMask(); 2289 } 2290 2291 // Register for MODL projection of divmodL. 2292 RegMask Matcher::modL_proj_mask() { 2293 ShouldNotReachHere(); 2294 return RegMask(); 2295 } 2296 2297 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2298 return RegMask(); 2299 } 2300 2301 const bool Matcher::convi2l_type_required = true; 2302 2303 %} 2304 2305 //----------ENCODING BLOCK----------------------------------------------------- 2306 // This block specifies the encoding classes used by the compiler to output 2307 // byte streams. Encoding classes are parameterized macros used by 2308 // Machine Instruction Nodes in order to generate the bit encoding of the 2309 // instruction. Operands specify their base encoding interface with the 2310 // interface keyword. There are currently supported four interfaces, 2311 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an 2312 // operand to generate a function which returns its register number when 2313 // queried. CONST_INTER causes an operand to generate a function which 2314 // returns the value of the constant when queried. MEMORY_INTER causes an 2315 // operand to generate four functions which return the Base Register, the 2316 // Index Register, the Scale Value, and the Offset Value of the operand when 2317 // queried. COND_INTER causes an operand to generate six functions which 2318 // return the encoding code (ie - encoding bits for the instruction) 2319 // associated with each basic boolean condition for a conditional instruction. 2320 // 2321 // Instructions specify two basic values for encoding. Again, a function 2322 // is available to check if the constant displacement is an oop. They use the 2323 // ins_encode keyword to specify their encoding classes (which must be 2324 // a sequence of enc_class names, and their parameters, specified in 2325 // the encoding block), and they use the 2326 // opcode keyword to specify, in order, their primary, secondary, and 2327 // tertiary opcode. Only the opcode sections which a particular instruction 2328 // needs for encoding need to be specified. 2329 encode %{ 2330 enc_class enc_unimplemented %{ 2331 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2332 MacroAssembler _masm(&cbuf); 2333 __ unimplemented("Unimplemented mach node encoding in AD file.", 13); 2334 %} 2335 2336 enc_class enc_untested %{ 2337 #ifdef ASSERT 2338 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2339 MacroAssembler _masm(&cbuf); 2340 __ untested("Untested mach node encoding in AD file."); 2341 #else 2342 // TODO: PPC port $archOpcode(ppc64Opcode_none); 2343 #endif 2344 %} 2345 2346 enc_class enc_lbz(iRegIdst dst, memory mem) %{ 2347 // TODO: PPC port $archOpcode(ppc64Opcode_lbz); 2348 MacroAssembler _masm(&cbuf); 2349 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2350 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2351 %} 2352 2353 // Load acquire. 2354 enc_class enc_lbz_ac(iRegIdst dst, memory mem) %{ 2355 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2356 MacroAssembler _masm(&cbuf); 2357 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2358 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2359 __ twi_0($dst$$Register); 2360 __ isync(); 2361 %} 2362 2363 enc_class enc_lhz(iRegIdst dst, memory mem) %{ 2364 // TODO: PPC port $archOpcode(ppc64Opcode_lhz); 2365 2366 MacroAssembler _masm(&cbuf); 2367 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2368 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2369 %} 2370 2371 // Load acquire. 2372 enc_class enc_lhz_ac(iRegIdst dst, memory mem) %{ 2373 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2374 2375 MacroAssembler _masm(&cbuf); 2376 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2377 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2378 __ twi_0($dst$$Register); 2379 __ isync(); 2380 %} 2381 2382 enc_class enc_lwz(iRegIdst dst, memory mem) %{ 2383 // TODO: PPC port $archOpcode(ppc64Opcode_lwz); 2384 2385 MacroAssembler _masm(&cbuf); 2386 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2387 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2388 %} 2389 2390 // Load acquire. 2391 enc_class enc_lwz_ac(iRegIdst dst, memory mem) %{ 2392 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2393 2394 MacroAssembler _masm(&cbuf); 2395 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2396 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2397 __ twi_0($dst$$Register); 2398 __ isync(); 2399 %} 2400 2401 enc_class enc_ld(iRegLdst dst, memoryAlg4 mem) %{ 2402 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 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 %} 2409 2410 // Load acquire. 2411 enc_class enc_ld_ac(iRegLdst dst, memoryAlg4 mem) %{ 2412 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2413 MacroAssembler _masm(&cbuf); 2414 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2415 // Operand 'ds' requires 4-alignment. 2416 assert((Idisp & 0x3) == 0, "unaligned offset"); 2417 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2418 __ twi_0($dst$$Register); 2419 __ isync(); 2420 %} 2421 2422 enc_class enc_lfd(RegF dst, memory mem) %{ 2423 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 2424 MacroAssembler _masm(&cbuf); 2425 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2426 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 2427 %} 2428 2429 enc_class enc_load_long_constL(iRegLdst dst, immL src, iRegLdst toc) %{ 2430 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2431 2432 MacroAssembler _masm(&cbuf); 2433 int toc_offset = 0; 2434 2435 address const_toc_addr; 2436 // Create a non-oop constant, no relocation needed. 2437 // If it is an IC, it has a virtual_call_Relocation. 2438 const_toc_addr = __ long_constant((jlong)$src$$constant); 2439 if (const_toc_addr == NULL) { 2440 ciEnv::current()->record_out_of_memory_failure(); 2441 return; 2442 } 2443 2444 // Get the constant's TOC offset. 2445 toc_offset = __ offset_to_method_toc(const_toc_addr); 2446 2447 // Keep the current instruction offset in mind. 2448 ((loadConLNode*)this)->_cbuf_insts_offset = __ offset(); 2449 2450 __ ld($dst$$Register, toc_offset, $toc$$Register); 2451 %} 2452 2453 enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{ 2454 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 2455 2456 MacroAssembler _masm(&cbuf); 2457 2458 if (!ra_->C->in_scratch_emit_size()) { 2459 address const_toc_addr; 2460 // Create a non-oop constant, no relocation needed. 2461 // If it is an IC, it has a virtual_call_Relocation. 2462 const_toc_addr = __ long_constant((jlong)$src$$constant); 2463 if (const_toc_addr == NULL) { 2464 ciEnv::current()->record_out_of_memory_failure(); 2465 return; 2466 } 2467 2468 // Get the constant's TOC offset. 2469 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 2470 // Store the toc offset of the constant. 2471 ((loadConL_hiNode*)this)->_const_toc_offset = toc_offset; 2472 2473 // Also keep the current instruction offset in mind. 2474 ((loadConL_hiNode*)this)->_cbuf_insts_offset = __ offset(); 2475 } 2476 2477 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 2478 %} 2479 2480 %} // encode 2481 2482 source %{ 2483 2484 typedef struct { 2485 loadConL_hiNode *_large_hi; 2486 loadConL_loNode *_large_lo; 2487 loadConLNode *_small; 2488 MachNode *_last; 2489 } loadConLNodesTuple; 2490 2491 loadConLNodesTuple loadConLNodesTuple_create(PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2492 OptoReg::Name reg_second, OptoReg::Name reg_first) { 2493 loadConLNodesTuple nodes; 2494 2495 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2496 if (large_constant_pool) { 2497 // Create new nodes. 2498 loadConL_hiNode *m1 = new loadConL_hiNode(); 2499 loadConL_loNode *m2 = new loadConL_loNode(); 2500 2501 // inputs for new nodes 2502 m1->add_req(NULL, toc); 2503 m2->add_req(NULL, m1); 2504 2505 // operands for new nodes 2506 m1->_opnds[0] = new iRegLdstOper(); // dst 2507 m1->_opnds[1] = immSrc; // src 2508 m1->_opnds[2] = new iRegPdstOper(); // toc 2509 m2->_opnds[0] = new iRegLdstOper(); // dst 2510 m2->_opnds[1] = immSrc; // src 2511 m2->_opnds[2] = new iRegLdstOper(); // base 2512 2513 // Initialize ins_attrib TOC fields. 2514 m1->_const_toc_offset = -1; 2515 m2->_const_toc_offset_hi_node = m1; 2516 2517 // Initialize ins_attrib instruction offset. 2518 m1->_cbuf_insts_offset = -1; 2519 2520 // register allocation for new nodes 2521 ra_->set_pair(m1->_idx, reg_second, reg_first); 2522 ra_->set_pair(m2->_idx, reg_second, reg_first); 2523 2524 // Create result. 2525 nodes._large_hi = m1; 2526 nodes._large_lo = m2; 2527 nodes._small = NULL; 2528 nodes._last = nodes._large_lo; 2529 assert(m2->bottom_type()->isa_long(), "must be long"); 2530 } else { 2531 loadConLNode *m2 = new loadConLNode(); 2532 2533 // inputs for new nodes 2534 m2->add_req(NULL, toc); 2535 2536 // operands for new nodes 2537 m2->_opnds[0] = new iRegLdstOper(); // dst 2538 m2->_opnds[1] = immSrc; // src 2539 m2->_opnds[2] = new iRegPdstOper(); // toc 2540 2541 // Initialize ins_attrib instruction offset. 2542 m2->_cbuf_insts_offset = -1; 2543 2544 // register allocation for new nodes 2545 ra_->set_pair(m2->_idx, reg_second, reg_first); 2546 2547 // Create result. 2548 nodes._large_hi = NULL; 2549 nodes._large_lo = NULL; 2550 nodes._small = m2; 2551 nodes._last = nodes._small; 2552 assert(m2->bottom_type()->isa_long(), "must be long"); 2553 } 2554 2555 return nodes; 2556 } 2557 2558 %} // source 2559 2560 encode %{ 2561 // Postalloc expand emitter for loading a long constant from the method's TOC. 2562 // Enc_class needed as consttanttablebase is not supported by postalloc 2563 // expand. 2564 enc_class postalloc_expand_load_long_constant(iRegLdst dst, immL src, iRegLdst toc) %{ 2565 // Create new nodes. 2566 loadConLNodesTuple loadConLNodes = 2567 loadConLNodesTuple_create(ra_, n_toc, op_src, 2568 ra_->get_reg_second(this), ra_->get_reg_first(this)); 2569 2570 // Push new nodes. 2571 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 2572 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 2573 2574 // some asserts 2575 assert(nodes->length() >= 1, "must have created at least 1 node"); 2576 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 2577 %} 2578 2579 enc_class enc_load_long_constP(iRegLdst dst, immP src, iRegLdst toc) %{ 2580 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2581 2582 MacroAssembler _masm(&cbuf); 2583 int toc_offset = 0; 2584 2585 intptr_t val = $src$$constant; 2586 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 2587 address const_toc_addr; 2588 if (constant_reloc == relocInfo::oop_type) { 2589 // Create an oop constant and a corresponding relocation. 2590 AddressLiteral a = __ allocate_oop_address((jobject)val); 2591 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2592 __ relocate(a.rspec()); 2593 } else if (constant_reloc == relocInfo::metadata_type) { 2594 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 2595 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2596 __ relocate(a.rspec()); 2597 } else { 2598 // Create a non-oop constant, no relocation needed. 2599 const_toc_addr = __ long_constant((jlong)$src$$constant); 2600 } 2601 2602 if (const_toc_addr == NULL) { 2603 ciEnv::current()->record_out_of_memory_failure(); 2604 return; 2605 } 2606 // Get the constant's TOC offset. 2607 toc_offset = __ offset_to_method_toc(const_toc_addr); 2608 2609 __ ld($dst$$Register, toc_offset, $toc$$Register); 2610 %} 2611 2612 enc_class enc_load_long_constP_hi(iRegLdst dst, immP src, iRegLdst toc) %{ 2613 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 2614 2615 MacroAssembler _masm(&cbuf); 2616 if (!ra_->C->in_scratch_emit_size()) { 2617 intptr_t val = $src$$constant; 2618 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 2619 address const_toc_addr; 2620 if (constant_reloc == relocInfo::oop_type) { 2621 // Create an oop constant and a corresponding relocation. 2622 AddressLiteral a = __ allocate_oop_address((jobject)val); 2623 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2624 __ relocate(a.rspec()); 2625 } else if (constant_reloc == relocInfo::metadata_type) { 2626 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 2627 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2628 __ relocate(a.rspec()); 2629 } else { // non-oop pointers, e.g. card mark base, heap top 2630 // Create a non-oop constant, no relocation needed. 2631 const_toc_addr = __ long_constant((jlong)$src$$constant); 2632 } 2633 2634 if (const_toc_addr == NULL) { 2635 ciEnv::current()->record_out_of_memory_failure(); 2636 return; 2637 } 2638 // Get the constant's TOC offset. 2639 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 2640 // Store the toc offset of the constant. 2641 ((loadConP_hiNode*)this)->_const_toc_offset = toc_offset; 2642 } 2643 2644 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 2645 %} 2646 2647 // Postalloc expand emitter for loading a ptr constant from the method's TOC. 2648 // Enc_class needed as consttanttablebase is not supported by postalloc 2649 // expand. 2650 enc_class postalloc_expand_load_ptr_constant(iRegPdst dst, immP src, iRegLdst toc) %{ 2651 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2652 if (large_constant_pool) { 2653 // Create new nodes. 2654 loadConP_hiNode *m1 = new loadConP_hiNode(); 2655 loadConP_loNode *m2 = new loadConP_loNode(); 2656 2657 // inputs for new nodes 2658 m1->add_req(NULL, n_toc); 2659 m2->add_req(NULL, m1); 2660 2661 // operands for new nodes 2662 m1->_opnds[0] = new iRegPdstOper(); // dst 2663 m1->_opnds[1] = op_src; // src 2664 m1->_opnds[2] = new iRegPdstOper(); // toc 2665 m2->_opnds[0] = new iRegPdstOper(); // dst 2666 m2->_opnds[1] = op_src; // src 2667 m2->_opnds[2] = new iRegLdstOper(); // base 2668 2669 // Initialize ins_attrib TOC fields. 2670 m1->_const_toc_offset = -1; 2671 m2->_const_toc_offset_hi_node = m1; 2672 2673 // Register allocation for new nodes. 2674 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2675 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2676 2677 nodes->push(m1); 2678 nodes->push(m2); 2679 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 2680 } else { 2681 loadConPNode *m2 = new loadConPNode(); 2682 2683 // inputs for new nodes 2684 m2->add_req(NULL, n_toc); 2685 2686 // operands for new nodes 2687 m2->_opnds[0] = new iRegPdstOper(); // dst 2688 m2->_opnds[1] = op_src; // src 2689 m2->_opnds[2] = new iRegPdstOper(); // toc 2690 2691 // Register allocation for new nodes. 2692 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2693 2694 nodes->push(m2); 2695 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 2696 } 2697 %} 2698 2699 // Enc_class needed as consttanttablebase is not supported by postalloc 2700 // expand. 2701 enc_class postalloc_expand_load_float_constant(regF dst, immF src, iRegLdst toc) %{ 2702 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2703 2704 MachNode *m2; 2705 if (large_constant_pool) { 2706 m2 = new loadConFCompNode(); 2707 } else { 2708 m2 = new loadConFNode(); 2709 } 2710 // inputs for new nodes 2711 m2->add_req(NULL, n_toc); 2712 2713 // operands for new nodes 2714 m2->_opnds[0] = op_dst; 2715 m2->_opnds[1] = op_src; 2716 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 2717 2718 // register allocation for new nodes 2719 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2720 nodes->push(m2); 2721 %} 2722 2723 // Enc_class needed as consttanttablebase is not supported by postalloc 2724 // expand. 2725 enc_class postalloc_expand_load_double_constant(regD dst, immD src, iRegLdst toc) %{ 2726 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2727 2728 MachNode *m2; 2729 if (large_constant_pool) { 2730 m2 = new loadConDCompNode(); 2731 } else { 2732 m2 = new loadConDNode(); 2733 } 2734 // inputs for new nodes 2735 m2->add_req(NULL, n_toc); 2736 2737 // operands for new nodes 2738 m2->_opnds[0] = op_dst; 2739 m2->_opnds[1] = op_src; 2740 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 2741 2742 // register allocation for new nodes 2743 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2744 nodes->push(m2); 2745 %} 2746 2747 enc_class enc_stw(iRegIsrc src, memory mem) %{ 2748 // TODO: PPC port $archOpcode(ppc64Opcode_stw); 2749 MacroAssembler _masm(&cbuf); 2750 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2751 __ stw($src$$Register, Idisp, $mem$$base$$Register); 2752 %} 2753 2754 enc_class enc_std(iRegIsrc src, memoryAlg4 mem) %{ 2755 // TODO: PPC port $archOpcode(ppc64Opcode_std); 2756 MacroAssembler _masm(&cbuf); 2757 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2758 // Operand 'ds' requires 4-alignment. 2759 assert((Idisp & 0x3) == 0, "unaligned offset"); 2760 __ std($src$$Register, Idisp, $mem$$base$$Register); 2761 %} 2762 2763 enc_class enc_stfs(RegF src, memory mem) %{ 2764 // TODO: PPC port $archOpcode(ppc64Opcode_stfs); 2765 MacroAssembler _masm(&cbuf); 2766 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2767 __ stfs($src$$FloatRegister, Idisp, $mem$$base$$Register); 2768 %} 2769 2770 enc_class enc_stfd(RegF src, memory mem) %{ 2771 // TODO: PPC port $archOpcode(ppc64Opcode_stfd); 2772 MacroAssembler _masm(&cbuf); 2773 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2774 __ stfd($src$$FloatRegister, Idisp, $mem$$base$$Register); 2775 %} 2776 2777 // Use release_store for card-marking to ensure that previous 2778 // oop-stores are visible before the card-mark change. 2779 enc_class enc_cms_card_mark(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 2780 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2781 // FIXME: Implement this as a cmove and use a fixed condition code 2782 // register which is written on every transition to compiled code, 2783 // e.g. in call-stub and when returning from runtime stubs. 2784 // 2785 // Proposed code sequence for the cmove implementation: 2786 // 2787 // Label skip_release; 2788 // __ beq(CCRfixed, skip_release); 2789 // __ release(); 2790 // __ bind(skip_release); 2791 // __ stb(card mark); 2792 2793 MacroAssembler _masm(&cbuf); 2794 Label skip_storestore; 2795 2796 #if 0 // TODO: PPC port 2797 // Check CMSCollectorCardTableModRefBSExt::_requires_release and do the 2798 // StoreStore barrier conditionally. 2799 __ lwz(R0, 0, $releaseFieldAddr$$Register); 2800 __ cmpwi($crx$$CondRegister, R0, 0); 2801 __ beq_predict_taken($crx$$CondRegister, skip_storestore); 2802 #endif 2803 __ membar(Assembler::StoreStore); 2804 #if 0 // TODO: PPC port 2805 __ bind(skip_storestore); 2806 #endif 2807 2808 // Do the store. 2809 if ($mem$$index == 0) { 2810 __ stb(R30_zero, $mem$$disp, $mem$$base$$Register); 2811 } else { 2812 assert(0 == $mem$$disp, "no displacement possible with indexed load/stores on ppc"); 2813 __ stbx(R30_zero, $mem$$base$$Register, $mem$$index$$Register); 2814 } 2815 %} 2816 2817 enc_class postalloc_expand_encode_oop(iRegNdst dst, iRegPdst src, flagsReg crx) %{ 2818 2819 if (VM_Version::has_isel()) { 2820 // use isel instruction with Power 7 2821 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 2822 encodeP_subNode *n_sub_base = new encodeP_subNode(); 2823 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 2824 cond_set_0_oopNode *n_cond_set = new cond_set_0_oopNode(); 2825 2826 n_compare->add_req(n_region, n_src); 2827 n_compare->_opnds[0] = op_crx; 2828 n_compare->_opnds[1] = op_src; 2829 n_compare->_opnds[2] = new immL16Oper(0); 2830 2831 n_sub_base->add_req(n_region, n_src); 2832 n_sub_base->_opnds[0] = op_dst; 2833 n_sub_base->_opnds[1] = op_src; 2834 n_sub_base->_bottom_type = _bottom_type; 2835 2836 n_shift->add_req(n_region, n_sub_base); 2837 n_shift->_opnds[0] = op_dst; 2838 n_shift->_opnds[1] = op_dst; 2839 n_shift->_bottom_type = _bottom_type; 2840 2841 n_cond_set->add_req(n_region, n_compare, n_shift); 2842 n_cond_set->_opnds[0] = op_dst; 2843 n_cond_set->_opnds[1] = op_crx; 2844 n_cond_set->_opnds[2] = op_dst; 2845 n_cond_set->_bottom_type = _bottom_type; 2846 2847 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 2848 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2849 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2850 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2851 2852 nodes->push(n_compare); 2853 nodes->push(n_sub_base); 2854 nodes->push(n_shift); 2855 nodes->push(n_cond_set); 2856 2857 } else { 2858 // before Power 7 2859 moveRegNode *n_move = new moveRegNode(); 2860 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 2861 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 2862 cond_sub_baseNode *n_sub_base = new cond_sub_baseNode(); 2863 2864 n_move->add_req(n_region, n_src); 2865 n_move->_opnds[0] = op_dst; 2866 n_move->_opnds[1] = op_src; 2867 ra_->set_oop(n_move, true); // Until here, 'n_move' still produces an oop. 2868 2869 n_compare->add_req(n_region, n_src); 2870 n_compare->add_prec(n_move); 2871 2872 n_compare->_opnds[0] = op_crx; 2873 n_compare->_opnds[1] = op_src; 2874 n_compare->_opnds[2] = new immL16Oper(0); 2875 2876 n_sub_base->add_req(n_region, n_compare, n_src); 2877 n_sub_base->_opnds[0] = op_dst; 2878 n_sub_base->_opnds[1] = op_crx; 2879 n_sub_base->_opnds[2] = op_src; 2880 n_sub_base->_bottom_type = _bottom_type; 2881 2882 n_shift->add_req(n_region, n_sub_base); 2883 n_shift->_opnds[0] = op_dst; 2884 n_shift->_opnds[1] = op_dst; 2885 n_shift->_bottom_type = _bottom_type; 2886 2887 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2888 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 2889 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2890 ra_->set_pair(n_move->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2891 2892 nodes->push(n_move); 2893 nodes->push(n_compare); 2894 nodes->push(n_sub_base); 2895 nodes->push(n_shift); 2896 } 2897 2898 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 2899 %} 2900 2901 enc_class postalloc_expand_encode_oop_not_null(iRegNdst dst, iRegPdst src) %{ 2902 2903 encodeP_subNode *n1 = new encodeP_subNode(); 2904 n1->add_req(n_region, n_src); 2905 n1->_opnds[0] = op_dst; 2906 n1->_opnds[1] = op_src; 2907 n1->_bottom_type = _bottom_type; 2908 2909 encodeP_shiftNode *n2 = new encodeP_shiftNode(); 2910 n2->add_req(n_region, n1); 2911 n2->_opnds[0] = op_dst; 2912 n2->_opnds[1] = op_dst; 2913 n2->_bottom_type = _bottom_type; 2914 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2915 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2916 2917 nodes->push(n1); 2918 nodes->push(n2); 2919 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 2920 %} 2921 2922 enc_class postalloc_expand_decode_oop(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 2923 decodeN_shiftNode *n_shift = new decodeN_shiftNode(); 2924 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 2925 2926 n_compare->add_req(n_region, n_src); 2927 n_compare->_opnds[0] = op_crx; 2928 n_compare->_opnds[1] = op_src; 2929 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 2930 2931 n_shift->add_req(n_region, n_src); 2932 n_shift->_opnds[0] = op_dst; 2933 n_shift->_opnds[1] = op_src; 2934 n_shift->_bottom_type = _bottom_type; 2935 2936 if (VM_Version::has_isel()) { 2937 // use isel instruction with Power 7 2938 2939 decodeN_addNode *n_add_base = new decodeN_addNode(); 2940 n_add_base->add_req(n_region, n_shift); 2941 n_add_base->_opnds[0] = op_dst; 2942 n_add_base->_opnds[1] = op_dst; 2943 n_add_base->_bottom_type = _bottom_type; 2944 2945 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 2946 n_cond_set->add_req(n_region, n_compare, n_add_base); 2947 n_cond_set->_opnds[0] = op_dst; 2948 n_cond_set->_opnds[1] = op_crx; 2949 n_cond_set->_opnds[2] = op_dst; 2950 n_cond_set->_bottom_type = _bottom_type; 2951 2952 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 2953 ra_->set_oop(n_cond_set, true); 2954 2955 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2956 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 2957 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2958 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2959 2960 nodes->push(n_compare); 2961 nodes->push(n_shift); 2962 nodes->push(n_add_base); 2963 nodes->push(n_cond_set); 2964 2965 } else { 2966 // before Power 7 2967 cond_add_baseNode *n_add_base = new cond_add_baseNode(); 2968 2969 n_add_base->add_req(n_region, n_compare, n_shift); 2970 n_add_base->_opnds[0] = op_dst; 2971 n_add_base->_opnds[1] = op_crx; 2972 n_add_base->_opnds[2] = op_dst; 2973 n_add_base->_bottom_type = _bottom_type; 2974 2975 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 2976 ra_->set_oop(n_add_base, true); 2977 2978 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2979 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 2980 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2981 2982 nodes->push(n_compare); 2983 nodes->push(n_shift); 2984 nodes->push(n_add_base); 2985 } 2986 %} 2987 2988 enc_class postalloc_expand_decode_oop_not_null(iRegPdst dst, iRegNsrc src) %{ 2989 decodeN_shiftNode *n1 = new decodeN_shiftNode(); 2990 n1->add_req(n_region, n_src); 2991 n1->_opnds[0] = op_dst; 2992 n1->_opnds[1] = op_src; 2993 n1->_bottom_type = _bottom_type; 2994 2995 decodeN_addNode *n2 = new decodeN_addNode(); 2996 n2->add_req(n_region, n1); 2997 n2->_opnds[0] = op_dst; 2998 n2->_opnds[1] = op_dst; 2999 n2->_bottom_type = _bottom_type; 3000 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3001 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3002 3003 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3004 ra_->set_oop(n2, true); 3005 3006 nodes->push(n1); 3007 nodes->push(n2); 3008 %} 3009 3010 enc_class enc_cmove_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src, cmpOp cmp) %{ 3011 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3012 3013 MacroAssembler _masm(&cbuf); 3014 int cc = $cmp$$cmpcode; 3015 int flags_reg = $crx$$reg; 3016 Label done; 3017 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3018 // Branch if not (cmp crx). 3019 __ bc(cc_to_inverse_boint(cc), cc_to_biint(cc, flags_reg), done); 3020 __ mr($dst$$Register, $src$$Register); 3021 // TODO PPC port __ endgroup_if_needed(_size == 12); 3022 __ bind(done); 3023 %} 3024 3025 enc_class enc_cmove_imm(iRegIdst dst, flagsRegSrc crx, immI16 src, cmpOp cmp) %{ 3026 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3027 3028 MacroAssembler _masm(&cbuf); 3029 Label done; 3030 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3031 // Branch if not (cmp crx). 3032 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 3033 __ li($dst$$Register, $src$$constant); 3034 // TODO PPC port __ endgroup_if_needed(_size == 12); 3035 __ bind(done); 3036 %} 3037 3038 // This enc_class is needed so that scheduler gets proper 3039 // input mapping for latency computation. 3040 enc_class enc_andc(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 3041 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 3042 MacroAssembler _masm(&cbuf); 3043 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 3044 %} 3045 3046 enc_class enc_convI2B_regI__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3047 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3048 3049 MacroAssembler _masm(&cbuf); 3050 3051 Label done; 3052 __ cmpwi($crx$$CondRegister, $src$$Register, 0); 3053 __ li($dst$$Register, $zero$$constant); 3054 __ beq($crx$$CondRegister, done); 3055 __ li($dst$$Register, $notzero$$constant); 3056 __ bind(done); 3057 %} 3058 3059 enc_class enc_convP2B_regP__cmove(iRegIdst dst, iRegPsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3060 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3061 3062 MacroAssembler _masm(&cbuf); 3063 3064 Label done; 3065 __ cmpdi($crx$$CondRegister, $src$$Register, 0); 3066 __ li($dst$$Register, $zero$$constant); 3067 __ beq($crx$$CondRegister, done); 3068 __ li($dst$$Register, $notzero$$constant); 3069 __ bind(done); 3070 %} 3071 3072 enc_class enc_cmove_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL mem ) %{ 3073 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3074 3075 MacroAssembler _masm(&cbuf); 3076 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3077 Label done; 3078 __ bso($crx$$CondRegister, done); 3079 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 3080 // TODO PPC port __ endgroup_if_needed(_size == 12); 3081 __ bind(done); 3082 %} 3083 3084 enc_class enc_bc(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3085 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3086 3087 MacroAssembler _masm(&cbuf); 3088 Label d; // dummy 3089 __ bind(d); 3090 Label* p = ($lbl$$label); 3091 // `p' is `NULL' when this encoding class is used only to 3092 // determine the size of the encoded instruction. 3093 Label& l = (NULL == p)? d : *(p); 3094 int cc = $cmp$$cmpcode; 3095 int flags_reg = $crx$$reg; 3096 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3097 int bhint = Assembler::bhintNoHint; 3098 3099 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3100 if (_prob <= PROB_NEVER) { 3101 bhint = Assembler::bhintIsNotTaken; 3102 } else if (_prob >= PROB_ALWAYS) { 3103 bhint = Assembler::bhintIsTaken; 3104 } 3105 } 3106 3107 __ bc(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3108 cc_to_biint(cc, flags_reg), 3109 l); 3110 %} 3111 3112 enc_class enc_bc_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3113 // The scheduler doesn't know about branch shortening, so we set the opcode 3114 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3115 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3116 3117 MacroAssembler _masm(&cbuf); 3118 Label d; // dummy 3119 __ bind(d); 3120 Label* p = ($lbl$$label); 3121 // `p' is `NULL' when this encoding class is used only to 3122 // determine the size of the encoded instruction. 3123 Label& l = (NULL == p)? d : *(p); 3124 int cc = $cmp$$cmpcode; 3125 int flags_reg = $crx$$reg; 3126 int bhint = Assembler::bhintNoHint; 3127 3128 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3129 if (_prob <= PROB_NEVER) { 3130 bhint = Assembler::bhintIsNotTaken; 3131 } else if (_prob >= PROB_ALWAYS) { 3132 bhint = Assembler::bhintIsTaken; 3133 } 3134 } 3135 3136 // Tell the conditional far branch to optimize itself when being relocated. 3137 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3138 cc_to_biint(cc, flags_reg), 3139 l, 3140 MacroAssembler::bc_far_optimize_on_relocate); 3141 %} 3142 3143 // Branch used with Power6 scheduling (can be shortened without changing the node). 3144 enc_class enc_bc_short_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3145 // The scheduler doesn't know about branch shortening, so we set the opcode 3146 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3147 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3148 3149 MacroAssembler _masm(&cbuf); 3150 Label d; // dummy 3151 __ bind(d); 3152 Label* p = ($lbl$$label); 3153 // `p' is `NULL' when this encoding class is used only to 3154 // determine the size of the encoded instruction. 3155 Label& l = (NULL == p)? d : *(p); 3156 int cc = $cmp$$cmpcode; 3157 int flags_reg = $crx$$reg; 3158 int bhint = Assembler::bhintNoHint; 3159 3160 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3161 if (_prob <= PROB_NEVER) { 3162 bhint = Assembler::bhintIsNotTaken; 3163 } else if (_prob >= PROB_ALWAYS) { 3164 bhint = Assembler::bhintIsTaken; 3165 } 3166 } 3167 3168 #if 0 // TODO: PPC port 3169 if (_size == 8) { 3170 // Tell the conditional far branch to optimize itself when being relocated. 3171 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3172 cc_to_biint(cc, flags_reg), 3173 l, 3174 MacroAssembler::bc_far_optimize_on_relocate); 3175 } else { 3176 __ bc (Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3177 cc_to_biint(cc, flags_reg), 3178 l); 3179 } 3180 #endif 3181 Unimplemented(); 3182 %} 3183 3184 // Postalloc expand emitter for loading a replicatef float constant from 3185 // the method's TOC. 3186 // Enc_class needed as consttanttablebase is not supported by postalloc 3187 // expand. 3188 enc_class postalloc_expand_load_replF_constant(iRegLdst dst, immF src, iRegLdst toc) %{ 3189 // Create new nodes. 3190 3191 // Make an operand with the bit pattern to load as float. 3192 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3193 3194 loadConLNodesTuple loadConLNodes = 3195 loadConLNodesTuple_create(ra_, n_toc, op_repl, 3196 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3197 3198 // Push new nodes. 3199 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 3200 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 3201 3202 assert(nodes->length() >= 1, "must have created at least 1 node"); 3203 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 3204 %} 3205 3206 // This enc_class is needed so that scheduler gets proper 3207 // input mapping for latency computation. 3208 enc_class enc_poll(immI dst, iRegLdst poll) %{ 3209 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 3210 // Fake operand dst needed for PPC scheduler. 3211 assert($dst$$constant == 0x0, "dst must be 0x0"); 3212 3213 MacroAssembler _masm(&cbuf); 3214 // Mark the code position where the load from the safepoint 3215 // polling page was emitted as relocInfo::poll_type. 3216 __ relocate(relocInfo::poll_type); 3217 __ load_from_polling_page($poll$$Register); 3218 %} 3219 3220 // A Java static call or a runtime call. 3221 // 3222 // Branch-and-link relative to a trampoline. 3223 // The trampoline loads the target address and does a long branch to there. 3224 // In case we call java, the trampoline branches to a interpreter_stub 3225 // which loads the inline cache and the real call target from the constant pool. 3226 // 3227 // This basically looks like this: 3228 // 3229 // >>>> consts -+ -+ 3230 // | |- offset1 3231 // [call target1] | <-+ 3232 // [IC cache] |- offset2 3233 // [call target2] <--+ 3234 // 3235 // <<<< consts 3236 // >>>> insts 3237 // 3238 // bl offset16 -+ -+ ??? // How many bits available? 3239 // | | 3240 // <<<< insts | | 3241 // >>>> stubs | | 3242 // | |- trampoline_stub_Reloc 3243 // trampoline stub: | <-+ 3244 // r2 = toc | 3245 // r2 = [r2 + offset1] | // Load call target1 from const section 3246 // mtctr r2 | 3247 // bctr |- static_stub_Reloc 3248 // comp_to_interp_stub: <---+ 3249 // r1 = toc 3250 // ICreg = [r1 + IC_offset] // Load IC from const section 3251 // r1 = [r1 + offset2] // Load call target2 from const section 3252 // mtctr r1 3253 // bctr 3254 // 3255 // <<<< stubs 3256 // 3257 // The call instruction in the code either 3258 // - Branches directly to a compiled method if the offset is encodable in instruction. 3259 // - Branches to the trampoline stub if the offset to the compiled method is not encodable. 3260 // - Branches to the compiled_to_interp stub if the target is interpreted. 3261 // 3262 // Further there are three relocations from the loads to the constants in 3263 // the constant section. 3264 // 3265 // Usage of r1 and r2 in the stubs allows to distinguish them. 3266 enc_class enc_java_static_call(method meth) %{ 3267 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3268 3269 MacroAssembler _masm(&cbuf); 3270 address entry_point = (address)$meth$$method; 3271 3272 if (!_method) { 3273 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3274 emit_call_with_trampoline_stub(_masm, entry_point, relocInfo::runtime_call_type); 3275 } else { 3276 // Remember the offset not the address. 3277 const int start_offset = __ offset(); 3278 3279 // The trampoline stub. 3280 // No entry point given, use the current pc. 3281 // Make sure branch fits into 3282 if (entry_point == 0) entry_point = __ pc(); 3283 3284 // Put the entry point as a constant into the constant pool. 3285 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 3286 if (entry_point_toc_addr == NULL) { 3287 ciEnv::current()->record_out_of_memory_failure(); 3288 return; 3289 } 3290 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 3291 3292 // Emit the trampoline stub which will be related to the branch-and-link below. 3293 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset); 3294 if (ciEnv::current()->failing()) { return; } // Code cache may be full. 3295 int method_index = resolved_method_index(cbuf); 3296 __ relocate(_optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 3297 : static_call_Relocation::spec(method_index)); 3298 3299 // The real call. 3300 // Note: At this point we do not have the address of the trampoline 3301 // stub, and the entry point might be too far away for bl, so __ pc() 3302 // serves as dummy and the bl will be patched later. 3303 cbuf.set_insts_mark(); 3304 __ bl(__ pc()); // Emits a relocation. 3305 3306 // The stub for call to interpreter. 3307 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); 3308 if (stub == NULL) { 3309 ciEnv::current()->record_failure("CodeCache is full"); 3310 return; 3311 } 3312 } 3313 %} 3314 3315 // Second node of expanded dynamic call - the call. 3316 enc_class enc_java_dynamic_call_sched(method meth) %{ 3317 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3318 3319 MacroAssembler _masm(&cbuf); 3320 3321 if (!ra_->C->in_scratch_emit_size()) { 3322 // Create a call trampoline stub for the given method. 3323 const address entry_point = !($meth$$method) ? 0 : (address)$meth$$method; 3324 const address entry_point_const = __ address_constant(entry_point, RelocationHolder::none); 3325 if (entry_point_const == NULL) { 3326 ciEnv::current()->record_out_of_memory_failure(); 3327 return; 3328 } 3329 const int entry_point_const_toc_offset = __ offset_to_method_toc(entry_point_const); 3330 CallStubImpl::emit_trampoline_stub(_masm, entry_point_const_toc_offset, __ offset()); 3331 if (ra_->C->env()->failing()) { return; } // Code cache may be full. 3332 3333 // Build relocation at call site with ic position as data. 3334 assert((_load_ic_hi_node != NULL && _load_ic_node == NULL) || 3335 (_load_ic_hi_node == NULL && _load_ic_node != NULL), 3336 "must have one, but can't have both"); 3337 assert((_load_ic_hi_node != NULL && _load_ic_hi_node->_cbuf_insts_offset != -1) || 3338 (_load_ic_node != NULL && _load_ic_node->_cbuf_insts_offset != -1), 3339 "must contain instruction offset"); 3340 const int virtual_call_oop_addr_offset = _load_ic_hi_node != NULL 3341 ? _load_ic_hi_node->_cbuf_insts_offset 3342 : _load_ic_node->_cbuf_insts_offset; 3343 const address virtual_call_oop_addr = __ addr_at(virtual_call_oop_addr_offset); 3344 assert(MacroAssembler::is_load_const_from_method_toc_at(virtual_call_oop_addr), 3345 "should be load from TOC"); 3346 int method_index = resolved_method_index(cbuf); 3347 __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr, method_index)); 3348 } 3349 3350 // At this point I do not have the address of the trampoline stub, 3351 // and the entry point might be too far away for bl. Pc() serves 3352 // as dummy and bl will be patched later. 3353 __ bl((address) __ pc()); 3354 %} 3355 3356 // postalloc expand emitter for virtual calls. 3357 enc_class postalloc_expand_java_dynamic_call_sched(method meth, iRegLdst toc) %{ 3358 3359 // Create the nodes for loading the IC from the TOC. 3360 loadConLNodesTuple loadConLNodes_IC = 3361 loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong)Universe::non_oop_word()), 3362 OptoReg::Name(R19_H_num), OptoReg::Name(R19_num)); 3363 3364 // Create the call node. 3365 CallDynamicJavaDirectSchedNode *call = new CallDynamicJavaDirectSchedNode(); 3366 call->_method_handle_invoke = _method_handle_invoke; 3367 call->_vtable_index = _vtable_index; 3368 call->_method = _method; 3369 call->_bci = _bci; 3370 call->_optimized_virtual = _optimized_virtual; 3371 call->_tf = _tf; 3372 call->_entry_point = _entry_point; 3373 call->_cnt = _cnt; 3374 call->_argsize = _argsize; 3375 call->_oop_map = _oop_map; 3376 call->_jvms = _jvms; 3377 call->_jvmadj = _jvmadj; 3378 call->_in_rms = _in_rms; 3379 call->_nesting = _nesting; 3380 call->_override_symbolic_info = _override_symbolic_info; 3381 3382 // New call needs all inputs of old call. 3383 // Req... 3384 for (uint i = 0; i < req(); ++i) { 3385 // The expanded node does not need toc any more. 3386 // Add the inline cache constant here instead. This expresses the 3387 // register of the inline cache must be live at the call. 3388 // Else we would have to adapt JVMState by -1. 3389 if (i == mach_constant_base_node_input()) { 3390 call->add_req(loadConLNodes_IC._last); 3391 } else { 3392 call->add_req(in(i)); 3393 } 3394 } 3395 // ...as well as prec 3396 for (uint i = req(); i < len(); ++i) { 3397 call->add_prec(in(i)); 3398 } 3399 3400 // Remember nodes loading the inline cache into r19. 3401 call->_load_ic_hi_node = loadConLNodes_IC._large_hi; 3402 call->_load_ic_node = loadConLNodes_IC._small; 3403 3404 // Operands for new nodes. 3405 call->_opnds[0] = _opnds[0]; 3406 call->_opnds[1] = _opnds[1]; 3407 3408 // Only the inline cache is associated with a register. 3409 assert(Matcher::inline_cache_reg() == OptoReg::Name(R19_num), "ic reg should be R19"); 3410 3411 // Push new nodes. 3412 if (loadConLNodes_IC._large_hi) nodes->push(loadConLNodes_IC._large_hi); 3413 if (loadConLNodes_IC._last) nodes->push(loadConLNodes_IC._last); 3414 nodes->push(call); 3415 %} 3416 3417 // Compound version of call dynamic 3418 // Toc is only passed so that it can be used in ins_encode statement. 3419 // In the code we have to use $constanttablebase. 3420 enc_class enc_java_dynamic_call(method meth, iRegLdst toc) %{ 3421 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3422 MacroAssembler _masm(&cbuf); 3423 int start_offset = __ offset(); 3424 3425 Register Rtoc = (ra_) ? $constanttablebase : R2_TOC; 3426 #if 0 3427 int vtable_index = this->_vtable_index; 3428 if (_vtable_index < 0) { 3429 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 3430 assert(_vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 3431 Register ic_reg = as_Register(Matcher::inline_cache_reg_encode()); 3432 3433 // Virtual call relocation will point to ic load. 3434 address virtual_call_meta_addr = __ pc(); 3435 // Load a clear inline cache. 3436 AddressLiteral empty_ic((address) Universe::non_oop_word()); 3437 bool success = __ load_const_from_method_toc(ic_reg, empty_ic, Rtoc, /*fixed_size*/ true); 3438 if (!success) { 3439 ciEnv::current()->record_out_of_memory_failure(); 3440 return; 3441 } 3442 // CALL to fixup routine. Fixup routine uses ScopeDesc info 3443 // to determine who we intended to call. 3444 __ relocate(virtual_call_Relocation::spec(virtual_call_meta_addr)); 3445 emit_call_with_trampoline_stub(_masm, (address)$meth$$method, relocInfo::none); 3446 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3447 "Fix constant in ret_addr_offset()"); 3448 } else { 3449 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 3450 // Go thru the vtable. Get receiver klass. Receiver already 3451 // checked for non-null. If we'll go thru a C2I adapter, the 3452 // interpreter expects method in R19_method. 3453 3454 __ load_klass(R11_scratch1, R3); 3455 3456 int entry_offset = in_bytes(Klass::vtable_start_offset()) + _vtable_index * vtableEntry::size_in_bytes(); 3457 int v_off = entry_offset + vtableEntry::method_offset_in_bytes(); 3458 __ li(R19_method, v_off); 3459 __ ldx(R19_method/*method oop*/, R19_method/*method offset*/, R11_scratch1/*class*/); 3460 // NOTE: for vtable dispatches, the vtable entry will never be 3461 // null. However it may very well end up in handle_wrong_method 3462 // if the method is abstract for the particular class. 3463 __ ld(R11_scratch1, in_bytes(Method::from_compiled_offset()), R19_method); 3464 // Call target. Either compiled code or C2I adapter. 3465 __ mtctr(R11_scratch1); 3466 __ bctrl(); 3467 if (((MachCallDynamicJavaNode*)this)->ret_addr_offset() != __ offset() - start_offset) { 3468 tty->print(" %d, %d\n", ((MachCallDynamicJavaNode*)this)->ret_addr_offset(),__ offset() - start_offset); 3469 } 3470 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3471 "Fix constant in ret_addr_offset()"); 3472 } 3473 #endif 3474 Unimplemented(); // ret_addr_offset not yet fixed. Depends on compressed oops (load klass!). 3475 %} 3476 3477 // a runtime call 3478 enc_class enc_java_to_runtime_call (method meth) %{ 3479 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3480 3481 MacroAssembler _masm(&cbuf); 3482 const address start_pc = __ pc(); 3483 3484 #if defined(ABI_ELFv2) 3485 address entry= !($meth$$method) ? NULL : (address)$meth$$method; 3486 __ call_c(entry, relocInfo::runtime_call_type); 3487 #else 3488 // The function we're going to call. 3489 FunctionDescriptor fdtemp; 3490 const FunctionDescriptor* fd = !($meth$$method) ? &fdtemp : (FunctionDescriptor*)$meth$$method; 3491 3492 Register Rtoc = R12_scratch2; 3493 // Calculate the method's TOC. 3494 __ calculate_address_from_global_toc(Rtoc, __ method_toc()); 3495 // Put entry, env, toc into the constant pool, this needs up to 3 constant 3496 // pool entries; call_c_using_toc will optimize the call. 3497 bool success = __ call_c_using_toc(fd, relocInfo::runtime_call_type, Rtoc); 3498 if (!success) { 3499 ciEnv::current()->record_out_of_memory_failure(); 3500 return; 3501 } 3502 #endif 3503 3504 // Check the ret_addr_offset. 3505 assert(((MachCallRuntimeNode*)this)->ret_addr_offset() == __ last_calls_return_pc() - start_pc, 3506 "Fix constant in ret_addr_offset()"); 3507 %} 3508 3509 // Move to ctr for leaf call. 3510 // This enc_class is needed so that scheduler gets proper 3511 // input mapping for latency computation. 3512 enc_class enc_leaf_call_mtctr(iRegLsrc src) %{ 3513 // TODO: PPC port $archOpcode(ppc64Opcode_mtctr); 3514 MacroAssembler _masm(&cbuf); 3515 __ mtctr($src$$Register); 3516 %} 3517 3518 // Postalloc expand emitter for runtime leaf calls. 3519 enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{ 3520 loadConLNodesTuple loadConLNodes_Entry; 3521 #if defined(ABI_ELFv2) 3522 jlong entry_address = (jlong) this->entry_point(); 3523 assert(entry_address, "need address here"); 3524 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3525 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3526 #else 3527 // Get the struct that describes the function we are about to call. 3528 FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point(); 3529 assert(fd, "need fd here"); 3530 jlong entry_address = (jlong) fd->entry(); 3531 // new nodes 3532 loadConLNodesTuple loadConLNodes_Env; 3533 loadConLNodesTuple loadConLNodes_Toc; 3534 3535 // Create nodes and operands for loading the entry point. 3536 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3537 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3538 3539 3540 // Create nodes and operands for loading the env pointer. 3541 if (fd->env() != NULL) { 3542 loadConLNodes_Env = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->env()), 3543 OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3544 } else { 3545 loadConLNodes_Env._large_hi = NULL; 3546 loadConLNodes_Env._large_lo = NULL; 3547 loadConLNodes_Env._small = NULL; 3548 loadConLNodes_Env._last = new loadConL16Node(); 3549 loadConLNodes_Env._last->_opnds[0] = new iRegLdstOper(); 3550 loadConLNodes_Env._last->_opnds[1] = new immL16Oper(0); 3551 ra_->set_pair(loadConLNodes_Env._last->_idx, OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3552 } 3553 3554 // Create nodes and operands for loading the Toc point. 3555 loadConLNodes_Toc = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->toc()), 3556 OptoReg::Name(R2_H_num), OptoReg::Name(R2_num)); 3557 #endif // ABI_ELFv2 3558 // mtctr node 3559 MachNode *mtctr = new CallLeafDirect_mtctrNode(); 3560 3561 assert(loadConLNodes_Entry._last != NULL, "entry must exist"); 3562 mtctr->add_req(0, loadConLNodes_Entry._last); 3563 3564 mtctr->_opnds[0] = new iRegLdstOper(); 3565 mtctr->_opnds[1] = new iRegLdstOper(); 3566 3567 // call node 3568 MachCallLeafNode *call = new CallLeafDirectNode(); 3569 3570 call->_opnds[0] = _opnds[0]; 3571 call->_opnds[1] = new methodOper((intptr_t) entry_address); // May get set later. 3572 3573 // Make the new call node look like the old one. 3574 call->_name = _name; 3575 call->_tf = _tf; 3576 call->_entry_point = _entry_point; 3577 call->_cnt = _cnt; 3578 call->_argsize = _argsize; 3579 call->_oop_map = _oop_map; 3580 guarantee(!_jvms, "You must clone the jvms and adapt the offsets by fix_jvms()."); 3581 call->_jvms = NULL; 3582 call->_jvmadj = _jvmadj; 3583 call->_in_rms = _in_rms; 3584 call->_nesting = _nesting; 3585 3586 3587 // New call needs all inputs of old call. 3588 // Req... 3589 for (uint i = 0; i < req(); ++i) { 3590 if (i != mach_constant_base_node_input()) { 3591 call->add_req(in(i)); 3592 } 3593 } 3594 3595 // These must be reqired edges, as the registers are live up to 3596 // the call. Else the constants are handled as kills. 3597 call->add_req(mtctr); 3598 #if !defined(ABI_ELFv2) 3599 call->add_req(loadConLNodes_Env._last); 3600 call->add_req(loadConLNodes_Toc._last); 3601 #endif 3602 3603 // ...as well as prec 3604 for (uint i = req(); i < len(); ++i) { 3605 call->add_prec(in(i)); 3606 } 3607 3608 // registers 3609 ra_->set1(mtctr->_idx, OptoReg::Name(SR_CTR_num)); 3610 3611 // Insert the new nodes. 3612 if (loadConLNodes_Entry._large_hi) nodes->push(loadConLNodes_Entry._large_hi); 3613 if (loadConLNodes_Entry._last) nodes->push(loadConLNodes_Entry._last); 3614 #if !defined(ABI_ELFv2) 3615 if (loadConLNodes_Env._large_hi) nodes->push(loadConLNodes_Env._large_hi); 3616 if (loadConLNodes_Env._last) nodes->push(loadConLNodes_Env._last); 3617 if (loadConLNodes_Toc._large_hi) nodes->push(loadConLNodes_Toc._large_hi); 3618 if (loadConLNodes_Toc._last) nodes->push(loadConLNodes_Toc._last); 3619 #endif 3620 nodes->push(mtctr); 3621 nodes->push(call); 3622 %} 3623 %} 3624 3625 //----------FRAME-------------------------------------------------------------- 3626 // Definition of frame structure and management information. 3627 3628 frame %{ 3629 // What direction does stack grow in (assumed to be same for native & Java). 3630 stack_direction(TOWARDS_LOW); 3631 3632 // These two registers define part of the calling convention between 3633 // compiled code and the interpreter. 3634 3635 // Inline Cache Register or method for I2C. 3636 inline_cache_reg(R19); // R19_method 3637 3638 // Method Oop Register when calling interpreter. 3639 interpreter_method_oop_reg(R19); // R19_method 3640 3641 // Optional: name the operand used by cisc-spilling to access 3642 // [stack_pointer + offset]. 3643 cisc_spilling_operand_name(indOffset); 3644 3645 // Number of stack slots consumed by a Monitor enter. 3646 sync_stack_slots((frame::jit_monitor_size / VMRegImpl::stack_slot_size)); 3647 3648 // Compiled code's Frame Pointer. 3649 frame_pointer(R1); // R1_SP 3650 3651 // Interpreter stores its frame pointer in a register which is 3652 // stored to the stack by I2CAdaptors. I2CAdaptors convert from 3653 // interpreted java to compiled java. 3654 // 3655 // R14_state holds pointer to caller's cInterpreter. 3656 interpreter_frame_pointer(R14); // R14_state 3657 3658 stack_alignment(frame::alignment_in_bytes); 3659 3660 in_preserve_stack_slots((frame::jit_in_preserve_size / VMRegImpl::stack_slot_size)); 3661 3662 // Number of outgoing stack slots killed above the 3663 // out_preserve_stack_slots for calls to C. Supports the var-args 3664 // backing area for register parms. 3665 // 3666 varargs_C_out_slots_killed(((frame::abi_reg_args_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size)); 3667 3668 // The after-PROLOG location of the return address. Location of 3669 // return address specifies a type (REG or STACK) and a number 3670 // representing the register number (i.e. - use a register name) or 3671 // stack slot. 3672 // 3673 // A: Link register is stored in stack slot ... 3674 // M: ... but it's in the caller's frame according to PPC-64 ABI. 3675 // J: Therefore, we make sure that the link register is also in R11_scratch1 3676 // at the end of the prolog. 3677 // B: We use R20, now. 3678 //return_addr(REG R20); 3679 3680 // G: After reading the comments made by all the luminaries on their 3681 // failure to tell the compiler where the return address really is, 3682 // I hardly dare to try myself. However, I'm convinced it's in slot 3683 // 4 what apparently works and saves us some spills. 3684 return_addr(STACK 4); 3685 3686 // This is the body of the function 3687 // 3688 // void Matcher::calling_convention(OptoRegPair* sig, // array of ideal regs 3689 // uint length, // length of array 3690 // bool is_outgoing) 3691 // 3692 // The `sig' array is to be updated. sig[j] represents the location 3693 // of the j-th argument, either a register or a stack slot. 3694 3695 // Comment taken from i486.ad: 3696 // Body of function which returns an integer array locating 3697 // arguments either in registers or in stack slots. Passed an array 3698 // of ideal registers called "sig" and a "length" count. Stack-slot 3699 // offsets are based on outgoing arguments, i.e. a CALLER setting up 3700 // arguments for a CALLEE. Incoming stack arguments are 3701 // automatically biased by the preserve_stack_slots field above. 3702 calling_convention %{ 3703 // No difference between ingoing/outgoing. Just pass false. 3704 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 3705 %} 3706 3707 // Comment taken from i486.ad: 3708 // Body of function which returns an integer array locating 3709 // arguments either in registers or in stack slots. Passed an array 3710 // of ideal registers called "sig" and a "length" count. Stack-slot 3711 // offsets are based on outgoing arguments, i.e. a CALLER setting up 3712 // arguments for a CALLEE. Incoming stack arguments are 3713 // automatically biased by the preserve_stack_slots field above. 3714 c_calling_convention %{ 3715 // This is obviously always outgoing. 3716 // C argument in register AND stack slot. 3717 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 3718 %} 3719 3720 // Location of native (C/C++) and interpreter return values. This 3721 // is specified to be the same as Java. In the 32-bit VM, long 3722 // values are actually returned from native calls in O0:O1 and 3723 // returned to the interpreter in I0:I1. The copying to and from 3724 // the register pairs is done by the appropriate call and epilog 3725 // opcodes. This simplifies the register allocator. 3726 c_return_value %{ 3727 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 3728 (ideal_reg == Op_RegN && Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0), 3729 "only return normal values"); 3730 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 3731 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 3732 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 3733 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 3734 %} 3735 3736 // Location of compiled Java return values. Same as C 3737 return_value %{ 3738 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 3739 (ideal_reg == Op_RegN && Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0), 3740 "only return normal values"); 3741 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 3742 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 3743 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 3744 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 3745 %} 3746 %} 3747 3748 3749 //----------ATTRIBUTES--------------------------------------------------------- 3750 3751 //----------Operand Attributes------------------------------------------------- 3752 op_attrib op_cost(1); // Required cost attribute. 3753 3754 //----------Instruction Attributes--------------------------------------------- 3755 3756 // Cost attribute. required. 3757 ins_attrib ins_cost(DEFAULT_COST); 3758 3759 // Is this instruction a non-matching short branch variant of some 3760 // long branch? Not required. 3761 ins_attrib ins_short_branch(0); 3762 3763 ins_attrib ins_is_TrapBasedCheckNode(true); 3764 3765 // Number of constants. 3766 // This instruction uses the given number of constants 3767 // (optional attribute). 3768 // This is needed to determine in time whether the constant pool will 3769 // exceed 4000 entries. Before postalloc_expand the overall number of constants 3770 // is determined. It's also used to compute the constant pool size 3771 // in Output(). 3772 ins_attrib ins_num_consts(0); 3773 3774 // Required alignment attribute (must be a power of 2) specifies the 3775 // alignment that some part of the instruction (not necessarily the 3776 // start) requires. If > 1, a compute_padding() function must be 3777 // provided for the instruction. 3778 ins_attrib ins_alignment(1); 3779 3780 // Enforce/prohibit rematerializations. 3781 // - If an instruction is attributed with 'ins_cannot_rematerialize(true)' 3782 // then rematerialization of that instruction is prohibited and the 3783 // instruction's value will be spilled if necessary. 3784 // Causes that MachNode::rematerialize() returns false. 3785 // - If an instruction is attributed with 'ins_should_rematerialize(true)' 3786 // then rematerialization should be enforced and a copy of the instruction 3787 // should be inserted if possible; rematerialization is not guaranteed. 3788 // Note: this may result in rematerializations in front of every use. 3789 // Causes that MachNode::rematerialize() can return true. 3790 // (optional attribute) 3791 ins_attrib ins_cannot_rematerialize(false); 3792 ins_attrib ins_should_rematerialize(false); 3793 3794 // Instruction has variable size depending on alignment. 3795 ins_attrib ins_variable_size_depending_on_alignment(false); 3796 3797 // Instruction is a nop. 3798 ins_attrib ins_is_nop(false); 3799 3800 // Instruction is mapped to a MachIfFastLock node (instead of MachFastLock). 3801 ins_attrib ins_use_mach_if_fast_lock_node(false); 3802 3803 // Field for the toc offset of a constant. 3804 // 3805 // This is needed if the toc offset is not encodable as an immediate in 3806 // the PPC load instruction. If so, the upper (hi) bits of the offset are 3807 // added to the toc, and from this a load with immediate is performed. 3808 // With postalloc expand, we get two nodes that require the same offset 3809 // but which don't know about each other. The offset is only known 3810 // when the constant is added to the constant pool during emitting. 3811 // It is generated in the 'hi'-node adding the upper bits, and saved 3812 // in this node. The 'lo'-node has a link to the 'hi'-node and reads 3813 // the offset from there when it gets encoded. 3814 ins_attrib ins_field_const_toc_offset(0); 3815 ins_attrib ins_field_const_toc_offset_hi_node(0); 3816 3817 // A field that can hold the instructions offset in the code buffer. 3818 // Set in the nodes emitter. 3819 ins_attrib ins_field_cbuf_insts_offset(-1); 3820 3821 // Fields for referencing a call's load-IC-node. 3822 // If the toc offset can not be encoded as an immediate in a load, we 3823 // use two nodes. 3824 ins_attrib ins_field_load_ic_hi_node(0); 3825 ins_attrib ins_field_load_ic_node(0); 3826 3827 //----------OPERANDS----------------------------------------------------------- 3828 // Operand definitions must precede instruction definitions for correct 3829 // parsing in the ADLC because operands constitute user defined types 3830 // which are used in instruction definitions. 3831 // 3832 // Formats are generated automatically for constants and base registers. 3833 3834 //----------Simple Operands---------------------------------------------------- 3835 // Immediate Operands 3836 3837 // Integer Immediate: 32-bit 3838 operand immI() %{ 3839 match(ConI); 3840 op_cost(40); 3841 format %{ %} 3842 interface(CONST_INTER); 3843 %} 3844 3845 operand immI8() %{ 3846 predicate(Assembler::is_simm(n->get_int(), 8)); 3847 op_cost(0); 3848 match(ConI); 3849 format %{ %} 3850 interface(CONST_INTER); 3851 %} 3852 3853 // Integer Immediate: 16-bit 3854 operand immI16() %{ 3855 predicate(Assembler::is_simm(n->get_int(), 16)); 3856 op_cost(0); 3857 match(ConI); 3858 format %{ %} 3859 interface(CONST_INTER); 3860 %} 3861 3862 // Integer Immediate: 32-bit, where lowest 16 bits are 0x0000. 3863 operand immIhi16() %{ 3864 predicate(((n->get_int() & 0xffff0000) != 0) && ((n->get_int() & 0xffff) == 0)); 3865 match(ConI); 3866 op_cost(0); 3867 format %{ %} 3868 interface(CONST_INTER); 3869 %} 3870 3871 operand immInegpow2() %{ 3872 predicate(is_power_of_2_long((jlong) (julong) (juint) (-(n->get_int())))); 3873 match(ConI); 3874 op_cost(0); 3875 format %{ %} 3876 interface(CONST_INTER); 3877 %} 3878 3879 operand immIpow2minus1() %{ 3880 predicate(is_power_of_2_long((((jlong) (n->get_int()))+1))); 3881 match(ConI); 3882 op_cost(0); 3883 format %{ %} 3884 interface(CONST_INTER); 3885 %} 3886 3887 operand immIpowerOf2() %{ 3888 predicate(is_power_of_2_long((((jlong) (julong) (juint) (n->get_int()))))); 3889 match(ConI); 3890 op_cost(0); 3891 format %{ %} 3892 interface(CONST_INTER); 3893 %} 3894 3895 // Unsigned Integer Immediate: the values 0-31 3896 operand uimmI5() %{ 3897 predicate(Assembler::is_uimm(n->get_int(), 5)); 3898 match(ConI); 3899 op_cost(0); 3900 format %{ %} 3901 interface(CONST_INTER); 3902 %} 3903 3904 // Unsigned Integer Immediate: 6-bit 3905 operand uimmI6() %{ 3906 predicate(Assembler::is_uimm(n->get_int(), 6)); 3907 match(ConI); 3908 op_cost(0); 3909 format %{ %} 3910 interface(CONST_INTER); 3911 %} 3912 3913 // Unsigned Integer Immediate: 6-bit int, greater than 32 3914 operand uimmI6_ge32() %{ 3915 predicate(Assembler::is_uimm(n->get_int(), 6) && n->get_int() >= 32); 3916 match(ConI); 3917 op_cost(0); 3918 format %{ %} 3919 interface(CONST_INTER); 3920 %} 3921 3922 // Unsigned Integer Immediate: 15-bit 3923 operand uimmI15() %{ 3924 predicate(Assembler::is_uimm(n->get_int(), 15)); 3925 match(ConI); 3926 op_cost(0); 3927 format %{ %} 3928 interface(CONST_INTER); 3929 %} 3930 3931 // Unsigned Integer Immediate: 16-bit 3932 operand uimmI16() %{ 3933 predicate(Assembler::is_uimm(n->get_int(), 16)); 3934 match(ConI); 3935 op_cost(0); 3936 format %{ %} 3937 interface(CONST_INTER); 3938 %} 3939 3940 // constant 'int 0'. 3941 operand immI_0() %{ 3942 predicate(n->get_int() == 0); 3943 match(ConI); 3944 op_cost(0); 3945 format %{ %} 3946 interface(CONST_INTER); 3947 %} 3948 3949 // constant 'int 1'. 3950 operand immI_1() %{ 3951 predicate(n->get_int() == 1); 3952 match(ConI); 3953 op_cost(0); 3954 format %{ %} 3955 interface(CONST_INTER); 3956 %} 3957 3958 // constant 'int -1'. 3959 operand immI_minus1() %{ 3960 predicate(n->get_int() == -1); 3961 match(ConI); 3962 op_cost(0); 3963 format %{ %} 3964 interface(CONST_INTER); 3965 %} 3966 3967 // int value 16. 3968 operand immI_16() %{ 3969 predicate(n->get_int() == 16); 3970 match(ConI); 3971 op_cost(0); 3972 format %{ %} 3973 interface(CONST_INTER); 3974 %} 3975 3976 // int value 24. 3977 operand immI_24() %{ 3978 predicate(n->get_int() == 24); 3979 match(ConI); 3980 op_cost(0); 3981 format %{ %} 3982 interface(CONST_INTER); 3983 %} 3984 3985 // Compressed oops constants 3986 // Pointer Immediate 3987 operand immN() %{ 3988 match(ConN); 3989 3990 op_cost(10); 3991 format %{ %} 3992 interface(CONST_INTER); 3993 %} 3994 3995 // NULL Pointer Immediate 3996 operand immN_0() %{ 3997 predicate(n->get_narrowcon() == 0); 3998 match(ConN); 3999 4000 op_cost(0); 4001 format %{ %} 4002 interface(CONST_INTER); 4003 %} 4004 4005 // Compressed klass constants 4006 operand immNKlass() %{ 4007 match(ConNKlass); 4008 4009 op_cost(0); 4010 format %{ %} 4011 interface(CONST_INTER); 4012 %} 4013 4014 // This operand can be used to avoid matching of an instruct 4015 // with chain rule. 4016 operand immNKlass_NM() %{ 4017 match(ConNKlass); 4018 predicate(false); 4019 op_cost(0); 4020 format %{ %} 4021 interface(CONST_INTER); 4022 %} 4023 4024 // Pointer Immediate: 64-bit 4025 operand immP() %{ 4026 match(ConP); 4027 op_cost(0); 4028 format %{ %} 4029 interface(CONST_INTER); 4030 %} 4031 4032 // Operand to avoid match of loadConP. 4033 // This operand can be used to avoid matching of an instruct 4034 // with chain rule. 4035 operand immP_NM() %{ 4036 match(ConP); 4037 predicate(false); 4038 op_cost(0); 4039 format %{ %} 4040 interface(CONST_INTER); 4041 %} 4042 4043 // costant 'pointer 0'. 4044 operand immP_0() %{ 4045 predicate(n->get_ptr() == 0); 4046 match(ConP); 4047 op_cost(0); 4048 format %{ %} 4049 interface(CONST_INTER); 4050 %} 4051 4052 // pointer 0x0 or 0x1 4053 operand immP_0or1() %{ 4054 predicate((n->get_ptr() == 0) || (n->get_ptr() == 1)); 4055 match(ConP); 4056 op_cost(0); 4057 format %{ %} 4058 interface(CONST_INTER); 4059 %} 4060 4061 operand immL() %{ 4062 match(ConL); 4063 op_cost(40); 4064 format %{ %} 4065 interface(CONST_INTER); 4066 %} 4067 4068 // Long Immediate: 16-bit 4069 operand immL16() %{ 4070 predicate(Assembler::is_simm(n->get_long(), 16)); 4071 match(ConL); 4072 op_cost(0); 4073 format %{ %} 4074 interface(CONST_INTER); 4075 %} 4076 4077 // Long Immediate: 16-bit, 4-aligned 4078 operand immL16Alg4() %{ 4079 predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0x3) == 0)); 4080 match(ConL); 4081 op_cost(0); 4082 format %{ %} 4083 interface(CONST_INTER); 4084 %} 4085 4086 // Long Immediate: 32-bit, where lowest 16 bits are 0x0000. 4087 operand immL32hi16() %{ 4088 predicate(Assembler::is_simm(n->get_long(), 32) && ((n->get_long() & 0xffffL) == 0L)); 4089 match(ConL); 4090 op_cost(0); 4091 format %{ %} 4092 interface(CONST_INTER); 4093 %} 4094 4095 // Long Immediate: 32-bit 4096 operand immL32() %{ 4097 predicate(Assembler::is_simm(n->get_long(), 32)); 4098 match(ConL); 4099 op_cost(0); 4100 format %{ %} 4101 interface(CONST_INTER); 4102 %} 4103 4104 // Long Immediate: 64-bit, where highest 16 bits are not 0x0000. 4105 operand immLhighest16() %{ 4106 predicate((n->get_long() & 0xffff000000000000L) != 0L && (n->get_long() & 0x0000ffffffffffffL) == 0L); 4107 match(ConL); 4108 op_cost(0); 4109 format %{ %} 4110 interface(CONST_INTER); 4111 %} 4112 4113 operand immLnegpow2() %{ 4114 predicate(is_power_of_2_long((jlong)-(n->get_long()))); 4115 match(ConL); 4116 op_cost(0); 4117 format %{ %} 4118 interface(CONST_INTER); 4119 %} 4120 4121 operand immLpow2minus1() %{ 4122 predicate(is_power_of_2_long((((jlong) (n->get_long()))+1)) && 4123 (n->get_long() != (jlong)0xffffffffffffffffL)); 4124 match(ConL); 4125 op_cost(0); 4126 format %{ %} 4127 interface(CONST_INTER); 4128 %} 4129 4130 // constant 'long 0'. 4131 operand immL_0() %{ 4132 predicate(n->get_long() == 0L); 4133 match(ConL); 4134 op_cost(0); 4135 format %{ %} 4136 interface(CONST_INTER); 4137 %} 4138 4139 // constat ' long -1'. 4140 operand immL_minus1() %{ 4141 predicate(n->get_long() == -1L); 4142 match(ConL); 4143 op_cost(0); 4144 format %{ %} 4145 interface(CONST_INTER); 4146 %} 4147 4148 // Long Immediate: low 32-bit mask 4149 operand immL_32bits() %{ 4150 predicate(n->get_long() == 0xFFFFFFFFL); 4151 match(ConL); 4152 op_cost(0); 4153 format %{ %} 4154 interface(CONST_INTER); 4155 %} 4156 4157 // Unsigned Long Immediate: 16-bit 4158 operand uimmL16() %{ 4159 predicate(Assembler::is_uimm(n->get_long(), 16)); 4160 match(ConL); 4161 op_cost(0); 4162 format %{ %} 4163 interface(CONST_INTER); 4164 %} 4165 4166 // Float Immediate 4167 operand immF() %{ 4168 match(ConF); 4169 op_cost(40); 4170 format %{ %} 4171 interface(CONST_INTER); 4172 %} 4173 4174 // Float Immediate: +0.0f. 4175 operand immF_0() %{ 4176 predicate(jint_cast(n->getf()) == 0); 4177 match(ConF); 4178 4179 op_cost(0); 4180 format %{ %} 4181 interface(CONST_INTER); 4182 %} 4183 4184 // Double Immediate 4185 operand immD() %{ 4186 match(ConD); 4187 op_cost(40); 4188 format %{ %} 4189 interface(CONST_INTER); 4190 %} 4191 4192 // Integer Register Operands 4193 // Integer Destination Register 4194 // See definition of reg_class bits32_reg_rw. 4195 operand iRegIdst() %{ 4196 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4197 match(RegI); 4198 match(rscratch1RegI); 4199 match(rscratch2RegI); 4200 match(rarg1RegI); 4201 match(rarg2RegI); 4202 match(rarg3RegI); 4203 match(rarg4RegI); 4204 format %{ %} 4205 interface(REG_INTER); 4206 %} 4207 4208 // Integer Source Register 4209 // See definition of reg_class bits32_reg_ro. 4210 operand iRegIsrc() %{ 4211 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4212 match(RegI); 4213 match(rscratch1RegI); 4214 match(rscratch2RegI); 4215 match(rarg1RegI); 4216 match(rarg2RegI); 4217 match(rarg3RegI); 4218 match(rarg4RegI); 4219 format %{ %} 4220 interface(REG_INTER); 4221 %} 4222 4223 operand rscratch1RegI() %{ 4224 constraint(ALLOC_IN_RC(rscratch1_bits32_reg)); 4225 match(iRegIdst); 4226 format %{ %} 4227 interface(REG_INTER); 4228 %} 4229 4230 operand rscratch2RegI() %{ 4231 constraint(ALLOC_IN_RC(rscratch2_bits32_reg)); 4232 match(iRegIdst); 4233 format %{ %} 4234 interface(REG_INTER); 4235 %} 4236 4237 operand rarg1RegI() %{ 4238 constraint(ALLOC_IN_RC(rarg1_bits32_reg)); 4239 match(iRegIdst); 4240 format %{ %} 4241 interface(REG_INTER); 4242 %} 4243 4244 operand rarg2RegI() %{ 4245 constraint(ALLOC_IN_RC(rarg2_bits32_reg)); 4246 match(iRegIdst); 4247 format %{ %} 4248 interface(REG_INTER); 4249 %} 4250 4251 operand rarg3RegI() %{ 4252 constraint(ALLOC_IN_RC(rarg3_bits32_reg)); 4253 match(iRegIdst); 4254 format %{ %} 4255 interface(REG_INTER); 4256 %} 4257 4258 operand rarg4RegI() %{ 4259 constraint(ALLOC_IN_RC(rarg4_bits32_reg)); 4260 match(iRegIdst); 4261 format %{ %} 4262 interface(REG_INTER); 4263 %} 4264 4265 operand rarg1RegL() %{ 4266 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4267 match(iRegLdst); 4268 format %{ %} 4269 interface(REG_INTER); 4270 %} 4271 4272 operand rarg2RegL() %{ 4273 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4274 match(iRegLdst); 4275 format %{ %} 4276 interface(REG_INTER); 4277 %} 4278 4279 operand rarg3RegL() %{ 4280 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4281 match(iRegLdst); 4282 format %{ %} 4283 interface(REG_INTER); 4284 %} 4285 4286 operand rarg4RegL() %{ 4287 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4288 match(iRegLdst); 4289 format %{ %} 4290 interface(REG_INTER); 4291 %} 4292 4293 // Pointer Destination Register 4294 // See definition of reg_class bits64_reg_rw. 4295 operand iRegPdst() %{ 4296 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4297 match(RegP); 4298 match(rscratch1RegP); 4299 match(rscratch2RegP); 4300 match(rarg1RegP); 4301 match(rarg2RegP); 4302 match(rarg3RegP); 4303 match(rarg4RegP); 4304 format %{ %} 4305 interface(REG_INTER); 4306 %} 4307 4308 // Pointer Destination Register 4309 // Operand not using r11 and r12 (killed in epilog). 4310 operand iRegPdstNoScratch() %{ 4311 constraint(ALLOC_IN_RC(bits64_reg_leaf_call)); 4312 match(RegP); 4313 match(rarg1RegP); 4314 match(rarg2RegP); 4315 match(rarg3RegP); 4316 match(rarg4RegP); 4317 format %{ %} 4318 interface(REG_INTER); 4319 %} 4320 4321 // Pointer Source Register 4322 // See definition of reg_class bits64_reg_ro. 4323 operand iRegPsrc() %{ 4324 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4325 match(RegP); 4326 match(iRegPdst); 4327 match(rscratch1RegP); 4328 match(rscratch2RegP); 4329 match(rarg1RegP); 4330 match(rarg2RegP); 4331 match(rarg3RegP); 4332 match(rarg4RegP); 4333 match(threadRegP); 4334 format %{ %} 4335 interface(REG_INTER); 4336 %} 4337 4338 // Thread operand. 4339 operand threadRegP() %{ 4340 constraint(ALLOC_IN_RC(thread_bits64_reg)); 4341 match(iRegPdst); 4342 format %{ "R16" %} 4343 interface(REG_INTER); 4344 %} 4345 4346 operand rscratch1RegP() %{ 4347 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4348 match(iRegPdst); 4349 format %{ "R11" %} 4350 interface(REG_INTER); 4351 %} 4352 4353 operand rscratch2RegP() %{ 4354 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4355 match(iRegPdst); 4356 format %{ %} 4357 interface(REG_INTER); 4358 %} 4359 4360 operand rarg1RegP() %{ 4361 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4362 match(iRegPdst); 4363 format %{ %} 4364 interface(REG_INTER); 4365 %} 4366 4367 operand rarg2RegP() %{ 4368 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4369 match(iRegPdst); 4370 format %{ %} 4371 interface(REG_INTER); 4372 %} 4373 4374 operand rarg3RegP() %{ 4375 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4376 match(iRegPdst); 4377 format %{ %} 4378 interface(REG_INTER); 4379 %} 4380 4381 operand rarg4RegP() %{ 4382 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4383 match(iRegPdst); 4384 format %{ %} 4385 interface(REG_INTER); 4386 %} 4387 4388 operand iRegNsrc() %{ 4389 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4390 match(RegN); 4391 match(iRegNdst); 4392 4393 format %{ %} 4394 interface(REG_INTER); 4395 %} 4396 4397 operand iRegNdst() %{ 4398 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4399 match(RegN); 4400 4401 format %{ %} 4402 interface(REG_INTER); 4403 %} 4404 4405 // Long Destination Register 4406 // See definition of reg_class bits64_reg_rw. 4407 operand iRegLdst() %{ 4408 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4409 match(RegL); 4410 match(rscratch1RegL); 4411 match(rscratch2RegL); 4412 format %{ %} 4413 interface(REG_INTER); 4414 %} 4415 4416 // Long Source Register 4417 // See definition of reg_class bits64_reg_ro. 4418 operand iRegLsrc() %{ 4419 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4420 match(RegL); 4421 match(iRegLdst); 4422 match(rscratch1RegL); 4423 match(rscratch2RegL); 4424 format %{ %} 4425 interface(REG_INTER); 4426 %} 4427 4428 // Special operand for ConvL2I. 4429 operand iRegL2Isrc(iRegLsrc reg) %{ 4430 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4431 match(ConvL2I reg); 4432 format %{ "ConvL2I($reg)" %} 4433 interface(REG_INTER) 4434 %} 4435 4436 operand rscratch1RegL() %{ 4437 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4438 match(RegL); 4439 format %{ %} 4440 interface(REG_INTER); 4441 %} 4442 4443 operand rscratch2RegL() %{ 4444 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4445 match(RegL); 4446 format %{ %} 4447 interface(REG_INTER); 4448 %} 4449 4450 // Condition Code Flag Registers 4451 operand flagsReg() %{ 4452 constraint(ALLOC_IN_RC(int_flags)); 4453 match(RegFlags); 4454 format %{ %} 4455 interface(REG_INTER); 4456 %} 4457 4458 operand flagsRegSrc() %{ 4459 constraint(ALLOC_IN_RC(int_flags_ro)); 4460 match(RegFlags); 4461 match(flagsReg); 4462 match(flagsRegCR0); 4463 format %{ %} 4464 interface(REG_INTER); 4465 %} 4466 4467 // Condition Code Flag Register CR0 4468 operand flagsRegCR0() %{ 4469 constraint(ALLOC_IN_RC(int_flags_CR0)); 4470 match(RegFlags); 4471 format %{ "CR0" %} 4472 interface(REG_INTER); 4473 %} 4474 4475 operand flagsRegCR1() %{ 4476 constraint(ALLOC_IN_RC(int_flags_CR1)); 4477 match(RegFlags); 4478 format %{ "CR1" %} 4479 interface(REG_INTER); 4480 %} 4481 4482 operand flagsRegCR6() %{ 4483 constraint(ALLOC_IN_RC(int_flags_CR6)); 4484 match(RegFlags); 4485 format %{ "CR6" %} 4486 interface(REG_INTER); 4487 %} 4488 4489 operand regCTR() %{ 4490 constraint(ALLOC_IN_RC(ctr_reg)); 4491 // RegFlags should work. Introducing a RegSpecial type would cause a 4492 // lot of changes. 4493 match(RegFlags); 4494 format %{"SR_CTR" %} 4495 interface(REG_INTER); 4496 %} 4497 4498 operand regD() %{ 4499 constraint(ALLOC_IN_RC(dbl_reg)); 4500 match(RegD); 4501 format %{ %} 4502 interface(REG_INTER); 4503 %} 4504 4505 operand regF() %{ 4506 constraint(ALLOC_IN_RC(flt_reg)); 4507 match(RegF); 4508 format %{ %} 4509 interface(REG_INTER); 4510 %} 4511 4512 // Special Registers 4513 4514 // Method Register 4515 operand inline_cache_regP(iRegPdst reg) %{ 4516 constraint(ALLOC_IN_RC(r19_bits64_reg)); // inline_cache_reg 4517 match(reg); 4518 format %{ %} 4519 interface(REG_INTER); 4520 %} 4521 4522 operand compiler_method_oop_regP(iRegPdst reg) %{ 4523 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); // compiler_method_oop_reg 4524 match(reg); 4525 format %{ %} 4526 interface(REG_INTER); 4527 %} 4528 4529 operand interpreter_method_oop_regP(iRegPdst reg) %{ 4530 constraint(ALLOC_IN_RC(r19_bits64_reg)); // interpreter_method_oop_reg 4531 match(reg); 4532 format %{ %} 4533 interface(REG_INTER); 4534 %} 4535 4536 // Operands to remove register moves in unscaled mode. 4537 // Match read/write registers with an EncodeP node if neither shift nor add are required. 4538 operand iRegP2N(iRegPsrc reg) %{ 4539 predicate(false /* TODO: PPC port MatchDecodeNodes*/&& Universe::narrow_oop_shift() == 0); 4540 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4541 match(EncodeP reg); 4542 format %{ "$reg" %} 4543 interface(REG_INTER) 4544 %} 4545 4546 operand iRegN2P(iRegNsrc reg) %{ 4547 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4548 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4549 match(DecodeN reg); 4550 format %{ "$reg" %} 4551 interface(REG_INTER) 4552 %} 4553 4554 operand iRegN2P_klass(iRegNsrc reg) %{ 4555 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 4556 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4557 match(DecodeNKlass reg); 4558 format %{ "$reg" %} 4559 interface(REG_INTER) 4560 %} 4561 4562 //----------Complex Operands--------------------------------------------------- 4563 // Indirect Memory Reference 4564 operand indirect(iRegPsrc reg) %{ 4565 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4566 match(reg); 4567 op_cost(100); 4568 format %{ "[$reg]" %} 4569 interface(MEMORY_INTER) %{ 4570 base($reg); 4571 index(0x0); 4572 scale(0x0); 4573 disp(0x0); 4574 %} 4575 %} 4576 4577 // Indirect with Offset 4578 operand indOffset16(iRegPsrc reg, immL16 offset) %{ 4579 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4580 match(AddP reg offset); 4581 op_cost(100); 4582 format %{ "[$reg + $offset]" %} 4583 interface(MEMORY_INTER) %{ 4584 base($reg); 4585 index(0x0); 4586 scale(0x0); 4587 disp($offset); 4588 %} 4589 %} 4590 4591 // Indirect with 4-aligned Offset 4592 operand indOffset16Alg4(iRegPsrc reg, immL16Alg4 offset) %{ 4593 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4594 match(AddP reg offset); 4595 op_cost(100); 4596 format %{ "[$reg + $offset]" %} 4597 interface(MEMORY_INTER) %{ 4598 base($reg); 4599 index(0x0); 4600 scale(0x0); 4601 disp($offset); 4602 %} 4603 %} 4604 4605 //----------Complex Operands for Compressed OOPs------------------------------- 4606 // Compressed OOPs with narrow_oop_shift == 0. 4607 4608 // Indirect Memory Reference, compressed OOP 4609 operand indirectNarrow(iRegNsrc reg) %{ 4610 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4611 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4612 match(DecodeN reg); 4613 op_cost(100); 4614 format %{ "[$reg]" %} 4615 interface(MEMORY_INTER) %{ 4616 base($reg); 4617 index(0x0); 4618 scale(0x0); 4619 disp(0x0); 4620 %} 4621 %} 4622 4623 operand indirectNarrow_klass(iRegNsrc reg) %{ 4624 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 4625 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4626 match(DecodeNKlass reg); 4627 op_cost(100); 4628 format %{ "[$reg]" %} 4629 interface(MEMORY_INTER) %{ 4630 base($reg); 4631 index(0x0); 4632 scale(0x0); 4633 disp(0x0); 4634 %} 4635 %} 4636 4637 // Indirect with Offset, compressed OOP 4638 operand indOffset16Narrow(iRegNsrc reg, immL16 offset) %{ 4639 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4640 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4641 match(AddP (DecodeN reg) offset); 4642 op_cost(100); 4643 format %{ "[$reg + $offset]" %} 4644 interface(MEMORY_INTER) %{ 4645 base($reg); 4646 index(0x0); 4647 scale(0x0); 4648 disp($offset); 4649 %} 4650 %} 4651 4652 operand indOffset16Narrow_klass(iRegNsrc reg, immL16 offset) %{ 4653 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 4654 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4655 match(AddP (DecodeNKlass reg) offset); 4656 op_cost(100); 4657 format %{ "[$reg + $offset]" %} 4658 interface(MEMORY_INTER) %{ 4659 base($reg); 4660 index(0x0); 4661 scale(0x0); 4662 disp($offset); 4663 %} 4664 %} 4665 4666 // Indirect with 4-aligned Offset, compressed OOP 4667 operand indOffset16NarrowAlg4(iRegNsrc reg, immL16Alg4 offset) %{ 4668 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4669 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4670 match(AddP (DecodeN reg) offset); 4671 op_cost(100); 4672 format %{ "[$reg + $offset]" %} 4673 interface(MEMORY_INTER) %{ 4674 base($reg); 4675 index(0x0); 4676 scale(0x0); 4677 disp($offset); 4678 %} 4679 %} 4680 4681 operand indOffset16NarrowAlg4_klass(iRegNsrc reg, immL16Alg4 offset) %{ 4682 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 4683 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4684 match(AddP (DecodeNKlass reg) offset); 4685 op_cost(100); 4686 format %{ "[$reg + $offset]" %} 4687 interface(MEMORY_INTER) %{ 4688 base($reg); 4689 index(0x0); 4690 scale(0x0); 4691 disp($offset); 4692 %} 4693 %} 4694 4695 //----------Special Memory Operands-------------------------------------------- 4696 // Stack Slot Operand 4697 // 4698 // This operand is used for loading and storing temporary values on 4699 // the stack where a match requires a value to flow through memory. 4700 operand stackSlotI(sRegI reg) %{ 4701 constraint(ALLOC_IN_RC(stack_slots)); 4702 op_cost(100); 4703 //match(RegI); 4704 format %{ "[sp+$reg]" %} 4705 interface(MEMORY_INTER) %{ 4706 base(0x1); // R1_SP 4707 index(0x0); 4708 scale(0x0); 4709 disp($reg); // Stack Offset 4710 %} 4711 %} 4712 4713 operand stackSlotL(sRegL reg) %{ 4714 constraint(ALLOC_IN_RC(stack_slots)); 4715 op_cost(100); 4716 //match(RegL); 4717 format %{ "[sp+$reg]" %} 4718 interface(MEMORY_INTER) %{ 4719 base(0x1); // R1_SP 4720 index(0x0); 4721 scale(0x0); 4722 disp($reg); // Stack Offset 4723 %} 4724 %} 4725 4726 operand stackSlotP(sRegP reg) %{ 4727 constraint(ALLOC_IN_RC(stack_slots)); 4728 op_cost(100); 4729 //match(RegP); 4730 format %{ "[sp+$reg]" %} 4731 interface(MEMORY_INTER) %{ 4732 base(0x1); // R1_SP 4733 index(0x0); 4734 scale(0x0); 4735 disp($reg); // Stack Offset 4736 %} 4737 %} 4738 4739 operand stackSlotF(sRegF reg) %{ 4740 constraint(ALLOC_IN_RC(stack_slots)); 4741 op_cost(100); 4742 //match(RegF); 4743 format %{ "[sp+$reg]" %} 4744 interface(MEMORY_INTER) %{ 4745 base(0x1); // R1_SP 4746 index(0x0); 4747 scale(0x0); 4748 disp($reg); // Stack Offset 4749 %} 4750 %} 4751 4752 operand stackSlotD(sRegD reg) %{ 4753 constraint(ALLOC_IN_RC(stack_slots)); 4754 op_cost(100); 4755 //match(RegD); 4756 format %{ "[sp+$reg]" %} 4757 interface(MEMORY_INTER) %{ 4758 base(0x1); // R1_SP 4759 index(0x0); 4760 scale(0x0); 4761 disp($reg); // Stack Offset 4762 %} 4763 %} 4764 4765 // Operands for expressing Control Flow 4766 // NOTE: Label is a predefined operand which should not be redefined in 4767 // the AD file. It is generically handled within the ADLC. 4768 4769 //----------Conditional Branch Operands---------------------------------------- 4770 // Comparison Op 4771 // 4772 // This is the operation of the comparison, and is limited to the 4773 // following set of codes: L (<), LE (<=), G (>), GE (>=), E (==), NE 4774 // (!=). 4775 // 4776 // Other attributes of the comparison, such as unsignedness, are specified 4777 // by the comparison instruction that sets a condition code flags register. 4778 // That result is represented by a flags operand whose subtype is appropriate 4779 // to the unsignedness (etc.) of the comparison. 4780 // 4781 // Later, the instruction which matches both the Comparison Op (a Bool) and 4782 // the flags (produced by the Cmp) specifies the coding of the comparison op 4783 // by matching a specific subtype of Bool operand below. 4784 4785 // When used for floating point comparisons: unordered same as less. 4786 operand cmpOp() %{ 4787 match(Bool); 4788 format %{ "" %} 4789 interface(COND_INTER) %{ 4790 // BO only encodes bit 4 of bcondCRbiIsX, as bits 1-3 are always '100'. 4791 // BO & BI 4792 equal(0xA); // 10 10: bcondCRbiIs1 & Condition::equal 4793 not_equal(0x2); // 00 10: bcondCRbiIs0 & Condition::equal 4794 less(0x8); // 10 00: bcondCRbiIs1 & Condition::less 4795 greater_equal(0x0); // 00 00: bcondCRbiIs0 & Condition::less 4796 less_equal(0x1); // 00 01: bcondCRbiIs0 & Condition::greater 4797 greater(0x9); // 10 01: bcondCRbiIs1 & Condition::greater 4798 overflow(0xB); // 10 11: bcondCRbiIs1 & Condition::summary_overflow 4799 no_overflow(0x3); // 00 11: bcondCRbiIs0 & Condition::summary_overflow 4800 %} 4801 %} 4802 4803 //----------OPERAND CLASSES---------------------------------------------------- 4804 // Operand Classes are groups of operands that are used to simplify 4805 // instruction definitions by not requiring the AD writer to specify 4806 // seperate instructions for every form of operand when the 4807 // instruction accepts multiple operand types with the same basic 4808 // encoding and format. The classic case of this is memory operands. 4809 // Indirect is not included since its use is limited to Compare & Swap. 4810 4811 opclass memory(indirect, indOffset16 /*, indIndex, tlsReference*/, indirectNarrow, indirectNarrow_klass, indOffset16Narrow, indOffset16Narrow_klass); 4812 // Memory operand where offsets are 4-aligned. Required for ld, std. 4813 opclass memoryAlg4(indirect, indOffset16Alg4, indirectNarrow, indOffset16NarrowAlg4, indOffset16NarrowAlg4_klass); 4814 opclass indirectMemory(indirect, indirectNarrow); 4815 4816 // Special opclass for I and ConvL2I. 4817 opclass iRegIsrc_iRegL2Isrc(iRegIsrc, iRegL2Isrc); 4818 4819 // Operand classes to match encode and decode. iRegN_P2N is only used 4820 // for storeN. I have never seen an encode node elsewhere. 4821 opclass iRegN_P2N(iRegNsrc, iRegP2N); 4822 opclass iRegP_N2P(iRegPsrc, iRegN2P, iRegN2P_klass); 4823 4824 //----------PIPELINE----------------------------------------------------------- 4825 4826 pipeline %{ 4827 4828 // See J.M.Tendler et al. "Power4 system microarchitecture", IBM 4829 // J. Res. & Dev., No. 1, Jan. 2002. 4830 4831 //----------ATTRIBUTES--------------------------------------------------------- 4832 attributes %{ 4833 4834 // Power4 instructions are of fixed length. 4835 fixed_size_instructions; 4836 4837 // TODO: if `bundle' means number of instructions fetched 4838 // per cycle, this is 8. If `bundle' means Power4 `group', that is 4839 // max instructions issued per cycle, this is 5. 4840 max_instructions_per_bundle = 8; 4841 4842 // A Power4 instruction is 4 bytes long. 4843 instruction_unit_size = 4; 4844 4845 // The Power4 processor fetches 64 bytes... 4846 instruction_fetch_unit_size = 64; 4847 4848 // ...in one line 4849 instruction_fetch_units = 1 4850 4851 // Unused, list one so that array generated by adlc is not empty. 4852 // Aix compiler chokes if _nop_count = 0. 4853 nops(fxNop); 4854 %} 4855 4856 //----------RESOURCES---------------------------------------------------------- 4857 // Resources are the functional units available to the machine 4858 resources( 4859 PPC_BR, // branch unit 4860 PPC_CR, // condition unit 4861 PPC_FX1, // integer arithmetic unit 1 4862 PPC_FX2, // integer arithmetic unit 2 4863 PPC_LDST1, // load/store unit 1 4864 PPC_LDST2, // load/store unit 2 4865 PPC_FP1, // float arithmetic unit 1 4866 PPC_FP2, // float arithmetic unit 2 4867 PPC_LDST = PPC_LDST1 | PPC_LDST2, 4868 PPC_FX = PPC_FX1 | PPC_FX2, 4869 PPC_FP = PPC_FP1 | PPC_FP2 4870 ); 4871 4872 //----------PIPELINE DESCRIPTION----------------------------------------------- 4873 // Pipeline Description specifies the stages in the machine's pipeline 4874 pipe_desc( 4875 // Power4 longest pipeline path 4876 PPC_IF, // instruction fetch 4877 PPC_IC, 4878 //PPC_BP, // branch prediction 4879 PPC_D0, // decode 4880 PPC_D1, // decode 4881 PPC_D2, // decode 4882 PPC_D3, // decode 4883 PPC_Xfer1, 4884 PPC_GD, // group definition 4885 PPC_MP, // map 4886 PPC_ISS, // issue 4887 PPC_RF, // resource fetch 4888 PPC_EX1, // execute (all units) 4889 PPC_EX2, // execute (FP, LDST) 4890 PPC_EX3, // execute (FP, LDST) 4891 PPC_EX4, // execute (FP) 4892 PPC_EX5, // execute (FP) 4893 PPC_EX6, // execute (FP) 4894 PPC_WB, // write back 4895 PPC_Xfer2, 4896 PPC_CP 4897 ); 4898 4899 //----------PIPELINE CLASSES--------------------------------------------------- 4900 // Pipeline Classes describe the stages in which input and output are 4901 // referenced by the hardware pipeline. 4902 4903 // Simple pipeline classes. 4904 4905 // Default pipeline class. 4906 pipe_class pipe_class_default() %{ 4907 single_instruction; 4908 fixed_latency(2); 4909 %} 4910 4911 // Pipeline class for empty instructions. 4912 pipe_class pipe_class_empty() %{ 4913 single_instruction; 4914 fixed_latency(0); 4915 %} 4916 4917 // Pipeline class for compares. 4918 pipe_class pipe_class_compare() %{ 4919 single_instruction; 4920 fixed_latency(16); 4921 %} 4922 4923 // Pipeline class for traps. 4924 pipe_class pipe_class_trap() %{ 4925 single_instruction; 4926 fixed_latency(100); 4927 %} 4928 4929 // Pipeline class for memory operations. 4930 pipe_class pipe_class_memory() %{ 4931 single_instruction; 4932 fixed_latency(16); 4933 %} 4934 4935 // Pipeline class for call. 4936 pipe_class pipe_class_call() %{ 4937 single_instruction; 4938 fixed_latency(100); 4939 %} 4940 4941 // Define the class for the Nop node. 4942 define %{ 4943 MachNop = pipe_class_default; 4944 %} 4945 4946 %} 4947 4948 //----------INSTRUCTIONS------------------------------------------------------- 4949 4950 // Naming of instructions: 4951 // opA_operB / opA_operB_operC: 4952 // Operation 'op' with one or two source operands 'oper'. Result 4953 // type is A, source operand types are B and C. 4954 // Iff A == B == C, B and C are left out. 4955 // 4956 // The instructions are ordered according to the following scheme: 4957 // - loads 4958 // - load constants 4959 // - prefetch 4960 // - store 4961 // - encode/decode 4962 // - membar 4963 // - conditional moves 4964 // - compare & swap 4965 // - arithmetic and logic operations 4966 // * int: Add, Sub, Mul, Div, Mod 4967 // * int: lShift, arShift, urShift, rot 4968 // * float: Add, Sub, Mul, Div 4969 // * and, or, xor ... 4970 // - register moves: float <-> int, reg <-> stack, repl 4971 // - cast (high level type cast, XtoP, castPP, castII, not_null etc. 4972 // - conv (low level type cast requiring bit changes (sign extend etc) 4973 // - compares, range & zero checks. 4974 // - branches 4975 // - complex operations, intrinsics, min, max, replicate 4976 // - lock 4977 // - Calls 4978 // 4979 // If there are similar instructions with different types they are sorted: 4980 // int before float 4981 // small before big 4982 // signed before unsigned 4983 // e.g., loadS before loadUS before loadI before loadF. 4984 4985 4986 //----------Load/Store Instructions-------------------------------------------- 4987 4988 //----------Load Instructions-------------------------------------------------- 4989 4990 // Converts byte to int. 4991 // As convB2I_reg, but without match rule. The match rule of convB2I_reg 4992 // reuses the 'amount' operand, but adlc expects that operand specification 4993 // and operands in match rule are equivalent. 4994 instruct convB2I_reg_2(iRegIdst dst, iRegIsrc src) %{ 4995 effect(DEF dst, USE src); 4996 format %{ "EXTSB $dst, $src \t// byte->int" %} 4997 size(4); 4998 ins_encode %{ 4999 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 5000 __ extsb($dst$$Register, $src$$Register); 5001 %} 5002 ins_pipe(pipe_class_default); 5003 %} 5004 5005 instruct loadUB_indirect(iRegIdst dst, indirectMemory mem) %{ 5006 // match-rule, false predicate 5007 match(Set dst (LoadB mem)); 5008 predicate(false); 5009 5010 format %{ "LBZ $dst, $mem" %} 5011 size(4); 5012 ins_encode( enc_lbz(dst, mem) ); 5013 ins_pipe(pipe_class_memory); 5014 %} 5015 5016 instruct loadUB_indirect_ac(iRegIdst dst, indirectMemory mem) %{ 5017 // match-rule, false predicate 5018 match(Set dst (LoadB mem)); 5019 predicate(false); 5020 5021 format %{ "LBZ $dst, $mem\n\t" 5022 "TWI $dst\n\t" 5023 "ISYNC" %} 5024 size(12); 5025 ins_encode( enc_lbz_ac(dst, mem) ); 5026 ins_pipe(pipe_class_memory); 5027 %} 5028 5029 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5030 instruct loadB_indirect_Ex(iRegIdst dst, indirectMemory mem) %{ 5031 match(Set dst (LoadB mem)); 5032 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5033 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5034 expand %{ 5035 iRegIdst tmp; 5036 loadUB_indirect(tmp, mem); 5037 convB2I_reg_2(dst, tmp); 5038 %} 5039 %} 5040 5041 instruct loadB_indirect_ac_Ex(iRegIdst dst, indirectMemory mem) %{ 5042 match(Set dst (LoadB mem)); 5043 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5044 expand %{ 5045 iRegIdst tmp; 5046 loadUB_indirect_ac(tmp, mem); 5047 convB2I_reg_2(dst, tmp); 5048 %} 5049 %} 5050 5051 instruct loadUB_indOffset16(iRegIdst dst, indOffset16 mem) %{ 5052 // match-rule, false predicate 5053 match(Set dst (LoadB mem)); 5054 predicate(false); 5055 5056 format %{ "LBZ $dst, $mem" %} 5057 size(4); 5058 ins_encode( enc_lbz(dst, mem) ); 5059 ins_pipe(pipe_class_memory); 5060 %} 5061 5062 instruct loadUB_indOffset16_ac(iRegIdst dst, indOffset16 mem) %{ 5063 // match-rule, false predicate 5064 match(Set dst (LoadB mem)); 5065 predicate(false); 5066 5067 format %{ "LBZ $dst, $mem\n\t" 5068 "TWI $dst\n\t" 5069 "ISYNC" %} 5070 size(12); 5071 ins_encode( enc_lbz_ac(dst, mem) ); 5072 ins_pipe(pipe_class_memory); 5073 %} 5074 5075 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5076 instruct loadB_indOffset16_Ex(iRegIdst dst, indOffset16 mem) %{ 5077 match(Set dst (LoadB mem)); 5078 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5079 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5080 5081 expand %{ 5082 iRegIdst tmp; 5083 loadUB_indOffset16(tmp, mem); 5084 convB2I_reg_2(dst, tmp); 5085 %} 5086 %} 5087 5088 instruct loadB_indOffset16_ac_Ex(iRegIdst dst, indOffset16 mem) %{ 5089 match(Set dst (LoadB mem)); 5090 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5091 5092 expand %{ 5093 iRegIdst tmp; 5094 loadUB_indOffset16_ac(tmp, mem); 5095 convB2I_reg_2(dst, tmp); 5096 %} 5097 %} 5098 5099 // Load Unsigned Byte (8bit UNsigned) into an int reg. 5100 instruct loadUB(iRegIdst dst, memory mem) %{ 5101 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5102 match(Set dst (LoadUB mem)); 5103 ins_cost(MEMORY_REF_COST); 5104 5105 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int" %} 5106 size(4); 5107 ins_encode( enc_lbz(dst, mem) ); 5108 ins_pipe(pipe_class_memory); 5109 %} 5110 5111 // Load Unsigned Byte (8bit UNsigned) acquire. 5112 instruct loadUB_ac(iRegIdst dst, memory mem) %{ 5113 match(Set dst (LoadUB mem)); 5114 ins_cost(3*MEMORY_REF_COST); 5115 5116 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int, acquire\n\t" 5117 "TWI $dst\n\t" 5118 "ISYNC" %} 5119 size(12); 5120 ins_encode( enc_lbz_ac(dst, mem) ); 5121 ins_pipe(pipe_class_memory); 5122 %} 5123 5124 // Load Unsigned Byte (8bit UNsigned) into a Long Register. 5125 instruct loadUB2L(iRegLdst dst, memory mem) %{ 5126 match(Set dst (ConvI2L (LoadUB mem))); 5127 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5128 ins_cost(MEMORY_REF_COST); 5129 5130 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long" %} 5131 size(4); 5132 ins_encode( enc_lbz(dst, mem) ); 5133 ins_pipe(pipe_class_memory); 5134 %} 5135 5136 instruct loadUB2L_ac(iRegLdst dst, memory mem) %{ 5137 match(Set dst (ConvI2L (LoadUB mem))); 5138 ins_cost(3*MEMORY_REF_COST); 5139 5140 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long, acquire\n\t" 5141 "TWI $dst\n\t" 5142 "ISYNC" %} 5143 size(12); 5144 ins_encode( enc_lbz_ac(dst, mem) ); 5145 ins_pipe(pipe_class_memory); 5146 %} 5147 5148 // Load Short (16bit signed) 5149 instruct loadS(iRegIdst dst, memory mem) %{ 5150 match(Set dst (LoadS mem)); 5151 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5152 ins_cost(MEMORY_REF_COST); 5153 5154 format %{ "LHA $dst, $mem" %} 5155 size(4); 5156 ins_encode %{ 5157 // TODO: PPC port $archOpcode(ppc64Opcode_lha); 5158 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5159 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5160 %} 5161 ins_pipe(pipe_class_memory); 5162 %} 5163 5164 // Load Short (16bit signed) acquire. 5165 instruct loadS_ac(iRegIdst dst, memory mem) %{ 5166 match(Set dst (LoadS mem)); 5167 ins_cost(3*MEMORY_REF_COST); 5168 5169 format %{ "LHA $dst, $mem\t acquire\n\t" 5170 "TWI $dst\n\t" 5171 "ISYNC" %} 5172 size(12); 5173 ins_encode %{ 5174 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5175 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5176 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5177 __ twi_0($dst$$Register); 5178 __ isync(); 5179 %} 5180 ins_pipe(pipe_class_memory); 5181 %} 5182 5183 // Load Char (16bit unsigned) 5184 instruct loadUS(iRegIdst dst, memory mem) %{ 5185 match(Set dst (LoadUS mem)); 5186 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5187 ins_cost(MEMORY_REF_COST); 5188 5189 format %{ "LHZ $dst, $mem" %} 5190 size(4); 5191 ins_encode( enc_lhz(dst, mem) ); 5192 ins_pipe(pipe_class_memory); 5193 %} 5194 5195 // Load Char (16bit unsigned) acquire. 5196 instruct loadUS_ac(iRegIdst dst, memory mem) %{ 5197 match(Set dst (LoadUS mem)); 5198 ins_cost(3*MEMORY_REF_COST); 5199 5200 format %{ "LHZ $dst, $mem \t// acquire\n\t" 5201 "TWI $dst\n\t" 5202 "ISYNC" %} 5203 size(12); 5204 ins_encode( enc_lhz_ac(dst, mem) ); 5205 ins_pipe(pipe_class_memory); 5206 %} 5207 5208 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register. 5209 instruct loadUS2L(iRegLdst dst, memory mem) %{ 5210 match(Set dst (ConvI2L (LoadUS mem))); 5211 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5212 ins_cost(MEMORY_REF_COST); 5213 5214 format %{ "LHZ $dst, $mem \t// short, zero-extend to long" %} 5215 size(4); 5216 ins_encode( enc_lhz(dst, mem) ); 5217 ins_pipe(pipe_class_memory); 5218 %} 5219 5220 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register acquire. 5221 instruct loadUS2L_ac(iRegLdst dst, memory mem) %{ 5222 match(Set dst (ConvI2L (LoadUS mem))); 5223 ins_cost(3*MEMORY_REF_COST); 5224 5225 format %{ "LHZ $dst, $mem \t// short, zero-extend to long, acquire\n\t" 5226 "TWI $dst\n\t" 5227 "ISYNC" %} 5228 size(12); 5229 ins_encode( enc_lhz_ac(dst, mem) ); 5230 ins_pipe(pipe_class_memory); 5231 %} 5232 5233 // Load Integer. 5234 instruct loadI(iRegIdst dst, memory mem) %{ 5235 match(Set dst (LoadI mem)); 5236 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5237 ins_cost(MEMORY_REF_COST); 5238 5239 format %{ "LWZ $dst, $mem" %} 5240 size(4); 5241 ins_encode( enc_lwz(dst, mem) ); 5242 ins_pipe(pipe_class_memory); 5243 %} 5244 5245 // Load Integer acquire. 5246 instruct loadI_ac(iRegIdst dst, memory mem) %{ 5247 match(Set dst (LoadI mem)); 5248 ins_cost(3*MEMORY_REF_COST); 5249 5250 format %{ "LWZ $dst, $mem \t// load acquire\n\t" 5251 "TWI $dst\n\t" 5252 "ISYNC" %} 5253 size(12); 5254 ins_encode( enc_lwz_ac(dst, mem) ); 5255 ins_pipe(pipe_class_memory); 5256 %} 5257 5258 // Match loading integer and casting it to unsigned int in 5259 // long register. 5260 // LoadI + ConvI2L + AndL 0xffffffff. 5261 instruct loadUI2L(iRegLdst dst, memory mem, immL_32bits mask) %{ 5262 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5263 predicate(_kids[0]->_kids[0]->_leaf->as_Load()->is_unordered()); 5264 ins_cost(MEMORY_REF_COST); 5265 5266 format %{ "LWZ $dst, $mem \t// zero-extend to long" %} 5267 size(4); 5268 ins_encode( enc_lwz(dst, mem) ); 5269 ins_pipe(pipe_class_memory); 5270 %} 5271 5272 // Match loading integer and casting it to long. 5273 instruct loadI2L(iRegLdst dst, memoryAlg4 mem) %{ 5274 match(Set dst (ConvI2L (LoadI mem))); 5275 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5276 ins_cost(MEMORY_REF_COST); 5277 5278 format %{ "LWA $dst, $mem \t// loadI2L" %} 5279 size(4); 5280 ins_encode %{ 5281 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5282 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5283 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5284 %} 5285 ins_pipe(pipe_class_memory); 5286 %} 5287 5288 // Match loading integer and casting it to long - acquire. 5289 instruct loadI2L_ac(iRegLdst dst, memoryAlg4 mem) %{ 5290 match(Set dst (ConvI2L (LoadI mem))); 5291 ins_cost(3*MEMORY_REF_COST); 5292 5293 format %{ "LWA $dst, $mem \t// loadI2L acquire" 5294 "TWI $dst\n\t" 5295 "ISYNC" %} 5296 size(12); 5297 ins_encode %{ 5298 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5299 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5300 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5301 __ twi_0($dst$$Register); 5302 __ isync(); 5303 %} 5304 ins_pipe(pipe_class_memory); 5305 %} 5306 5307 // Load Long - aligned 5308 instruct loadL(iRegLdst dst, memoryAlg4 mem) %{ 5309 match(Set dst (LoadL mem)); 5310 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5311 ins_cost(MEMORY_REF_COST); 5312 5313 format %{ "LD $dst, $mem \t// long" %} 5314 size(4); 5315 ins_encode( enc_ld(dst, mem) ); 5316 ins_pipe(pipe_class_memory); 5317 %} 5318 5319 // Load Long - aligned acquire. 5320 instruct loadL_ac(iRegLdst dst, memoryAlg4 mem) %{ 5321 match(Set dst (LoadL mem)); 5322 ins_cost(3*MEMORY_REF_COST); 5323 5324 format %{ "LD $dst, $mem \t// long acquire\n\t" 5325 "TWI $dst\n\t" 5326 "ISYNC" %} 5327 size(12); 5328 ins_encode( enc_ld_ac(dst, mem) ); 5329 ins_pipe(pipe_class_memory); 5330 %} 5331 5332 // Load Long - UNaligned 5333 instruct loadL_unaligned(iRegLdst dst, memoryAlg4 mem) %{ 5334 match(Set dst (LoadL_unaligned mem)); 5335 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 5336 ins_cost(MEMORY_REF_COST); 5337 5338 format %{ "LD $dst, $mem \t// unaligned long" %} 5339 size(4); 5340 ins_encode( enc_ld(dst, mem) ); 5341 ins_pipe(pipe_class_memory); 5342 %} 5343 5344 // Load nodes for superwords 5345 5346 // Load Aligned Packed Byte 5347 instruct loadV8(iRegLdst dst, memoryAlg4 mem) %{ 5348 predicate(n->as_LoadVector()->memory_size() == 8); 5349 match(Set dst (LoadVector mem)); 5350 ins_cost(MEMORY_REF_COST); 5351 5352 format %{ "LD $dst, $mem \t// load 8-byte Vector" %} 5353 size(4); 5354 ins_encode( enc_ld(dst, mem) ); 5355 ins_pipe(pipe_class_memory); 5356 %} 5357 5358 // Load Range, range = array length (=jint) 5359 instruct loadRange(iRegIdst dst, memory mem) %{ 5360 match(Set dst (LoadRange mem)); 5361 ins_cost(MEMORY_REF_COST); 5362 5363 format %{ "LWZ $dst, $mem \t// range" %} 5364 size(4); 5365 ins_encode( enc_lwz(dst, mem) ); 5366 ins_pipe(pipe_class_memory); 5367 %} 5368 5369 // Load Compressed Pointer 5370 instruct loadN(iRegNdst dst, memory mem) %{ 5371 match(Set dst (LoadN mem)); 5372 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5373 ins_cost(MEMORY_REF_COST); 5374 5375 format %{ "LWZ $dst, $mem \t// load compressed ptr" %} 5376 size(4); 5377 ins_encode( enc_lwz(dst, mem) ); 5378 ins_pipe(pipe_class_memory); 5379 %} 5380 5381 // Load Compressed Pointer acquire. 5382 instruct loadN_ac(iRegNdst dst, memory mem) %{ 5383 match(Set dst (LoadN mem)); 5384 ins_cost(3*MEMORY_REF_COST); 5385 5386 format %{ "LWZ $dst, $mem \t// load acquire compressed ptr\n\t" 5387 "TWI $dst\n\t" 5388 "ISYNC" %} 5389 size(12); 5390 ins_encode( enc_lwz_ac(dst, mem) ); 5391 ins_pipe(pipe_class_memory); 5392 %} 5393 5394 // Load Compressed Pointer and decode it if narrow_oop_shift == 0. 5395 instruct loadN2P_unscaled(iRegPdst dst, memory mem) %{ 5396 match(Set dst (DecodeN (LoadN mem))); 5397 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && Universe::narrow_oop_shift() == 0); 5398 ins_cost(MEMORY_REF_COST); 5399 5400 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5401 size(4); 5402 ins_encode( enc_lwz(dst, mem) ); 5403 ins_pipe(pipe_class_memory); 5404 %} 5405 5406 instruct loadN2P_klass_unscaled(iRegPdst dst, memory mem) %{ 5407 match(Set dst (DecodeNKlass (LoadNKlass mem))); 5408 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0 && 5409 _kids[0]->_leaf->as_Load()->is_unordered()); 5410 ins_cost(MEMORY_REF_COST); 5411 5412 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5413 size(4); 5414 ins_encode( enc_lwz(dst, mem) ); 5415 ins_pipe(pipe_class_memory); 5416 %} 5417 5418 // Load Pointer 5419 instruct loadP(iRegPdst dst, memoryAlg4 mem) %{ 5420 match(Set dst (LoadP mem)); 5421 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5422 ins_cost(MEMORY_REF_COST); 5423 5424 format %{ "LD $dst, $mem \t// ptr" %} 5425 size(4); 5426 ins_encode( enc_ld(dst, mem) ); 5427 ins_pipe(pipe_class_memory); 5428 %} 5429 5430 // Load Pointer acquire. 5431 instruct loadP_ac(iRegPdst dst, memoryAlg4 mem) %{ 5432 match(Set dst (LoadP mem)); 5433 ins_cost(3*MEMORY_REF_COST); 5434 5435 format %{ "LD $dst, $mem \t// ptr acquire\n\t" 5436 "TWI $dst\n\t" 5437 "ISYNC" %} 5438 size(12); 5439 ins_encode( enc_ld_ac(dst, mem) ); 5440 ins_pipe(pipe_class_memory); 5441 %} 5442 5443 // LoadP + CastP2L 5444 instruct loadP2X(iRegLdst dst, memoryAlg4 mem) %{ 5445 match(Set dst (CastP2X (LoadP mem))); 5446 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5447 ins_cost(MEMORY_REF_COST); 5448 5449 format %{ "LD $dst, $mem \t// ptr + p2x" %} 5450 size(4); 5451 ins_encode( enc_ld(dst, mem) ); 5452 ins_pipe(pipe_class_memory); 5453 %} 5454 5455 // Load compressed klass pointer. 5456 instruct loadNKlass(iRegNdst dst, memory mem) %{ 5457 match(Set dst (LoadNKlass mem)); 5458 ins_cost(MEMORY_REF_COST); 5459 5460 format %{ "LWZ $dst, $mem \t// compressed klass ptr" %} 5461 size(4); 5462 ins_encode( enc_lwz(dst, mem) ); 5463 ins_pipe(pipe_class_memory); 5464 %} 5465 5466 // Load Klass Pointer 5467 instruct loadKlass(iRegPdst dst, memoryAlg4 mem) %{ 5468 match(Set dst (LoadKlass mem)); 5469 ins_cost(MEMORY_REF_COST); 5470 5471 format %{ "LD $dst, $mem \t// klass ptr" %} 5472 size(4); 5473 ins_encode( enc_ld(dst, mem) ); 5474 ins_pipe(pipe_class_memory); 5475 %} 5476 5477 // Load Float 5478 instruct loadF(regF dst, memory mem) %{ 5479 match(Set dst (LoadF mem)); 5480 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5481 ins_cost(MEMORY_REF_COST); 5482 5483 format %{ "LFS $dst, $mem" %} 5484 size(4); 5485 ins_encode %{ 5486 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 5487 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5488 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5489 %} 5490 ins_pipe(pipe_class_memory); 5491 %} 5492 5493 // Load Float acquire. 5494 instruct loadF_ac(regF dst, memory mem, flagsRegCR0 cr0) %{ 5495 match(Set dst (LoadF mem)); 5496 effect(TEMP cr0); 5497 ins_cost(3*MEMORY_REF_COST); 5498 5499 format %{ "LFS $dst, $mem \t// acquire\n\t" 5500 "FCMPU cr0, $dst, $dst\n\t" 5501 "BNE cr0, next\n" 5502 "next:\n\t" 5503 "ISYNC" %} 5504 size(16); 5505 ins_encode %{ 5506 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5507 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5508 Label next; 5509 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5510 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 5511 __ bne(CCR0, next); 5512 __ bind(next); 5513 __ isync(); 5514 %} 5515 ins_pipe(pipe_class_memory); 5516 %} 5517 5518 // Load Double - aligned 5519 instruct loadD(regD dst, memory mem) %{ 5520 match(Set dst (LoadD mem)); 5521 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5522 ins_cost(MEMORY_REF_COST); 5523 5524 format %{ "LFD $dst, $mem" %} 5525 size(4); 5526 ins_encode( enc_lfd(dst, mem) ); 5527 ins_pipe(pipe_class_memory); 5528 %} 5529 5530 // Load Double - aligned acquire. 5531 instruct loadD_ac(regD dst, memory mem, flagsRegCR0 cr0) %{ 5532 match(Set dst (LoadD mem)); 5533 effect(TEMP cr0); 5534 ins_cost(3*MEMORY_REF_COST); 5535 5536 format %{ "LFD $dst, $mem \t// acquire\n\t" 5537 "FCMPU cr0, $dst, $dst\n\t" 5538 "BNE cr0, next\n" 5539 "next:\n\t" 5540 "ISYNC" %} 5541 size(16); 5542 ins_encode %{ 5543 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5544 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5545 Label next; 5546 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5547 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 5548 __ bne(CCR0, next); 5549 __ bind(next); 5550 __ isync(); 5551 %} 5552 ins_pipe(pipe_class_memory); 5553 %} 5554 5555 // Load Double - UNaligned 5556 instruct loadD_unaligned(regD dst, memory mem) %{ 5557 match(Set dst (LoadD_unaligned mem)); 5558 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 5559 ins_cost(MEMORY_REF_COST); 5560 5561 format %{ "LFD $dst, $mem" %} 5562 size(4); 5563 ins_encode( enc_lfd(dst, mem) ); 5564 ins_pipe(pipe_class_memory); 5565 %} 5566 5567 //----------Constants-------------------------------------------------------- 5568 5569 // Load MachConstantTableBase: add hi offset to global toc. 5570 // TODO: Handle hidden register r29 in bundler! 5571 instruct loadToc_hi(iRegLdst dst) %{ 5572 effect(DEF dst); 5573 ins_cost(DEFAULT_COST); 5574 5575 format %{ "ADDIS $dst, R29, DISP.hi \t// load TOC hi" %} 5576 size(4); 5577 ins_encode %{ 5578 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 5579 __ calculate_address_from_global_toc_hi16only($dst$$Register, __ method_toc()); 5580 %} 5581 ins_pipe(pipe_class_default); 5582 %} 5583 5584 // Load MachConstantTableBase: add lo offset to global toc. 5585 instruct loadToc_lo(iRegLdst dst, iRegLdst src) %{ 5586 effect(DEF dst, USE src); 5587 ins_cost(DEFAULT_COST); 5588 5589 format %{ "ADDI $dst, $src, DISP.lo \t// load TOC lo" %} 5590 size(4); 5591 ins_encode %{ 5592 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 5593 __ calculate_address_from_global_toc_lo16only($dst$$Register, __ method_toc()); 5594 %} 5595 ins_pipe(pipe_class_default); 5596 %} 5597 5598 // Load 16-bit integer constant 0xssss???? 5599 instruct loadConI16(iRegIdst dst, immI16 src) %{ 5600 match(Set dst src); 5601 5602 format %{ "LI $dst, $src" %} 5603 size(4); 5604 ins_encode %{ 5605 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 5606 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 5607 %} 5608 ins_pipe(pipe_class_default); 5609 %} 5610 5611 // Load integer constant 0x????0000 5612 instruct loadConIhi16(iRegIdst dst, immIhi16 src) %{ 5613 match(Set dst src); 5614 ins_cost(DEFAULT_COST); 5615 5616 format %{ "LIS $dst, $src.hi" %} 5617 size(4); 5618 ins_encode %{ 5619 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 5620 // Lis sign extends 16-bit src then shifts it 16 bit to the left. 5621 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 5622 %} 5623 ins_pipe(pipe_class_default); 5624 %} 5625 5626 // Part 2 of loading 32 bit constant: hi16 is is src1 (properly shifted 5627 // and sign extended), this adds the low 16 bits. 5628 instruct loadConI32_lo16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 5629 // no match-rule, false predicate 5630 effect(DEF dst, USE src1, USE src2); 5631 predicate(false); 5632 5633 format %{ "ORI $dst, $src1.hi, $src2.lo" %} 5634 size(4); 5635 ins_encode %{ 5636 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 5637 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 5638 %} 5639 ins_pipe(pipe_class_default); 5640 %} 5641 5642 instruct loadConI_Ex(iRegIdst dst, immI src) %{ 5643 match(Set dst src); 5644 ins_cost(DEFAULT_COST*2); 5645 5646 expand %{ 5647 // Would like to use $src$$constant. 5648 immI16 srcLo %{ _opnds[1]->constant() %} 5649 // srcHi can be 0000 if srcLo sign-extends to a negative number. 5650 immIhi16 srcHi %{ _opnds[1]->constant() %} 5651 iRegIdst tmpI; 5652 loadConIhi16(tmpI, srcHi); 5653 loadConI32_lo16(dst, tmpI, srcLo); 5654 %} 5655 %} 5656 5657 // No constant pool entries required. 5658 instruct loadConL16(iRegLdst dst, immL16 src) %{ 5659 match(Set dst src); 5660 5661 format %{ "LI $dst, $src \t// long" %} 5662 size(4); 5663 ins_encode %{ 5664 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 5665 __ li($dst$$Register, (int)((short) ($src$$constant & 0xFFFF))); 5666 %} 5667 ins_pipe(pipe_class_default); 5668 %} 5669 5670 // Load long constant 0xssssssss????0000 5671 instruct loadConL32hi16(iRegLdst dst, immL32hi16 src) %{ 5672 match(Set dst src); 5673 ins_cost(DEFAULT_COST); 5674 5675 format %{ "LIS $dst, $src.hi \t// long" %} 5676 size(4); 5677 ins_encode %{ 5678 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 5679 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 5680 %} 5681 ins_pipe(pipe_class_default); 5682 %} 5683 5684 // To load a 32 bit constant: merge lower 16 bits into already loaded 5685 // high 16 bits. 5686 instruct loadConL32_lo16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 5687 // no match-rule, false predicate 5688 effect(DEF dst, USE src1, USE src2); 5689 predicate(false); 5690 5691 format %{ "ORI $dst, $src1, $src2.lo" %} 5692 size(4); 5693 ins_encode %{ 5694 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 5695 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 5696 %} 5697 ins_pipe(pipe_class_default); 5698 %} 5699 5700 // Load 32-bit long constant 5701 instruct loadConL32_Ex(iRegLdst dst, immL32 src) %{ 5702 match(Set dst src); 5703 ins_cost(DEFAULT_COST*2); 5704 5705 expand %{ 5706 // Would like to use $src$$constant. 5707 immL16 srcLo %{ _opnds[1]->constant() /*& 0x0000FFFFL */%} 5708 // srcHi can be 0000 if srcLo sign-extends to a negative number. 5709 immL32hi16 srcHi %{ _opnds[1]->constant() /*& 0xFFFF0000L */%} 5710 iRegLdst tmpL; 5711 loadConL32hi16(tmpL, srcHi); 5712 loadConL32_lo16(dst, tmpL, srcLo); 5713 %} 5714 %} 5715 5716 // Load long constant 0x????000000000000. 5717 instruct loadConLhighest16_Ex(iRegLdst dst, immLhighest16 src) %{ 5718 match(Set dst src); 5719 ins_cost(DEFAULT_COST); 5720 5721 expand %{ 5722 immL32hi16 srcHi %{ _opnds[1]->constant() >> 32 /*& 0xFFFF0000L */%} 5723 immI shift32 %{ 32 %} 5724 iRegLdst tmpL; 5725 loadConL32hi16(tmpL, srcHi); 5726 lshiftL_regL_immI(dst, tmpL, shift32); 5727 %} 5728 %} 5729 5730 // Expand node for constant pool load: small offset. 5731 instruct loadConL(iRegLdst dst, immL src, iRegLdst toc) %{ 5732 effect(DEF dst, USE src, USE toc); 5733 ins_cost(MEMORY_REF_COST); 5734 5735 ins_num_consts(1); 5736 // Needed so that CallDynamicJavaDirect can compute the address of this 5737 // instruction for relocation. 5738 ins_field_cbuf_insts_offset(int); 5739 5740 format %{ "LD $dst, offset, $toc \t// load long $src from TOC" %} 5741 size(4); 5742 ins_encode( enc_load_long_constL(dst, src, toc) ); 5743 ins_pipe(pipe_class_memory); 5744 %} 5745 5746 // Expand node for constant pool load: large offset. 5747 instruct loadConL_hi(iRegLdst dst, immL src, iRegLdst toc) %{ 5748 effect(DEF dst, USE src, USE toc); 5749 predicate(false); 5750 5751 ins_num_consts(1); 5752 ins_field_const_toc_offset(int); 5753 // Needed so that CallDynamicJavaDirect can compute the address of this 5754 // instruction for relocation. 5755 ins_field_cbuf_insts_offset(int); 5756 5757 format %{ "ADDIS $dst, $toc, offset \t// load long $src from TOC (hi)" %} 5758 size(4); 5759 ins_encode( enc_load_long_constL_hi(dst, toc, src) ); 5760 ins_pipe(pipe_class_default); 5761 %} 5762 5763 // Expand node for constant pool load: large offset. 5764 // No constant pool entries required. 5765 instruct loadConL_lo(iRegLdst dst, immL src, iRegLdst base) %{ 5766 effect(DEF dst, USE src, USE base); 5767 predicate(false); 5768 5769 ins_field_const_toc_offset_hi_node(loadConL_hiNode*); 5770 5771 format %{ "LD $dst, offset, $base \t// load long $src from TOC (lo)" %} 5772 size(4); 5773 ins_encode %{ 5774 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 5775 int offset = ra_->C->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 5776 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 5777 %} 5778 ins_pipe(pipe_class_memory); 5779 %} 5780 5781 // Load long constant from constant table. Expand in case of 5782 // offset > 16 bit is needed. 5783 // Adlc adds toc node MachConstantTableBase. 5784 instruct loadConL_Ex(iRegLdst dst, immL src) %{ 5785 match(Set dst src); 5786 ins_cost(MEMORY_REF_COST); 5787 5788 format %{ "LD $dst, offset, $constanttablebase\t// load long $src from table, postalloc expanded" %} 5789 // We can not inline the enc_class for the expand as that does not support constanttablebase. 5790 postalloc_expand( postalloc_expand_load_long_constant(dst, src, constanttablebase) ); 5791 %} 5792 5793 // Load NULL as compressed oop. 5794 instruct loadConN0(iRegNdst dst, immN_0 src) %{ 5795 match(Set dst src); 5796 ins_cost(DEFAULT_COST); 5797 5798 format %{ "LI $dst, $src \t// compressed ptr" %} 5799 size(4); 5800 ins_encode %{ 5801 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 5802 __ li($dst$$Register, 0); 5803 %} 5804 ins_pipe(pipe_class_default); 5805 %} 5806 5807 // Load hi part of compressed oop constant. 5808 instruct loadConN_hi(iRegNdst dst, immN src) %{ 5809 effect(DEF dst, USE src); 5810 ins_cost(DEFAULT_COST); 5811 5812 format %{ "LIS $dst, $src \t// narrow oop hi" %} 5813 size(4); 5814 ins_encode %{ 5815 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 5816 __ lis($dst$$Register, (int)(short)(($src$$constant >> 16) & 0xffff)); 5817 %} 5818 ins_pipe(pipe_class_default); 5819 %} 5820 5821 // Add lo part of compressed oop constant to already loaded hi part. 5822 instruct loadConN_lo(iRegNdst dst, iRegNsrc src1, immN src2) %{ 5823 effect(DEF dst, USE src1, USE src2); 5824 ins_cost(DEFAULT_COST); 5825 5826 format %{ "ORI $dst, $src1, $src2 \t// narrow oop lo" %} 5827 size(4); 5828 ins_encode %{ 5829 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 5830 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 5831 int oop_index = __ oop_recorder()->find_index((jobject)$src2$$constant); 5832 RelocationHolder rspec = oop_Relocation::spec(oop_index); 5833 __ relocate(rspec, 1); 5834 __ ori($dst$$Register, $src1$$Register, $src2$$constant & 0xffff); 5835 %} 5836 ins_pipe(pipe_class_default); 5837 %} 5838 5839 // Needed to postalloc expand loadConN: ConN is loaded as ConI 5840 // leaving the upper 32 bits with sign-extension bits. 5841 // This clears these bits: dst = src & 0xFFFFFFFF. 5842 // TODO: Eventually call this maskN_regN_FFFFFFFF. 5843 instruct clearMs32b(iRegNdst dst, iRegNsrc src) %{ 5844 effect(DEF dst, USE src); 5845 predicate(false); 5846 5847 format %{ "MASK $dst, $src, 0xFFFFFFFF" %} // mask 5848 size(4); 5849 ins_encode %{ 5850 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 5851 __ clrldi($dst$$Register, $src$$Register, 0x20); 5852 %} 5853 ins_pipe(pipe_class_default); 5854 %} 5855 5856 // Optimize DecodeN for disjoint base. 5857 // Load base of compressed oops into a register 5858 instruct loadBase(iRegLdst dst) %{ 5859 effect(DEF dst); 5860 5861 format %{ "LoadConst $dst, heapbase" %} 5862 ins_encode %{ 5863 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5864 __ load_const_optimized($dst$$Register, Universe::narrow_oop_base(), R0); 5865 %} 5866 ins_pipe(pipe_class_default); 5867 %} 5868 5869 // Loading ConN must be postalloc expanded so that edges between 5870 // the nodes are safe. They may not interfere with a safepoint. 5871 // GL TODO: This needs three instructions: better put this into the constant pool. 5872 instruct loadConN_Ex(iRegNdst dst, immN src) %{ 5873 match(Set dst src); 5874 ins_cost(DEFAULT_COST*2); 5875 5876 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 5877 postalloc_expand %{ 5878 MachNode *m1 = new loadConN_hiNode(); 5879 MachNode *m2 = new loadConN_loNode(); 5880 MachNode *m3 = new clearMs32bNode(); 5881 m1->add_req(NULL); 5882 m2->add_req(NULL, m1); 5883 m3->add_req(NULL, m2); 5884 m1->_opnds[0] = op_dst; 5885 m1->_opnds[1] = op_src; 5886 m2->_opnds[0] = op_dst; 5887 m2->_opnds[1] = op_dst; 5888 m2->_opnds[2] = op_src; 5889 m3->_opnds[0] = op_dst; 5890 m3->_opnds[1] = op_dst; 5891 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5892 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5893 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5894 nodes->push(m1); 5895 nodes->push(m2); 5896 nodes->push(m3); 5897 %} 5898 %} 5899 5900 // We have seen a safepoint between the hi and lo parts, and this node was handled 5901 // as an oop. Therefore this needs a match rule so that build_oop_map knows this is 5902 // not a narrow oop. 5903 instruct loadConNKlass_hi(iRegNdst dst, immNKlass_NM src) %{ 5904 match(Set dst src); 5905 effect(DEF dst, USE src); 5906 ins_cost(DEFAULT_COST); 5907 5908 format %{ "LIS $dst, $src \t// narrow klass hi" %} 5909 size(4); 5910 ins_encode %{ 5911 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 5912 intptr_t Csrc = Klass::encode_klass((Klass *)$src$$constant); 5913 __ lis($dst$$Register, (int)(short)((Csrc >> 16) & 0xffff)); 5914 %} 5915 ins_pipe(pipe_class_default); 5916 %} 5917 5918 // As loadConNKlass_hi this must be recognized as narrow klass, not oop! 5919 instruct loadConNKlass_mask(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 5920 match(Set dst src1); 5921 effect(TEMP src2); 5922 ins_cost(DEFAULT_COST); 5923 5924 format %{ "MASK $dst, $src2, 0xFFFFFFFF" %} // mask 5925 size(4); 5926 ins_encode %{ 5927 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 5928 __ clrldi($dst$$Register, $src2$$Register, 0x20); 5929 %} 5930 ins_pipe(pipe_class_default); 5931 %} 5932 5933 // This needs a match rule so that build_oop_map knows this is 5934 // not a narrow oop. 5935 instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 5936 match(Set dst src1); 5937 effect(TEMP src2); 5938 ins_cost(DEFAULT_COST); 5939 5940 format %{ "ORI $dst, $src1, $src2 \t// narrow klass lo" %} 5941 size(4); 5942 ins_encode %{ 5943 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 5944 intptr_t Csrc = Klass::encode_klass((Klass *)$src1$$constant); 5945 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 5946 int klass_index = __ oop_recorder()->find_index((Klass *)$src1$$constant); 5947 RelocationHolder rspec = metadata_Relocation::spec(klass_index); 5948 5949 __ relocate(rspec, 1); 5950 __ ori($dst$$Register, $src2$$Register, Csrc & 0xffff); 5951 %} 5952 ins_pipe(pipe_class_default); 5953 %} 5954 5955 // Loading ConNKlass must be postalloc expanded so that edges between 5956 // the nodes are safe. They may not interfere with a safepoint. 5957 instruct loadConNKlass_Ex(iRegNdst dst, immNKlass src) %{ 5958 match(Set dst src); 5959 ins_cost(DEFAULT_COST*2); 5960 5961 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 5962 postalloc_expand %{ 5963 // Load high bits into register. Sign extended. 5964 MachNode *m1 = new loadConNKlass_hiNode(); 5965 m1->add_req(NULL); 5966 m1->_opnds[0] = op_dst; 5967 m1->_opnds[1] = op_src; 5968 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5969 nodes->push(m1); 5970 5971 MachNode *m2 = m1; 5972 if (!Assembler::is_uimm((jlong)Klass::encode_klass((Klass *)op_src->constant()), 31)) { 5973 // Value might be 1-extended. Mask out these bits. 5974 m2 = new loadConNKlass_maskNode(); 5975 m2->add_req(NULL, m1); 5976 m2->_opnds[0] = op_dst; 5977 m2->_opnds[1] = op_src; 5978 m2->_opnds[2] = op_dst; 5979 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5980 nodes->push(m2); 5981 } 5982 5983 MachNode *m3 = new loadConNKlass_loNode(); 5984 m3->add_req(NULL, m2); 5985 m3->_opnds[0] = op_dst; 5986 m3->_opnds[1] = op_src; 5987 m3->_opnds[2] = op_dst; 5988 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5989 nodes->push(m3); 5990 %} 5991 %} 5992 5993 // 0x1 is used in object initialization (initial object header). 5994 // No constant pool entries required. 5995 instruct loadConP0or1(iRegPdst dst, immP_0or1 src) %{ 5996 match(Set dst src); 5997 5998 format %{ "LI $dst, $src \t// ptr" %} 5999 size(4); 6000 ins_encode %{ 6001 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6002 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 6003 %} 6004 ins_pipe(pipe_class_default); 6005 %} 6006 6007 // Expand node for constant pool load: small offset. 6008 // The match rule is needed to generate the correct bottom_type(), 6009 // however this node should never match. The use of predicate is not 6010 // possible since ADLC forbids predicates for chain rules. The higher 6011 // costs do not prevent matching in this case. For that reason the 6012 // operand immP_NM with predicate(false) is used. 6013 instruct loadConP(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6014 match(Set dst src); 6015 effect(TEMP toc); 6016 6017 ins_num_consts(1); 6018 6019 format %{ "LD $dst, offset, $toc \t// load ptr $src from TOC" %} 6020 size(4); 6021 ins_encode( enc_load_long_constP(dst, src, toc) ); 6022 ins_pipe(pipe_class_memory); 6023 %} 6024 6025 // Expand node for constant pool load: large offset. 6026 instruct loadConP_hi(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6027 effect(DEF dst, USE src, USE toc); 6028 predicate(false); 6029 6030 ins_num_consts(1); 6031 ins_field_const_toc_offset(int); 6032 6033 format %{ "ADDIS $dst, $toc, offset \t// load ptr $src from TOC (hi)" %} 6034 size(4); 6035 ins_encode( enc_load_long_constP_hi(dst, src, toc) ); 6036 ins_pipe(pipe_class_default); 6037 %} 6038 6039 // Expand node for constant pool load: large offset. 6040 instruct loadConP_lo(iRegPdst dst, immP_NM src, iRegLdst base) %{ 6041 match(Set dst src); 6042 effect(TEMP base); 6043 6044 ins_field_const_toc_offset_hi_node(loadConP_hiNode*); 6045 6046 format %{ "LD $dst, offset, $base \t// load ptr $src from TOC (lo)" %} 6047 size(4); 6048 ins_encode %{ 6049 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 6050 int offset = ra_->C->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 6051 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 6052 %} 6053 ins_pipe(pipe_class_memory); 6054 %} 6055 6056 // Load pointer constant from constant table. Expand in case an 6057 // offset > 16 bit is needed. 6058 // Adlc adds toc node MachConstantTableBase. 6059 instruct loadConP_Ex(iRegPdst dst, immP src) %{ 6060 match(Set dst src); 6061 ins_cost(MEMORY_REF_COST); 6062 6063 // This rule does not use "expand" because then 6064 // the result type is not known to be an Oop. An ADLC 6065 // enhancement will be needed to make that work - not worth it! 6066 6067 // If this instruction rematerializes, it prolongs the live range 6068 // of the toc node, causing illegal graphs. 6069 // assert(edge_from_to(_reg_node[reg_lo],def)) fails in verify_good_schedule(). 6070 ins_cannot_rematerialize(true); 6071 6072 format %{ "LD $dst, offset, $constanttablebase \t// load ptr $src from table, postalloc expanded" %} 6073 postalloc_expand( postalloc_expand_load_ptr_constant(dst, src, constanttablebase) ); 6074 %} 6075 6076 // Expand node for constant pool load: small offset. 6077 instruct loadConF(regF dst, immF src, iRegLdst toc) %{ 6078 effect(DEF dst, USE src, USE toc); 6079 ins_cost(MEMORY_REF_COST); 6080 6081 ins_num_consts(1); 6082 6083 format %{ "LFS $dst, offset, $toc \t// load float $src from TOC" %} 6084 size(4); 6085 ins_encode %{ 6086 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 6087 address float_address = __ float_constant($src$$constant); 6088 if (float_address == NULL) { 6089 ciEnv::current()->record_out_of_memory_failure(); 6090 return; 6091 } 6092 __ lfs($dst$$FloatRegister, __ offset_to_method_toc(float_address), $toc$$Register); 6093 %} 6094 ins_pipe(pipe_class_memory); 6095 %} 6096 6097 // Expand node for constant pool load: large offset. 6098 instruct loadConFComp(regF dst, immF src, iRegLdst toc) %{ 6099 effect(DEF dst, USE src, USE toc); 6100 ins_cost(MEMORY_REF_COST); 6101 6102 ins_num_consts(1); 6103 6104 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6105 "LFS $dst, offset_lo, $toc \t// load float $src from TOC (hi/lo)\n\t" 6106 "ADDIS $toc, $toc, -offset_hi"%} 6107 size(12); 6108 ins_encode %{ 6109 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6110 FloatRegister Rdst = $dst$$FloatRegister; 6111 Register Rtoc = $toc$$Register; 6112 address float_address = __ float_constant($src$$constant); 6113 if (float_address == NULL) { 6114 ciEnv::current()->record_out_of_memory_failure(); 6115 return; 6116 } 6117 int offset = __ offset_to_method_toc(float_address); 6118 int hi = (offset + (1<<15))>>16; 6119 int lo = offset - hi * (1<<16); 6120 6121 __ addis(Rtoc, Rtoc, hi); 6122 __ lfs(Rdst, lo, Rtoc); 6123 __ addis(Rtoc, Rtoc, -hi); 6124 %} 6125 ins_pipe(pipe_class_memory); 6126 %} 6127 6128 // Adlc adds toc node MachConstantTableBase. 6129 instruct loadConF_Ex(regF dst, immF src) %{ 6130 match(Set dst src); 6131 ins_cost(MEMORY_REF_COST); 6132 6133 // See loadConP. 6134 ins_cannot_rematerialize(true); 6135 6136 format %{ "LFS $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6137 postalloc_expand( postalloc_expand_load_float_constant(dst, src, constanttablebase) ); 6138 %} 6139 6140 // Expand node for constant pool load: small offset. 6141 instruct loadConD(regD dst, immD src, iRegLdst toc) %{ 6142 effect(DEF dst, USE src, USE toc); 6143 ins_cost(MEMORY_REF_COST); 6144 6145 ins_num_consts(1); 6146 6147 format %{ "LFD $dst, offset, $toc \t// load double $src from TOC" %} 6148 size(4); 6149 ins_encode %{ 6150 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 6151 address float_address = __ double_constant($src$$constant); 6152 if (float_address == NULL) { 6153 ciEnv::current()->record_out_of_memory_failure(); 6154 return; 6155 } 6156 int offset = __ offset_to_method_toc(float_address); 6157 __ lfd($dst$$FloatRegister, offset, $toc$$Register); 6158 %} 6159 ins_pipe(pipe_class_memory); 6160 %} 6161 6162 // Expand node for constant pool load: large offset. 6163 instruct loadConDComp(regD dst, immD src, iRegLdst toc) %{ 6164 effect(DEF dst, USE src, USE toc); 6165 ins_cost(MEMORY_REF_COST); 6166 6167 ins_num_consts(1); 6168 6169 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6170 "LFD $dst, offset_lo, $toc \t// load double $src from TOC (hi/lo)\n\t" 6171 "ADDIS $toc, $toc, -offset_hi" %} 6172 size(12); 6173 ins_encode %{ 6174 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6175 FloatRegister Rdst = $dst$$FloatRegister; 6176 Register Rtoc = $toc$$Register; 6177 address float_address = __ double_constant($src$$constant); 6178 if (float_address == NULL) { 6179 ciEnv::current()->record_out_of_memory_failure(); 6180 return; 6181 } 6182 int offset = __ offset_to_method_toc(float_address); 6183 int hi = (offset + (1<<15))>>16; 6184 int lo = offset - hi * (1<<16); 6185 6186 __ addis(Rtoc, Rtoc, hi); 6187 __ lfd(Rdst, lo, Rtoc); 6188 __ addis(Rtoc, Rtoc, -hi); 6189 %} 6190 ins_pipe(pipe_class_memory); 6191 %} 6192 6193 // Adlc adds toc node MachConstantTableBase. 6194 instruct loadConD_Ex(regD dst, immD src) %{ 6195 match(Set dst src); 6196 ins_cost(MEMORY_REF_COST); 6197 6198 // See loadConP. 6199 ins_cannot_rematerialize(true); 6200 6201 format %{ "ConD $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6202 postalloc_expand( postalloc_expand_load_double_constant(dst, src, constanttablebase) ); 6203 %} 6204 6205 // Prefetch instructions. 6206 // Must be safe to execute with invalid address (cannot fault). 6207 6208 // Special prefetch versions which use the dcbz instruction. 6209 instruct prefetch_alloc_zero(indirectMemory mem, iRegLsrc src) %{ 6210 match(PrefetchAllocation (AddP mem src)); 6211 predicate(AllocatePrefetchStyle == 3); 6212 ins_cost(MEMORY_REF_COST); 6213 6214 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many with zero" %} 6215 size(4); 6216 ins_encode %{ 6217 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6218 __ dcbz($src$$Register, $mem$$base$$Register); 6219 %} 6220 ins_pipe(pipe_class_memory); 6221 %} 6222 6223 instruct prefetch_alloc_zero_no_offset(indirectMemory mem) %{ 6224 match(PrefetchAllocation mem); 6225 predicate(AllocatePrefetchStyle == 3); 6226 ins_cost(MEMORY_REF_COST); 6227 6228 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many with zero" %} 6229 size(4); 6230 ins_encode %{ 6231 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6232 __ dcbz($mem$$base$$Register); 6233 %} 6234 ins_pipe(pipe_class_memory); 6235 %} 6236 6237 instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{ 6238 match(PrefetchAllocation (AddP mem src)); 6239 predicate(AllocatePrefetchStyle != 3); 6240 ins_cost(MEMORY_REF_COST); 6241 6242 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many" %} 6243 size(4); 6244 ins_encode %{ 6245 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6246 __ dcbtst($src$$Register, $mem$$base$$Register); 6247 %} 6248 ins_pipe(pipe_class_memory); 6249 %} 6250 6251 instruct prefetch_alloc_no_offset(indirectMemory mem) %{ 6252 match(PrefetchAllocation mem); 6253 predicate(AllocatePrefetchStyle != 3); 6254 ins_cost(MEMORY_REF_COST); 6255 6256 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many" %} 6257 size(4); 6258 ins_encode %{ 6259 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6260 __ dcbtst($mem$$base$$Register); 6261 %} 6262 ins_pipe(pipe_class_memory); 6263 %} 6264 6265 //----------Store Instructions------------------------------------------------- 6266 6267 // Store Byte 6268 instruct storeB(memory mem, iRegIsrc src) %{ 6269 match(Set mem (StoreB mem src)); 6270 ins_cost(MEMORY_REF_COST); 6271 6272 format %{ "STB $src, $mem \t// byte" %} 6273 size(4); 6274 ins_encode %{ 6275 // TODO: PPC port $archOpcode(ppc64Opcode_stb); 6276 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6277 __ stb($src$$Register, Idisp, $mem$$base$$Register); 6278 %} 6279 ins_pipe(pipe_class_memory); 6280 %} 6281 6282 instruct storeB_0(memory mem, immI_0 zero) %{ 6283 match(Set mem (StoreB mem zero)); 6284 ins_cost(MEMORY_REF_COST); 6285 6286 format %{ "STB 0, $mem \t// store 0 on a byte" %} 6287 size(4); 6288 ins_encode %{ 6289 // TODO: PPC port $archOpcode(ppc64Opcode_stb); 6290 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6291 __ stb(R30_zero, Idisp, $mem$$base$$Register); 6292 %} 6293 ins_pipe(pipe_class_memory); 6294 %} 6295 6296 // Store Char/Short 6297 instruct storeC(memory mem, iRegIsrc src) %{ 6298 match(Set mem (StoreC mem src)); 6299 ins_cost(MEMORY_REF_COST); 6300 6301 format %{ "STH $src, $mem \t// short" %} 6302 size(4); 6303 ins_encode %{ 6304 // TODO: PPC port $archOpcode(ppc64Opcode_sth); 6305 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6306 __ sth($src$$Register, Idisp, $mem$$base$$Register); 6307 %} 6308 ins_pipe(pipe_class_memory); 6309 %} 6310 6311 instruct storeC_0(memory mem, immI_0 zero) %{ 6312 match(Set mem (StoreC mem zero)); 6313 ins_cost(MEMORY_REF_COST); 6314 6315 format %{ "STH 0, $mem \t// store 0 on a short" %} 6316 size(4); 6317 ins_encode %{ 6318 // TODO: PPC port $archOpcode(ppc64Opcode_sth); 6319 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6320 __ sth(R30_zero, Idisp, $mem$$base$$Register); 6321 %} 6322 ins_pipe(pipe_class_memory); 6323 %} 6324 6325 // Store Integer 6326 instruct storeI(memory mem, iRegIsrc src) %{ 6327 match(Set mem (StoreI mem src)); 6328 ins_cost(MEMORY_REF_COST); 6329 6330 format %{ "STW $src, $mem" %} 6331 size(4); 6332 ins_encode( enc_stw(src, mem) ); 6333 ins_pipe(pipe_class_memory); 6334 %} 6335 6336 instruct storeI_0(memory mem, immI_0 zero) %{ 6337 match(Set mem (StoreI mem zero)); 6338 ins_cost(MEMORY_REF_COST); 6339 6340 format %{ "STW 0, $mem \t// store 0 on a word" %} 6341 size(4); 6342 ins_encode %{ 6343 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6344 __ stw(R30_zero, Idisp, $mem$$base$$Register); 6345 %} 6346 ins_pipe(pipe_class_memory); 6347 %} 6348 6349 // ConvL2I + StoreI. 6350 instruct storeI_convL2I(memory mem, iRegLsrc src) %{ 6351 match(Set mem (StoreI mem (ConvL2I src))); 6352 ins_cost(MEMORY_REF_COST); 6353 6354 format %{ "STW l2i($src), $mem" %} 6355 size(4); 6356 ins_encode( enc_stw(src, mem) ); 6357 ins_pipe(pipe_class_memory); 6358 %} 6359 6360 // Store Long 6361 instruct storeL(memoryAlg4 mem, iRegLsrc src) %{ 6362 match(Set mem (StoreL mem src)); 6363 ins_cost(MEMORY_REF_COST); 6364 6365 format %{ "STD $src, $mem \t// long" %} 6366 size(4); 6367 ins_encode( enc_std(src, mem) ); 6368 ins_pipe(pipe_class_memory); 6369 %} 6370 6371 instruct storeL_0(memoryAlg4 mem, immL_0 zero) %{ 6372 match(Set mem (StoreL mem zero)); 6373 ins_cost(MEMORY_REF_COST); 6374 6375 format %{ "STD 0, $mem \t// store 0 on a long" %} 6376 size(4); 6377 ins_encode %{ 6378 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6379 // Operand 'ds' requires 4-alignment. 6380 assert((Idisp & 0x3) == 0, "unaligned offset"); 6381 __ std(R30_zero, Idisp, $mem$$base$$Register); 6382 %} 6383 ins_pipe(pipe_class_memory); 6384 %} 6385 6386 // Store super word nodes. 6387 6388 // Store Aligned Packed Byte long register to memory 6389 instruct storeA8B(memoryAlg4 mem, iRegLsrc src) %{ 6390 predicate(n->as_StoreVector()->memory_size() == 8); 6391 match(Set mem (StoreVector mem src)); 6392 ins_cost(MEMORY_REF_COST); 6393 6394 format %{ "STD $mem, $src \t// packed8B" %} 6395 size(4); 6396 ins_encode( enc_std(src, mem) ); 6397 ins_pipe(pipe_class_memory); 6398 %} 6399 6400 // Store Compressed Oop 6401 instruct storeN(memory dst, iRegN_P2N src) %{ 6402 match(Set dst (StoreN dst src)); 6403 ins_cost(MEMORY_REF_COST); 6404 6405 format %{ "STW $src, $dst \t// compressed oop" %} 6406 size(4); 6407 ins_encode( enc_stw(src, dst) ); 6408 ins_pipe(pipe_class_memory); 6409 %} 6410 6411 // Store Compressed KLass 6412 instruct storeNKlass(memory dst, iRegN_P2N src) %{ 6413 match(Set dst (StoreNKlass dst src)); 6414 ins_cost(MEMORY_REF_COST); 6415 6416 format %{ "STW $src, $dst \t// compressed klass" %} 6417 size(4); 6418 ins_encode( enc_stw(src, dst) ); 6419 ins_pipe(pipe_class_memory); 6420 %} 6421 6422 // Store Pointer 6423 instruct storeP(memoryAlg4 dst, iRegPsrc src) %{ 6424 match(Set dst (StoreP dst src)); 6425 ins_cost(MEMORY_REF_COST); 6426 6427 format %{ "STD $src, $dst \t// ptr" %} 6428 size(4); 6429 ins_encode( enc_std(src, dst) ); 6430 ins_pipe(pipe_class_memory); 6431 %} 6432 6433 // Store Float 6434 instruct storeF(memory mem, regF src) %{ 6435 match(Set mem (StoreF mem src)); 6436 ins_cost(MEMORY_REF_COST); 6437 6438 format %{ "STFS $src, $mem" %} 6439 size(4); 6440 ins_encode( enc_stfs(src, mem) ); 6441 ins_pipe(pipe_class_memory); 6442 %} 6443 6444 // Store Double 6445 instruct storeD(memory mem, regD src) %{ 6446 match(Set mem (StoreD mem src)); 6447 ins_cost(MEMORY_REF_COST); 6448 6449 format %{ "STFD $src, $mem" %} 6450 size(4); 6451 ins_encode( enc_stfd(src, mem) ); 6452 ins_pipe(pipe_class_memory); 6453 %} 6454 6455 //----------Store Instructions With Zeros-------------------------------------- 6456 6457 // Card-mark for CMS garbage collection. 6458 // This cardmark does an optimization so that it must not always 6459 // do a releasing store. For this, it gets the address of 6460 // CMSCollectorCardTableModRefBSExt::_requires_release as input. 6461 // (Using releaseFieldAddr in the match rule is a hack.) 6462 instruct storeCM_CMS(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 6463 match(Set mem (StoreCM mem releaseFieldAddr)); 6464 effect(TEMP crx); 6465 predicate(false); 6466 ins_cost(MEMORY_REF_COST); 6467 6468 // See loadConP. 6469 ins_cannot_rematerialize(true); 6470 6471 format %{ "STB #0, $mem \t// CMS card-mark byte (must be 0!), checking requires_release in [$releaseFieldAddr]" %} 6472 ins_encode( enc_cms_card_mark(mem, releaseFieldAddr, crx) ); 6473 ins_pipe(pipe_class_memory); 6474 %} 6475 6476 // Card-mark for CMS garbage collection. 6477 // This cardmark does an optimization so that it must not always 6478 // do a releasing store. For this, it needs the constant address of 6479 // CMSCollectorCardTableModRefBSExt::_requires_release. 6480 // This constant address is split off here by expand so we can use 6481 // adlc / matcher functionality to load it from the constant section. 6482 instruct storeCM_CMS_ExEx(memory mem, immI_0 zero) %{ 6483 match(Set mem (StoreCM mem zero)); 6484 predicate(UseConcMarkSweepGC); 6485 6486 expand %{ 6487 immL baseImm %{ 0 /* TODO: PPC port (jlong)CMSCollectorCardTableModRefBSExt::requires_release_address() */ %} 6488 iRegLdst releaseFieldAddress; 6489 flagsReg crx; 6490 loadConL_Ex(releaseFieldAddress, baseImm); 6491 storeCM_CMS(mem, releaseFieldAddress, crx); 6492 %} 6493 %} 6494 6495 instruct storeCM_G1(memory mem, immI_0 zero) %{ 6496 match(Set mem (StoreCM mem zero)); 6497 predicate(UseG1GC); 6498 ins_cost(MEMORY_REF_COST); 6499 6500 ins_cannot_rematerialize(true); 6501 6502 format %{ "STB #0, $mem \t// CMS card-mark byte store (G1)" %} 6503 size(8); 6504 ins_encode %{ 6505 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6506 //__ release(); // G1: oops are allowed to get visible after dirty marking 6507 guarantee($mem$$base$$Register != R1_SP, "use frame_slots_bias"); 6508 __ stb(R30_zero, $mem$$disp, $mem$$base$$Register); 6509 %} 6510 ins_pipe(pipe_class_memory); 6511 %} 6512 6513 // Convert oop pointer into compressed form. 6514 6515 // Nodes for postalloc expand. 6516 6517 // Shift node for expand. 6518 instruct encodeP_shift(iRegNdst dst, iRegNsrc src) %{ 6519 // The match rule is needed to make it a 'MachTypeNode'! 6520 match(Set dst (EncodeP src)); 6521 predicate(false); 6522 6523 format %{ "SRDI $dst, $src, 3 \t// encode" %} 6524 size(4); 6525 ins_encode %{ 6526 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6527 __ srdi($dst$$Register, $src$$Register, Universe::narrow_oop_shift() & 0x3f); 6528 %} 6529 ins_pipe(pipe_class_default); 6530 %} 6531 6532 // Add node for expand. 6533 instruct encodeP_sub(iRegPdst dst, iRegPdst src) %{ 6534 // The match rule is needed to make it a 'MachTypeNode'! 6535 match(Set dst (EncodeP src)); 6536 predicate(false); 6537 6538 format %{ "SUB $dst, $src, oop_base \t// encode" %} 6539 ins_encode %{ 6540 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6541 __ sub_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 6542 %} 6543 ins_pipe(pipe_class_default); 6544 %} 6545 6546 // Conditional sub base. 6547 instruct cond_sub_base(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6548 // The match rule is needed to make it a 'MachTypeNode'! 6549 match(Set dst (EncodeP (Binary crx src1))); 6550 predicate(false); 6551 6552 format %{ "BEQ $crx, done\n\t" 6553 "SUB $dst, $src1, heapbase \t// encode: subtract base if != NULL\n" 6554 "done:" %} 6555 ins_encode %{ 6556 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6557 Label done; 6558 __ beq($crx$$CondRegister, done); 6559 __ sub_const_optimized($dst$$Register, $src1$$Register, Universe::narrow_oop_base(), R0); 6560 __ bind(done); 6561 %} 6562 ins_pipe(pipe_class_default); 6563 %} 6564 6565 // Power 7 can use isel instruction 6566 instruct cond_set_0_oop(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6567 // The match rule is needed to make it a 'MachTypeNode'! 6568 match(Set dst (EncodeP (Binary crx src1))); 6569 predicate(false); 6570 6571 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// encode: preserve 0" %} 6572 size(4); 6573 ins_encode %{ 6574 // This is a Power7 instruction for which no machine description exists. 6575 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6576 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 6577 %} 6578 ins_pipe(pipe_class_default); 6579 %} 6580 6581 // Disjoint narrow oop base. 6582 instruct encodeP_Disjoint(iRegNdst dst, iRegPsrc src) %{ 6583 match(Set dst (EncodeP src)); 6584 predicate(Universe::narrow_oop_base_disjoint()); 6585 6586 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 6587 size(4); 6588 ins_encode %{ 6589 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6590 __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_oop_shift(), 32); 6591 %} 6592 ins_pipe(pipe_class_default); 6593 %} 6594 6595 // shift != 0, base != 0 6596 instruct encodeP_Ex(iRegNdst dst, flagsReg crx, iRegPsrc src) %{ 6597 match(Set dst (EncodeP src)); 6598 effect(TEMP crx); 6599 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull && 6600 Universe::narrow_oop_shift() != 0 && 6601 Universe::narrow_oop_base_overlaps()); 6602 6603 format %{ "EncodeP $dst, $crx, $src \t// postalloc expanded" %} 6604 postalloc_expand( postalloc_expand_encode_oop(dst, src, crx)); 6605 %} 6606 6607 // shift != 0, base != 0 6608 instruct encodeP_not_null_Ex(iRegNdst dst, iRegPsrc src) %{ 6609 match(Set dst (EncodeP src)); 6610 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull && 6611 Universe::narrow_oop_shift() != 0 && 6612 Universe::narrow_oop_base_overlaps()); 6613 6614 format %{ "EncodeP $dst, $src\t// $src != Null, postalloc expanded" %} 6615 postalloc_expand( postalloc_expand_encode_oop_not_null(dst, src) ); 6616 %} 6617 6618 // shift != 0, base == 0 6619 // TODO: This is the same as encodeP_shift. Merge! 6620 instruct encodeP_not_null_base_null(iRegNdst dst, iRegPsrc src) %{ 6621 match(Set dst (EncodeP src)); 6622 predicate(Universe::narrow_oop_shift() != 0 && 6623 Universe::narrow_oop_base() ==0); 6624 6625 format %{ "SRDI $dst, $src, #3 \t// encodeP, $src != NULL" %} 6626 size(4); 6627 ins_encode %{ 6628 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6629 __ srdi($dst$$Register, $src$$Register, Universe::narrow_oop_shift() & 0x3f); 6630 %} 6631 ins_pipe(pipe_class_default); 6632 %} 6633 6634 // Compressed OOPs with narrow_oop_shift == 0. 6635 // shift == 0, base == 0 6636 instruct encodeP_narrow_oop_shift_0(iRegNdst dst, iRegPsrc src) %{ 6637 match(Set dst (EncodeP src)); 6638 predicate(Universe::narrow_oop_shift() == 0); 6639 6640 format %{ "MR $dst, $src \t// Ptr->Narrow" %} 6641 // variable size, 0 or 4. 6642 ins_encode %{ 6643 // TODO: PPC port $archOpcode(ppc64Opcode_or); 6644 __ mr_if_needed($dst$$Register, $src$$Register); 6645 %} 6646 ins_pipe(pipe_class_default); 6647 %} 6648 6649 // Decode nodes. 6650 6651 // Shift node for expand. 6652 instruct decodeN_shift(iRegPdst dst, iRegPsrc src) %{ 6653 // The match rule is needed to make it a 'MachTypeNode'! 6654 match(Set dst (DecodeN src)); 6655 predicate(false); 6656 6657 format %{ "SLDI $dst, $src, #3 \t// DecodeN" %} 6658 size(4); 6659 ins_encode %{ 6660 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 6661 __ sldi($dst$$Register, $src$$Register, Universe::narrow_oop_shift()); 6662 %} 6663 ins_pipe(pipe_class_default); 6664 %} 6665 6666 // Add node for expand. 6667 instruct decodeN_add(iRegPdst dst, iRegPdst src) %{ 6668 // The match rule is needed to make it a 'MachTypeNode'! 6669 match(Set dst (DecodeN src)); 6670 predicate(false); 6671 6672 format %{ "ADD $dst, $src, heapbase \t// DecodeN, add oop base" %} 6673 ins_encode %{ 6674 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6675 __ add_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 6676 %} 6677 ins_pipe(pipe_class_default); 6678 %} 6679 6680 // conditianal add base for expand 6681 instruct cond_add_base(iRegPdst dst, flagsRegSrc crx, iRegPsrc src) %{ 6682 // The match rule is needed to make it a 'MachTypeNode'! 6683 // NOTICE that the rule is nonsense - we just have to make sure that: 6684 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 6685 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 6686 match(Set dst (DecodeN (Binary crx src))); 6687 predicate(false); 6688 6689 format %{ "BEQ $crx, done\n\t" 6690 "ADD $dst, $src, heapbase \t// DecodeN: add oop base if $src != NULL\n" 6691 "done:" %} 6692 ins_encode %{ 6693 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6694 Label done; 6695 __ beq($crx$$CondRegister, done); 6696 __ add_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 6697 __ bind(done); 6698 %} 6699 ins_pipe(pipe_class_default); 6700 %} 6701 6702 instruct cond_set_0_ptr(iRegPdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6703 // The match rule is needed to make it a 'MachTypeNode'! 6704 // NOTICE that the rule is nonsense - we just have to make sure that: 6705 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 6706 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 6707 match(Set dst (DecodeN (Binary crx src1))); 6708 predicate(false); 6709 6710 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// decode: preserve 0" %} 6711 size(4); 6712 ins_encode %{ 6713 // This is a Power7 instruction for which no machine description exists. 6714 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6715 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 6716 %} 6717 ins_pipe(pipe_class_default); 6718 %} 6719 6720 // shift != 0, base != 0 6721 instruct decodeN_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 6722 match(Set dst (DecodeN src)); 6723 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 6724 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 6725 Universe::narrow_oop_shift() != 0 && 6726 Universe::narrow_oop_base() != 0); 6727 ins_cost(4 * DEFAULT_COST); // Should be more expensive than decodeN_Disjoint_isel_Ex. 6728 effect(TEMP crx); 6729 6730 format %{ "DecodeN $dst, $src \t// Kills $crx, postalloc expanded" %} 6731 postalloc_expand( postalloc_expand_decode_oop(dst, src, crx) ); 6732 %} 6733 6734 // shift != 0, base == 0 6735 instruct decodeN_nullBase(iRegPdst dst, iRegNsrc src) %{ 6736 match(Set dst (DecodeN src)); 6737 predicate(Universe::narrow_oop_shift() != 0 && 6738 Universe::narrow_oop_base() == 0); 6739 6740 format %{ "SLDI $dst, $src, #3 \t// DecodeN (zerobased)" %} 6741 size(4); 6742 ins_encode %{ 6743 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 6744 __ sldi($dst$$Register, $src$$Register, Universe::narrow_oop_shift()); 6745 %} 6746 ins_pipe(pipe_class_default); 6747 %} 6748 6749 // Optimize DecodeN for disjoint base. 6750 // Shift narrow oop and or it into register that already contains the heap base. 6751 // Base == dst must hold, and is assured by construction in postaloc_expand. 6752 instruct decodeN_mergeDisjoint(iRegPdst dst, iRegNsrc src, iRegLsrc base) %{ 6753 match(Set dst (DecodeN src)); 6754 effect(TEMP base); 6755 predicate(false); 6756 6757 format %{ "RLDIMI $dst, $src, shift, 32-shift \t// DecodeN (disjoint base)" %} 6758 size(4); 6759 ins_encode %{ 6760 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 6761 __ rldimi($dst$$Register, $src$$Register, Universe::narrow_oop_shift(), 32-Universe::narrow_oop_shift()); 6762 %} 6763 ins_pipe(pipe_class_default); 6764 %} 6765 6766 // Optimize DecodeN for disjoint base. 6767 // This node requires only one cycle on the critical path. 6768 // We must postalloc_expand as we can not express use_def effects where 6769 // the used register is L and the def'ed register P. 6770 instruct decodeN_Disjoint_notNull_Ex(iRegPdst dst, iRegNsrc src) %{ 6771 match(Set dst (DecodeN src)); 6772 effect(TEMP_DEF dst); 6773 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 6774 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 6775 Universe::narrow_oop_base_disjoint()); 6776 ins_cost(DEFAULT_COST); 6777 6778 format %{ "MOV $dst, heapbase \t\n" 6779 "RLDIMI $dst, $src, shift, 32-shift \t// decode with disjoint base" %} 6780 postalloc_expand %{ 6781 loadBaseNode *n1 = new loadBaseNode(); 6782 n1->add_req(NULL); 6783 n1->_opnds[0] = op_dst; 6784 6785 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 6786 n2->add_req(n_region, n_src, n1); 6787 n2->_opnds[0] = op_dst; 6788 n2->_opnds[1] = op_src; 6789 n2->_opnds[2] = op_dst; 6790 n2->_bottom_type = _bottom_type; 6791 6792 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6793 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6794 6795 nodes->push(n1); 6796 nodes->push(n2); 6797 %} 6798 %} 6799 6800 instruct decodeN_Disjoint_isel_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 6801 match(Set dst (DecodeN src)); 6802 effect(TEMP_DEF dst, TEMP crx); 6803 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 6804 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 6805 Universe::narrow_oop_base_disjoint() && VM_Version::has_isel()); 6806 ins_cost(3 * DEFAULT_COST); 6807 6808 format %{ "DecodeN $dst, $src \t// decode with disjoint base using isel" %} 6809 postalloc_expand %{ 6810 loadBaseNode *n1 = new loadBaseNode(); 6811 n1->add_req(NULL); 6812 n1->_opnds[0] = op_dst; 6813 6814 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 6815 n_compare->add_req(n_region, n_src); 6816 n_compare->_opnds[0] = op_crx; 6817 n_compare->_opnds[1] = op_src; 6818 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 6819 6820 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 6821 n2->add_req(n_region, n_src, n1); 6822 n2->_opnds[0] = op_dst; 6823 n2->_opnds[1] = op_src; 6824 n2->_opnds[2] = op_dst; 6825 n2->_bottom_type = _bottom_type; 6826 6827 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 6828 n_cond_set->add_req(n_region, n_compare, n2); 6829 n_cond_set->_opnds[0] = op_dst; 6830 n_cond_set->_opnds[1] = op_crx; 6831 n_cond_set->_opnds[2] = op_dst; 6832 n_cond_set->_bottom_type = _bottom_type; 6833 6834 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 6835 ra_->set_oop(n_cond_set, true); 6836 6837 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6838 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 6839 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6840 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6841 6842 nodes->push(n1); 6843 nodes->push(n_compare); 6844 nodes->push(n2); 6845 nodes->push(n_cond_set); 6846 %} 6847 %} 6848 6849 // src != 0, shift != 0, base != 0 6850 instruct decodeN_notNull_addBase_Ex(iRegPdst dst, iRegNsrc src) %{ 6851 match(Set dst (DecodeN src)); 6852 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 6853 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 6854 Universe::narrow_oop_shift() != 0 && 6855 Universe::narrow_oop_base() != 0); 6856 ins_cost(2 * DEFAULT_COST); 6857 6858 format %{ "DecodeN $dst, $src \t// $src != NULL, postalloc expanded" %} 6859 postalloc_expand( postalloc_expand_decode_oop_not_null(dst, src)); 6860 %} 6861 6862 // Compressed OOPs with narrow_oop_shift == 0. 6863 instruct decodeN_unscaled(iRegPdst dst, iRegNsrc src) %{ 6864 match(Set dst (DecodeN src)); 6865 predicate(Universe::narrow_oop_shift() == 0); 6866 ins_cost(DEFAULT_COST); 6867 6868 format %{ "MR $dst, $src \t// DecodeN (unscaled)" %} 6869 // variable size, 0 or 4. 6870 ins_encode %{ 6871 // TODO: PPC port $archOpcode(ppc64Opcode_or); 6872 __ mr_if_needed($dst$$Register, $src$$Register); 6873 %} 6874 ins_pipe(pipe_class_default); 6875 %} 6876 6877 // Convert compressed oop into int for vectors alignment masking. 6878 instruct decodeN2I_unscaled(iRegIdst dst, iRegNsrc src) %{ 6879 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6880 predicate(Universe::narrow_oop_shift() == 0); 6881 ins_cost(DEFAULT_COST); 6882 6883 format %{ "MR $dst, $src \t// (int)DecodeN (unscaled)" %} 6884 // variable size, 0 or 4. 6885 ins_encode %{ 6886 // TODO: PPC port $archOpcode(ppc64Opcode_or); 6887 __ mr_if_needed($dst$$Register, $src$$Register); 6888 %} 6889 ins_pipe(pipe_class_default); 6890 %} 6891 6892 // Convert klass pointer into compressed form. 6893 6894 // Nodes for postalloc expand. 6895 6896 // Shift node for expand. 6897 instruct encodePKlass_shift(iRegNdst dst, iRegNsrc src) %{ 6898 // The match rule is needed to make it a 'MachTypeNode'! 6899 match(Set dst (EncodePKlass src)); 6900 predicate(false); 6901 6902 format %{ "SRDI $dst, $src, 3 \t// encode" %} 6903 size(4); 6904 ins_encode %{ 6905 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6906 __ srdi($dst$$Register, $src$$Register, Universe::narrow_klass_shift()); 6907 %} 6908 ins_pipe(pipe_class_default); 6909 %} 6910 6911 // Add node for expand. 6912 instruct encodePKlass_sub_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 6913 // The match rule is needed to make it a 'MachTypeNode'! 6914 match(Set dst (EncodePKlass (Binary base src))); 6915 predicate(false); 6916 6917 format %{ "SUB $dst, $base, $src \t// encode" %} 6918 size(4); 6919 ins_encode %{ 6920 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 6921 __ subf($dst$$Register, $base$$Register, $src$$Register); 6922 %} 6923 ins_pipe(pipe_class_default); 6924 %} 6925 6926 // Disjoint narrow oop base. 6927 instruct encodePKlass_Disjoint(iRegNdst dst, iRegPsrc src) %{ 6928 match(Set dst (EncodePKlass src)); 6929 predicate(false /* TODO: PPC port Universe::narrow_klass_base_disjoint()*/); 6930 6931 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 6932 size(4); 6933 ins_encode %{ 6934 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6935 __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_klass_shift(), 32); 6936 %} 6937 ins_pipe(pipe_class_default); 6938 %} 6939 6940 // shift != 0, base != 0 6941 instruct encodePKlass_not_null_Ex(iRegNdst dst, iRegLsrc base, iRegPsrc src) %{ 6942 match(Set dst (EncodePKlass (Binary base src))); 6943 predicate(false); 6944 6945 format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 6946 postalloc_expand %{ 6947 encodePKlass_sub_baseNode *n1 = new encodePKlass_sub_baseNode(); 6948 n1->add_req(n_region, n_base, n_src); 6949 n1->_opnds[0] = op_dst; 6950 n1->_opnds[1] = op_base; 6951 n1->_opnds[2] = op_src; 6952 n1->_bottom_type = _bottom_type; 6953 6954 encodePKlass_shiftNode *n2 = new encodePKlass_shiftNode(); 6955 n2->add_req(n_region, n1); 6956 n2->_opnds[0] = op_dst; 6957 n2->_opnds[1] = op_dst; 6958 n2->_bottom_type = _bottom_type; 6959 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6960 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6961 6962 nodes->push(n1); 6963 nodes->push(n2); 6964 %} 6965 %} 6966 6967 // shift != 0, base != 0 6968 instruct encodePKlass_not_null_ExEx(iRegNdst dst, iRegPsrc src) %{ 6969 match(Set dst (EncodePKlass src)); 6970 //predicate(Universe::narrow_klass_shift() != 0 && 6971 // true /* TODO: PPC port Universe::narrow_klass_base_overlaps()*/); 6972 6973 //format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 6974 ins_cost(DEFAULT_COST*2); // Don't count constant. 6975 expand %{ 6976 immL baseImm %{ (jlong)(intptr_t)Universe::narrow_klass_base() %} 6977 iRegLdst base; 6978 loadConL_Ex(base, baseImm); 6979 encodePKlass_not_null_Ex(dst, base, src); 6980 %} 6981 %} 6982 6983 // Decode nodes. 6984 6985 // Shift node for expand. 6986 instruct decodeNKlass_shift(iRegPdst dst, iRegPsrc src) %{ 6987 // The match rule is needed to make it a 'MachTypeNode'! 6988 match(Set dst (DecodeNKlass src)); 6989 predicate(false); 6990 6991 format %{ "SLDI $dst, $src, #3 \t// DecodeNKlass" %} 6992 size(4); 6993 ins_encode %{ 6994 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 6995 __ sldi($dst$$Register, $src$$Register, Universe::narrow_klass_shift()); 6996 %} 6997 ins_pipe(pipe_class_default); 6998 %} 6999 7000 // Add node for expand. 7001 7002 instruct decodeNKlass_add_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 7003 // The match rule is needed to make it a 'MachTypeNode'! 7004 match(Set dst (DecodeNKlass (Binary base src))); 7005 predicate(false); 7006 7007 format %{ "ADD $dst, $base, $src \t// DecodeNKlass, add klass base" %} 7008 size(4); 7009 ins_encode %{ 7010 // TODO: PPC port $archOpcode(ppc64Opcode_add); 7011 __ add($dst$$Register, $base$$Register, $src$$Register); 7012 %} 7013 ins_pipe(pipe_class_default); 7014 %} 7015 7016 // src != 0, shift != 0, base != 0 7017 instruct decodeNKlass_notNull_addBase_Ex(iRegPdst dst, iRegLsrc base, iRegNsrc src) %{ 7018 match(Set dst (DecodeNKlass (Binary base src))); 7019 //effect(kill src); // We need a register for the immediate result after shifting. 7020 predicate(false); 7021 7022 format %{ "DecodeNKlass $dst = $base + ($src << 3) \t// $src != NULL, postalloc expanded" %} 7023 postalloc_expand %{ 7024 decodeNKlass_add_baseNode *n1 = new decodeNKlass_add_baseNode(); 7025 n1->add_req(n_region, n_base, n_src); 7026 n1->_opnds[0] = op_dst; 7027 n1->_opnds[1] = op_base; 7028 n1->_opnds[2] = op_src; 7029 n1->_bottom_type = _bottom_type; 7030 7031 decodeNKlass_shiftNode *n2 = new decodeNKlass_shiftNode(); 7032 n2->add_req(n_region, n1); 7033 n2->_opnds[0] = op_dst; 7034 n2->_opnds[1] = op_dst; 7035 n2->_bottom_type = _bottom_type; 7036 7037 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7038 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7039 7040 nodes->push(n1); 7041 nodes->push(n2); 7042 %} 7043 %} 7044 7045 // src != 0, shift != 0, base != 0 7046 instruct decodeNKlass_notNull_addBase_ExEx(iRegPdst dst, iRegNsrc src) %{ 7047 match(Set dst (DecodeNKlass src)); 7048 // predicate(Universe::narrow_klass_shift() != 0 && 7049 // Universe::narrow_klass_base() != 0); 7050 7051 //format %{ "DecodeNKlass $dst, $src \t// $src != NULL, expanded" %} 7052 7053 ins_cost(DEFAULT_COST*2); // Don't count constant. 7054 expand %{ 7055 // We add first, then we shift. Like this, we can get along with one register less. 7056 // But we have to load the base pre-shifted. 7057 immL baseImm %{ (jlong)((intptr_t)Universe::narrow_klass_base() >> Universe::narrow_klass_shift()) %} 7058 iRegLdst base; 7059 loadConL_Ex(base, baseImm); 7060 decodeNKlass_notNull_addBase_Ex(dst, base, src); 7061 %} 7062 %} 7063 7064 //----------MemBar Instructions----------------------------------------------- 7065 // Memory barrier flavors 7066 7067 instruct membar_acquire() %{ 7068 match(LoadFence); 7069 ins_cost(4*MEMORY_REF_COST); 7070 7071 format %{ "MEMBAR-acquire" %} 7072 size(4); 7073 ins_encode %{ 7074 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7075 __ acquire(); 7076 %} 7077 ins_pipe(pipe_class_default); 7078 %} 7079 7080 instruct unnecessary_membar_acquire() %{ 7081 match(MemBarAcquire); 7082 ins_cost(0); 7083 7084 format %{ " -- \t// redundant MEMBAR-acquire - empty" %} 7085 size(0); 7086 ins_encode( /*empty*/ ); 7087 ins_pipe(pipe_class_default); 7088 %} 7089 7090 instruct membar_acquire_lock() %{ 7091 match(MemBarAcquireLock); 7092 ins_cost(0); 7093 7094 format %{ " -- \t// redundant MEMBAR-acquire - empty (acquire as part of CAS in prior FastLock)" %} 7095 size(0); 7096 ins_encode( /*empty*/ ); 7097 ins_pipe(pipe_class_default); 7098 %} 7099 7100 instruct membar_release() %{ 7101 match(MemBarRelease); 7102 match(StoreFence); 7103 ins_cost(4*MEMORY_REF_COST); 7104 7105 format %{ "MEMBAR-release" %} 7106 size(4); 7107 ins_encode %{ 7108 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7109 __ release(); 7110 %} 7111 ins_pipe(pipe_class_default); 7112 %} 7113 7114 instruct membar_storestore() %{ 7115 match(MemBarStoreStore); 7116 ins_cost(4*MEMORY_REF_COST); 7117 7118 format %{ "MEMBAR-store-store" %} 7119 size(4); 7120 ins_encode %{ 7121 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7122 __ membar(Assembler::StoreStore); 7123 %} 7124 ins_pipe(pipe_class_default); 7125 %} 7126 7127 instruct membar_release_lock() %{ 7128 match(MemBarReleaseLock); 7129 ins_cost(0); 7130 7131 format %{ " -- \t// redundant MEMBAR-release - empty (release in FastUnlock)" %} 7132 size(0); 7133 ins_encode( /*empty*/ ); 7134 ins_pipe(pipe_class_default); 7135 %} 7136 7137 instruct membar_volatile() %{ 7138 match(MemBarVolatile); 7139 ins_cost(4*MEMORY_REF_COST); 7140 7141 format %{ "MEMBAR-volatile" %} 7142 size(4); 7143 ins_encode %{ 7144 // TODO: PPC port $archOpcode(ppc64Opcode_sync); 7145 __ fence(); 7146 %} 7147 ins_pipe(pipe_class_default); 7148 %} 7149 7150 // This optimization is wrong on PPC. The following pattern is not supported: 7151 // MemBarVolatile 7152 // ^ ^ 7153 // | | 7154 // CtrlProj MemProj 7155 // ^ ^ 7156 // | | 7157 // | Load 7158 // | 7159 // MemBarVolatile 7160 // 7161 // The first MemBarVolatile could get optimized out! According to 7162 // Vladimir, this pattern can not occur on Oracle platforms. 7163 // However, it does occur on PPC64 (because of membars in 7164 // inline_unsafe_load_store). 7165 // 7166 // Add this node again if we found a good solution for inline_unsafe_load_store(). 7167 // Don't forget to look at the implementation of post_store_load_barrier again, 7168 // we did other fixes in that method. 7169 //instruct unnecessary_membar_volatile() %{ 7170 // match(MemBarVolatile); 7171 // predicate(Matcher::post_store_load_barrier(n)); 7172 // ins_cost(0); 7173 // 7174 // format %{ " -- \t// redundant MEMBAR-volatile - empty" %} 7175 // size(0); 7176 // ins_encode( /*empty*/ ); 7177 // ins_pipe(pipe_class_default); 7178 //%} 7179 7180 instruct membar_CPUOrder() %{ 7181 match(MemBarCPUOrder); 7182 ins_cost(0); 7183 7184 format %{ " -- \t// MEMBAR-CPUOrder - empty: PPC64 processors are self-consistent." %} 7185 size(0); 7186 ins_encode( /*empty*/ ); 7187 ins_pipe(pipe_class_default); 7188 %} 7189 7190 //----------Conditional Move--------------------------------------------------- 7191 7192 // Cmove using isel. 7193 instruct cmovI_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7194 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7195 predicate(VM_Version::has_isel()); 7196 ins_cost(DEFAULT_COST); 7197 7198 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7199 size(4); 7200 ins_encode %{ 7201 // This is a Power7 instruction for which no machine description 7202 // exists. Anyways, the scheduler should be off on Power7. 7203 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7204 int cc = $cmp$$cmpcode; 7205 __ isel($dst$$Register, $crx$$CondRegister, 7206 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7207 %} 7208 ins_pipe(pipe_class_default); 7209 %} 7210 7211 instruct cmovI_reg(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7212 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7213 predicate(!VM_Version::has_isel()); 7214 ins_cost(DEFAULT_COST+BRANCH_COST); 7215 7216 ins_variable_size_depending_on_alignment(true); 7217 7218 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7219 // Worst case is branch + move + stop, no stop without scheduler 7220 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7221 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7222 ins_pipe(pipe_class_default); 7223 %} 7224 7225 instruct cmovI_imm(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, immI16 src) %{ 7226 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7227 ins_cost(DEFAULT_COST+BRANCH_COST); 7228 7229 ins_variable_size_depending_on_alignment(true); 7230 7231 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7232 // Worst case is branch + move + stop, no stop without scheduler 7233 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7234 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7235 ins_pipe(pipe_class_default); 7236 %} 7237 7238 // Cmove using isel. 7239 instruct cmovL_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7240 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7241 predicate(VM_Version::has_isel()); 7242 ins_cost(DEFAULT_COST); 7243 7244 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7245 size(4); 7246 ins_encode %{ 7247 // This is a Power7 instruction for which no machine description 7248 // exists. Anyways, the scheduler should be off on Power7. 7249 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7250 int cc = $cmp$$cmpcode; 7251 __ isel($dst$$Register, $crx$$CondRegister, 7252 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7253 %} 7254 ins_pipe(pipe_class_default); 7255 %} 7256 7257 instruct cmovL_reg(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7258 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7259 predicate(!VM_Version::has_isel()); 7260 ins_cost(DEFAULT_COST+BRANCH_COST); 7261 7262 ins_variable_size_depending_on_alignment(true); 7263 7264 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7265 // Worst case is branch + move + stop, no stop without scheduler. 7266 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7267 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7268 ins_pipe(pipe_class_default); 7269 %} 7270 7271 instruct cmovL_imm(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, immL16 src) %{ 7272 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7273 ins_cost(DEFAULT_COST+BRANCH_COST); 7274 7275 ins_variable_size_depending_on_alignment(true); 7276 7277 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7278 // Worst case is branch + move + stop, no stop without scheduler. 7279 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7280 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7281 ins_pipe(pipe_class_default); 7282 %} 7283 7284 // Cmove using isel. 7285 instruct cmovN_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7286 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7287 predicate(VM_Version::has_isel()); 7288 ins_cost(DEFAULT_COST); 7289 7290 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7291 size(4); 7292 ins_encode %{ 7293 // This is a Power7 instruction for which no machine description 7294 // exists. Anyways, the scheduler should be off on Power7. 7295 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7296 int cc = $cmp$$cmpcode; 7297 __ isel($dst$$Register, $crx$$CondRegister, 7298 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7299 %} 7300 ins_pipe(pipe_class_default); 7301 %} 7302 7303 // Conditional move for RegN. Only cmov(reg, reg). 7304 instruct cmovN_reg(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7305 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7306 predicate(!VM_Version::has_isel()); 7307 ins_cost(DEFAULT_COST+BRANCH_COST); 7308 7309 ins_variable_size_depending_on_alignment(true); 7310 7311 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7312 // Worst case is branch + move + stop, no stop without scheduler. 7313 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7314 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7315 ins_pipe(pipe_class_default); 7316 %} 7317 7318 instruct cmovN_imm(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, immN_0 src) %{ 7319 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7320 ins_cost(DEFAULT_COST+BRANCH_COST); 7321 7322 ins_variable_size_depending_on_alignment(true); 7323 7324 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7325 // Worst case is branch + move + stop, no stop without scheduler. 7326 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7327 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7328 ins_pipe(pipe_class_default); 7329 %} 7330 7331 // Cmove using isel. 7332 instruct cmovP_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegPsrc src) %{ 7333 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7334 predicate(VM_Version::has_isel()); 7335 ins_cost(DEFAULT_COST); 7336 7337 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7338 size(4); 7339 ins_encode %{ 7340 // This is a Power7 instruction for which no machine description 7341 // exists. Anyways, the scheduler should be off on Power7. 7342 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7343 int cc = $cmp$$cmpcode; 7344 __ isel($dst$$Register, $crx$$CondRegister, 7345 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7346 %} 7347 ins_pipe(pipe_class_default); 7348 %} 7349 7350 instruct cmovP_reg(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegP_N2P src) %{ 7351 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7352 predicate(!VM_Version::has_isel()); 7353 ins_cost(DEFAULT_COST+BRANCH_COST); 7354 7355 ins_variable_size_depending_on_alignment(true); 7356 7357 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7358 // Worst case is branch + move + stop, no stop without scheduler. 7359 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7360 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7361 ins_pipe(pipe_class_default); 7362 %} 7363 7364 instruct cmovP_imm(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, immP_0 src) %{ 7365 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7366 ins_cost(DEFAULT_COST+BRANCH_COST); 7367 7368 ins_variable_size_depending_on_alignment(true); 7369 7370 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7371 // Worst case is branch + move + stop, no stop without scheduler. 7372 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7373 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7374 ins_pipe(pipe_class_default); 7375 %} 7376 7377 instruct cmovF_reg(cmpOp cmp, flagsRegSrc crx, regF dst, regF src) %{ 7378 match(Set dst (CMoveF (Binary cmp crx) (Binary dst src))); 7379 ins_cost(DEFAULT_COST+BRANCH_COST); 7380 7381 ins_variable_size_depending_on_alignment(true); 7382 7383 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7384 // Worst case is branch + move + stop, no stop without scheduler. 7385 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 7386 ins_encode %{ 7387 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7388 Label done; 7389 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7390 // Branch if not (cmp crx). 7391 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7392 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7393 // TODO PPC port __ endgroup_if_needed(_size == 12); 7394 __ bind(done); 7395 %} 7396 ins_pipe(pipe_class_default); 7397 %} 7398 7399 instruct cmovD_reg(cmpOp cmp, flagsRegSrc crx, regD dst, regD src) %{ 7400 match(Set dst (CMoveD (Binary cmp crx) (Binary dst src))); 7401 ins_cost(DEFAULT_COST+BRANCH_COST); 7402 7403 ins_variable_size_depending_on_alignment(true); 7404 7405 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7406 // Worst case is branch + move + stop, no stop without scheduler. 7407 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 7408 ins_encode %{ 7409 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7410 Label done; 7411 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7412 // Branch if not (cmp crx). 7413 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7414 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7415 // TODO PPC port __ endgroup_if_needed(_size == 12); 7416 __ bind(done); 7417 %} 7418 ins_pipe(pipe_class_default); 7419 %} 7420 7421 //----------Conditional_store-------------------------------------------------- 7422 // Conditional-store of the updated heap-top. 7423 // Used during allocation of the shared heap. 7424 // Sets flags (EQ) on success. Implemented with a CASA on Sparc. 7425 7426 // As compareAndSwapL, but return flag register instead of boolean value in 7427 // int register. 7428 // Used by sun/misc/AtomicLongCSImpl.java. 7429 // Mem_ptr must be a memory operand, else this node does not get 7430 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7431 // can be rematerialized which leads to errors. 7432 instruct storeLConditional_regP_regL_regL(flagsReg crx, indirect mem_ptr, iRegLsrc oldVal, iRegLsrc newVal, flagsRegCR0 cr0) %{ 7433 match(Set crx (StoreLConditional mem_ptr (Binary oldVal newVal))); 7434 effect(TEMP cr0); 7435 format %{ "CMPXCHGD if ($crx = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7436 ins_encode %{ 7437 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7438 __ cmpxchgd($crx$$CondRegister, R0, $oldVal$$Register, $newVal$$Register, $mem_ptr$$Register, 7439 MacroAssembler::MemBarAcq, MacroAssembler::cmpxchgx_hint_atomic_update(), 7440 noreg, NULL, true); 7441 %} 7442 ins_pipe(pipe_class_default); 7443 %} 7444 7445 // As compareAndSwapP, but return flag register instead of boolean value in 7446 // int register. 7447 // This instruction is matched if UseTLAB is off. 7448 // Mem_ptr must be a memory operand, else this node does not get 7449 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7450 // can be rematerialized which leads to errors. 7451 instruct storePConditional_regP_regP_regP(flagsRegCR0 cr0, indirect mem_ptr, iRegPsrc oldVal, iRegPsrc newVal) %{ 7452 match(Set cr0 (StorePConditional mem_ptr (Binary oldVal newVal))); 7453 ins_cost(2*MEMORY_REF_COST); 7454 7455 format %{ "STDCX_ if ($cr0 = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7456 ins_encode %{ 7457 // TODO: PPC port $archOpcode(ppc64Opcode_stdcx_); 7458 __ stdcx_($newVal$$Register, $mem_ptr$$Register); 7459 %} 7460 ins_pipe(pipe_class_memory); 7461 %} 7462 7463 // Implement LoadPLocked. Must be ordered against changes of the memory location 7464 // by storePConditional. 7465 // Don't know whether this is ever used. 7466 instruct loadPLocked(iRegPdst dst, memory mem) %{ 7467 match(Set dst (LoadPLocked mem)); 7468 ins_cost(2*MEMORY_REF_COST); 7469 7470 format %{ "LDARX $dst, $mem \t// loadPLocked\n\t" %} 7471 size(4); 7472 ins_encode %{ 7473 // TODO: PPC port $archOpcode(ppc64Opcode_ldarx); 7474 __ ldarx($dst$$Register, $mem$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 7475 %} 7476 ins_pipe(pipe_class_memory); 7477 %} 7478 7479 //----------Compare-And-Swap--------------------------------------------------- 7480 7481 // CompareAndSwap{P,I,L} have more than one output, therefore "CmpI 7482 // (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be 7483 // matched. 7484 7485 // Strong versions: 7486 7487 instruct compareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7488 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7489 predicate(VM_Version::has_lqarx()); 7490 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7491 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7492 ins_encode %{ 7493 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7494 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7495 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7496 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7497 $res$$Register, true); 7498 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7499 __ isync(); 7500 } else { 7501 __ sync(); 7502 } 7503 %} 7504 ins_pipe(pipe_class_default); 7505 %} 7506 7507 instruct compareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7508 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7509 predicate(!VM_Version::has_lqarx()); 7510 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7511 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7512 ins_encode %{ 7513 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7514 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7515 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7516 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7517 $res$$Register, true); 7518 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7519 __ isync(); 7520 } else { 7521 __ sync(); 7522 } 7523 %} 7524 ins_pipe(pipe_class_default); 7525 %} 7526 7527 instruct compareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7528 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7529 predicate(VM_Version::has_lqarx()); 7530 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7531 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7532 ins_encode %{ 7533 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7534 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7535 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7536 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7537 $res$$Register, true); 7538 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7539 __ isync(); 7540 } else { 7541 __ sync(); 7542 } 7543 %} 7544 ins_pipe(pipe_class_default); 7545 %} 7546 7547 instruct compareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7548 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7549 predicate(!VM_Version::has_lqarx()); 7550 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7551 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7552 ins_encode %{ 7553 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7554 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7555 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7556 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7557 $res$$Register, true); 7558 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7559 __ isync(); 7560 } else { 7561 __ sync(); 7562 } 7563 %} 7564 ins_pipe(pipe_class_default); 7565 %} 7566 7567 instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7568 match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2))); 7569 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7570 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7571 ins_encode %{ 7572 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7573 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7574 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7575 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7576 $res$$Register, true); 7577 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7578 __ isync(); 7579 } else { 7580 __ sync(); 7581 } 7582 %} 7583 ins_pipe(pipe_class_default); 7584 %} 7585 7586 instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 7587 match(Set res (CompareAndSwapN mem_ptr (Binary src1 src2))); 7588 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7589 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7590 ins_encode %{ 7591 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7592 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7593 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7594 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7595 $res$$Register, true); 7596 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7597 __ isync(); 7598 } else { 7599 __ sync(); 7600 } 7601 %} 7602 ins_pipe(pipe_class_default); 7603 %} 7604 7605 instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 7606 match(Set res (CompareAndSwapL mem_ptr (Binary src1 src2))); 7607 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7608 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 7609 ins_encode %{ 7610 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7611 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7612 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7613 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7614 $res$$Register, NULL, true); 7615 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7616 __ isync(); 7617 } else { 7618 __ sync(); 7619 } 7620 %} 7621 ins_pipe(pipe_class_default); 7622 %} 7623 7624 instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 7625 match(Set res (CompareAndSwapP mem_ptr (Binary src1 src2))); 7626 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7627 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 7628 ins_encode %{ 7629 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7630 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7631 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7632 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7633 $res$$Register, NULL, true); 7634 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7635 __ isync(); 7636 } else { 7637 __ sync(); 7638 } 7639 %} 7640 ins_pipe(pipe_class_default); 7641 %} 7642 7643 // Weak versions: 7644 7645 instruct weakCompareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7646 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7647 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7648 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7649 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7650 ins_encode %{ 7651 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7652 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7653 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7654 MacroAssembler::MemBarNone, 7655 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7656 %} 7657 ins_pipe(pipe_class_default); 7658 %} 7659 7660 instruct weakCompareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7661 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7662 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 7663 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7664 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7665 ins_encode %{ 7666 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7667 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7668 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7669 MacroAssembler::MemBarNone, 7670 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7671 %} 7672 ins_pipe(pipe_class_default); 7673 %} 7674 7675 instruct weakCompareAndSwapB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7676 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7677 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 7678 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7679 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 7680 ins_encode %{ 7681 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7682 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7683 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7684 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7685 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7686 %} 7687 ins_pipe(pipe_class_default); 7688 %} 7689 7690 instruct weakCompareAndSwapB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7691 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7692 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 7693 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7694 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 7695 ins_encode %{ 7696 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7697 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7698 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7699 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7700 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7701 %} 7702 ins_pipe(pipe_class_default); 7703 %} 7704 7705 instruct weakCompareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7706 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 7707 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7708 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7709 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7710 ins_encode %{ 7711 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7712 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7713 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7714 MacroAssembler::MemBarNone, 7715 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7716 %} 7717 ins_pipe(pipe_class_default); 7718 %} 7719 7720 instruct weakCompareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7721 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 7722 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 7723 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7724 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7725 ins_encode %{ 7726 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7727 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7728 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7729 MacroAssembler::MemBarNone, 7730 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7731 %} 7732 ins_pipe(pipe_class_default); 7733 %} 7734 7735 instruct weakCompareAndSwapS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7736 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 7737 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 7738 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7739 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 7740 ins_encode %{ 7741 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7742 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7743 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7744 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7745 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7746 %} 7747 ins_pipe(pipe_class_default); 7748 %} 7749 7750 instruct weakCompareAndSwapS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7751 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 7752 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 7753 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7754 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 7755 ins_encode %{ 7756 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7757 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7758 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$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 weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7766 match(Set res (WeakCompareAndSwapI 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 CMPXCHGW $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 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7774 MacroAssembler::MemBarNone, 7775 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7776 %} 7777 ins_pipe(pipe_class_default); 7778 %} 7779 7780 instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7781 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 7782 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 7783 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7784 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 7785 ins_encode %{ 7786 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7787 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7788 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 7789 // value is never passed to caller. 7790 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7791 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7792 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7793 %} 7794 ins_pipe(pipe_class_default); 7795 %} 7796 7797 instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 7798 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 7799 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7800 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7801 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7802 ins_encode %{ 7803 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7804 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7805 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7806 MacroAssembler::MemBarNone, 7807 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7808 %} 7809 ins_pipe(pipe_class_default); 7810 %} 7811 7812 instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 7813 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 7814 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 7815 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7816 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 7817 ins_encode %{ 7818 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7819 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7820 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 7821 // value is never passed to caller. 7822 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7823 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7824 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7825 %} 7826 ins_pipe(pipe_class_default); 7827 %} 7828 7829 instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 7830 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 7831 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7832 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7833 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 7834 ins_encode %{ 7835 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7836 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7837 // value is never passed to caller. 7838 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7839 MacroAssembler::MemBarNone, 7840 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 7841 %} 7842 ins_pipe(pipe_class_default); 7843 %} 7844 7845 instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 7846 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 7847 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 7848 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7849 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %} 7850 ins_encode %{ 7851 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7852 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7853 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 7854 // value is never passed to caller. 7855 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7856 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7857 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 7858 %} 7859 ins_pipe(pipe_class_default); 7860 %} 7861 7862 instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 7863 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 7864 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7865 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7866 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 7867 ins_encode %{ 7868 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7869 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7870 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7871 MacroAssembler::MemBarNone, 7872 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 7873 %} 7874 ins_pipe(pipe_class_default); 7875 %} 7876 7877 instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 7878 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 7879 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 7880 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7881 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 7882 ins_encode %{ 7883 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7884 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7885 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 7886 // value is never passed to caller. 7887 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7888 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7889 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 7890 %} 7891 ins_pipe(pipe_class_default); 7892 %} 7893 7894 // CompareAndExchange 7895 7896 instruct compareAndExchangeB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7897 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 7898 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7899 effect(TEMP_DEF res, TEMP cr0); 7900 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 7901 ins_encode %{ 7902 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7903 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7904 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7905 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7906 noreg, true); 7907 %} 7908 ins_pipe(pipe_class_default); 7909 %} 7910 7911 instruct compareAndExchangeB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 7912 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 7913 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 7914 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 7915 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 7916 ins_encode %{ 7917 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7918 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7919 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 7920 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7921 noreg, true); 7922 %} 7923 ins_pipe(pipe_class_default); 7924 %} 7925 7926 instruct compareAndExchangeB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7927 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 7928 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 7929 effect(TEMP_DEF res, TEMP cr0); 7930 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 7931 ins_encode %{ 7932 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7933 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7934 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7935 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7936 noreg, true); 7937 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7938 __ isync(); 7939 } else { 7940 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 7941 __ sync(); 7942 } 7943 %} 7944 ins_pipe(pipe_class_default); 7945 %} 7946 7947 instruct compareAndExchangeB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 7948 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 7949 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 7950 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 7951 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 7952 ins_encode %{ 7953 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7954 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7955 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 7956 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7957 noreg, true); 7958 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7959 __ isync(); 7960 } else { 7961 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 7962 __ sync(); 7963 } 7964 %} 7965 ins_pipe(pipe_class_default); 7966 %} 7967 7968 instruct compareAndExchangeS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7969 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 7970 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7971 effect(TEMP_DEF res, TEMP cr0); 7972 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 7973 ins_encode %{ 7974 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7975 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7976 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7977 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7978 noreg, true); 7979 %} 7980 ins_pipe(pipe_class_default); 7981 %} 7982 7983 instruct compareAndExchangeS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 7984 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 7985 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 7986 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 7987 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 7988 ins_encode %{ 7989 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7990 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7991 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 7992 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7993 noreg, true); 7994 %} 7995 ins_pipe(pipe_class_default); 7996 %} 7997 7998 instruct compareAndExchangeS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7999 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8000 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 8001 effect(TEMP_DEF res, TEMP cr0); 8002 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 8003 ins_encode %{ 8004 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8005 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8006 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 8007 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8008 noreg, true); 8009 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8010 __ isync(); 8011 } else { 8012 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8013 __ sync(); 8014 } 8015 %} 8016 ins_pipe(pipe_class_default); 8017 %} 8018 8019 instruct compareAndExchangeS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 8020 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 8021 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 8022 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 8023 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 8024 ins_encode %{ 8025 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8026 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8027 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 8028 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8029 noreg, true); 8030 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8031 __ isync(); 8032 } else { 8033 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8034 __ sync(); 8035 } 8036 %} 8037 ins_pipe(pipe_class_default); 8038 %} 8039 8040 instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8041 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8042 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8043 effect(TEMP_DEF res, TEMP cr0); 8044 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %} 8045 ins_encode %{ 8046 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8047 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8048 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8049 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8050 noreg, true); 8051 %} 8052 ins_pipe(pipe_class_default); 8053 %} 8054 8055 instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8056 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8057 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8058 effect(TEMP_DEF res, TEMP cr0); 8059 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %} 8060 ins_encode %{ 8061 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8062 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8063 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8064 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8065 noreg, true); 8066 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8067 __ isync(); 8068 } else { 8069 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8070 __ sync(); 8071 } 8072 %} 8073 ins_pipe(pipe_class_default); 8074 %} 8075 8076 instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8077 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8078 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8079 effect(TEMP_DEF res, TEMP cr0); 8080 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8081 ins_encode %{ 8082 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8083 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8084 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8085 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8086 noreg, true); 8087 %} 8088 ins_pipe(pipe_class_default); 8089 %} 8090 8091 instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8092 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8093 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8094 effect(TEMP_DEF res, TEMP cr0); 8095 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8096 ins_encode %{ 8097 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8098 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8099 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8100 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8101 noreg, true); 8102 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8103 __ isync(); 8104 } else { 8105 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8106 __ sync(); 8107 } 8108 %} 8109 ins_pipe(pipe_class_default); 8110 %} 8111 8112 instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8113 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8114 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8115 effect(TEMP_DEF res, TEMP cr0); 8116 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %} 8117 ins_encode %{ 8118 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8119 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8120 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8121 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8122 noreg, NULL, true); 8123 %} 8124 ins_pipe(pipe_class_default); 8125 %} 8126 8127 instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8128 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8129 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8130 effect(TEMP_DEF res, TEMP cr0); 8131 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %} 8132 ins_encode %{ 8133 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8134 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8135 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8136 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8137 noreg, NULL, true); 8138 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8139 __ isync(); 8140 } else { 8141 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8142 __ sync(); 8143 } 8144 %} 8145 ins_pipe(pipe_class_default); 8146 %} 8147 8148 instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8149 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8150 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8151 effect(TEMP_DEF res, TEMP cr0); 8152 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8153 ins_encode %{ 8154 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8155 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8156 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8157 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8158 noreg, NULL, true); 8159 %} 8160 ins_pipe(pipe_class_default); 8161 %} 8162 8163 instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8164 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8165 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8166 effect(TEMP_DEF res, TEMP cr0); 8167 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8168 ins_encode %{ 8169 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8170 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8171 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8172 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8173 noreg, NULL, true); 8174 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8175 __ isync(); 8176 } else { 8177 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8178 __ sync(); 8179 } 8180 %} 8181 ins_pipe(pipe_class_default); 8182 %} 8183 8184 // Special RMW 8185 8186 instruct getAndAddB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8187 match(Set res (GetAndAddB mem_ptr src)); 8188 predicate(VM_Version::has_lqarx()); 8189 effect(TEMP_DEF res, TEMP cr0); 8190 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8191 ins_encode %{ 8192 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8193 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8194 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8195 __ isync(); 8196 } else { 8197 __ sync(); 8198 } 8199 %} 8200 ins_pipe(pipe_class_default); 8201 %} 8202 8203 instruct getAndAddB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8204 match(Set res (GetAndAddB mem_ptr src)); 8205 predicate(!VM_Version::has_lqarx()); 8206 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8207 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8208 ins_encode %{ 8209 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8210 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8211 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8212 __ isync(); 8213 } else { 8214 __ sync(); 8215 } 8216 %} 8217 ins_pipe(pipe_class_default); 8218 %} 8219 8220 instruct getAndAddS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8221 match(Set res (GetAndAddS mem_ptr src)); 8222 predicate(VM_Version::has_lqarx()); 8223 effect(TEMP_DEF res, TEMP cr0); 8224 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8225 ins_encode %{ 8226 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8227 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8228 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8229 __ isync(); 8230 } else { 8231 __ sync(); 8232 } 8233 %} 8234 ins_pipe(pipe_class_default); 8235 %} 8236 8237 instruct getAndAddS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8238 match(Set res (GetAndAddS mem_ptr src)); 8239 predicate(!VM_Version::has_lqarx()); 8240 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8241 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8242 ins_encode %{ 8243 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8244 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8245 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8246 __ isync(); 8247 } else { 8248 __ sync(); 8249 } 8250 %} 8251 ins_pipe(pipe_class_default); 8252 %} 8253 8254 instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8255 match(Set res (GetAndAddI mem_ptr src)); 8256 effect(TEMP_DEF res, TEMP cr0); 8257 format %{ "GetAndAddI $res, $mem_ptr, $src" %} 8258 ins_encode %{ 8259 __ getandaddw($res$$Register, $src$$Register, $mem_ptr$$Register, 8260 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8261 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8262 __ isync(); 8263 } else { 8264 __ sync(); 8265 } 8266 %} 8267 ins_pipe(pipe_class_default); 8268 %} 8269 8270 instruct getAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8271 match(Set res (GetAndAddL mem_ptr src)); 8272 effect(TEMP_DEF res, TEMP cr0); 8273 format %{ "GetAndAddL $res, $mem_ptr, $src" %} 8274 ins_encode %{ 8275 __ getandaddd($res$$Register, $src$$Register, $mem_ptr$$Register, 8276 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8277 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8278 __ isync(); 8279 } else { 8280 __ sync(); 8281 } 8282 %} 8283 ins_pipe(pipe_class_default); 8284 %} 8285 8286 instruct getAndSetB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8287 match(Set res (GetAndSetB mem_ptr src)); 8288 predicate(VM_Version::has_lqarx()); 8289 effect(TEMP_DEF res, TEMP cr0); 8290 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8291 ins_encode %{ 8292 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8293 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8294 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8295 __ isync(); 8296 } else { 8297 __ sync(); 8298 } 8299 %} 8300 ins_pipe(pipe_class_default); 8301 %} 8302 8303 instruct getAndSetB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8304 match(Set res (GetAndSetB mem_ptr src)); 8305 predicate(!VM_Version::has_lqarx()); 8306 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8307 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8308 ins_encode %{ 8309 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8310 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8311 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8312 __ isync(); 8313 } else { 8314 __ sync(); 8315 } 8316 %} 8317 ins_pipe(pipe_class_default); 8318 %} 8319 8320 instruct getAndSetS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8321 match(Set res (GetAndSetS mem_ptr src)); 8322 predicate(VM_Version::has_lqarx()); 8323 effect(TEMP_DEF res, TEMP cr0); 8324 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8325 ins_encode %{ 8326 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8327 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8328 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8329 __ isync(); 8330 } else { 8331 __ sync(); 8332 } 8333 %} 8334 ins_pipe(pipe_class_default); 8335 %} 8336 8337 instruct getAndSetS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8338 match(Set res (GetAndSetS mem_ptr src)); 8339 predicate(!VM_Version::has_lqarx()); 8340 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8341 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8342 ins_encode %{ 8343 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8344 R0, $tmp1$$Register, $tmp2$$Register, 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 instruct getAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8355 match(Set res (GetAndSetI mem_ptr src)); 8356 effect(TEMP_DEF res, TEMP cr0); 8357 format %{ "GetAndSetI $res, $mem_ptr, $src" %} 8358 ins_encode %{ 8359 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8360 MacroAssembler::cmpxchgx_hint_atomic_update()); 8361 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8362 __ isync(); 8363 } else { 8364 __ sync(); 8365 } 8366 %} 8367 ins_pipe(pipe_class_default); 8368 %} 8369 8370 instruct getAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8371 match(Set res (GetAndSetL mem_ptr src)); 8372 effect(TEMP_DEF res, TEMP cr0); 8373 format %{ "GetAndSetL $res, $mem_ptr, $src" %} 8374 ins_encode %{ 8375 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8376 MacroAssembler::cmpxchgx_hint_atomic_update()); 8377 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8378 __ isync(); 8379 } else { 8380 __ sync(); 8381 } 8382 %} 8383 ins_pipe(pipe_class_default); 8384 %} 8385 8386 instruct getAndSetP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src, flagsRegCR0 cr0) %{ 8387 match(Set res (GetAndSetP mem_ptr src)); 8388 effect(TEMP_DEF res, TEMP cr0); 8389 format %{ "GetAndSetP $res, $mem_ptr, $src" %} 8390 ins_encode %{ 8391 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8392 MacroAssembler::cmpxchgx_hint_atomic_update()); 8393 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8394 __ isync(); 8395 } else { 8396 __ sync(); 8397 } 8398 %} 8399 ins_pipe(pipe_class_default); 8400 %} 8401 8402 instruct getAndSetN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src, flagsRegCR0 cr0) %{ 8403 match(Set res (GetAndSetN mem_ptr src)); 8404 effect(TEMP_DEF res, TEMP cr0); 8405 format %{ "GetAndSetN $res, $mem_ptr, $src" %} 8406 ins_encode %{ 8407 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8408 MacroAssembler::cmpxchgx_hint_atomic_update()); 8409 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8410 __ isync(); 8411 } else { 8412 __ sync(); 8413 } 8414 %} 8415 ins_pipe(pipe_class_default); 8416 %} 8417 8418 //----------Arithmetic Instructions-------------------------------------------- 8419 // Addition Instructions 8420 8421 // Register Addition 8422 instruct addI_reg_reg(iRegIdst dst, iRegIsrc_iRegL2Isrc src1, iRegIsrc_iRegL2Isrc src2) %{ 8423 match(Set dst (AddI src1 src2)); 8424 format %{ "ADD $dst, $src1, $src2" %} 8425 size(4); 8426 ins_encode %{ 8427 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8428 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8429 %} 8430 ins_pipe(pipe_class_default); 8431 %} 8432 8433 // Expand does not work with above instruct. (??) 8434 instruct addI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8435 // no match-rule 8436 effect(DEF dst, USE src1, USE src2); 8437 format %{ "ADD $dst, $src1, $src2" %} 8438 size(4); 8439 ins_encode %{ 8440 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8441 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8442 %} 8443 ins_pipe(pipe_class_default); 8444 %} 8445 8446 instruct tree_addI_addI_addI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 8447 match(Set dst (AddI (AddI (AddI src1 src2) src3) src4)); 8448 ins_cost(DEFAULT_COST*3); 8449 8450 expand %{ 8451 // FIXME: we should do this in the ideal world. 8452 iRegIdst tmp1; 8453 iRegIdst tmp2; 8454 addI_reg_reg(tmp1, src1, src2); 8455 addI_reg_reg_2(tmp2, src3, src4); // Adlc complains about addI_reg_reg. 8456 addI_reg_reg(dst, tmp1, tmp2); 8457 %} 8458 %} 8459 8460 // Immediate Addition 8461 instruct addI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 8462 match(Set dst (AddI src1 src2)); 8463 format %{ "ADDI $dst, $src1, $src2" %} 8464 size(4); 8465 ins_encode %{ 8466 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8467 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8468 %} 8469 ins_pipe(pipe_class_default); 8470 %} 8471 8472 // Immediate Addition with 16-bit shifted operand 8473 instruct addI_reg_immhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2) %{ 8474 match(Set dst (AddI src1 src2)); 8475 format %{ "ADDIS $dst, $src1, $src2" %} 8476 size(4); 8477 ins_encode %{ 8478 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8479 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8480 %} 8481 ins_pipe(pipe_class_default); 8482 %} 8483 8484 // Long Addition 8485 instruct addL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8486 match(Set dst (AddL src1 src2)); 8487 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8488 size(4); 8489 ins_encode %{ 8490 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8491 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8492 %} 8493 ins_pipe(pipe_class_default); 8494 %} 8495 8496 // Expand does not work with above instruct. (??) 8497 instruct addL_reg_reg_2(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8498 // no match-rule 8499 effect(DEF dst, USE src1, USE src2); 8500 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8501 size(4); 8502 ins_encode %{ 8503 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8504 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8505 %} 8506 ins_pipe(pipe_class_default); 8507 %} 8508 8509 instruct tree_addL_addL_addL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2, iRegLsrc src3, iRegLsrc src4) %{ 8510 match(Set dst (AddL (AddL (AddL src1 src2) src3) src4)); 8511 ins_cost(DEFAULT_COST*3); 8512 8513 expand %{ 8514 // FIXME: we should do this in the ideal world. 8515 iRegLdst tmp1; 8516 iRegLdst tmp2; 8517 addL_reg_reg(tmp1, src1, src2); 8518 addL_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 8519 addL_reg_reg(dst, tmp1, tmp2); 8520 %} 8521 %} 8522 8523 // AddL + ConvL2I. 8524 instruct addI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8525 match(Set dst (ConvL2I (AddL src1 src2))); 8526 8527 format %{ "ADD $dst, $src1, $src2 \t// long + l2i" %} 8528 size(4); 8529 ins_encode %{ 8530 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8531 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8532 %} 8533 ins_pipe(pipe_class_default); 8534 %} 8535 8536 // No constant pool entries required. 8537 instruct addL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 8538 match(Set dst (AddL src1 src2)); 8539 8540 format %{ "ADDI $dst, $src1, $src2" %} 8541 size(4); 8542 ins_encode %{ 8543 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8544 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8545 %} 8546 ins_pipe(pipe_class_default); 8547 %} 8548 8549 // Long Immediate Addition with 16-bit shifted operand. 8550 // No constant pool entries required. 8551 instruct addL_reg_immhi16(iRegLdst dst, iRegLsrc src1, immL32hi16 src2) %{ 8552 match(Set dst (AddL src1 src2)); 8553 8554 format %{ "ADDIS $dst, $src1, $src2" %} 8555 size(4); 8556 ins_encode %{ 8557 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8558 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8559 %} 8560 ins_pipe(pipe_class_default); 8561 %} 8562 8563 // Pointer Register Addition 8564 instruct addP_reg_reg(iRegPdst dst, iRegP_N2P src1, iRegLsrc src2) %{ 8565 match(Set dst (AddP src1 src2)); 8566 format %{ "ADD $dst, $src1, $src2" %} 8567 size(4); 8568 ins_encode %{ 8569 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8570 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8571 %} 8572 ins_pipe(pipe_class_default); 8573 %} 8574 8575 // Pointer Immediate Addition 8576 // No constant pool entries required. 8577 instruct addP_reg_imm16(iRegPdst dst, iRegP_N2P src1, immL16 src2) %{ 8578 match(Set dst (AddP src1 src2)); 8579 8580 format %{ "ADDI $dst, $src1, $src2" %} 8581 size(4); 8582 ins_encode %{ 8583 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8584 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8585 %} 8586 ins_pipe(pipe_class_default); 8587 %} 8588 8589 // Pointer Immediate Addition with 16-bit shifted operand. 8590 // No constant pool entries required. 8591 instruct addP_reg_immhi16(iRegPdst dst, iRegP_N2P src1, immL32hi16 src2) %{ 8592 match(Set dst (AddP src1 src2)); 8593 8594 format %{ "ADDIS $dst, $src1, $src2" %} 8595 size(4); 8596 ins_encode %{ 8597 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8598 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8599 %} 8600 ins_pipe(pipe_class_default); 8601 %} 8602 8603 //--------------------- 8604 // Subtraction Instructions 8605 8606 // Register Subtraction 8607 instruct subI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8608 match(Set dst (SubI src1 src2)); 8609 format %{ "SUBF $dst, $src2, $src1" %} 8610 size(4); 8611 ins_encode %{ 8612 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 8613 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 8614 %} 8615 ins_pipe(pipe_class_default); 8616 %} 8617 8618 // Immediate Subtraction 8619 // Immediate Subtraction: The compiler converts "x-c0" into "x+ -c0" (see SubLNode::Ideal), 8620 // Don't try to use addi with - $src2$$constant since it can overflow when $src2$$constant == minI16. 8621 8622 // SubI from constant (using subfic). 8623 instruct subI_imm16_reg(iRegIdst dst, immI16 src1, iRegIsrc src2) %{ 8624 match(Set dst (SubI src1 src2)); 8625 format %{ "SUBI $dst, $src1, $src2" %} 8626 8627 size(4); 8628 ins_encode %{ 8629 // TODO: PPC port $archOpcode(ppc64Opcode_subfic); 8630 __ subfic($dst$$Register, $src2$$Register, $src1$$constant); 8631 %} 8632 ins_pipe(pipe_class_default); 8633 %} 8634 8635 // Turn the sign-bit of an integer into a 32-bit mask, 0x0...0 for 8636 // positive integers and 0xF...F for negative ones. 8637 instruct signmask32I_regI(iRegIdst dst, iRegIsrc src) %{ 8638 // no match-rule, false predicate 8639 effect(DEF dst, USE src); 8640 predicate(false); 8641 8642 format %{ "SRAWI $dst, $src, #31" %} 8643 size(4); 8644 ins_encode %{ 8645 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 8646 __ srawi($dst$$Register, $src$$Register, 0x1f); 8647 %} 8648 ins_pipe(pipe_class_default); 8649 %} 8650 8651 instruct absI_reg_Ex(iRegIdst dst, iRegIsrc src) %{ 8652 match(Set dst (AbsI src)); 8653 ins_cost(DEFAULT_COST*3); 8654 8655 expand %{ 8656 iRegIdst tmp1; 8657 iRegIdst tmp2; 8658 signmask32I_regI(tmp1, src); 8659 xorI_reg_reg(tmp2, tmp1, src); 8660 subI_reg_reg(dst, tmp2, tmp1); 8661 %} 8662 %} 8663 8664 instruct negI_regI(iRegIdst dst, immI_0 zero, iRegIsrc src2) %{ 8665 match(Set dst (SubI zero src2)); 8666 format %{ "NEG $dst, $src2" %} 8667 size(4); 8668 ins_encode %{ 8669 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 8670 __ neg($dst$$Register, $src2$$Register); 8671 %} 8672 ins_pipe(pipe_class_default); 8673 %} 8674 8675 // Long subtraction 8676 instruct subL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8677 match(Set dst (SubL src1 src2)); 8678 format %{ "SUBF $dst, $src2, $src1 \t// long" %} 8679 size(4); 8680 ins_encode %{ 8681 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 8682 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 8683 %} 8684 ins_pipe(pipe_class_default); 8685 %} 8686 8687 // SubL + convL2I. 8688 instruct subI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8689 match(Set dst (ConvL2I (SubL src1 src2))); 8690 8691 format %{ "SUBF $dst, $src2, $src1 \t// long + l2i" %} 8692 size(4); 8693 ins_encode %{ 8694 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 8695 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 8696 %} 8697 ins_pipe(pipe_class_default); 8698 %} 8699 8700 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 8701 // positive longs and 0xF...F for negative ones. 8702 instruct signmask64I_regL(iRegIdst dst, iRegLsrc src) %{ 8703 // no match-rule, false predicate 8704 effect(DEF dst, USE src); 8705 predicate(false); 8706 8707 format %{ "SRADI $dst, $src, #63" %} 8708 size(4); 8709 ins_encode %{ 8710 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 8711 __ sradi($dst$$Register, $src$$Register, 0x3f); 8712 %} 8713 ins_pipe(pipe_class_default); 8714 %} 8715 8716 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 8717 // positive longs and 0xF...F for negative ones. 8718 instruct signmask64L_regL(iRegLdst dst, iRegLsrc src) %{ 8719 // no match-rule, false predicate 8720 effect(DEF dst, USE src); 8721 predicate(false); 8722 8723 format %{ "SRADI $dst, $src, #63" %} 8724 size(4); 8725 ins_encode %{ 8726 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 8727 __ sradi($dst$$Register, $src$$Register, 0x3f); 8728 %} 8729 ins_pipe(pipe_class_default); 8730 %} 8731 8732 // Long negation 8733 instruct negL_reg_reg(iRegLdst dst, immL_0 zero, iRegLsrc src2) %{ 8734 match(Set dst (SubL zero src2)); 8735 format %{ "NEG $dst, $src2 \t// long" %} 8736 size(4); 8737 ins_encode %{ 8738 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 8739 __ neg($dst$$Register, $src2$$Register); 8740 %} 8741 ins_pipe(pipe_class_default); 8742 %} 8743 8744 // NegL + ConvL2I. 8745 instruct negI_con0_regL(iRegIdst dst, immL_0 zero, iRegLsrc src2) %{ 8746 match(Set dst (ConvL2I (SubL zero src2))); 8747 8748 format %{ "NEG $dst, $src2 \t// long + l2i" %} 8749 size(4); 8750 ins_encode %{ 8751 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 8752 __ neg($dst$$Register, $src2$$Register); 8753 %} 8754 ins_pipe(pipe_class_default); 8755 %} 8756 8757 // Multiplication Instructions 8758 // Integer Multiplication 8759 8760 // Register Multiplication 8761 instruct mulI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8762 match(Set dst (MulI src1 src2)); 8763 ins_cost(DEFAULT_COST); 8764 8765 format %{ "MULLW $dst, $src1, $src2" %} 8766 size(4); 8767 ins_encode %{ 8768 // TODO: PPC port $archOpcode(ppc64Opcode_mullw); 8769 __ mullw($dst$$Register, $src1$$Register, $src2$$Register); 8770 %} 8771 ins_pipe(pipe_class_default); 8772 %} 8773 8774 // Immediate Multiplication 8775 instruct mulI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 8776 match(Set dst (MulI src1 src2)); 8777 ins_cost(DEFAULT_COST); 8778 8779 format %{ "MULLI $dst, $src1, $src2" %} 8780 size(4); 8781 ins_encode %{ 8782 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 8783 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 8784 %} 8785 ins_pipe(pipe_class_default); 8786 %} 8787 8788 instruct mulL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8789 match(Set dst (MulL src1 src2)); 8790 ins_cost(DEFAULT_COST); 8791 8792 format %{ "MULLD $dst $src1, $src2 \t// long" %} 8793 size(4); 8794 ins_encode %{ 8795 // TODO: PPC port $archOpcode(ppc64Opcode_mulld); 8796 __ mulld($dst$$Register, $src1$$Register, $src2$$Register); 8797 %} 8798 ins_pipe(pipe_class_default); 8799 %} 8800 8801 // Multiply high for optimized long division by constant. 8802 instruct mulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8803 match(Set dst (MulHiL src1 src2)); 8804 ins_cost(DEFAULT_COST); 8805 8806 format %{ "MULHD $dst $src1, $src2 \t// long" %} 8807 size(4); 8808 ins_encode %{ 8809 // TODO: PPC port $archOpcode(ppc64Opcode_mulhd); 8810 __ mulhd($dst$$Register, $src1$$Register, $src2$$Register); 8811 %} 8812 ins_pipe(pipe_class_default); 8813 %} 8814 8815 // Immediate Multiplication 8816 instruct mulL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 8817 match(Set dst (MulL src1 src2)); 8818 ins_cost(DEFAULT_COST); 8819 8820 format %{ "MULLI $dst, $src1, $src2" %} 8821 size(4); 8822 ins_encode %{ 8823 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 8824 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 8825 %} 8826 ins_pipe(pipe_class_default); 8827 %} 8828 8829 // Integer Division with Immediate -1: Negate. 8830 instruct divI_reg_immIvalueMinus1(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 8831 match(Set dst (DivI src1 src2)); 8832 ins_cost(DEFAULT_COST); 8833 8834 format %{ "NEG $dst, $src1 \t// /-1" %} 8835 size(4); 8836 ins_encode %{ 8837 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 8838 __ neg($dst$$Register, $src1$$Register); 8839 %} 8840 ins_pipe(pipe_class_default); 8841 %} 8842 8843 // Integer Division with constant, but not -1. 8844 // We should be able to improve this by checking the type of src2. 8845 // It might well be that src2 is known to be positive. 8846 instruct divI_reg_regnotMinus1(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8847 match(Set dst (DivI src1 src2)); 8848 predicate(n->in(2)->find_int_con(-1) != -1); // src2 is a constant, but not -1 8849 ins_cost(2*DEFAULT_COST); 8850 8851 format %{ "DIVW $dst, $src1, $src2 \t// /not-1" %} 8852 size(4); 8853 ins_encode %{ 8854 // TODO: PPC port $archOpcode(ppc64Opcode_divw); 8855 __ divw($dst$$Register, $src1$$Register, $src2$$Register); 8856 %} 8857 ins_pipe(pipe_class_default); 8858 %} 8859 8860 instruct cmovI_bne_negI_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src1) %{ 8861 effect(USE_DEF dst, USE src1, USE crx); 8862 predicate(false); 8863 8864 ins_variable_size_depending_on_alignment(true); 8865 8866 format %{ "CMOVE $dst, neg($src1), $crx" %} 8867 // Worst case is branch + move + stop, no stop without scheduler. 8868 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 8869 ins_encode %{ 8870 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 8871 Label done; 8872 __ bne($crx$$CondRegister, done); 8873 __ neg($dst$$Register, $src1$$Register); 8874 // TODO PPC port __ endgroup_if_needed(_size == 12); 8875 __ bind(done); 8876 %} 8877 ins_pipe(pipe_class_default); 8878 %} 8879 8880 // Integer Division with Registers not containing constants. 8881 instruct divI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8882 match(Set dst (DivI src1 src2)); 8883 ins_cost(10*DEFAULT_COST); 8884 8885 expand %{ 8886 immI16 imm %{ (int)-1 %} 8887 flagsReg tmp1; 8888 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 8889 divI_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 8890 cmovI_bne_negI_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 8891 %} 8892 %} 8893 8894 // Long Division with Immediate -1: Negate. 8895 instruct divL_reg_immLvalueMinus1(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 8896 match(Set dst (DivL src1 src2)); 8897 ins_cost(DEFAULT_COST); 8898 8899 format %{ "NEG $dst, $src1 \t// /-1, long" %} 8900 size(4); 8901 ins_encode %{ 8902 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 8903 __ neg($dst$$Register, $src1$$Register); 8904 %} 8905 ins_pipe(pipe_class_default); 8906 %} 8907 8908 // Long Division with constant, but not -1. 8909 instruct divL_reg_regnotMinus1(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8910 match(Set dst (DivL src1 src2)); 8911 predicate(n->in(2)->find_long_con(-1L) != -1L); // Src2 is a constant, but not -1. 8912 ins_cost(2*DEFAULT_COST); 8913 8914 format %{ "DIVD $dst, $src1, $src2 \t// /not-1, long" %} 8915 size(4); 8916 ins_encode %{ 8917 // TODO: PPC port $archOpcode(ppc64Opcode_divd); 8918 __ divd($dst$$Register, $src1$$Register, $src2$$Register); 8919 %} 8920 ins_pipe(pipe_class_default); 8921 %} 8922 8923 instruct cmovL_bne_negL_reg(iRegLdst dst, flagsRegSrc crx, iRegLsrc src1) %{ 8924 effect(USE_DEF dst, USE src1, USE crx); 8925 predicate(false); 8926 8927 ins_variable_size_depending_on_alignment(true); 8928 8929 format %{ "CMOVE $dst, neg($src1), $crx" %} 8930 // Worst case is branch + move + stop, no stop without scheduler. 8931 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 8932 ins_encode %{ 8933 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 8934 Label done; 8935 __ bne($crx$$CondRegister, done); 8936 __ neg($dst$$Register, $src1$$Register); 8937 // TODO PPC port __ endgroup_if_needed(_size == 12); 8938 __ bind(done); 8939 %} 8940 ins_pipe(pipe_class_default); 8941 %} 8942 8943 // Long Division with Registers not containing constants. 8944 instruct divL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8945 match(Set dst (DivL src1 src2)); 8946 ins_cost(10*DEFAULT_COST); 8947 8948 expand %{ 8949 immL16 imm %{ (int)-1 %} 8950 flagsReg tmp1; 8951 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 8952 divL_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 8953 cmovL_bne_negL_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 8954 %} 8955 %} 8956 8957 // Integer Remainder with registers. 8958 instruct modI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8959 match(Set dst (ModI src1 src2)); 8960 ins_cost(10*DEFAULT_COST); 8961 8962 expand %{ 8963 immI16 imm %{ (int)-1 %} 8964 flagsReg tmp1; 8965 iRegIdst tmp2; 8966 iRegIdst tmp3; 8967 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 8968 divI_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 8969 cmovI_bne_negI_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 8970 mulI_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 8971 subI_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 8972 %} 8973 %} 8974 8975 // Long Remainder with registers 8976 instruct modL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8977 match(Set dst (ModL src1 src2)); 8978 ins_cost(10*DEFAULT_COST); 8979 8980 expand %{ 8981 immL16 imm %{ (int)-1 %} 8982 flagsReg tmp1; 8983 iRegLdst tmp2; 8984 iRegLdst tmp3; 8985 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 8986 divL_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 8987 cmovL_bne_negL_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 8988 mulL_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 8989 subL_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 8990 %} 8991 %} 8992 8993 // Integer Shift Instructions 8994 8995 // Register Shift Left 8996 8997 // Clear all but the lowest #mask bits. 8998 // Used to normalize shift amounts in registers. 8999 instruct maskI_reg_imm(iRegIdst dst, iRegIsrc src, uimmI6 mask) %{ 9000 // no match-rule, false predicate 9001 effect(DEF dst, USE src, USE mask); 9002 predicate(false); 9003 9004 format %{ "MASK $dst, $src, $mask \t// clear $mask upper bits" %} 9005 size(4); 9006 ins_encode %{ 9007 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9008 __ clrldi($dst$$Register, $src$$Register, $mask$$constant); 9009 %} 9010 ins_pipe(pipe_class_default); 9011 %} 9012 9013 instruct lShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9014 // no match-rule, false predicate 9015 effect(DEF dst, USE src1, USE src2); 9016 predicate(false); 9017 9018 format %{ "SLW $dst, $src1, $src2" %} 9019 size(4); 9020 ins_encode %{ 9021 // TODO: PPC port $archOpcode(ppc64Opcode_slw); 9022 __ slw($dst$$Register, $src1$$Register, $src2$$Register); 9023 %} 9024 ins_pipe(pipe_class_default); 9025 %} 9026 9027 instruct lShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9028 match(Set dst (LShiftI src1 src2)); 9029 ins_cost(DEFAULT_COST*2); 9030 expand %{ 9031 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9032 iRegIdst tmpI; 9033 maskI_reg_imm(tmpI, src2, mask); 9034 lShiftI_reg_reg(dst, src1, tmpI); 9035 %} 9036 %} 9037 9038 // Register Shift Left Immediate 9039 instruct lShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9040 match(Set dst (LShiftI src1 src2)); 9041 9042 format %{ "SLWI $dst, $src1, ($src2 & 0x1f)" %} 9043 size(4); 9044 ins_encode %{ 9045 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9046 __ slwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9047 %} 9048 ins_pipe(pipe_class_default); 9049 %} 9050 9051 // AndI with negpow2-constant + LShiftI 9052 instruct lShiftI_andI_immInegpow2_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9053 match(Set dst (LShiftI (AndI src1 src2) src3)); 9054 predicate(UseRotateAndMaskInstructionsPPC64); 9055 9056 format %{ "RLWINM $dst, lShiftI(AndI($src1, $src2), $src3)" %} 9057 size(4); 9058 ins_encode %{ 9059 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9060 long src2 = $src2$$constant; 9061 long src3 = $src3$$constant; 9062 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9063 if (maskbits >= 32) { 9064 __ li($dst$$Register, 0); // addi 9065 } else { 9066 __ rlwinm($dst$$Register, $src1$$Register, src3 & 0x1f, 0, (31-maskbits) & 0x1f); 9067 } 9068 %} 9069 ins_pipe(pipe_class_default); 9070 %} 9071 9072 // RShiftI + AndI with negpow2-constant + LShiftI 9073 instruct lShiftI_andI_immInegpow2_rShiftI_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9074 match(Set dst (LShiftI (AndI (RShiftI src1 src3) src2) src3)); 9075 predicate(UseRotateAndMaskInstructionsPPC64); 9076 9077 format %{ "RLWINM $dst, lShiftI(AndI(RShiftI($src1, $src3), $src2), $src3)" %} 9078 size(4); 9079 ins_encode %{ 9080 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9081 long src2 = $src2$$constant; 9082 long src3 = $src3$$constant; 9083 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9084 if (maskbits >= 32) { 9085 __ li($dst$$Register, 0); // addi 9086 } else { 9087 __ rlwinm($dst$$Register, $src1$$Register, 0, 0, (31-maskbits) & 0x1f); 9088 } 9089 %} 9090 ins_pipe(pipe_class_default); 9091 %} 9092 9093 instruct lShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9094 // no match-rule, false predicate 9095 effect(DEF dst, USE src1, USE src2); 9096 predicate(false); 9097 9098 format %{ "SLD $dst, $src1, $src2" %} 9099 size(4); 9100 ins_encode %{ 9101 // TODO: PPC port $archOpcode(ppc64Opcode_sld); 9102 __ sld($dst$$Register, $src1$$Register, $src2$$Register); 9103 %} 9104 ins_pipe(pipe_class_default); 9105 %} 9106 9107 // Register Shift Left 9108 instruct lShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9109 match(Set dst (LShiftL src1 src2)); 9110 ins_cost(DEFAULT_COST*2); 9111 expand %{ 9112 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9113 iRegIdst tmpI; 9114 maskI_reg_imm(tmpI, src2, mask); 9115 lShiftL_regL_regI(dst, src1, tmpI); 9116 %} 9117 %} 9118 9119 // Register Shift Left Immediate 9120 instruct lshiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9121 match(Set dst (LShiftL src1 src2)); 9122 format %{ "SLDI $dst, $src1, ($src2 & 0x3f)" %} 9123 size(4); 9124 ins_encode %{ 9125 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9126 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9127 %} 9128 ins_pipe(pipe_class_default); 9129 %} 9130 9131 // If we shift more than 32 bits, we need not convert I2L. 9132 instruct lShiftL_regI_immGE32(iRegLdst dst, iRegIsrc src1, uimmI6_ge32 src2) %{ 9133 match(Set dst (LShiftL (ConvI2L src1) src2)); 9134 ins_cost(DEFAULT_COST); 9135 9136 size(4); 9137 format %{ "SLDI $dst, i2l($src1), $src2" %} 9138 ins_encode %{ 9139 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9140 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9141 %} 9142 ins_pipe(pipe_class_default); 9143 %} 9144 9145 // Shift a postivie int to the left. 9146 // Clrlsldi clears the upper 32 bits and shifts. 9147 instruct scaledPositiveI2L_lShiftL_convI2L_reg_imm6(iRegLdst dst, iRegIsrc src1, uimmI6 src2) %{ 9148 match(Set dst (LShiftL (ConvI2L src1) src2)); 9149 predicate(((ConvI2LNode*)(_kids[0]->_leaf))->type()->is_long()->is_positive_int()); 9150 9151 format %{ "SLDI $dst, i2l(positive_int($src1)), $src2" %} 9152 size(4); 9153 ins_encode %{ 9154 // TODO: PPC port $archOpcode(ppc64Opcode_rldic); 9155 __ clrlsldi($dst$$Register, $src1$$Register, 0x20, $src2$$constant); 9156 %} 9157 ins_pipe(pipe_class_default); 9158 %} 9159 9160 instruct arShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9161 // no match-rule, false predicate 9162 effect(DEF dst, USE src1, USE src2); 9163 predicate(false); 9164 9165 format %{ "SRAW $dst, $src1, $src2" %} 9166 size(4); 9167 ins_encode %{ 9168 // TODO: PPC port $archOpcode(ppc64Opcode_sraw); 9169 __ sraw($dst$$Register, $src1$$Register, $src2$$Register); 9170 %} 9171 ins_pipe(pipe_class_default); 9172 %} 9173 9174 // Register Arithmetic Shift Right 9175 instruct arShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9176 match(Set dst (RShiftI src1 src2)); 9177 ins_cost(DEFAULT_COST*2); 9178 expand %{ 9179 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9180 iRegIdst tmpI; 9181 maskI_reg_imm(tmpI, src2, mask); 9182 arShiftI_reg_reg(dst, src1, tmpI); 9183 %} 9184 %} 9185 9186 // Register Arithmetic Shift Right Immediate 9187 instruct arShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9188 match(Set dst (RShiftI src1 src2)); 9189 9190 format %{ "SRAWI $dst, $src1, ($src2 & 0x1f)" %} 9191 size(4); 9192 ins_encode %{ 9193 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 9194 __ srawi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9195 %} 9196 ins_pipe(pipe_class_default); 9197 %} 9198 9199 instruct arShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9200 // no match-rule, false predicate 9201 effect(DEF dst, USE src1, USE src2); 9202 predicate(false); 9203 9204 format %{ "SRAD $dst, $src1, $src2" %} 9205 size(4); 9206 ins_encode %{ 9207 // TODO: PPC port $archOpcode(ppc64Opcode_srad); 9208 __ srad($dst$$Register, $src1$$Register, $src2$$Register); 9209 %} 9210 ins_pipe(pipe_class_default); 9211 %} 9212 9213 // Register Shift Right Arithmetic Long 9214 instruct arShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9215 match(Set dst (RShiftL src1 src2)); 9216 ins_cost(DEFAULT_COST*2); 9217 9218 expand %{ 9219 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9220 iRegIdst tmpI; 9221 maskI_reg_imm(tmpI, src2, mask); 9222 arShiftL_regL_regI(dst, src1, tmpI); 9223 %} 9224 %} 9225 9226 // Register Shift Right Immediate 9227 instruct arShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9228 match(Set dst (RShiftL src1 src2)); 9229 9230 format %{ "SRADI $dst, $src1, ($src2 & 0x3f)" %} 9231 size(4); 9232 ins_encode %{ 9233 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9234 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9235 %} 9236 ins_pipe(pipe_class_default); 9237 %} 9238 9239 // RShiftL + ConvL2I 9240 instruct convL2I_arShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9241 match(Set dst (ConvL2I (RShiftL src1 src2))); 9242 9243 format %{ "SRADI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9244 size(4); 9245 ins_encode %{ 9246 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9247 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9248 %} 9249 ins_pipe(pipe_class_default); 9250 %} 9251 9252 instruct urShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9253 // no match-rule, false predicate 9254 effect(DEF dst, USE src1, USE src2); 9255 predicate(false); 9256 9257 format %{ "SRW $dst, $src1, $src2" %} 9258 size(4); 9259 ins_encode %{ 9260 // TODO: PPC port $archOpcode(ppc64Opcode_srw); 9261 __ srw($dst$$Register, $src1$$Register, $src2$$Register); 9262 %} 9263 ins_pipe(pipe_class_default); 9264 %} 9265 9266 // Register Shift Right 9267 instruct urShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9268 match(Set dst (URShiftI src1 src2)); 9269 ins_cost(DEFAULT_COST*2); 9270 9271 expand %{ 9272 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9273 iRegIdst tmpI; 9274 maskI_reg_imm(tmpI, src2, mask); 9275 urShiftI_reg_reg(dst, src1, tmpI); 9276 %} 9277 %} 9278 9279 // Register Shift Right Immediate 9280 instruct urShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9281 match(Set dst (URShiftI src1 src2)); 9282 9283 format %{ "SRWI $dst, $src1, ($src2 & 0x1f)" %} 9284 size(4); 9285 ins_encode %{ 9286 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9287 __ srwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9288 %} 9289 ins_pipe(pipe_class_default); 9290 %} 9291 9292 instruct urShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9293 // no match-rule, false predicate 9294 effect(DEF dst, USE src1, USE src2); 9295 predicate(false); 9296 9297 format %{ "SRD $dst, $src1, $src2" %} 9298 size(4); 9299 ins_encode %{ 9300 // TODO: PPC port $archOpcode(ppc64Opcode_srd); 9301 __ srd($dst$$Register, $src1$$Register, $src2$$Register); 9302 %} 9303 ins_pipe(pipe_class_default); 9304 %} 9305 9306 // Register Shift Right 9307 instruct urShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9308 match(Set dst (URShiftL src1 src2)); 9309 ins_cost(DEFAULT_COST*2); 9310 9311 expand %{ 9312 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9313 iRegIdst tmpI; 9314 maskI_reg_imm(tmpI, src2, mask); 9315 urShiftL_regL_regI(dst, src1, tmpI); 9316 %} 9317 %} 9318 9319 // Register Shift Right Immediate 9320 instruct urShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9321 match(Set dst (URShiftL src1 src2)); 9322 9323 format %{ "SRDI $dst, $src1, ($src2 & 0x3f)" %} 9324 size(4); 9325 ins_encode %{ 9326 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9327 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9328 %} 9329 ins_pipe(pipe_class_default); 9330 %} 9331 9332 // URShiftL + ConvL2I. 9333 instruct convL2I_urShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9334 match(Set dst (ConvL2I (URShiftL src1 src2))); 9335 9336 format %{ "SRDI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9337 size(4); 9338 ins_encode %{ 9339 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9340 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9341 %} 9342 ins_pipe(pipe_class_default); 9343 %} 9344 9345 // Register Shift Right Immediate with a CastP2X 9346 instruct shrP_convP2X_reg_imm6(iRegLdst dst, iRegP_N2P src1, uimmI6 src2) %{ 9347 match(Set dst (URShiftL (CastP2X src1) src2)); 9348 9349 format %{ "SRDI $dst, $src1, $src2 \t// Cast ptr $src1 to long and shift" %} 9350 size(4); 9351 ins_encode %{ 9352 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9353 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9354 %} 9355 ins_pipe(pipe_class_default); 9356 %} 9357 9358 instruct sxtI_reg(iRegIdst dst, iRegIsrc src) %{ 9359 match(Set dst (ConvL2I (ConvI2L src))); 9360 9361 format %{ "EXTSW $dst, $src \t// int->int" %} 9362 size(4); 9363 ins_encode %{ 9364 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 9365 __ extsw($dst$$Register, $src$$Register); 9366 %} 9367 ins_pipe(pipe_class_default); 9368 %} 9369 9370 //----------Rotate Instructions------------------------------------------------ 9371 9372 // Rotate Left by 8-bit immediate 9373 instruct rotlI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 lshift, immI8 rshift) %{ 9374 match(Set dst (OrI (LShiftI src lshift) (URShiftI src rshift))); 9375 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9376 9377 format %{ "ROTLWI $dst, $src, $lshift" %} 9378 size(4); 9379 ins_encode %{ 9380 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9381 __ rotlwi($dst$$Register, $src$$Register, $lshift$$constant); 9382 %} 9383 ins_pipe(pipe_class_default); 9384 %} 9385 9386 // Rotate Right by 8-bit immediate 9387 instruct rotrI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 rshift, immI8 lshift) %{ 9388 match(Set dst (OrI (URShiftI src rshift) (LShiftI src lshift))); 9389 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9390 9391 format %{ "ROTRWI $dst, $rshift" %} 9392 size(4); 9393 ins_encode %{ 9394 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9395 __ rotrwi($dst$$Register, $src$$Register, $rshift$$constant); 9396 %} 9397 ins_pipe(pipe_class_default); 9398 %} 9399 9400 //----------Floating Point Arithmetic Instructions----------------------------- 9401 9402 // Add float single precision 9403 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{ 9404 match(Set dst (AddF src1 src2)); 9405 9406 format %{ "FADDS $dst, $src1, $src2" %} 9407 size(4); 9408 ins_encode %{ 9409 // TODO: PPC port $archOpcode(ppc64Opcode_fadds); 9410 __ fadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9411 %} 9412 ins_pipe(pipe_class_default); 9413 %} 9414 9415 // Add float double precision 9416 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{ 9417 match(Set dst (AddD src1 src2)); 9418 9419 format %{ "FADD $dst, $src1, $src2" %} 9420 size(4); 9421 ins_encode %{ 9422 // TODO: PPC port $archOpcode(ppc64Opcode_fadd); 9423 __ fadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9424 %} 9425 ins_pipe(pipe_class_default); 9426 %} 9427 9428 // Sub float single precision 9429 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{ 9430 match(Set dst (SubF src1 src2)); 9431 9432 format %{ "FSUBS $dst, $src1, $src2" %} 9433 size(4); 9434 ins_encode %{ 9435 // TODO: PPC port $archOpcode(ppc64Opcode_fsubs); 9436 __ fsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9437 %} 9438 ins_pipe(pipe_class_default); 9439 %} 9440 9441 // Sub float double precision 9442 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{ 9443 match(Set dst (SubD src1 src2)); 9444 format %{ "FSUB $dst, $src1, $src2" %} 9445 size(4); 9446 ins_encode %{ 9447 // TODO: PPC port $archOpcode(ppc64Opcode_fsub); 9448 __ fsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9449 %} 9450 ins_pipe(pipe_class_default); 9451 %} 9452 9453 // Mul float single precision 9454 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{ 9455 match(Set dst (MulF src1 src2)); 9456 format %{ "FMULS $dst, $src1, $src2" %} 9457 size(4); 9458 ins_encode %{ 9459 // TODO: PPC port $archOpcode(ppc64Opcode_fmuls); 9460 __ fmuls($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9461 %} 9462 ins_pipe(pipe_class_default); 9463 %} 9464 9465 // Mul float double precision 9466 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{ 9467 match(Set dst (MulD src1 src2)); 9468 format %{ "FMUL $dst, $src1, $src2" %} 9469 size(4); 9470 ins_encode %{ 9471 // TODO: PPC port $archOpcode(ppc64Opcode_fmul); 9472 __ fmul($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9473 %} 9474 ins_pipe(pipe_class_default); 9475 %} 9476 9477 // Div float single precision 9478 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{ 9479 match(Set dst (DivF src1 src2)); 9480 format %{ "FDIVS $dst, $src1, $src2" %} 9481 size(4); 9482 ins_encode %{ 9483 // TODO: PPC port $archOpcode(ppc64Opcode_fdivs); 9484 __ fdivs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9485 %} 9486 ins_pipe(pipe_class_default); 9487 %} 9488 9489 // Div float double precision 9490 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{ 9491 match(Set dst (DivD src1 src2)); 9492 format %{ "FDIV $dst, $src1, $src2" %} 9493 size(4); 9494 ins_encode %{ 9495 // TODO: PPC port $archOpcode(ppc64Opcode_fdiv); 9496 __ fdiv($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9497 %} 9498 ins_pipe(pipe_class_default); 9499 %} 9500 9501 // Absolute float single precision 9502 instruct absF_reg(regF dst, regF src) %{ 9503 match(Set dst (AbsF src)); 9504 format %{ "FABS $dst, $src \t// float" %} 9505 size(4); 9506 ins_encode %{ 9507 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 9508 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9509 %} 9510 ins_pipe(pipe_class_default); 9511 %} 9512 9513 // Absolute float double precision 9514 instruct absD_reg(regD dst, regD src) %{ 9515 match(Set dst (AbsD src)); 9516 format %{ "FABS $dst, $src \t// double" %} 9517 size(4); 9518 ins_encode %{ 9519 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 9520 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9521 %} 9522 ins_pipe(pipe_class_default); 9523 %} 9524 9525 instruct negF_reg(regF dst, regF src) %{ 9526 match(Set dst (NegF src)); 9527 format %{ "FNEG $dst, $src \t// float" %} 9528 size(4); 9529 ins_encode %{ 9530 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 9531 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 9532 %} 9533 ins_pipe(pipe_class_default); 9534 %} 9535 9536 instruct negD_reg(regD dst, regD src) %{ 9537 match(Set dst (NegD src)); 9538 format %{ "FNEG $dst, $src \t// double" %} 9539 size(4); 9540 ins_encode %{ 9541 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 9542 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 9543 %} 9544 ins_pipe(pipe_class_default); 9545 %} 9546 9547 // AbsF + NegF. 9548 instruct negF_absF_reg(regF dst, regF src) %{ 9549 match(Set dst (NegF (AbsF src))); 9550 format %{ "FNABS $dst, $src \t// float" %} 9551 size(4); 9552 ins_encode %{ 9553 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 9554 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 9555 %} 9556 ins_pipe(pipe_class_default); 9557 %} 9558 9559 // AbsD + NegD. 9560 instruct negD_absD_reg(regD dst, regD src) %{ 9561 match(Set dst (NegD (AbsD src))); 9562 format %{ "FNABS $dst, $src \t// double" %} 9563 size(4); 9564 ins_encode %{ 9565 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 9566 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 9567 %} 9568 ins_pipe(pipe_class_default); 9569 %} 9570 9571 // VM_Version::has_fsqrt() decides if this node will be used. 9572 // Sqrt float double precision 9573 instruct sqrtD_reg(regD dst, regD src) %{ 9574 match(Set dst (SqrtD src)); 9575 format %{ "FSQRT $dst, $src" %} 9576 size(4); 9577 ins_encode %{ 9578 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrt); 9579 __ fsqrt($dst$$FloatRegister, $src$$FloatRegister); 9580 %} 9581 ins_pipe(pipe_class_default); 9582 %} 9583 9584 // Single-precision sqrt. 9585 instruct sqrtF_reg(regF dst, regF src) %{ 9586 match(Set dst (ConvD2F (SqrtD (ConvF2D src)))); 9587 predicate(VM_Version::has_fsqrts()); 9588 ins_cost(DEFAULT_COST); 9589 9590 format %{ "FSQRTS $dst, $src" %} 9591 size(4); 9592 ins_encode %{ 9593 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrts); 9594 __ fsqrts($dst$$FloatRegister, $src$$FloatRegister); 9595 %} 9596 ins_pipe(pipe_class_default); 9597 %} 9598 9599 instruct roundDouble_nop(regD dst) %{ 9600 match(Set dst (RoundDouble dst)); 9601 ins_cost(0); 9602 9603 format %{ " -- \t// RoundDouble not needed - empty" %} 9604 size(0); 9605 // PPC results are already "rounded" (i.e., normal-format IEEE). 9606 ins_encode( /*empty*/ ); 9607 ins_pipe(pipe_class_default); 9608 %} 9609 9610 instruct roundFloat_nop(regF dst) %{ 9611 match(Set dst (RoundFloat dst)); 9612 ins_cost(0); 9613 9614 format %{ " -- \t// RoundFloat not needed - empty" %} 9615 size(0); 9616 // PPC results are already "rounded" (i.e., normal-format IEEE). 9617 ins_encode( /*empty*/ ); 9618 ins_pipe(pipe_class_default); 9619 %} 9620 9621 //----------Logical Instructions----------------------------------------------- 9622 9623 // And Instructions 9624 9625 // Register And 9626 instruct andI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9627 match(Set dst (AndI src1 src2)); 9628 format %{ "AND $dst, $src1, $src2" %} 9629 size(4); 9630 ins_encode %{ 9631 // TODO: PPC port $archOpcode(ppc64Opcode_and); 9632 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 9633 %} 9634 ins_pipe(pipe_class_default); 9635 %} 9636 9637 // Immediate And 9638 instruct andI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2, flagsRegCR0 cr0) %{ 9639 match(Set dst (AndI src1 src2)); 9640 effect(KILL cr0); 9641 9642 format %{ "ANDI $dst, $src1, $src2" %} 9643 size(4); 9644 ins_encode %{ 9645 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 9646 // FIXME: avoid andi_ ? 9647 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 9648 %} 9649 ins_pipe(pipe_class_default); 9650 %} 9651 9652 // Immediate And where the immediate is a negative power of 2. 9653 instruct andI_reg_immInegpow2(iRegIdst dst, iRegIsrc src1, immInegpow2 src2) %{ 9654 match(Set dst (AndI src1 src2)); 9655 format %{ "ANDWI $dst, $src1, $src2" %} 9656 size(4); 9657 ins_encode %{ 9658 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9659 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)(julong)(juint)-($src2$$constant))); 9660 %} 9661 ins_pipe(pipe_class_default); 9662 %} 9663 9664 instruct andI_reg_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immIpow2minus1 src2) %{ 9665 match(Set dst (AndI src1 src2)); 9666 format %{ "ANDWI $dst, $src1, $src2" %} 9667 size(4); 9668 ins_encode %{ 9669 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9670 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 9671 %} 9672 ins_pipe(pipe_class_default); 9673 %} 9674 9675 instruct andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src1, immIpowerOf2 src2) %{ 9676 match(Set dst (AndI src1 src2)); 9677 predicate(UseRotateAndMaskInstructionsPPC64); 9678 format %{ "ANDWI $dst, $src1, $src2" %} 9679 size(4); 9680 ins_encode %{ 9681 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9682 __ rlwinm($dst$$Register, $src1$$Register, 0, 9683 (31-log2_long((jlong) $src2$$constant)) & 0x1f, (31-log2_long((jlong) $src2$$constant)) & 0x1f); 9684 %} 9685 ins_pipe(pipe_class_default); 9686 %} 9687 9688 // Register And Long 9689 instruct andL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9690 match(Set dst (AndL src1 src2)); 9691 ins_cost(DEFAULT_COST); 9692 9693 format %{ "AND $dst, $src1, $src2 \t// long" %} 9694 size(4); 9695 ins_encode %{ 9696 // TODO: PPC port $archOpcode(ppc64Opcode_and); 9697 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 9698 %} 9699 ins_pipe(pipe_class_default); 9700 %} 9701 9702 // Immediate And long 9703 instruct andL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2, flagsRegCR0 cr0) %{ 9704 match(Set dst (AndL src1 src2)); 9705 effect(KILL cr0); 9706 9707 format %{ "ANDI $dst, $src1, $src2 \t// long" %} 9708 size(4); 9709 ins_encode %{ 9710 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 9711 // FIXME: avoid andi_ ? 9712 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 9713 %} 9714 ins_pipe(pipe_class_default); 9715 %} 9716 9717 // Immediate And Long where the immediate is a negative power of 2. 9718 instruct andL_reg_immLnegpow2(iRegLdst dst, iRegLsrc src1, immLnegpow2 src2) %{ 9719 match(Set dst (AndL src1 src2)); 9720 format %{ "ANDDI $dst, $src1, $src2" %} 9721 size(4); 9722 ins_encode %{ 9723 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9724 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)-$src2$$constant)); 9725 %} 9726 ins_pipe(pipe_class_default); 9727 %} 9728 9729 instruct andL_reg_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 9730 match(Set dst (AndL src1 src2)); 9731 format %{ "ANDDI $dst, $src1, $src2" %} 9732 size(4); 9733 ins_encode %{ 9734 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9735 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 9736 %} 9737 ins_pipe(pipe_class_default); 9738 %} 9739 9740 // AndL + ConvL2I. 9741 instruct convL2I_andL_reg_immLpow2minus1(iRegIdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 9742 match(Set dst (ConvL2I (AndL src1 src2))); 9743 ins_cost(DEFAULT_COST); 9744 9745 format %{ "ANDDI $dst, $src1, $src2 \t// long + l2i" %} 9746 size(4); 9747 ins_encode %{ 9748 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9749 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 9750 %} 9751 ins_pipe(pipe_class_default); 9752 %} 9753 9754 // Or Instructions 9755 9756 // Register Or 9757 instruct orI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9758 match(Set dst (OrI src1 src2)); 9759 format %{ "OR $dst, $src1, $src2" %} 9760 size(4); 9761 ins_encode %{ 9762 // TODO: PPC port $archOpcode(ppc64Opcode_or); 9763 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 9764 %} 9765 ins_pipe(pipe_class_default); 9766 %} 9767 9768 // Expand does not work with above instruct. (??) 9769 instruct orI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9770 // no match-rule 9771 effect(DEF dst, USE src1, USE src2); 9772 format %{ "OR $dst, $src1, $src2" %} 9773 size(4); 9774 ins_encode %{ 9775 // TODO: PPC port $archOpcode(ppc64Opcode_or); 9776 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 9777 %} 9778 ins_pipe(pipe_class_default); 9779 %} 9780 9781 instruct tree_orI_orI_orI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 9782 match(Set dst (OrI (OrI (OrI src1 src2) src3) src4)); 9783 ins_cost(DEFAULT_COST*3); 9784 9785 expand %{ 9786 // FIXME: we should do this in the ideal world. 9787 iRegIdst tmp1; 9788 iRegIdst tmp2; 9789 orI_reg_reg(tmp1, src1, src2); 9790 orI_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 9791 orI_reg_reg(dst, tmp1, tmp2); 9792 %} 9793 %} 9794 9795 // Immediate Or 9796 instruct orI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 9797 match(Set dst (OrI src1 src2)); 9798 format %{ "ORI $dst, $src1, $src2" %} 9799 size(4); 9800 ins_encode %{ 9801 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 9802 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 9803 %} 9804 ins_pipe(pipe_class_default); 9805 %} 9806 9807 // Register Or Long 9808 instruct orL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9809 match(Set dst (OrL src1 src2)); 9810 ins_cost(DEFAULT_COST); 9811 9812 size(4); 9813 format %{ "OR $dst, $src1, $src2 \t// long" %} 9814 ins_encode %{ 9815 // TODO: PPC port $archOpcode(ppc64Opcode_or); 9816 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 9817 %} 9818 ins_pipe(pipe_class_default); 9819 %} 9820 9821 // OrL + ConvL2I. 9822 instruct orI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9823 match(Set dst (ConvL2I (OrL src1 src2))); 9824 ins_cost(DEFAULT_COST); 9825 9826 format %{ "OR $dst, $src1, $src2 \t// long + l2i" %} 9827 size(4); 9828 ins_encode %{ 9829 // TODO: PPC port $archOpcode(ppc64Opcode_or); 9830 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 9831 %} 9832 ins_pipe(pipe_class_default); 9833 %} 9834 9835 // Immediate Or long 9836 instruct orL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 con) %{ 9837 match(Set dst (OrL src1 con)); 9838 ins_cost(DEFAULT_COST); 9839 9840 format %{ "ORI $dst, $src1, $con \t// long" %} 9841 size(4); 9842 ins_encode %{ 9843 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 9844 __ ori($dst$$Register, $src1$$Register, ($con$$constant) & 0xFFFF); 9845 %} 9846 ins_pipe(pipe_class_default); 9847 %} 9848 9849 // Xor Instructions 9850 9851 // Register Xor 9852 instruct xorI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9853 match(Set dst (XorI src1 src2)); 9854 format %{ "XOR $dst, $src1, $src2" %} 9855 size(4); 9856 ins_encode %{ 9857 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 9858 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 9859 %} 9860 ins_pipe(pipe_class_default); 9861 %} 9862 9863 // Expand does not work with above instruct. (??) 9864 instruct xorI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9865 // no match-rule 9866 effect(DEF dst, USE src1, USE src2); 9867 format %{ "XOR $dst, $src1, $src2" %} 9868 size(4); 9869 ins_encode %{ 9870 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 9871 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 9872 %} 9873 ins_pipe(pipe_class_default); 9874 %} 9875 9876 instruct tree_xorI_xorI_xorI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 9877 match(Set dst (XorI (XorI (XorI src1 src2) src3) src4)); 9878 ins_cost(DEFAULT_COST*3); 9879 9880 expand %{ 9881 // FIXME: we should do this in the ideal world. 9882 iRegIdst tmp1; 9883 iRegIdst tmp2; 9884 xorI_reg_reg(tmp1, src1, src2); 9885 xorI_reg_reg_2(tmp2, src3, src4); // Adlc complains about xorI_reg_reg. 9886 xorI_reg_reg(dst, tmp1, tmp2); 9887 %} 9888 %} 9889 9890 // Immediate Xor 9891 instruct xorI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 9892 match(Set dst (XorI src1 src2)); 9893 format %{ "XORI $dst, $src1, $src2" %} 9894 size(4); 9895 ins_encode %{ 9896 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 9897 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 9898 %} 9899 ins_pipe(pipe_class_default); 9900 %} 9901 9902 // Register Xor Long 9903 instruct xorL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9904 match(Set dst (XorL src1 src2)); 9905 ins_cost(DEFAULT_COST); 9906 9907 format %{ "XOR $dst, $src1, $src2 \t// long" %} 9908 size(4); 9909 ins_encode %{ 9910 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 9911 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 9912 %} 9913 ins_pipe(pipe_class_default); 9914 %} 9915 9916 // XorL + ConvL2I. 9917 instruct xorI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9918 match(Set dst (ConvL2I (XorL src1 src2))); 9919 ins_cost(DEFAULT_COST); 9920 9921 format %{ "XOR $dst, $src1, $src2 \t// long + l2i" %} 9922 size(4); 9923 ins_encode %{ 9924 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 9925 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 9926 %} 9927 ins_pipe(pipe_class_default); 9928 %} 9929 9930 // Immediate Xor Long 9931 instruct xorL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2) %{ 9932 match(Set dst (XorL src1 src2)); 9933 ins_cost(DEFAULT_COST); 9934 9935 format %{ "XORI $dst, $src1, $src2 \t// long" %} 9936 size(4); 9937 ins_encode %{ 9938 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 9939 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 9940 %} 9941 ins_pipe(pipe_class_default); 9942 %} 9943 9944 instruct notI_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 9945 match(Set dst (XorI src1 src2)); 9946 ins_cost(DEFAULT_COST); 9947 9948 format %{ "NOT $dst, $src1 ($src2)" %} 9949 size(4); 9950 ins_encode %{ 9951 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 9952 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 9953 %} 9954 ins_pipe(pipe_class_default); 9955 %} 9956 9957 instruct notL_reg(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 9958 match(Set dst (XorL src1 src2)); 9959 ins_cost(DEFAULT_COST); 9960 9961 format %{ "NOT $dst, $src1 ($src2) \t// long" %} 9962 size(4); 9963 ins_encode %{ 9964 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 9965 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 9966 %} 9967 ins_pipe(pipe_class_default); 9968 %} 9969 9970 // And-complement 9971 instruct andcI_reg_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2, iRegIsrc src3) %{ 9972 match(Set dst (AndI (XorI src1 src2) src3)); 9973 ins_cost(DEFAULT_COST); 9974 9975 format %{ "ANDW $dst, xori($src1, $src2), $src3" %} 9976 size(4); 9977 ins_encode( enc_andc(dst, src3, src1) ); 9978 ins_pipe(pipe_class_default); 9979 %} 9980 9981 // And-complement 9982 instruct andcL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9983 // no match-rule, false predicate 9984 effect(DEF dst, USE src1, USE src2); 9985 predicate(false); 9986 9987 format %{ "ANDC $dst, $src1, $src2" %} 9988 size(4); 9989 ins_encode %{ 9990 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 9991 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 9992 %} 9993 ins_pipe(pipe_class_default); 9994 %} 9995 9996 //----------Moves between int/long and float/double---------------------------- 9997 // 9998 // The following rules move values from int/long registers/stack-locations 9999 // to float/double registers/stack-locations and vice versa, without doing any 10000 // conversions. These rules are used to implement the bit-conversion methods 10001 // of java.lang.Float etc., e.g. 10002 // int floatToIntBits(float value) 10003 // float intBitsToFloat(int bits) 10004 // 10005 // Notes on the implementation on ppc64: 10006 // We only provide rules which move between a register and a stack-location, 10007 // because we always have to go through memory when moving between a float 10008 // register and an integer register. 10009 10010 //---------- Chain stack slots between similar types -------- 10011 10012 // These are needed so that the rules below can match. 10013 10014 // Load integer from stack slot 10015 instruct stkI_to_regI(iRegIdst dst, stackSlotI src) %{ 10016 match(Set dst src); 10017 ins_cost(MEMORY_REF_COST); 10018 10019 format %{ "LWZ $dst, $src" %} 10020 size(4); 10021 ins_encode( enc_lwz(dst, src) ); 10022 ins_pipe(pipe_class_memory); 10023 %} 10024 10025 // Store integer to stack slot 10026 instruct regI_to_stkI(stackSlotI dst, iRegIsrc src) %{ 10027 match(Set dst src); 10028 ins_cost(MEMORY_REF_COST); 10029 10030 format %{ "STW $src, $dst \t// stk" %} 10031 size(4); 10032 ins_encode( enc_stw(src, dst) ); // rs=rt 10033 ins_pipe(pipe_class_memory); 10034 %} 10035 10036 // Load long from stack slot 10037 instruct stkL_to_regL(iRegLdst dst, stackSlotL src) %{ 10038 match(Set dst src); 10039 ins_cost(MEMORY_REF_COST); 10040 10041 format %{ "LD $dst, $src \t// long" %} 10042 size(4); 10043 ins_encode( enc_ld(dst, src) ); 10044 ins_pipe(pipe_class_memory); 10045 %} 10046 10047 // Store long to stack slot 10048 instruct regL_to_stkL(stackSlotL dst, iRegLsrc src) %{ 10049 match(Set dst src); 10050 ins_cost(MEMORY_REF_COST); 10051 10052 format %{ "STD $src, $dst \t// long" %} 10053 size(4); 10054 ins_encode( enc_std(src, dst) ); // rs=rt 10055 ins_pipe(pipe_class_memory); 10056 %} 10057 10058 //----------Moves between int and float 10059 10060 // Move float value from float stack-location to integer register. 10061 instruct moveF2I_stack_reg(iRegIdst dst, stackSlotF src) %{ 10062 match(Set dst (MoveF2I src)); 10063 ins_cost(MEMORY_REF_COST); 10064 10065 format %{ "LWZ $dst, $src \t// MoveF2I" %} 10066 size(4); 10067 ins_encode( enc_lwz(dst, src) ); 10068 ins_pipe(pipe_class_memory); 10069 %} 10070 10071 // Move float value from float register to integer stack-location. 10072 instruct moveF2I_reg_stack(stackSlotI dst, regF src) %{ 10073 match(Set dst (MoveF2I src)); 10074 ins_cost(MEMORY_REF_COST); 10075 10076 format %{ "STFS $src, $dst \t// MoveF2I" %} 10077 size(4); 10078 ins_encode( enc_stfs(src, dst) ); 10079 ins_pipe(pipe_class_memory); 10080 %} 10081 10082 // Move integer value from integer stack-location to float register. 10083 instruct moveI2F_stack_reg(regF dst, stackSlotI src) %{ 10084 match(Set dst (MoveI2F src)); 10085 ins_cost(MEMORY_REF_COST); 10086 10087 format %{ "LFS $dst, $src \t// MoveI2F" %} 10088 size(4); 10089 ins_encode %{ 10090 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 10091 int Idisp = $src$$disp + frame_slots_bias($src$$base, ra_); 10092 __ lfs($dst$$FloatRegister, Idisp, $src$$base$$Register); 10093 %} 10094 ins_pipe(pipe_class_memory); 10095 %} 10096 10097 // Move integer value from integer register to float stack-location. 10098 instruct moveI2F_reg_stack(stackSlotF dst, iRegIsrc src) %{ 10099 match(Set dst (MoveI2F src)); 10100 ins_cost(MEMORY_REF_COST); 10101 10102 format %{ "STW $src, $dst \t// MoveI2F" %} 10103 size(4); 10104 ins_encode( enc_stw(src, dst) ); 10105 ins_pipe(pipe_class_memory); 10106 %} 10107 10108 //----------Moves between long and float 10109 10110 instruct moveF2L_reg_stack(stackSlotL dst, regF src) %{ 10111 // no match-rule, false predicate 10112 effect(DEF dst, USE src); 10113 predicate(false); 10114 10115 format %{ "storeD $src, $dst \t// STACK" %} 10116 size(4); 10117 ins_encode( enc_stfd(src, dst) ); 10118 ins_pipe(pipe_class_default); 10119 %} 10120 10121 //----------Moves between long and double 10122 10123 // Move double value from double stack-location to long register. 10124 instruct moveD2L_stack_reg(iRegLdst dst, stackSlotD src) %{ 10125 match(Set dst (MoveD2L src)); 10126 ins_cost(MEMORY_REF_COST); 10127 size(4); 10128 format %{ "LD $dst, $src \t// MoveD2L" %} 10129 ins_encode( enc_ld(dst, src) ); 10130 ins_pipe(pipe_class_memory); 10131 %} 10132 10133 // Move double value from double register to long stack-location. 10134 instruct moveD2L_reg_stack(stackSlotL dst, regD src) %{ 10135 match(Set dst (MoveD2L src)); 10136 effect(DEF dst, USE src); 10137 ins_cost(MEMORY_REF_COST); 10138 10139 format %{ "STFD $src, $dst \t// MoveD2L" %} 10140 size(4); 10141 ins_encode( enc_stfd(src, dst) ); 10142 ins_pipe(pipe_class_memory); 10143 %} 10144 10145 // Move long value from long stack-location to double register. 10146 instruct moveL2D_stack_reg(regD dst, stackSlotL src) %{ 10147 match(Set dst (MoveL2D src)); 10148 ins_cost(MEMORY_REF_COST); 10149 10150 format %{ "LFD $dst, $src \t// MoveL2D" %} 10151 size(4); 10152 ins_encode( enc_lfd(dst, src) ); 10153 ins_pipe(pipe_class_memory); 10154 %} 10155 10156 // Move long value from long register to double stack-location. 10157 instruct moveL2D_reg_stack(stackSlotD dst, iRegLsrc src) %{ 10158 match(Set dst (MoveL2D src)); 10159 ins_cost(MEMORY_REF_COST); 10160 10161 format %{ "STD $src, $dst \t// MoveL2D" %} 10162 size(4); 10163 ins_encode( enc_std(src, dst) ); 10164 ins_pipe(pipe_class_memory); 10165 %} 10166 10167 //----------Register Move Instructions----------------------------------------- 10168 10169 // Replicate for Superword 10170 10171 instruct moveReg(iRegLdst dst, iRegIsrc src) %{ 10172 predicate(false); 10173 effect(DEF dst, USE src); 10174 10175 format %{ "MR $dst, $src \t// replicate " %} 10176 // variable size, 0 or 4. 10177 ins_encode %{ 10178 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10179 __ mr_if_needed($dst$$Register, $src$$Register); 10180 %} 10181 ins_pipe(pipe_class_default); 10182 %} 10183 10184 //----------Cast instructions (Java-level type cast)--------------------------- 10185 10186 // Cast Long to Pointer for unsafe natives. 10187 instruct castX2P(iRegPdst dst, iRegLsrc src) %{ 10188 match(Set dst (CastX2P src)); 10189 10190 format %{ "MR $dst, $src \t// Long->Ptr" %} 10191 // variable size, 0 or 4. 10192 ins_encode %{ 10193 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10194 __ mr_if_needed($dst$$Register, $src$$Register); 10195 %} 10196 ins_pipe(pipe_class_default); 10197 %} 10198 10199 // Cast Pointer to Long for unsafe natives. 10200 instruct castP2X(iRegLdst dst, iRegP_N2P src) %{ 10201 match(Set dst (CastP2X src)); 10202 10203 format %{ "MR $dst, $src \t// Ptr->Long" %} 10204 // variable size, 0 or 4. 10205 ins_encode %{ 10206 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10207 __ mr_if_needed($dst$$Register, $src$$Register); 10208 %} 10209 ins_pipe(pipe_class_default); 10210 %} 10211 10212 instruct castPP(iRegPdst dst) %{ 10213 match(Set dst (CastPP dst)); 10214 format %{ " -- \t// castPP of $dst" %} 10215 size(0); 10216 ins_encode( /*empty*/ ); 10217 ins_pipe(pipe_class_default); 10218 %} 10219 10220 instruct castII(iRegIdst dst) %{ 10221 match(Set dst (CastII dst)); 10222 format %{ " -- \t// castII of $dst" %} 10223 size(0); 10224 ins_encode( /*empty*/ ); 10225 ins_pipe(pipe_class_default); 10226 %} 10227 10228 instruct checkCastPP(iRegPdst dst) %{ 10229 match(Set dst (CheckCastPP dst)); 10230 format %{ " -- \t// checkcastPP of $dst" %} 10231 size(0); 10232 ins_encode( /*empty*/ ); 10233 ins_pipe(pipe_class_default); 10234 %} 10235 10236 //----------Convert instructions----------------------------------------------- 10237 10238 // Convert to boolean. 10239 10240 // int_to_bool(src) : { 1 if src != 0 10241 // { 0 else 10242 // 10243 // strategy: 10244 // 1) Count leading zeros of 32 bit-value src, 10245 // this returns 32 (0b10.0000) iff src == 0 and <32 otherwise. 10246 // 2) Shift 5 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10247 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10248 10249 // convI2Bool 10250 instruct convI2Bool_reg__cntlz_Ex(iRegIdst dst, iRegIsrc src) %{ 10251 match(Set dst (Conv2B src)); 10252 predicate(UseCountLeadingZerosInstructionsPPC64); 10253 ins_cost(DEFAULT_COST); 10254 10255 expand %{ 10256 immI shiftAmount %{ 0x5 %} 10257 uimmI16 mask %{ 0x1 %} 10258 iRegIdst tmp1; 10259 iRegIdst tmp2; 10260 countLeadingZerosI(tmp1, src); 10261 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10262 xorI_reg_uimm16(dst, tmp2, mask); 10263 %} 10264 %} 10265 10266 instruct convI2Bool_reg__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx) %{ 10267 match(Set dst (Conv2B src)); 10268 effect(TEMP crx); 10269 predicate(!UseCountLeadingZerosInstructionsPPC64); 10270 ins_cost(DEFAULT_COST); 10271 10272 format %{ "CMPWI $crx, $src, #0 \t// convI2B" 10273 "LI $dst, #0\n\t" 10274 "BEQ $crx, done\n\t" 10275 "LI $dst, #1\n" 10276 "done:" %} 10277 size(16); 10278 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x0, 0x1) ); 10279 ins_pipe(pipe_class_compare); 10280 %} 10281 10282 // ConvI2B + XorI 10283 instruct xorI_convI2Bool_reg_immIvalue1__cntlz_Ex(iRegIdst dst, iRegIsrc src, immI_1 mask) %{ 10284 match(Set dst (XorI (Conv2B src) mask)); 10285 predicate(UseCountLeadingZerosInstructionsPPC64); 10286 ins_cost(DEFAULT_COST); 10287 10288 expand %{ 10289 immI shiftAmount %{ 0x5 %} 10290 iRegIdst tmp1; 10291 countLeadingZerosI(tmp1, src); 10292 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10293 %} 10294 %} 10295 10296 instruct xorI_convI2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI_1 mask) %{ 10297 match(Set dst (XorI (Conv2B src) mask)); 10298 effect(TEMP crx); 10299 predicate(!UseCountLeadingZerosInstructionsPPC64); 10300 ins_cost(DEFAULT_COST); 10301 10302 format %{ "CMPWI $crx, $src, #0 \t// Xor(convI2B($src), $mask)" 10303 "LI $dst, #1\n\t" 10304 "BEQ $crx, done\n\t" 10305 "LI $dst, #0\n" 10306 "done:" %} 10307 size(16); 10308 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x1, 0x0) ); 10309 ins_pipe(pipe_class_compare); 10310 %} 10311 10312 // AndI 0b0..010..0 + ConvI2B 10313 instruct convI2Bool_andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src, immIpowerOf2 mask) %{ 10314 match(Set dst (Conv2B (AndI src mask))); 10315 predicate(UseRotateAndMaskInstructionsPPC64); 10316 ins_cost(DEFAULT_COST); 10317 10318 format %{ "RLWINM $dst, $src, $mask \t// convI2B(AndI($src, $mask))" %} 10319 size(4); 10320 ins_encode %{ 10321 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 10322 __ rlwinm($dst$$Register, $src$$Register, (32-log2_long((jlong)$mask$$constant)) & 0x1f, 31, 31); 10323 %} 10324 ins_pipe(pipe_class_default); 10325 %} 10326 10327 // Convert pointer to boolean. 10328 // 10329 // ptr_to_bool(src) : { 1 if src != 0 10330 // { 0 else 10331 // 10332 // strategy: 10333 // 1) Count leading zeros of 64 bit-value src, 10334 // this returns 64 (0b100.0000) iff src == 0 and <64 otherwise. 10335 // 2) Shift 6 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10336 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10337 10338 // ConvP2B 10339 instruct convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src) %{ 10340 match(Set dst (Conv2B src)); 10341 predicate(UseCountLeadingZerosInstructionsPPC64); 10342 ins_cost(DEFAULT_COST); 10343 10344 expand %{ 10345 immI shiftAmount %{ 0x6 %} 10346 uimmI16 mask %{ 0x1 %} 10347 iRegIdst tmp1; 10348 iRegIdst tmp2; 10349 countLeadingZerosP(tmp1, src); 10350 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10351 xorI_reg_uimm16(dst, tmp2, mask); 10352 %} 10353 %} 10354 10355 instruct convP2Bool_reg__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx) %{ 10356 match(Set dst (Conv2B src)); 10357 effect(TEMP crx); 10358 predicate(!UseCountLeadingZerosInstructionsPPC64); 10359 ins_cost(DEFAULT_COST); 10360 10361 format %{ "CMPDI $crx, $src, #0 \t// convP2B" 10362 "LI $dst, #0\n\t" 10363 "BEQ $crx, done\n\t" 10364 "LI $dst, #1\n" 10365 "done:" %} 10366 size(16); 10367 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x0, 0x1) ); 10368 ins_pipe(pipe_class_compare); 10369 %} 10370 10371 // ConvP2B + XorI 10372 instruct xorI_convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src, immI_1 mask) %{ 10373 match(Set dst (XorI (Conv2B src) mask)); 10374 predicate(UseCountLeadingZerosInstructionsPPC64); 10375 ins_cost(DEFAULT_COST); 10376 10377 expand %{ 10378 immI shiftAmount %{ 0x6 %} 10379 iRegIdst tmp1; 10380 countLeadingZerosP(tmp1, src); 10381 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10382 %} 10383 %} 10384 10385 instruct xorI_convP2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx, immI_1 mask) %{ 10386 match(Set dst (XorI (Conv2B src) mask)); 10387 effect(TEMP crx); 10388 predicate(!UseCountLeadingZerosInstructionsPPC64); 10389 ins_cost(DEFAULT_COST); 10390 10391 format %{ "CMPDI $crx, $src, #0 \t// XorI(convP2B($src), $mask)" 10392 "LI $dst, #1\n\t" 10393 "BEQ $crx, done\n\t" 10394 "LI $dst, #0\n" 10395 "done:" %} 10396 size(16); 10397 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x1, 0x0) ); 10398 ins_pipe(pipe_class_compare); 10399 %} 10400 10401 // if src1 < src2, return -1 else return 0 10402 instruct cmpLTMask_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10403 match(Set dst (CmpLTMask src1 src2)); 10404 ins_cost(DEFAULT_COST*4); 10405 10406 expand %{ 10407 iRegLdst src1s; 10408 iRegLdst src2s; 10409 iRegLdst diff; 10410 convI2L_reg(src1s, src1); // Ensure proper sign extension. 10411 convI2L_reg(src2s, src2); // Ensure proper sign extension. 10412 subL_reg_reg(diff, src1s, src2s); 10413 // Need to consider >=33 bit result, therefore we need signmaskL. 10414 signmask64I_regL(dst, diff); 10415 %} 10416 %} 10417 10418 instruct cmpLTMask_reg_immI0(iRegIdst dst, iRegIsrc src1, immI_0 src2) %{ 10419 match(Set dst (CmpLTMask src1 src2)); // if src1 < src2, return -1 else return 0 10420 format %{ "SRAWI $dst, $src1, $src2 \t// CmpLTMask" %} 10421 size(4); 10422 ins_encode %{ 10423 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 10424 __ srawi($dst$$Register, $src1$$Register, 0x1f); 10425 %} 10426 ins_pipe(pipe_class_default); 10427 %} 10428 10429 //----------Arithmetic Conversion Instructions--------------------------------- 10430 10431 // Convert to Byte -- nop 10432 // Convert to Short -- nop 10433 10434 // Convert to Int 10435 10436 instruct convB2I_reg(iRegIdst dst, iRegIsrc src, immI_24 amount) %{ 10437 match(Set dst (RShiftI (LShiftI src amount) amount)); 10438 format %{ "EXTSB $dst, $src \t// byte->int" %} 10439 size(4); 10440 ins_encode %{ 10441 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 10442 __ extsb($dst$$Register, $src$$Register); 10443 %} 10444 ins_pipe(pipe_class_default); 10445 %} 10446 10447 // LShiftI 16 + RShiftI 16 converts short to int. 10448 instruct convS2I_reg(iRegIdst dst, iRegIsrc src, immI_16 amount) %{ 10449 match(Set dst (RShiftI (LShiftI src amount) amount)); 10450 format %{ "EXTSH $dst, $src \t// short->int" %} 10451 size(4); 10452 ins_encode %{ 10453 // TODO: PPC port $archOpcode(ppc64Opcode_extsh); 10454 __ extsh($dst$$Register, $src$$Register); 10455 %} 10456 ins_pipe(pipe_class_default); 10457 %} 10458 10459 // ConvL2I + ConvI2L: Sign extend int in long register. 10460 instruct sxtI_L2L_reg(iRegLdst dst, iRegLsrc src) %{ 10461 match(Set dst (ConvI2L (ConvL2I src))); 10462 10463 format %{ "EXTSW $dst, $src \t// long->long" %} 10464 size(4); 10465 ins_encode %{ 10466 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 10467 __ extsw($dst$$Register, $src$$Register); 10468 %} 10469 ins_pipe(pipe_class_default); 10470 %} 10471 10472 instruct convL2I_reg(iRegIdst dst, iRegLsrc src) %{ 10473 match(Set dst (ConvL2I src)); 10474 format %{ "MR $dst, $src \t// long->int" %} 10475 // variable size, 0 or 4 10476 ins_encode %{ 10477 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10478 __ mr_if_needed($dst$$Register, $src$$Register); 10479 %} 10480 ins_pipe(pipe_class_default); 10481 %} 10482 10483 instruct convD2IRaw_regD(regD dst, regD src) %{ 10484 // no match-rule, false predicate 10485 effect(DEF dst, USE src); 10486 predicate(false); 10487 10488 format %{ "FCTIWZ $dst, $src \t// convD2I, $src != NaN" %} 10489 size(4); 10490 ins_encode %{ 10491 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz);; 10492 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 10493 %} 10494 ins_pipe(pipe_class_default); 10495 %} 10496 10497 instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL src) %{ 10498 // no match-rule, false predicate 10499 effect(DEF dst, USE crx, USE src); 10500 predicate(false); 10501 10502 ins_variable_size_depending_on_alignment(true); 10503 10504 format %{ "cmovI $crx, $dst, $src" %} 10505 // Worst case is branch + move + stop, no stop without scheduler. 10506 size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 10507 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 10508 ins_pipe(pipe_class_default); 10509 %} 10510 10511 instruct cmovI_bso_stackSlotL_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, stackSlotL mem) %{ 10512 // no match-rule, false predicate 10513 effect(DEF dst, USE crx, USE mem); 10514 predicate(false); 10515 10516 format %{ "CmovI $dst, $crx, $mem \t// postalloc expanded" %} 10517 postalloc_expand %{ 10518 // 10519 // replaces 10520 // 10521 // region dst crx mem 10522 // \ | | / 10523 // dst=cmovI_bso_stackSlotL_conLvalue0 10524 // 10525 // with 10526 // 10527 // region dst 10528 // \ / 10529 // dst=loadConI16(0) 10530 // | 10531 // ^ region dst crx mem 10532 // | \ | | / 10533 // dst=cmovI_bso_stackSlotL 10534 // 10535 10536 // Create new nodes. 10537 MachNode *m1 = new loadConI16Node(); 10538 MachNode *m2 = new cmovI_bso_stackSlotLNode(); 10539 10540 // inputs for new nodes 10541 m1->add_req(n_region); 10542 m2->add_req(n_region, n_crx, n_mem); 10543 10544 // precedences for new nodes 10545 m2->add_prec(m1); 10546 10547 // operands for new nodes 10548 m1->_opnds[0] = op_dst; 10549 m1->_opnds[1] = new immI16Oper(0); 10550 10551 m2->_opnds[0] = op_dst; 10552 m2->_opnds[1] = op_crx; 10553 m2->_opnds[2] = op_mem; 10554 10555 // registers for new nodes 10556 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10557 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10558 10559 // Insert new nodes. 10560 nodes->push(m1); 10561 nodes->push(m2); 10562 %} 10563 %} 10564 10565 // Double to Int conversion, NaN is mapped to 0. 10566 instruct convD2I_reg_ExEx(iRegIdst dst, regD src) %{ 10567 match(Set dst (ConvD2I src)); 10568 ins_cost(DEFAULT_COST); 10569 10570 expand %{ 10571 regD tmpD; 10572 stackSlotL tmpS; 10573 flagsReg crx; 10574 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10575 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 10576 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 10577 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 10578 %} 10579 %} 10580 10581 instruct convF2IRaw_regF(regF dst, regF src) %{ 10582 // no match-rule, false predicate 10583 effect(DEF dst, USE src); 10584 predicate(false); 10585 10586 format %{ "FCTIWZ $dst, $src \t// convF2I, $src != NaN" %} 10587 size(4); 10588 ins_encode %{ 10589 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 10590 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 10591 %} 10592 ins_pipe(pipe_class_default); 10593 %} 10594 10595 // Float to Int conversion, NaN is mapped to 0. 10596 instruct convF2I_regF_ExEx(iRegIdst dst, regF src) %{ 10597 match(Set dst (ConvF2I src)); 10598 ins_cost(DEFAULT_COST); 10599 10600 expand %{ 10601 regF tmpF; 10602 stackSlotL tmpS; 10603 flagsReg crx; 10604 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10605 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 10606 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 10607 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 10608 %} 10609 %} 10610 10611 // Convert to Long 10612 10613 instruct convI2L_reg(iRegLdst dst, iRegIsrc src) %{ 10614 match(Set dst (ConvI2L src)); 10615 format %{ "EXTSW $dst, $src \t// int->long" %} 10616 size(4); 10617 ins_encode %{ 10618 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 10619 __ extsw($dst$$Register, $src$$Register); 10620 %} 10621 ins_pipe(pipe_class_default); 10622 %} 10623 10624 // Zero-extend: convert unsigned int to long (convUI2L). 10625 instruct zeroExtendL_regI(iRegLdst dst, iRegIsrc src, immL_32bits mask) %{ 10626 match(Set dst (AndL (ConvI2L src) mask)); 10627 ins_cost(DEFAULT_COST); 10628 10629 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 10630 size(4); 10631 ins_encode %{ 10632 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10633 __ clrldi($dst$$Register, $src$$Register, 32); 10634 %} 10635 ins_pipe(pipe_class_default); 10636 %} 10637 10638 // Zero-extend: convert unsigned int to long in long register. 10639 instruct zeroExtendL_regL(iRegLdst dst, iRegLsrc src, immL_32bits mask) %{ 10640 match(Set dst (AndL src mask)); 10641 ins_cost(DEFAULT_COST); 10642 10643 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 10644 size(4); 10645 ins_encode %{ 10646 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10647 __ clrldi($dst$$Register, $src$$Register, 32); 10648 %} 10649 ins_pipe(pipe_class_default); 10650 %} 10651 10652 instruct convF2LRaw_regF(regF dst, regF src) %{ 10653 // no match-rule, false predicate 10654 effect(DEF dst, USE src); 10655 predicate(false); 10656 10657 format %{ "FCTIDZ $dst, $src \t// convF2L, $src != NaN" %} 10658 size(4); 10659 ins_encode %{ 10660 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 10661 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 10662 %} 10663 ins_pipe(pipe_class_default); 10664 %} 10665 10666 instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL src) %{ 10667 // no match-rule, false predicate 10668 effect(DEF dst, USE crx, USE src); 10669 predicate(false); 10670 10671 ins_variable_size_depending_on_alignment(true); 10672 10673 format %{ "cmovL $crx, $dst, $src" %} 10674 // Worst case is branch + move + stop, no stop without scheduler. 10675 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 10676 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 10677 ins_pipe(pipe_class_default); 10678 %} 10679 10680 instruct cmovL_bso_stackSlotL_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, stackSlotL mem) %{ 10681 // no match-rule, false predicate 10682 effect(DEF dst, USE crx, USE mem); 10683 predicate(false); 10684 10685 format %{ "CmovL $dst, $crx, $mem \t// postalloc expanded" %} 10686 postalloc_expand %{ 10687 // 10688 // replaces 10689 // 10690 // region dst crx mem 10691 // \ | | / 10692 // dst=cmovL_bso_stackSlotL_conLvalue0 10693 // 10694 // with 10695 // 10696 // region dst 10697 // \ / 10698 // dst=loadConL16(0) 10699 // | 10700 // ^ region dst crx mem 10701 // | \ | | / 10702 // dst=cmovL_bso_stackSlotL 10703 // 10704 10705 // Create new nodes. 10706 MachNode *m1 = new loadConL16Node(); 10707 MachNode *m2 = new cmovL_bso_stackSlotLNode(); 10708 10709 // inputs for new nodes 10710 m1->add_req(n_region); 10711 m2->add_req(n_region, n_crx, n_mem); 10712 m2->add_prec(m1); 10713 10714 // operands for new nodes 10715 m1->_opnds[0] = op_dst; 10716 m1->_opnds[1] = new immL16Oper(0); 10717 m2->_opnds[0] = op_dst; 10718 m2->_opnds[1] = op_crx; 10719 m2->_opnds[2] = op_mem; 10720 10721 // registers for new nodes 10722 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10723 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10724 10725 // Insert new nodes. 10726 nodes->push(m1); 10727 nodes->push(m2); 10728 %} 10729 %} 10730 10731 // Float to Long conversion, NaN is mapped to 0. 10732 instruct convF2L_reg_ExEx(iRegLdst dst, regF src) %{ 10733 match(Set dst (ConvF2L src)); 10734 ins_cost(DEFAULT_COST); 10735 10736 expand %{ 10737 regF tmpF; 10738 stackSlotL tmpS; 10739 flagsReg crx; 10740 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10741 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 10742 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 10743 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 10744 %} 10745 %} 10746 10747 instruct convD2LRaw_regD(regD dst, regD src) %{ 10748 // no match-rule, false predicate 10749 effect(DEF dst, USE src); 10750 predicate(false); 10751 10752 format %{ "FCTIDZ $dst, $src \t// convD2L $src != NaN" %} 10753 size(4); 10754 ins_encode %{ 10755 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 10756 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 10757 %} 10758 ins_pipe(pipe_class_default); 10759 %} 10760 10761 // Double to Long conversion, NaN is mapped to 0. 10762 instruct convD2L_reg_ExEx(iRegLdst dst, regD src) %{ 10763 match(Set dst (ConvD2L src)); 10764 ins_cost(DEFAULT_COST); 10765 10766 expand %{ 10767 regD tmpD; 10768 stackSlotL tmpS; 10769 flagsReg crx; 10770 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10771 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 10772 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 10773 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 10774 %} 10775 %} 10776 10777 // Convert to Float 10778 10779 // Placed here as needed in expand. 10780 instruct convL2DRaw_regD(regD dst, regD src) %{ 10781 // no match-rule, false predicate 10782 effect(DEF dst, USE src); 10783 predicate(false); 10784 10785 format %{ "FCFID $dst, $src \t// convL2D" %} 10786 size(4); 10787 ins_encode %{ 10788 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 10789 __ fcfid($dst$$FloatRegister, $src$$FloatRegister); 10790 %} 10791 ins_pipe(pipe_class_default); 10792 %} 10793 10794 // Placed here as needed in expand. 10795 instruct convD2F_reg(regF dst, regD src) %{ 10796 match(Set dst (ConvD2F src)); 10797 format %{ "FRSP $dst, $src \t// convD2F" %} 10798 size(4); 10799 ins_encode %{ 10800 // TODO: PPC port $archOpcode(ppc64Opcode_frsp); 10801 __ frsp($dst$$FloatRegister, $src$$FloatRegister); 10802 %} 10803 ins_pipe(pipe_class_default); 10804 %} 10805 10806 // Integer to Float conversion. 10807 instruct convI2F_ireg_Ex(regF dst, iRegIsrc src) %{ 10808 match(Set dst (ConvI2F src)); 10809 predicate(!VM_Version::has_fcfids()); 10810 ins_cost(DEFAULT_COST); 10811 10812 expand %{ 10813 iRegLdst tmpL; 10814 stackSlotL tmpS; 10815 regD tmpD; 10816 regD tmpD2; 10817 convI2L_reg(tmpL, src); // Sign-extension int to long. 10818 regL_to_stkL(tmpS, tmpL); // Store long to stack. 10819 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 10820 convL2DRaw_regD(tmpD2, tmpD); // Convert to double. 10821 convD2F_reg(dst, tmpD2); // Convert double to float. 10822 %} 10823 %} 10824 10825 instruct convL2FRaw_regF(regF dst, regD src) %{ 10826 // no match-rule, false predicate 10827 effect(DEF dst, USE src); 10828 predicate(false); 10829 10830 format %{ "FCFIDS $dst, $src \t// convL2F" %} 10831 size(4); 10832 ins_encode %{ 10833 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 10834 __ fcfids($dst$$FloatRegister, $src$$FloatRegister); 10835 %} 10836 ins_pipe(pipe_class_default); 10837 %} 10838 10839 // Integer to Float conversion. Special version for Power7. 10840 instruct convI2F_ireg_fcfids_Ex(regF dst, iRegIsrc src) %{ 10841 match(Set dst (ConvI2F src)); 10842 predicate(VM_Version::has_fcfids()); 10843 ins_cost(DEFAULT_COST); 10844 10845 expand %{ 10846 iRegLdst tmpL; 10847 stackSlotL tmpS; 10848 regD tmpD; 10849 convI2L_reg(tmpL, src); // Sign-extension int to long. 10850 regL_to_stkL(tmpS, tmpL); // Store long to stack. 10851 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 10852 convL2FRaw_regF(dst, tmpD); // Convert to float. 10853 %} 10854 %} 10855 10856 // L2F to avoid runtime call. 10857 instruct convL2F_ireg_fcfids_Ex(regF dst, iRegLsrc src) %{ 10858 match(Set dst (ConvL2F src)); 10859 predicate(VM_Version::has_fcfids()); 10860 ins_cost(DEFAULT_COST); 10861 10862 expand %{ 10863 stackSlotL tmpS; 10864 regD tmpD; 10865 regL_to_stkL(tmpS, src); // Store long to stack. 10866 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 10867 convL2FRaw_regF(dst, tmpD); // Convert to float. 10868 %} 10869 %} 10870 10871 // Moved up as used in expand. 10872 //instruct convD2F_reg(regF dst, regD src) %{%} 10873 10874 // Convert to Double 10875 10876 // Integer to Double conversion. 10877 instruct convI2D_reg_Ex(regD dst, iRegIsrc src) %{ 10878 match(Set dst (ConvI2D src)); 10879 ins_cost(DEFAULT_COST); 10880 10881 expand %{ 10882 iRegLdst tmpL; 10883 stackSlotL tmpS; 10884 regD tmpD; 10885 convI2L_reg(tmpL, src); // Sign-extension int to long. 10886 regL_to_stkL(tmpS, tmpL); // Store long to stack. 10887 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 10888 convL2DRaw_regD(dst, tmpD); // Convert to double. 10889 %} 10890 %} 10891 10892 // Long to Double conversion 10893 instruct convL2D_reg_Ex(regD dst, stackSlotL src) %{ 10894 match(Set dst (ConvL2D src)); 10895 ins_cost(DEFAULT_COST + MEMORY_REF_COST); 10896 10897 expand %{ 10898 regD tmpD; 10899 moveL2D_stack_reg(tmpD, src); 10900 convL2DRaw_regD(dst, tmpD); 10901 %} 10902 %} 10903 10904 instruct convF2D_reg(regD dst, regF src) %{ 10905 match(Set dst (ConvF2D src)); 10906 format %{ "FMR $dst, $src \t// float->double" %} 10907 // variable size, 0 or 4 10908 ins_encode %{ 10909 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 10910 __ fmr_if_needed($dst$$FloatRegister, $src$$FloatRegister); 10911 %} 10912 ins_pipe(pipe_class_default); 10913 %} 10914 10915 //----------Control Flow Instructions------------------------------------------ 10916 // Compare Instructions 10917 10918 // Compare Integers 10919 instruct cmpI_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 10920 match(Set crx (CmpI src1 src2)); 10921 size(4); 10922 format %{ "CMPW $crx, $src1, $src2" %} 10923 ins_encode %{ 10924 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 10925 __ cmpw($crx$$CondRegister, $src1$$Register, $src2$$Register); 10926 %} 10927 ins_pipe(pipe_class_compare); 10928 %} 10929 10930 instruct cmpI_reg_imm16(flagsReg crx, iRegIsrc src1, immI16 src2) %{ 10931 match(Set crx (CmpI src1 src2)); 10932 format %{ "CMPWI $crx, $src1, $src2" %} 10933 size(4); 10934 ins_encode %{ 10935 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 10936 __ cmpwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 10937 %} 10938 ins_pipe(pipe_class_compare); 10939 %} 10940 10941 // (src1 & src2) == 0? 10942 instruct testI_reg_imm(flagsRegCR0 cr0, iRegIsrc src1, uimmI16 src2, immI_0 zero) %{ 10943 match(Set cr0 (CmpI (AndI src1 src2) zero)); 10944 // r0 is killed 10945 format %{ "ANDI R0, $src1, $src2 \t// BTST int" %} 10946 size(4); 10947 ins_encode %{ 10948 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 10949 __ andi_(R0, $src1$$Register, $src2$$constant); 10950 %} 10951 ins_pipe(pipe_class_compare); 10952 %} 10953 10954 instruct cmpL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 10955 match(Set crx (CmpL src1 src2)); 10956 format %{ "CMPD $crx, $src1, $src2" %} 10957 size(4); 10958 ins_encode %{ 10959 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 10960 __ cmpd($crx$$CondRegister, $src1$$Register, $src2$$Register); 10961 %} 10962 ins_pipe(pipe_class_compare); 10963 %} 10964 10965 instruct cmpL_reg_imm16(flagsReg crx, iRegLsrc src1, immL16 src2) %{ 10966 match(Set crx (CmpL src1 src2)); 10967 format %{ "CMPDI $crx, $src1, $src2" %} 10968 size(4); 10969 ins_encode %{ 10970 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 10971 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 10972 %} 10973 ins_pipe(pipe_class_compare); 10974 %} 10975 10976 instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zero) %{ 10977 match(Set cr0 (CmpL (AndL src1 src2) zero)); 10978 // r0 is killed 10979 format %{ "AND R0, $src1, $src2 \t// BTST long" %} 10980 size(4); 10981 ins_encode %{ 10982 // TODO: PPC port $archOpcode(ppc64Opcode_and_); 10983 __ and_(R0, $src1$$Register, $src2$$Register); 10984 %} 10985 ins_pipe(pipe_class_compare); 10986 %} 10987 10988 instruct testL_reg_imm(flagsRegCR0 cr0, iRegLsrc src1, uimmL16 src2, immL_0 zero) %{ 10989 match(Set cr0 (CmpL (AndL src1 src2) zero)); 10990 // r0 is killed 10991 format %{ "ANDI R0, $src1, $src2 \t// BTST long" %} 10992 size(4); 10993 ins_encode %{ 10994 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 10995 __ andi_(R0, $src1$$Register, $src2$$constant); 10996 %} 10997 ins_pipe(pipe_class_compare); 10998 %} 10999 11000 instruct cmovI_conIvalueMinus1_conIvalue1(iRegIdst dst, flagsRegSrc crx) %{ 11001 // no match-rule, false predicate 11002 effect(DEF dst, USE crx); 11003 predicate(false); 11004 11005 ins_variable_size_depending_on_alignment(true); 11006 11007 format %{ "cmovI $crx, $dst, -1, 0, +1" %} 11008 // Worst case is branch + move + branch + move + stop, no stop without scheduler. 11009 size(false /* TODO: PPC PORTInsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 20 : 16); 11010 ins_encode %{ 11011 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 11012 Label done; 11013 // li(Rdst, 0); // equal -> 0 11014 __ beq($crx$$CondRegister, done); 11015 __ li($dst$$Register, 1); // greater -> +1 11016 __ bgt($crx$$CondRegister, done); 11017 __ li($dst$$Register, -1); // unordered or less -> -1 11018 // TODO: PPC port__ endgroup_if_needed(_size == 20); 11019 __ bind(done); 11020 %} 11021 ins_pipe(pipe_class_compare); 11022 %} 11023 11024 instruct cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(iRegIdst dst, flagsRegSrc crx) %{ 11025 // no match-rule, false predicate 11026 effect(DEF dst, USE crx); 11027 predicate(false); 11028 11029 format %{ "CmovI $crx, $dst, -1, 0, +1 \t// postalloc expanded" %} 11030 postalloc_expand %{ 11031 // 11032 // replaces 11033 // 11034 // region crx 11035 // \ | 11036 // dst=cmovI_conIvalueMinus1_conIvalue0_conIvalue1 11037 // 11038 // with 11039 // 11040 // region 11041 // \ 11042 // dst=loadConI16(0) 11043 // | 11044 // ^ region crx 11045 // | \ | 11046 // dst=cmovI_conIvalueMinus1_conIvalue1 11047 // 11048 11049 // Create new nodes. 11050 MachNode *m1 = new loadConI16Node(); 11051 MachNode *m2 = new cmovI_conIvalueMinus1_conIvalue1Node(); 11052 11053 // inputs for new nodes 11054 m1->add_req(n_region); 11055 m2->add_req(n_region, n_crx); 11056 m2->add_prec(m1); 11057 11058 // operands for new nodes 11059 m1->_opnds[0] = op_dst; 11060 m1->_opnds[1] = new immI16Oper(0); 11061 m2->_opnds[0] = op_dst; 11062 m2->_opnds[1] = op_crx; 11063 11064 // registers for new nodes 11065 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11066 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11067 11068 // Insert new nodes. 11069 nodes->push(m1); 11070 nodes->push(m2); 11071 %} 11072 %} 11073 11074 // Manifest a CmpL3 result in an integer register. Very painful. 11075 // This is the test to avoid. 11076 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 11077 instruct cmpL3_reg_reg_ExEx(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 11078 match(Set dst (CmpL3 src1 src2)); 11079 ins_cost(DEFAULT_COST*5+BRANCH_COST); 11080 11081 expand %{ 11082 flagsReg tmp1; 11083 cmpL_reg_reg(tmp1, src1, src2); 11084 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 11085 %} 11086 %} 11087 11088 // Implicit range checks. 11089 // A range check in the ideal world has one of the following shapes: 11090 // - (If le (CmpU length index)), (IfTrue throw exception) 11091 // - (If lt (CmpU index length)), (IfFalse throw exception) 11092 // 11093 // Match range check 'If le (CmpU length index)'. 11094 instruct rangeCheck_iReg_uimm15(cmpOp cmp, iRegIsrc src_length, uimmI15 index, label labl) %{ 11095 match(If cmp (CmpU src_length index)); 11096 effect(USE labl); 11097 predicate(TrapBasedRangeChecks && 11098 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le && 11099 PROB_UNLIKELY(_leaf->as_If()->_prob) >= PROB_ALWAYS && 11100 (Matcher::branches_to_uncommon_trap(_leaf))); 11101 11102 ins_is_TrapBasedCheckNode(true); 11103 11104 format %{ "TWI $index $cmp $src_length \t// RangeCheck => trap $labl" %} 11105 size(4); 11106 ins_encode %{ 11107 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 11108 if ($cmp$$cmpcode == 0x1 /* less_equal */) { 11109 __ trap_range_check_le($src_length$$Register, $index$$constant); 11110 } else { 11111 // Both successors are uncommon traps, probability is 0. 11112 // Node got flipped during fixup flow. 11113 assert($cmp$$cmpcode == 0x9, "must be greater"); 11114 __ trap_range_check_g($src_length$$Register, $index$$constant); 11115 } 11116 %} 11117 ins_pipe(pipe_class_trap); 11118 %} 11119 11120 // Match range check 'If lt (CmpU index length)'. 11121 instruct rangeCheck_iReg_iReg(cmpOp cmp, iRegIsrc src_index, iRegIsrc src_length, label labl) %{ 11122 match(If cmp (CmpU src_index src_length)); 11123 effect(USE labl); 11124 predicate(TrapBasedRangeChecks && 11125 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 11126 _leaf->as_If()->_prob >= PROB_ALWAYS && 11127 (Matcher::branches_to_uncommon_trap(_leaf))); 11128 11129 ins_is_TrapBasedCheckNode(true); 11130 11131 format %{ "TW $src_index $cmp $src_length \t// RangeCheck => trap $labl" %} 11132 size(4); 11133 ins_encode %{ 11134 // TODO: PPC port $archOpcode(ppc64Opcode_tw); 11135 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 11136 __ trap_range_check_ge($src_index$$Register, $src_length$$Register); 11137 } else { 11138 // Both successors are uncommon traps, probability is 0. 11139 // Node got flipped during fixup flow. 11140 assert($cmp$$cmpcode == 0x8, "must be less"); 11141 __ trap_range_check_l($src_index$$Register, $src_length$$Register); 11142 } 11143 %} 11144 ins_pipe(pipe_class_trap); 11145 %} 11146 11147 // Match range check 'If lt (CmpU index length)'. 11148 instruct rangeCheck_uimm15_iReg(cmpOp cmp, iRegIsrc src_index, uimmI15 length, label labl) %{ 11149 match(If cmp (CmpU src_index length)); 11150 effect(USE labl); 11151 predicate(TrapBasedRangeChecks && 11152 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 11153 _leaf->as_If()->_prob >= PROB_ALWAYS && 11154 (Matcher::branches_to_uncommon_trap(_leaf))); 11155 11156 ins_is_TrapBasedCheckNode(true); 11157 11158 format %{ "TWI $src_index $cmp $length \t// RangeCheck => trap $labl" %} 11159 size(4); 11160 ins_encode %{ 11161 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 11162 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 11163 __ trap_range_check_ge($src_index$$Register, $length$$constant); 11164 } else { 11165 // Both successors are uncommon traps, probability is 0. 11166 // Node got flipped during fixup flow. 11167 assert($cmp$$cmpcode == 0x8, "must be less"); 11168 __ trap_range_check_l($src_index$$Register, $length$$constant); 11169 } 11170 %} 11171 ins_pipe(pipe_class_trap); 11172 %} 11173 11174 instruct compU_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 11175 match(Set crx (CmpU src1 src2)); 11176 format %{ "CMPLW $crx, $src1, $src2 \t// unsigned" %} 11177 size(4); 11178 ins_encode %{ 11179 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11180 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11181 %} 11182 ins_pipe(pipe_class_compare); 11183 %} 11184 11185 instruct compU_reg_uimm16(flagsReg crx, iRegIsrc src1, uimmI16 src2) %{ 11186 match(Set crx (CmpU src1 src2)); 11187 size(4); 11188 format %{ "CMPLWI $crx, $src1, $src2" %} 11189 ins_encode %{ 11190 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 11191 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11192 %} 11193 ins_pipe(pipe_class_compare); 11194 %} 11195 11196 // Implicit zero checks (more implicit null checks). 11197 // No constant pool entries required. 11198 instruct zeroCheckN_iReg_imm0(cmpOp cmp, iRegNsrc value, immN_0 zero, label labl) %{ 11199 match(If cmp (CmpN value zero)); 11200 effect(USE labl); 11201 predicate(TrapBasedNullChecks && 11202 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 11203 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 11204 Matcher::branches_to_uncommon_trap(_leaf)); 11205 ins_cost(1); 11206 11207 ins_is_TrapBasedCheckNode(true); 11208 11209 format %{ "TDI $value $cmp $zero \t// ZeroCheckN => trap $labl" %} 11210 size(4); 11211 ins_encode %{ 11212 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 11213 if ($cmp$$cmpcode == 0xA) { 11214 __ trap_null_check($value$$Register); 11215 } else { 11216 // Both successors are uncommon traps, probability is 0. 11217 // Node got flipped during fixup flow. 11218 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 11219 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 11220 } 11221 %} 11222 ins_pipe(pipe_class_trap); 11223 %} 11224 11225 // Compare narrow oops. 11226 instruct cmpN_reg_reg(flagsReg crx, iRegNsrc src1, iRegNsrc src2) %{ 11227 match(Set crx (CmpN src1 src2)); 11228 11229 size(4); 11230 ins_cost(2); 11231 format %{ "CMPLW $crx, $src1, $src2 \t// compressed ptr" %} 11232 ins_encode %{ 11233 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11234 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11235 %} 11236 ins_pipe(pipe_class_compare); 11237 %} 11238 11239 instruct cmpN_reg_imm0(flagsReg crx, iRegNsrc src1, immN_0 src2) %{ 11240 match(Set crx (CmpN src1 src2)); 11241 // Make this more expensive than zeroCheckN_iReg_imm0. 11242 ins_cost(2); 11243 11244 format %{ "CMPLWI $crx, $src1, $src2 \t// compressed ptr" %} 11245 size(4); 11246 ins_encode %{ 11247 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 11248 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11249 %} 11250 ins_pipe(pipe_class_compare); 11251 %} 11252 11253 // Implicit zero checks (more implicit null checks). 11254 // No constant pool entries required. 11255 instruct zeroCheckP_reg_imm0(cmpOp cmp, iRegP_N2P value, immP_0 zero, label labl) %{ 11256 match(If cmp (CmpP value zero)); 11257 effect(USE labl); 11258 predicate(TrapBasedNullChecks && 11259 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 11260 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 11261 Matcher::branches_to_uncommon_trap(_leaf)); 11262 ins_cost(1); // Should not be cheaper than zeroCheckN. 11263 11264 ins_is_TrapBasedCheckNode(true); 11265 11266 format %{ "TDI $value $cmp $zero \t// ZeroCheckP => trap $labl" %} 11267 size(4); 11268 ins_encode %{ 11269 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 11270 if ($cmp$$cmpcode == 0xA) { 11271 __ trap_null_check($value$$Register); 11272 } else { 11273 // Both successors are uncommon traps, probability is 0. 11274 // Node got flipped during fixup flow. 11275 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 11276 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 11277 } 11278 %} 11279 ins_pipe(pipe_class_trap); 11280 %} 11281 11282 // Compare Pointers 11283 instruct cmpP_reg_reg(flagsReg crx, iRegP_N2P src1, iRegP_N2P src2) %{ 11284 match(Set crx (CmpP src1 src2)); 11285 format %{ "CMPLD $crx, $src1, $src2 \t// ptr" %} 11286 size(4); 11287 ins_encode %{ 11288 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11289 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 11290 %} 11291 ins_pipe(pipe_class_compare); 11292 %} 11293 11294 instruct cmpP_reg_null(flagsReg crx, iRegP_N2P src1, immP_0or1 src2) %{ 11295 match(Set crx (CmpP src1 src2)); 11296 format %{ "CMPLDI $crx, $src1, $src2 \t// ptr" %} 11297 size(4); 11298 ins_encode %{ 11299 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11300 __ cmpldi($crx$$CondRegister, $src1$$Register, (int)((short)($src2$$constant & 0xFFFF))); 11301 %} 11302 ins_pipe(pipe_class_compare); 11303 %} 11304 11305 // Used in postalloc expand. 11306 instruct cmpP_reg_imm16(flagsReg crx, iRegPsrc src1, immL16 src2) %{ 11307 // This match rule prevents reordering of node before a safepoint. 11308 // This only makes sense if this instructions is used exclusively 11309 // for the expansion of EncodeP! 11310 match(Set crx (CmpP src1 src2)); 11311 predicate(false); 11312 11313 format %{ "CMPDI $crx, $src1, $src2" %} 11314 size(4); 11315 ins_encode %{ 11316 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11317 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11318 %} 11319 ins_pipe(pipe_class_compare); 11320 %} 11321 11322 //----------Float Compares---------------------------------------------------- 11323 11324 instruct cmpFUnordered_reg_reg(flagsReg crx, regF src1, regF src2) %{ 11325 // Needs matchrule, see cmpDUnordered. 11326 match(Set crx (CmpF src1 src2)); 11327 // no match-rule, false predicate 11328 predicate(false); 11329 11330 format %{ "cmpFUrd $crx, $src1, $src2" %} 11331 size(4); 11332 ins_encode %{ 11333 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 11334 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 11335 %} 11336 ins_pipe(pipe_class_default); 11337 %} 11338 11339 instruct cmov_bns_less(flagsReg crx) %{ 11340 // no match-rule, false predicate 11341 effect(DEF crx); 11342 predicate(false); 11343 11344 ins_variable_size_depending_on_alignment(true); 11345 11346 format %{ "cmov $crx" %} 11347 // Worst case is branch + move + stop, no stop without scheduler. 11348 size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 16 : 12); 11349 ins_encode %{ 11350 // TODO: PPC port $archOpcode(ppc64Opcode_cmovecr); 11351 Label done; 11352 __ bns($crx$$CondRegister, done); // not unordered -> keep crx 11353 __ cmpwi($crx$$CondRegister, R30_zero, 1); // unordered -> set crx to 'less' 11354 // TODO PPC port __ endgroup_if_needed(_size == 16); 11355 __ bind(done); 11356 %} 11357 ins_pipe(pipe_class_default); 11358 %} 11359 11360 // Compare floating, generate condition code. 11361 instruct cmpF_reg_reg_Ex(flagsReg crx, regF src1, regF src2) %{ 11362 // FIXME: should we match 'If cmp (CmpF src1 src2))' ?? 11363 // 11364 // The following code sequence occurs a lot in mpegaudio: 11365 // 11366 // block BXX: 11367 // 0: instruct cmpFUnordered_reg_reg (cmpF_reg_reg-0): 11368 // cmpFUrd CCR6, F11, F9 11369 // 4: instruct cmov_bns_less (cmpF_reg_reg-1): 11370 // cmov CCR6 11371 // 8: instruct branchConSched: 11372 // B_FARle CCR6, B56 P=0.500000 C=-1.000000 11373 match(Set crx (CmpF src1 src2)); 11374 ins_cost(DEFAULT_COST+BRANCH_COST); 11375 11376 format %{ "CmpF $crx, $src1, $src2 \t// postalloc expanded" %} 11377 postalloc_expand %{ 11378 // 11379 // replaces 11380 // 11381 // region src1 src2 11382 // \ | | 11383 // crx=cmpF_reg_reg 11384 // 11385 // with 11386 // 11387 // region src1 src2 11388 // \ | | 11389 // crx=cmpFUnordered_reg_reg 11390 // | 11391 // ^ region 11392 // | \ 11393 // crx=cmov_bns_less 11394 // 11395 11396 // Create new nodes. 11397 MachNode *m1 = new cmpFUnordered_reg_regNode(); 11398 MachNode *m2 = new cmov_bns_lessNode(); 11399 11400 // inputs for new nodes 11401 m1->add_req(n_region, n_src1, n_src2); 11402 m2->add_req(n_region); 11403 m2->add_prec(m1); 11404 11405 // operands for new nodes 11406 m1->_opnds[0] = op_crx; 11407 m1->_opnds[1] = op_src1; 11408 m1->_opnds[2] = op_src2; 11409 m2->_opnds[0] = op_crx; 11410 11411 // registers for new nodes 11412 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 11413 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 11414 11415 // Insert new nodes. 11416 nodes->push(m1); 11417 nodes->push(m2); 11418 %} 11419 %} 11420 11421 // Compare float, generate -1,0,1 11422 instruct cmpF3_reg_reg_ExEx(iRegIdst dst, regF src1, regF src2) %{ 11423 match(Set dst (CmpF3 src1 src2)); 11424 ins_cost(DEFAULT_COST*5+BRANCH_COST); 11425 11426 expand %{ 11427 flagsReg tmp1; 11428 cmpFUnordered_reg_reg(tmp1, src1, src2); 11429 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 11430 %} 11431 %} 11432 11433 instruct cmpDUnordered_reg_reg(flagsReg crx, regD src1, regD src2) %{ 11434 // Needs matchrule so that ideal opcode is Cmp. This causes that gcm places the 11435 // node right before the conditional move using it. 11436 // In jck test api/java_awt/geom/QuadCurve2DFloat/index.html#SetCurveTesttestCase7, 11437 // compilation of java.awt.geom.RectangularShape::getBounds()Ljava/awt/Rectangle 11438 // crashed in register allocation where the flags Reg between cmpDUnoredered and a 11439 // conditional move was supposed to be spilled. 11440 match(Set crx (CmpD src1 src2)); 11441 // False predicate, shall not be matched. 11442 predicate(false); 11443 11444 format %{ "cmpFUrd $crx, $src1, $src2" %} 11445 size(4); 11446 ins_encode %{ 11447 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 11448 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 11449 %} 11450 ins_pipe(pipe_class_default); 11451 %} 11452 11453 instruct cmpD_reg_reg_Ex(flagsReg crx, regD src1, regD src2) %{ 11454 match(Set crx (CmpD src1 src2)); 11455 ins_cost(DEFAULT_COST+BRANCH_COST); 11456 11457 format %{ "CmpD $crx, $src1, $src2 \t// postalloc expanded" %} 11458 postalloc_expand %{ 11459 // 11460 // replaces 11461 // 11462 // region src1 src2 11463 // \ | | 11464 // crx=cmpD_reg_reg 11465 // 11466 // with 11467 // 11468 // region src1 src2 11469 // \ | | 11470 // crx=cmpDUnordered_reg_reg 11471 // | 11472 // ^ region 11473 // | \ 11474 // crx=cmov_bns_less 11475 // 11476 11477 // create new nodes 11478 MachNode *m1 = new cmpDUnordered_reg_regNode(); 11479 MachNode *m2 = new cmov_bns_lessNode(); 11480 11481 // inputs for new nodes 11482 m1->add_req(n_region, n_src1, n_src2); 11483 m2->add_req(n_region); 11484 m2->add_prec(m1); 11485 11486 // operands for new nodes 11487 m1->_opnds[0] = op_crx; 11488 m1->_opnds[1] = op_src1; 11489 m1->_opnds[2] = op_src2; 11490 m2->_opnds[0] = op_crx; 11491 11492 // registers for new nodes 11493 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 11494 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 11495 11496 // Insert new nodes. 11497 nodes->push(m1); 11498 nodes->push(m2); 11499 %} 11500 %} 11501 11502 // Compare double, generate -1,0,1 11503 instruct cmpD3_reg_reg_ExEx(iRegIdst dst, regD src1, regD src2) %{ 11504 match(Set dst (CmpD3 src1 src2)); 11505 ins_cost(DEFAULT_COST*5+BRANCH_COST); 11506 11507 expand %{ 11508 flagsReg tmp1; 11509 cmpDUnordered_reg_reg(tmp1, src1, src2); 11510 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 11511 %} 11512 %} 11513 11514 //----------Branches--------------------------------------------------------- 11515 // Jump 11516 11517 // Direct Branch. 11518 instruct branch(label labl) %{ 11519 match(Goto); 11520 effect(USE labl); 11521 ins_cost(BRANCH_COST); 11522 11523 format %{ "B $labl" %} 11524 size(4); 11525 ins_encode %{ 11526 // TODO: PPC port $archOpcode(ppc64Opcode_b); 11527 Label d; // dummy 11528 __ bind(d); 11529 Label* p = $labl$$label; 11530 // `p' is `NULL' when this encoding class is used only to 11531 // determine the size of the encoded instruction. 11532 Label& l = (NULL == p)? d : *(p); 11533 __ b(l); 11534 %} 11535 ins_pipe(pipe_class_default); 11536 %} 11537 11538 // Conditional Near Branch 11539 instruct branchCon(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 11540 // Same match rule as `branchConFar'. 11541 match(If cmp crx); 11542 effect(USE lbl); 11543 ins_cost(BRANCH_COST); 11544 11545 // If set to 1 this indicates that the current instruction is a 11546 // short variant of a long branch. This avoids using this 11547 // instruction in first-pass matching. It will then only be used in 11548 // the `Shorten_branches' pass. 11549 ins_short_branch(1); 11550 11551 format %{ "B$cmp $crx, $lbl" %} 11552 size(4); 11553 ins_encode( enc_bc(crx, cmp, lbl) ); 11554 ins_pipe(pipe_class_default); 11555 %} 11556 11557 // This is for cases when the ppc64 `bc' instruction does not 11558 // reach far enough. So we emit a far branch here, which is more 11559 // expensive. 11560 // 11561 // Conditional Far Branch 11562 instruct branchConFar(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 11563 // Same match rule as `branchCon'. 11564 match(If cmp crx); 11565 effect(USE crx, USE lbl); 11566 predicate(!false /* TODO: PPC port HB_Schedule*/); 11567 // Higher cost than `branchCon'. 11568 ins_cost(5*BRANCH_COST); 11569 11570 // This is not a short variant of a branch, but the long variant. 11571 ins_short_branch(0); 11572 11573 format %{ "B_FAR$cmp $crx, $lbl" %} 11574 size(8); 11575 ins_encode( enc_bc_far(crx, cmp, lbl) ); 11576 ins_pipe(pipe_class_default); 11577 %} 11578 11579 // Conditional Branch used with Power6 scheduler (can be far or short). 11580 instruct branchConSched(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 11581 // Same match rule as `branchCon'. 11582 match(If cmp crx); 11583 effect(USE crx, USE lbl); 11584 predicate(false /* TODO: PPC port HB_Schedule*/); 11585 // Higher cost than `branchCon'. 11586 ins_cost(5*BRANCH_COST); 11587 11588 // Actually size doesn't depend on alignment but on shortening. 11589 ins_variable_size_depending_on_alignment(true); 11590 // long variant. 11591 ins_short_branch(0); 11592 11593 format %{ "B_FAR$cmp $crx, $lbl" %} 11594 size(8); // worst case 11595 ins_encode( enc_bc_short_far(crx, cmp, lbl) ); 11596 ins_pipe(pipe_class_default); 11597 %} 11598 11599 instruct branchLoopEnd(cmpOp cmp, flagsRegSrc crx, label labl) %{ 11600 match(CountedLoopEnd cmp crx); 11601 effect(USE labl); 11602 ins_cost(BRANCH_COST); 11603 11604 // short variant. 11605 ins_short_branch(1); 11606 11607 format %{ "B$cmp $crx, $labl \t// counted loop end" %} 11608 size(4); 11609 ins_encode( enc_bc(crx, cmp, labl) ); 11610 ins_pipe(pipe_class_default); 11611 %} 11612 11613 instruct branchLoopEndFar(cmpOp cmp, flagsRegSrc crx, label labl) %{ 11614 match(CountedLoopEnd cmp crx); 11615 effect(USE labl); 11616 predicate(!false /* TODO: PPC port HB_Schedule */); 11617 ins_cost(BRANCH_COST); 11618 11619 // Long variant. 11620 ins_short_branch(0); 11621 11622 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 11623 size(8); 11624 ins_encode( enc_bc_far(crx, cmp, labl) ); 11625 ins_pipe(pipe_class_default); 11626 %} 11627 11628 // Conditional Branch used with Power6 scheduler (can be far or short). 11629 instruct branchLoopEndSched(cmpOp cmp, flagsRegSrc crx, label labl) %{ 11630 match(CountedLoopEnd cmp crx); 11631 effect(USE labl); 11632 predicate(false /* TODO: PPC port HB_Schedule */); 11633 // Higher cost than `branchCon'. 11634 ins_cost(5*BRANCH_COST); 11635 11636 // Actually size doesn't depend on alignment but on shortening. 11637 ins_variable_size_depending_on_alignment(true); 11638 // Long variant. 11639 ins_short_branch(0); 11640 11641 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 11642 size(8); // worst case 11643 ins_encode( enc_bc_short_far(crx, cmp, labl) ); 11644 ins_pipe(pipe_class_default); 11645 %} 11646 11647 // ============================================================================ 11648 // Java runtime operations, intrinsics and other complex operations. 11649 11650 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass 11651 // array for an instance of the superklass. Set a hidden internal cache on a 11652 // hit (cache is checked with exposed code in gen_subtype_check()). Return 11653 // not zero for a miss or zero for a hit. The encoding ALSO sets flags. 11654 // 11655 // GL TODO: Improve this. 11656 // - result should not be a TEMP 11657 // - Add match rule as on sparc avoiding additional Cmp. 11658 instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass, 11659 iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{ 11660 match(Set result (PartialSubtypeCheck subklass superklass)); 11661 effect(TEMP_DEF result, TEMP tmp_klass, TEMP tmp_arrayptr); 11662 ins_cost(DEFAULT_COST*10); 11663 11664 format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %} 11665 ins_encode %{ 11666 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11667 __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register, 11668 $tmp_klass$$Register, NULL, $result$$Register); 11669 %} 11670 ins_pipe(pipe_class_default); 11671 %} 11672 11673 // inlined locking and unlocking 11674 11675 instruct cmpFastLock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2) %{ 11676 match(Set crx (FastLock oop box)); 11677 effect(TEMP tmp1, TEMP tmp2); 11678 predicate(!Compile::current()->use_rtm()); 11679 11680 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2" %} 11681 ins_encode %{ 11682 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11683 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 11684 $tmp1$$Register, $tmp2$$Register, /*tmp3*/ R0, 11685 UseBiasedLocking && !UseOptoBiasInlining); 11686 // If locking was successfull, crx should indicate 'EQ'. 11687 // The compiler generates a branch to the runtime call to 11688 // _complete_monitor_locking_Java for the case where crx is 'NE'. 11689 %} 11690 ins_pipe(pipe_class_compare); 11691 %} 11692 11693 // Separate version for TM. Use bound register for box to enable USE_KILL. 11694 instruct cmpFastLock_tm(flagsReg crx, iRegPdst oop, rarg2RegP box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 11695 match(Set crx (FastLock oop box)); 11696 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL box); 11697 predicate(Compile::current()->use_rtm()); 11698 11699 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2, $tmp3 (TM)" %} 11700 ins_encode %{ 11701 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11702 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 11703 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 11704 /*Biased Locking*/ false, 11705 _rtm_counters, _stack_rtm_counters, 11706 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 11707 /*TM*/ true, ra_->C->profile_rtm()); 11708 // If locking was successfull, crx should indicate 'EQ'. 11709 // The compiler generates a branch to the runtime call to 11710 // _complete_monitor_locking_Java for the case where crx is 'NE'. 11711 %} 11712 ins_pipe(pipe_class_compare); 11713 %} 11714 11715 instruct cmpFastUnlock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 11716 match(Set crx (FastUnlock oop box)); 11717 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 11718 predicate(!Compile::current()->use_rtm()); 11719 11720 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2" %} 11721 ins_encode %{ 11722 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11723 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 11724 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 11725 UseBiasedLocking && !UseOptoBiasInlining, 11726 false); 11727 // If unlocking was successfull, crx should indicate 'EQ'. 11728 // The compiler generates a branch to the runtime call to 11729 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 11730 %} 11731 ins_pipe(pipe_class_compare); 11732 %} 11733 11734 instruct cmpFastUnlock_tm(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 11735 match(Set crx (FastUnlock oop box)); 11736 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 11737 predicate(Compile::current()->use_rtm()); 11738 11739 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2 (TM)" %} 11740 ins_encode %{ 11741 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11742 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 11743 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 11744 /*Biased Locking*/ false, /*TM*/ true); 11745 // If unlocking was successfull, crx should indicate 'EQ'. 11746 // The compiler generates a branch to the runtime call to 11747 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 11748 %} 11749 ins_pipe(pipe_class_compare); 11750 %} 11751 11752 // Align address. 11753 instruct align_addr(iRegPdst dst, iRegPsrc src, immLnegpow2 mask) %{ 11754 match(Set dst (CastX2P (AndL (CastP2X src) mask))); 11755 11756 format %{ "ANDDI $dst, $src, $mask \t// next aligned address" %} 11757 size(4); 11758 ins_encode %{ 11759 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 11760 __ clrrdi($dst$$Register, $src$$Register, log2_long((jlong)-$mask$$constant)); 11761 %} 11762 ins_pipe(pipe_class_default); 11763 %} 11764 11765 // Array size computation. 11766 instruct array_size(iRegLdst dst, iRegPsrc end, iRegPsrc start) %{ 11767 match(Set dst (SubL (CastP2X end) (CastP2X start))); 11768 11769 format %{ "SUB $dst, $end, $start \t// array size in bytes" %} 11770 size(4); 11771 ins_encode %{ 11772 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 11773 __ subf($dst$$Register, $start$$Register, $end$$Register); 11774 %} 11775 ins_pipe(pipe_class_default); 11776 %} 11777 11778 // Clear-array with dynamic array-size. 11779 instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 11780 match(Set dummy (ClearArray cnt base)); 11781 effect(USE_KILL cnt, USE_KILL base, KILL ctr); 11782 ins_cost(MEMORY_REF_COST); 11783 11784 ins_alignment(4); // 'compute_padding()' gets called, up to this number-1 nops will get inserted. 11785 11786 format %{ "ClearArray $cnt, $base" %} 11787 ins_encode %{ 11788 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11789 __ clear_memory_doubleword($base$$Register, $cnt$$Register); // kills cnt, base, R0 11790 %} 11791 ins_pipe(pipe_class_default); 11792 %} 11793 11794 instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 11795 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 11796 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 11797 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11798 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 11799 ins_cost(300); 11800 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 11801 ins_encode %{ 11802 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11803 __ string_compare($str1$$Register, $str2$$Register, 11804 $cnt1$$Register, $cnt2$$Register, 11805 $tmp$$Register, 11806 $result$$Register, StrIntrinsicNode::LL); 11807 %} 11808 ins_pipe(pipe_class_default); 11809 %} 11810 11811 instruct string_compareU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 11812 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 11813 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 11814 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11815 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 11816 ins_cost(300); 11817 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 11818 ins_encode %{ 11819 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11820 __ string_compare($str1$$Register, $str2$$Register, 11821 $cnt1$$Register, $cnt2$$Register, 11822 $tmp$$Register, 11823 $result$$Register, StrIntrinsicNode::UU); 11824 %} 11825 ins_pipe(pipe_class_default); 11826 %} 11827 11828 instruct string_compareLU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 11829 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 11830 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 11831 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11832 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 11833 ins_cost(300); 11834 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 11835 ins_encode %{ 11836 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11837 __ string_compare($str1$$Register, $str2$$Register, 11838 $cnt1$$Register, $cnt2$$Register, 11839 $tmp$$Register, 11840 $result$$Register, StrIntrinsicNode::LU); 11841 %} 11842 ins_pipe(pipe_class_default); 11843 %} 11844 11845 instruct string_compareUL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 11846 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 11847 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 11848 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11849 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 11850 ins_cost(300); 11851 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 11852 ins_encode %{ 11853 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11854 __ string_compare($str2$$Register, $str1$$Register, 11855 $cnt2$$Register, $cnt1$$Register, 11856 $tmp$$Register, 11857 $result$$Register, StrIntrinsicNode::UL); 11858 %} 11859 ins_pipe(pipe_class_default); 11860 %} 11861 11862 instruct string_equalsL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 11863 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 11864 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 11865 match(Set result (StrEquals (Binary str1 str2) cnt)); 11866 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 11867 ins_cost(300); 11868 format %{ "String Equals byte[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 11869 ins_encode %{ 11870 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11871 __ array_equals(false, $str1$$Register, $str2$$Register, 11872 $cnt$$Register, $tmp$$Register, 11873 $result$$Register, true /* byte */); 11874 %} 11875 ins_pipe(pipe_class_default); 11876 %} 11877 11878 instruct string_equalsU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 11879 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 11880 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 11881 match(Set result (StrEquals (Binary str1 str2) cnt)); 11882 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 11883 ins_cost(300); 11884 format %{ "String Equals char[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 11885 ins_encode %{ 11886 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11887 __ array_equals(false, $str1$$Register, $str2$$Register, 11888 $cnt$$Register, $tmp$$Register, 11889 $result$$Register, false /* byte */); 11890 %} 11891 ins_pipe(pipe_class_default); 11892 %} 11893 11894 instruct array_equalsB(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 11895 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 11896 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11897 match(Set result (AryEq ary1 ary2)); 11898 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 11899 ins_cost(300); 11900 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 11901 ins_encode %{ 11902 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11903 __ array_equals(true, $ary1$$Register, $ary2$$Register, 11904 $tmp1$$Register, $tmp2$$Register, 11905 $result$$Register, true /* byte */); 11906 %} 11907 ins_pipe(pipe_class_default); 11908 %} 11909 11910 instruct array_equalsC(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 11911 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 11912 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11913 match(Set result (AryEq ary1 ary2)); 11914 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 11915 ins_cost(300); 11916 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 11917 ins_encode %{ 11918 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11919 __ array_equals(true, $ary1$$Register, $ary2$$Register, 11920 $tmp1$$Register, $tmp2$$Register, 11921 $result$$Register, false /* byte */); 11922 %} 11923 ins_pipe(pipe_class_default); 11924 %} 11925 11926 instruct indexOf_imm1_char_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 11927 immP needleImm, immL offsetImm, immI_1 needlecntImm, 11928 iRegIdst tmp1, iRegIdst tmp2, 11929 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 11930 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 11931 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 11932 // Required for EA: check if it is still a type_array. 11933 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 11934 ins_cost(150); 11935 11936 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 11937 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 11938 11939 ins_encode %{ 11940 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11941 immPOper *needleOper = (immPOper *)$needleImm; 11942 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 11943 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 11944 jchar chr; 11945 #ifdef VM_LITTLE_ENDIAN 11946 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 11947 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 11948 #else 11949 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 11950 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 11951 #endif 11952 __ string_indexof_char($result$$Register, 11953 $haystack$$Register, $haycnt$$Register, 11954 R0, chr, 11955 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 11956 %} 11957 ins_pipe(pipe_class_compare); 11958 %} 11959 11960 instruct indexOf_imm1_char_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 11961 immP needleImm, immL offsetImm, immI_1 needlecntImm, 11962 iRegIdst tmp1, iRegIdst tmp2, 11963 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 11964 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 11965 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 11966 // Required for EA: check if it is still a type_array. 11967 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 11968 ins_cost(150); 11969 11970 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 11971 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 11972 11973 ins_encode %{ 11974 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11975 immPOper *needleOper = (immPOper *)$needleImm; 11976 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 11977 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 11978 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 11979 __ string_indexof_char($result$$Register, 11980 $haystack$$Register, $haycnt$$Register, 11981 R0, chr, 11982 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 11983 %} 11984 ins_pipe(pipe_class_compare); 11985 %} 11986 11987 instruct indexOf_imm1_char_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 11988 immP needleImm, immL offsetImm, immI_1 needlecntImm, 11989 iRegIdst tmp1, iRegIdst tmp2, 11990 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 11991 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 11992 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 11993 // Required for EA: check if it is still a type_array. 11994 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 11995 ins_cost(150); 11996 11997 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 11998 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 11999 12000 ins_encode %{ 12001 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12002 immPOper *needleOper = (immPOper *)$needleImm; 12003 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12004 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12005 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12006 __ string_indexof_char($result$$Register, 12007 $haystack$$Register, $haycnt$$Register, 12008 R0, chr, 12009 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12010 %} 12011 ins_pipe(pipe_class_compare); 12012 %} 12013 12014 instruct indexOf_imm1_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12015 rscratch2RegP needle, immI_1 needlecntImm, 12016 iRegIdst tmp1, iRegIdst tmp2, 12017 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12018 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12019 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12020 // Required for EA: check if it is still a type_array. 12021 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 12022 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12023 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12024 ins_cost(180); 12025 12026 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12027 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12028 ins_encode %{ 12029 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12030 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12031 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12032 guarantee(needle_values, "sanity"); 12033 jchar chr; 12034 #ifdef VM_LITTLE_ENDIAN 12035 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 12036 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 12037 #else 12038 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 12039 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 12040 #endif 12041 __ string_indexof_char($result$$Register, 12042 $haystack$$Register, $haycnt$$Register, 12043 R0, chr, 12044 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12045 %} 12046 ins_pipe(pipe_class_compare); 12047 %} 12048 12049 instruct indexOf_imm1_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12050 rscratch2RegP needle, immI_1 needlecntImm, 12051 iRegIdst tmp1, iRegIdst tmp2, 12052 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12053 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12054 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12055 // Required for EA: check if it is still a type_array. 12056 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 12057 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12058 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12059 ins_cost(180); 12060 12061 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12062 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12063 ins_encode %{ 12064 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12065 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12066 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12067 guarantee(needle_values, "sanity"); 12068 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12069 __ string_indexof_char($result$$Register, 12070 $haystack$$Register, $haycnt$$Register, 12071 R0, chr, 12072 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 12073 %} 12074 ins_pipe(pipe_class_compare); 12075 %} 12076 12077 instruct indexOf_imm1_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12078 rscratch2RegP needle, immI_1 needlecntImm, 12079 iRegIdst tmp1, iRegIdst tmp2, 12080 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12081 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12082 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12083 // Required for EA: check if it is still a type_array. 12084 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 12085 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12086 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12087 ins_cost(180); 12088 12089 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12090 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12091 ins_encode %{ 12092 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12093 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12094 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12095 guarantee(needle_values, "sanity"); 12096 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12097 __ string_indexof_char($result$$Register, 12098 $haystack$$Register, $haycnt$$Register, 12099 R0, chr, 12100 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12101 %} 12102 ins_pipe(pipe_class_compare); 12103 %} 12104 12105 instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12106 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2, 12107 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12108 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch)); 12109 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12110 ins_cost(180); 12111 12112 format %{ "String IndexOfChar $haystack[0..$haycnt], $ch" 12113 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12114 ins_encode %{ 12115 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12116 __ string_indexof_char($result$$Register, 12117 $haystack$$Register, $haycnt$$Register, 12118 $ch$$Register, 0 /* this is not used if the character is already in a register */, 12119 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12120 %} 12121 ins_pipe(pipe_class_compare); 12122 %} 12123 12124 instruct indexOf_imm_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 12125 iRegPsrc needle, uimmI15 needlecntImm, 12126 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 12127 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12128 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12129 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 12130 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12131 // Required for EA: check if it is still a type_array. 12132 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 12133 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12134 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12135 ins_cost(250); 12136 12137 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12138 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 12139 ins_encode %{ 12140 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12141 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12142 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12143 12144 __ string_indexof($result$$Register, 12145 $haystack$$Register, $haycnt$$Register, 12146 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 12147 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 12148 %} 12149 ins_pipe(pipe_class_compare); 12150 %} 12151 12152 instruct indexOf_imm_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 12153 iRegPsrc needle, uimmI15 needlecntImm, 12154 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 12155 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12156 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12157 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 12158 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12159 // Required for EA: check if it is still a type_array. 12160 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 12161 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12162 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12163 ins_cost(250); 12164 12165 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12166 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 12167 ins_encode %{ 12168 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12169 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12170 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12171 12172 __ string_indexof($result$$Register, 12173 $haystack$$Register, $haycnt$$Register, 12174 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 12175 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 12176 %} 12177 ins_pipe(pipe_class_compare); 12178 %} 12179 12180 instruct indexOf_imm_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 12181 iRegPsrc needle, uimmI15 needlecntImm, 12182 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 12183 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12184 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12185 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 12186 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12187 // Required for EA: check if it is still a type_array. 12188 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 12189 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12190 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12191 ins_cost(250); 12192 12193 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12194 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 12195 ins_encode %{ 12196 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12197 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12198 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12199 12200 __ string_indexof($result$$Register, 12201 $haystack$$Register, $haycnt$$Register, 12202 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 12203 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 12204 %} 12205 ins_pipe(pipe_class_compare); 12206 %} 12207 12208 instruct indexOf_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 12209 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 12210 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12211 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 12212 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 12213 TEMP_DEF result, 12214 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12215 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 12216 ins_cost(300); 12217 12218 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 12219 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 12220 ins_encode %{ 12221 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12222 __ string_indexof($result$$Register, 12223 $haystack$$Register, $haycnt$$Register, 12224 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 12225 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 12226 %} 12227 ins_pipe(pipe_class_compare); 12228 %} 12229 12230 instruct indexOf_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 12231 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 12232 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12233 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 12234 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 12235 TEMP_DEF result, 12236 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12237 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 12238 ins_cost(300); 12239 12240 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 12241 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 12242 ins_encode %{ 12243 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12244 __ string_indexof($result$$Register, 12245 $haystack$$Register, $haycnt$$Register, 12246 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 12247 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 12248 %} 12249 ins_pipe(pipe_class_compare); 12250 %} 12251 12252 instruct indexOf_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 12253 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 12254 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12255 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 12256 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 12257 TEMP_DEF result, 12258 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12259 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 12260 ins_cost(300); 12261 12262 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 12263 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 12264 ins_encode %{ 12265 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12266 __ string_indexof($result$$Register, 12267 $haystack$$Register, $haycnt$$Register, 12268 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 12269 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 12270 %} 12271 ins_pipe(pipe_class_compare); 12272 %} 12273 12274 // char[] to byte[] compression 12275 instruct string_compress(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 12276 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 12277 match(Set result (StrCompressedCopy src (Binary dst len))); 12278 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 12279 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 12280 ins_cost(300); 12281 format %{ "String Compress $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 12282 ins_encode %{ 12283 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12284 Label Lskip, Ldone; 12285 __ li($result$$Register, 0); 12286 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 12287 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Ldone); 12288 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 12289 __ beq(CCR0, Lskip); 12290 __ string_compress($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register, Ldone); 12291 __ bind(Lskip); 12292 __ mr($result$$Register, $len$$Register); 12293 __ bind(Ldone); 12294 %} 12295 ins_pipe(pipe_class_default); 12296 %} 12297 12298 // byte[] to char[] inflation 12299 instruct string_inflate(Universe dummy, rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegLdst tmp1, 12300 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 12301 match(Set dummy (StrInflatedCopy src (Binary dst len))); 12302 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 12303 ins_cost(300); 12304 format %{ "String Inflate $src,$dst,$len \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 12305 ins_encode %{ 12306 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12307 Label Ldone; 12308 __ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 12309 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register); 12310 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 12311 __ beq(CCR0, Ldone); 12312 __ string_inflate($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register); 12313 __ bind(Ldone); 12314 %} 12315 ins_pipe(pipe_class_default); 12316 %} 12317 12318 // StringCoding.java intrinsics 12319 instruct has_negatives(rarg1RegP ary1, iRegIsrc len, iRegIdst result, iRegLdst tmp1, iRegLdst tmp2, 12320 regCTR ctr, flagsRegCR0 cr0) 12321 %{ 12322 match(Set result (HasNegatives ary1 len)); 12323 effect(TEMP_DEF result, USE_KILL ary1, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0); 12324 ins_cost(300); 12325 format %{ "has negatives byte[] $ary1,$len -> $result \t// KILL $tmp1, $tmp2" %} 12326 ins_encode %{ 12327 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12328 __ has_negatives($ary1$$Register, $len$$Register, $result$$Register, 12329 $tmp1$$Register, $tmp2$$Register); 12330 %} 12331 ins_pipe(pipe_class_default); 12332 %} 12333 12334 // encode char[] to byte[] in ISO_8859_1 12335 instruct encode_iso_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 12336 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 12337 match(Set result (EncodeISOArray src (Binary dst len))); 12338 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 12339 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 12340 ins_cost(300); 12341 format %{ "Encode array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 12342 ins_encode %{ 12343 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12344 Label Lslow, Lfailure1, Lfailure2, Ldone; 12345 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 12346 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Lfailure1); 12347 __ rldicl_($result$$Register, $len$$Register, 0, 64-3); // Remaining characters. 12348 __ beq(CCR0, Ldone); 12349 __ bind(Lslow); 12350 __ string_compress($src$$Register, $dst$$Register, $result$$Register, $tmp2$$Register, Lfailure2); 12351 __ li($result$$Register, 0); 12352 __ b(Ldone); 12353 12354 __ bind(Lfailure1); 12355 __ mr($result$$Register, $len$$Register); 12356 __ mfctr($tmp1$$Register); 12357 __ rldimi_($result$$Register, $tmp1$$Register, 3, 0); // Remaining characters. 12358 __ beq(CCR0, Ldone); 12359 __ b(Lslow); 12360 12361 __ bind(Lfailure2); 12362 __ mfctr($result$$Register); // Remaining characters. 12363 12364 __ bind(Ldone); 12365 __ subf($result$$Register, $result$$Register, $len$$Register); 12366 %} 12367 ins_pipe(pipe_class_default); 12368 %} 12369 12370 12371 //---------- Min/Max Instructions --------------------------------------------- 12372 12373 instruct minI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 12374 match(Set dst (MinI src1 src2)); 12375 ins_cost(DEFAULT_COST*6); 12376 12377 expand %{ 12378 iRegLdst src1s; 12379 iRegLdst src2s; 12380 iRegLdst diff; 12381 iRegLdst sm; 12382 iRegLdst doz; // difference or zero 12383 convI2L_reg(src1s, src1); // Ensure proper sign extension. 12384 convI2L_reg(src2s, src2); // Ensure proper sign extension. 12385 subL_reg_reg(diff, src2s, src1s); 12386 // Need to consider >=33 bit result, therefore we need signmaskL. 12387 signmask64L_regL(sm, diff); 12388 andL_reg_reg(doz, diff, sm); // <=0 12389 addI_regL_regL(dst, doz, src1s); 12390 %} 12391 %} 12392 12393 instruct minI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 12394 match(Set dst (MinI src1 src2)); 12395 effect(KILL cr0); 12396 predicate(VM_Version::has_isel()); 12397 ins_cost(DEFAULT_COST*2); 12398 12399 ins_encode %{ 12400 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12401 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 12402 __ isel($dst$$Register, CCR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register); 12403 %} 12404 ins_pipe(pipe_class_default); 12405 %} 12406 12407 instruct maxI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 12408 match(Set dst (MaxI src1 src2)); 12409 ins_cost(DEFAULT_COST*6); 12410 12411 expand %{ 12412 iRegLdst src1s; 12413 iRegLdst src2s; 12414 iRegLdst diff; 12415 iRegLdst sm; 12416 iRegLdst doz; // difference or zero 12417 convI2L_reg(src1s, src1); // Ensure proper sign extension. 12418 convI2L_reg(src2s, src2); // Ensure proper sign extension. 12419 subL_reg_reg(diff, src2s, src1s); 12420 // Need to consider >=33 bit result, therefore we need signmaskL. 12421 signmask64L_regL(sm, diff); 12422 andcL_reg_reg(doz, diff, sm); // >=0 12423 addI_regL_regL(dst, doz, src1s); 12424 %} 12425 %} 12426 12427 instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 12428 match(Set dst (MaxI src1 src2)); 12429 effect(KILL cr0); 12430 predicate(VM_Version::has_isel()); 12431 ins_cost(DEFAULT_COST*2); 12432 12433 ins_encode %{ 12434 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12435 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 12436 __ isel($dst$$Register, CCR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register); 12437 %} 12438 ins_pipe(pipe_class_default); 12439 %} 12440 12441 //---------- Population Count Instructions ------------------------------------ 12442 12443 // Popcnt for Power7. 12444 instruct popCountI(iRegIdst dst, iRegIsrc src) %{ 12445 match(Set dst (PopCountI src)); 12446 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 12447 ins_cost(DEFAULT_COST); 12448 12449 format %{ "POPCNTW $dst, $src" %} 12450 size(4); 12451 ins_encode %{ 12452 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 12453 __ popcntw($dst$$Register, $src$$Register); 12454 %} 12455 ins_pipe(pipe_class_default); 12456 %} 12457 12458 // Popcnt for Power7. 12459 instruct popCountL(iRegIdst dst, iRegLsrc src) %{ 12460 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 12461 match(Set dst (PopCountL src)); 12462 ins_cost(DEFAULT_COST); 12463 12464 format %{ "POPCNTD $dst, $src" %} 12465 size(4); 12466 ins_encode %{ 12467 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 12468 __ popcntd($dst$$Register, $src$$Register); 12469 %} 12470 ins_pipe(pipe_class_default); 12471 %} 12472 12473 instruct countLeadingZerosI(iRegIdst dst, iRegIsrc src) %{ 12474 match(Set dst (CountLeadingZerosI src)); 12475 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 12476 ins_cost(DEFAULT_COST); 12477 12478 format %{ "CNTLZW $dst, $src" %} 12479 size(4); 12480 ins_encode %{ 12481 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzw); 12482 __ cntlzw($dst$$Register, $src$$Register); 12483 %} 12484 ins_pipe(pipe_class_default); 12485 %} 12486 12487 instruct countLeadingZerosL(iRegIdst dst, iRegLsrc src) %{ 12488 match(Set dst (CountLeadingZerosL src)); 12489 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 12490 ins_cost(DEFAULT_COST); 12491 12492 format %{ "CNTLZD $dst, $src" %} 12493 size(4); 12494 ins_encode %{ 12495 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 12496 __ cntlzd($dst$$Register, $src$$Register); 12497 %} 12498 ins_pipe(pipe_class_default); 12499 %} 12500 12501 instruct countLeadingZerosP(iRegIdst dst, iRegPsrc src) %{ 12502 // no match-rule, false predicate 12503 effect(DEF dst, USE src); 12504 predicate(false); 12505 12506 format %{ "CNTLZD $dst, $src" %} 12507 size(4); 12508 ins_encode %{ 12509 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 12510 __ cntlzd($dst$$Register, $src$$Register); 12511 %} 12512 ins_pipe(pipe_class_default); 12513 %} 12514 12515 instruct countTrailingZerosI_Ex(iRegIdst dst, iRegIsrc src) %{ 12516 match(Set dst (CountTrailingZerosI src)); 12517 predicate(UseCountLeadingZerosInstructionsPPC64); 12518 ins_cost(DEFAULT_COST); 12519 12520 expand %{ 12521 immI16 imm1 %{ (int)-1 %} 12522 immI16 imm2 %{ (int)32 %} 12523 immI_minus1 m1 %{ -1 %} 12524 iRegIdst tmpI1; 12525 iRegIdst tmpI2; 12526 iRegIdst tmpI3; 12527 addI_reg_imm16(tmpI1, src, imm1); 12528 andcI_reg_reg(tmpI2, src, m1, tmpI1); 12529 countLeadingZerosI(tmpI3, tmpI2); 12530 subI_imm16_reg(dst, imm2, tmpI3); 12531 %} 12532 %} 12533 12534 instruct countTrailingZerosL_Ex(iRegIdst dst, iRegLsrc src) %{ 12535 match(Set dst (CountTrailingZerosL src)); 12536 predicate(UseCountLeadingZerosInstructionsPPC64); 12537 ins_cost(DEFAULT_COST); 12538 12539 expand %{ 12540 immL16 imm1 %{ (long)-1 %} 12541 immI16 imm2 %{ (int)64 %} 12542 iRegLdst tmpL1; 12543 iRegLdst tmpL2; 12544 iRegIdst tmpL3; 12545 addL_reg_imm16(tmpL1, src, imm1); 12546 andcL_reg_reg(tmpL2, tmpL1, src); 12547 countLeadingZerosL(tmpL3, tmpL2); 12548 subI_imm16_reg(dst, imm2, tmpL3); 12549 %} 12550 %} 12551 12552 // Expand nodes for byte_reverse_int. 12553 instruct insrwi_a(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 12554 effect(DEF dst, USE src, USE pos, USE shift); 12555 predicate(false); 12556 12557 format %{ "INSRWI $dst, $src, $pos, $shift" %} 12558 size(4); 12559 ins_encode %{ 12560 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 12561 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 12562 %} 12563 ins_pipe(pipe_class_default); 12564 %} 12565 12566 // As insrwi_a, but with USE_DEF. 12567 instruct insrwi(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 12568 effect(USE_DEF dst, USE src, USE pos, USE shift); 12569 predicate(false); 12570 12571 format %{ "INSRWI $dst, $src, $pos, $shift" %} 12572 size(4); 12573 ins_encode %{ 12574 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 12575 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 12576 %} 12577 ins_pipe(pipe_class_default); 12578 %} 12579 12580 // Just slightly faster than java implementation. 12581 instruct bytes_reverse_int_Ex(iRegIdst dst, iRegIsrc src) %{ 12582 match(Set dst (ReverseBytesI src)); 12583 predicate(UseCountLeadingZerosInstructionsPPC64); 12584 ins_cost(DEFAULT_COST); 12585 12586 expand %{ 12587 immI16 imm24 %{ (int) 24 %} 12588 immI16 imm16 %{ (int) 16 %} 12589 immI16 imm8 %{ (int) 8 %} 12590 immI16 imm4 %{ (int) 4 %} 12591 immI16 imm0 %{ (int) 0 %} 12592 iRegLdst tmpI1; 12593 iRegLdst tmpI2; 12594 iRegLdst tmpI3; 12595 12596 urShiftI_reg_imm(tmpI1, src, imm24); 12597 insrwi_a(dst, tmpI1, imm24, imm8); 12598 urShiftI_reg_imm(tmpI2, src, imm16); 12599 insrwi(dst, tmpI2, imm8, imm16); 12600 urShiftI_reg_imm(tmpI3, src, imm8); 12601 insrwi(dst, tmpI3, imm8, imm8); 12602 insrwi(dst, src, imm0, imm8); 12603 %} 12604 %} 12605 12606 //---------- Replicate Vector Instructions ------------------------------------ 12607 12608 // Insrdi does replicate if src == dst. 12609 instruct repl32(iRegLdst dst) %{ 12610 predicate(false); 12611 effect(USE_DEF dst); 12612 12613 format %{ "INSRDI $dst, #0, $dst, #32 \t// replicate" %} 12614 size(4); 12615 ins_encode %{ 12616 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 12617 __ insrdi($dst$$Register, $dst$$Register, 32, 0); 12618 %} 12619 ins_pipe(pipe_class_default); 12620 %} 12621 12622 // Insrdi does replicate if src == dst. 12623 instruct repl48(iRegLdst dst) %{ 12624 predicate(false); 12625 effect(USE_DEF dst); 12626 12627 format %{ "INSRDI $dst, #0, $dst, #48 \t// replicate" %} 12628 size(4); 12629 ins_encode %{ 12630 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 12631 __ insrdi($dst$$Register, $dst$$Register, 48, 0); 12632 %} 12633 ins_pipe(pipe_class_default); 12634 %} 12635 12636 // Insrdi does replicate if src == dst. 12637 instruct repl56(iRegLdst dst) %{ 12638 predicate(false); 12639 effect(USE_DEF dst); 12640 12641 format %{ "INSRDI $dst, #0, $dst, #56 \t// replicate" %} 12642 size(4); 12643 ins_encode %{ 12644 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 12645 __ insrdi($dst$$Register, $dst$$Register, 56, 0); 12646 %} 12647 ins_pipe(pipe_class_default); 12648 %} 12649 12650 instruct repl8B_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 12651 match(Set dst (ReplicateB src)); 12652 predicate(n->as_Vector()->length() == 8); 12653 expand %{ 12654 moveReg(dst, src); 12655 repl56(dst); 12656 repl48(dst); 12657 repl32(dst); 12658 %} 12659 %} 12660 12661 instruct repl8B_immI0(iRegLdst dst, immI_0 zero) %{ 12662 match(Set dst (ReplicateB zero)); 12663 predicate(n->as_Vector()->length() == 8); 12664 format %{ "LI $dst, #0 \t// replicate8B" %} 12665 size(4); 12666 ins_encode %{ 12667 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12668 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 12669 %} 12670 ins_pipe(pipe_class_default); 12671 %} 12672 12673 instruct repl8B_immIminus1(iRegLdst dst, immI_minus1 src) %{ 12674 match(Set dst (ReplicateB src)); 12675 predicate(n->as_Vector()->length() == 8); 12676 format %{ "LI $dst, #-1 \t// replicate8B" %} 12677 size(4); 12678 ins_encode %{ 12679 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12680 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 12681 %} 12682 ins_pipe(pipe_class_default); 12683 %} 12684 12685 instruct repl4S_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 12686 match(Set dst (ReplicateS src)); 12687 predicate(n->as_Vector()->length() == 4); 12688 expand %{ 12689 moveReg(dst, src); 12690 repl48(dst); 12691 repl32(dst); 12692 %} 12693 %} 12694 12695 instruct repl4S_immI0(iRegLdst dst, immI_0 zero) %{ 12696 match(Set dst (ReplicateS zero)); 12697 predicate(n->as_Vector()->length() == 4); 12698 format %{ "LI $dst, #0 \t// replicate4C" %} 12699 size(4); 12700 ins_encode %{ 12701 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12702 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 12703 %} 12704 ins_pipe(pipe_class_default); 12705 %} 12706 12707 instruct repl4S_immIminus1(iRegLdst dst, immI_minus1 src) %{ 12708 match(Set dst (ReplicateS src)); 12709 predicate(n->as_Vector()->length() == 4); 12710 format %{ "LI $dst, -1 \t// replicate4C" %} 12711 size(4); 12712 ins_encode %{ 12713 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12714 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 12715 %} 12716 ins_pipe(pipe_class_default); 12717 %} 12718 12719 instruct repl2I_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 12720 match(Set dst (ReplicateI src)); 12721 predicate(n->as_Vector()->length() == 2); 12722 ins_cost(2 * DEFAULT_COST); 12723 expand %{ 12724 moveReg(dst, src); 12725 repl32(dst); 12726 %} 12727 %} 12728 12729 instruct repl2I_immI0(iRegLdst dst, immI_0 zero) %{ 12730 match(Set dst (ReplicateI zero)); 12731 predicate(n->as_Vector()->length() == 2); 12732 format %{ "LI $dst, #0 \t// replicate4C" %} 12733 size(4); 12734 ins_encode %{ 12735 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12736 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 12737 %} 12738 ins_pipe(pipe_class_default); 12739 %} 12740 12741 instruct repl2I_immIminus1(iRegLdst dst, immI_minus1 src) %{ 12742 match(Set dst (ReplicateI src)); 12743 predicate(n->as_Vector()->length() == 2); 12744 format %{ "LI $dst, -1 \t// replicate4C" %} 12745 size(4); 12746 ins_encode %{ 12747 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12748 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 12749 %} 12750 ins_pipe(pipe_class_default); 12751 %} 12752 12753 // Move float to int register via stack, replicate. 12754 instruct repl2F_reg_Ex(iRegLdst dst, regF src) %{ 12755 match(Set dst (ReplicateF src)); 12756 predicate(n->as_Vector()->length() == 2); 12757 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST); 12758 expand %{ 12759 stackSlotL tmpS; 12760 iRegIdst tmpI; 12761 moveF2I_reg_stack(tmpS, src); // Move float to stack. 12762 moveF2I_stack_reg(tmpI, tmpS); // Move stack to int reg. 12763 moveReg(dst, tmpI); // Move int to long reg. 12764 repl32(dst); // Replicate bitpattern. 12765 %} 12766 %} 12767 12768 // Replicate scalar constant to packed float values in Double register 12769 instruct repl2F_immF_Ex(iRegLdst dst, immF src) %{ 12770 match(Set dst (ReplicateF src)); 12771 predicate(n->as_Vector()->length() == 2); 12772 ins_cost(5 * DEFAULT_COST); 12773 12774 format %{ "LD $dst, offset, $constanttablebase\t// load replicated float $src $src from table, postalloc expanded" %} 12775 postalloc_expand( postalloc_expand_load_replF_constant(dst, src, constanttablebase) ); 12776 %} 12777 12778 // Replicate scalar zero constant to packed float values in Double register 12779 instruct repl2F_immF0(iRegLdst dst, immF_0 zero) %{ 12780 match(Set dst (ReplicateF zero)); 12781 predicate(n->as_Vector()->length() == 2); 12782 12783 format %{ "LI $dst, #0 \t// replicate2F" %} 12784 ins_encode %{ 12785 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12786 __ li($dst$$Register, 0x0); 12787 %} 12788 ins_pipe(pipe_class_default); 12789 %} 12790 12791 12792 //----------Overflow Math Instructions----------------------------------------- 12793 12794 // Note that we have to make sure that XER.SO is reset before using overflow instructions. 12795 // Simple Overflow operations can be matched by very few instructions (e.g. addExact: xor, and_, bc). 12796 // Seems like only Long intrinsincs have an advantage. (The only expensive one is OverflowMulL.) 12797 12798 instruct overflowAddL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 12799 match(Set cr0 (OverflowAddL op1 op2)); 12800 12801 format %{ "add_ $op1, $op2\t# overflow check long" %} 12802 ins_encode %{ 12803 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12804 __ mtxer(R30_zero); // clear XER.SO 12805 __ addo_(R30_zero, $op1$$Register, $op2$$Register); 12806 %} 12807 ins_pipe(pipe_class_default); 12808 %} 12809 12810 instruct overflowSubL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 12811 match(Set cr0 (OverflowSubL op1 op2)); 12812 12813 format %{ "subfo_ R0, $op2, $op1\t# overflow check long" %} 12814 ins_encode %{ 12815 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12816 __ mtxer(R30_zero); // clear XER.SO 12817 __ subfo_(R30_zero, $op2$$Register, $op1$$Register); 12818 %} 12819 ins_pipe(pipe_class_default); 12820 %} 12821 12822 instruct overflowNegL_reg(flagsRegCR0 cr0, immL_0 zero, iRegLsrc op2) %{ 12823 match(Set cr0 (OverflowSubL zero op2)); 12824 12825 format %{ "nego_ R0, $op2\t# overflow check long" %} 12826 ins_encode %{ 12827 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12828 __ mtxer(R30_zero); // clear XER.SO 12829 __ nego_(R30_zero, $op2$$Register); 12830 %} 12831 ins_pipe(pipe_class_default); 12832 %} 12833 12834 instruct overflowMulL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 12835 match(Set cr0 (OverflowMulL op1 op2)); 12836 12837 format %{ "mulldo_ R0, $op1, $op2\t# overflow check long" %} 12838 ins_encode %{ 12839 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12840 __ mtxer(R30_zero); // clear XER.SO 12841 __ mulldo_(R30_zero, $op1$$Register, $op2$$Register); 12842 %} 12843 ins_pipe(pipe_class_default); 12844 %} 12845 12846 12847 // ============================================================================ 12848 // Safepoint Instruction 12849 12850 instruct safePoint_poll(iRegPdst poll) %{ 12851 match(SafePoint poll); 12852 predicate(LoadPollAddressFromThread); 12853 12854 // It caused problems to add the effect that r0 is killed, but this 12855 // effect no longer needs to be mentioned, since r0 is not contained 12856 // in a reg_class. 12857 12858 format %{ "LD R0, #0, $poll \t// Safepoint poll for GC" %} 12859 size(4); 12860 ins_encode( enc_poll(0x0, poll) ); 12861 ins_pipe(pipe_class_default); 12862 %} 12863 12864 // Safepoint without per-thread support. Load address of page to poll 12865 // as constant. 12866 // Rscratch2RegP is R12. 12867 // LoadConPollAddr node is added in pd_post_matching_hook(). It must be 12868 // a seperate node so that the oop map is at the right location. 12869 instruct safePoint_poll_conPollAddr(rscratch2RegP poll) %{ 12870 match(SafePoint poll); 12871 predicate(!LoadPollAddressFromThread); 12872 12873 // It caused problems to add the effect that r0 is killed, but this 12874 // effect no longer needs to be mentioned, since r0 is not contained 12875 // in a reg_class. 12876 12877 format %{ "LD R0, #0, R12 \t// Safepoint poll for GC" %} 12878 ins_encode( enc_poll(0x0, poll) ); 12879 ins_pipe(pipe_class_default); 12880 %} 12881 12882 // ============================================================================ 12883 // Call Instructions 12884 12885 // Call Java Static Instruction 12886 12887 // Schedulable version of call static node. 12888 instruct CallStaticJavaDirect(method meth) %{ 12889 match(CallStaticJava); 12890 effect(USE meth); 12891 ins_cost(CALL_COST); 12892 12893 ins_num_consts(3 /* up to 3 patchable constants: inline cache, 2 call targets. */); 12894 12895 format %{ "CALL,static $meth \t// ==> " %} 12896 size(4); 12897 ins_encode( enc_java_static_call(meth) ); 12898 ins_pipe(pipe_class_call); 12899 %} 12900 12901 // Call Java Dynamic Instruction 12902 12903 // Used by postalloc expand of CallDynamicJavaDirectSchedEx (actual call). 12904 // Loading of IC was postalloc expanded. The nodes loading the IC are reachable 12905 // via fields ins_field_load_ic_hi_node and ins_field_load_ic_node. 12906 // The call destination must still be placed in the constant pool. 12907 instruct CallDynamicJavaDirectSched(method meth) %{ 12908 match(CallDynamicJava); // To get all the data fields we need ... 12909 effect(USE meth); 12910 predicate(false); // ... but never match. 12911 12912 ins_field_load_ic_hi_node(loadConL_hiNode*); 12913 ins_field_load_ic_node(loadConLNode*); 12914 ins_num_consts(1 /* 1 patchable constant: call destination */); 12915 12916 format %{ "BL \t// dynamic $meth ==> " %} 12917 size(4); 12918 ins_encode( enc_java_dynamic_call_sched(meth) ); 12919 ins_pipe(pipe_class_call); 12920 %} 12921 12922 // Schedulable (i.e. postalloc expanded) version of call dynamic java. 12923 // We use postalloc expanded calls if we use inline caches 12924 // and do not update method data. 12925 // 12926 // This instruction has two constants: inline cache (IC) and call destination. 12927 // Loading the inline cache will be postalloc expanded, thus leaving a call with 12928 // one constant. 12929 instruct CallDynamicJavaDirectSched_Ex(method meth) %{ 12930 match(CallDynamicJava); 12931 effect(USE meth); 12932 predicate(UseInlineCaches); 12933 ins_cost(CALL_COST); 12934 12935 ins_num_consts(2 /* 2 patchable constants: inline cache, call destination. */); 12936 12937 format %{ "CALL,dynamic $meth \t// postalloc expanded" %} 12938 postalloc_expand( postalloc_expand_java_dynamic_call_sched(meth, constanttablebase) ); 12939 %} 12940 12941 // Compound version of call dynamic java 12942 // We use postalloc expanded calls if we use inline caches 12943 // and do not update method data. 12944 instruct CallDynamicJavaDirect(method meth) %{ 12945 match(CallDynamicJava); 12946 effect(USE meth); 12947 predicate(!UseInlineCaches); 12948 ins_cost(CALL_COST); 12949 12950 // Enc_java_to_runtime_call needs up to 4 constants (method data oop). 12951 ins_num_consts(4); 12952 12953 format %{ "CALL,dynamic $meth \t// ==> " %} 12954 ins_encode( enc_java_dynamic_call(meth, constanttablebase) ); 12955 ins_pipe(pipe_class_call); 12956 %} 12957 12958 // Call Runtime Instruction 12959 12960 instruct CallRuntimeDirect(method meth) %{ 12961 match(CallRuntime); 12962 effect(USE meth); 12963 ins_cost(CALL_COST); 12964 12965 // Enc_java_to_runtime_call needs up to 3 constants: call target, 12966 // env for callee, C-toc. 12967 ins_num_consts(3); 12968 12969 format %{ "CALL,runtime" %} 12970 ins_encode( enc_java_to_runtime_call(meth) ); 12971 ins_pipe(pipe_class_call); 12972 %} 12973 12974 // Call Leaf 12975 12976 // Used by postalloc expand of CallLeafDirect_Ex (mtctr). 12977 instruct CallLeafDirect_mtctr(iRegLdst dst, iRegLsrc src) %{ 12978 effect(DEF dst, USE src); 12979 12980 ins_num_consts(1); 12981 12982 format %{ "MTCTR $src" %} 12983 size(4); 12984 ins_encode( enc_leaf_call_mtctr(src) ); 12985 ins_pipe(pipe_class_default); 12986 %} 12987 12988 // Used by postalloc expand of CallLeafDirect_Ex (actual call). 12989 instruct CallLeafDirect(method meth) %{ 12990 match(CallLeaf); // To get the data all the data fields we need ... 12991 effect(USE meth); 12992 predicate(false); // but never match. 12993 12994 format %{ "BCTRL \t// leaf call $meth ==> " %} 12995 size(4); 12996 ins_encode %{ 12997 // TODO: PPC port $archOpcode(ppc64Opcode_bctrl); 12998 __ bctrl(); 12999 %} 13000 ins_pipe(pipe_class_call); 13001 %} 13002 13003 // postalloc expand of CallLeafDirect. 13004 // Load adress to call from TOC, then bl to it. 13005 instruct CallLeafDirect_Ex(method meth) %{ 13006 match(CallLeaf); 13007 effect(USE meth); 13008 ins_cost(CALL_COST); 13009 13010 // Postalloc_expand_java_to_runtime_call needs up to 3 constants: call target, 13011 // env for callee, C-toc. 13012 ins_num_consts(3); 13013 13014 format %{ "CALL,runtime leaf $meth \t// postalloc expanded" %} 13015 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 13016 %} 13017 13018 // Call runtime without safepoint - same as CallLeaf. 13019 // postalloc expand of CallLeafNoFPDirect. 13020 // Load adress to call from TOC, then bl to it. 13021 instruct CallLeafNoFPDirect_Ex(method meth) %{ 13022 match(CallLeafNoFP); 13023 effect(USE meth); 13024 ins_cost(CALL_COST); 13025 13026 // Enc_java_to_runtime_call needs up to 3 constants: call target, 13027 // env for callee, C-toc. 13028 ins_num_consts(3); 13029 13030 format %{ "CALL,runtime leaf nofp $meth \t// postalloc expanded" %} 13031 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 13032 %} 13033 13034 // Tail Call; Jump from runtime stub to Java code. 13035 // Also known as an 'interprocedural jump'. 13036 // Target of jump will eventually return to caller. 13037 // TailJump below removes the return address. 13038 instruct TailCalljmpInd(iRegPdstNoScratch jump_target, inline_cache_regP method_oop) %{ 13039 match(TailCall jump_target method_oop); 13040 ins_cost(CALL_COST); 13041 13042 format %{ "MTCTR $jump_target \t// $method_oop holds method oop\n\t" 13043 "BCTR \t// tail call" %} 13044 size(8); 13045 ins_encode %{ 13046 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13047 __ mtctr($jump_target$$Register); 13048 __ bctr(); 13049 %} 13050 ins_pipe(pipe_class_call); 13051 %} 13052 13053 // Return Instruction 13054 instruct Ret() %{ 13055 match(Return); 13056 format %{ "BLR \t// branch to link register" %} 13057 size(4); 13058 ins_encode %{ 13059 // TODO: PPC port $archOpcode(ppc64Opcode_blr); 13060 // LR is restored in MachEpilogNode. Just do the RET here. 13061 __ blr(); 13062 %} 13063 ins_pipe(pipe_class_default); 13064 %} 13065 13066 // Tail Jump; remove the return address; jump to target. 13067 // TailCall above leaves the return address around. 13068 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2). 13069 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a 13070 // "restore" before this instruction (in Epilogue), we need to materialize it 13071 // in %i0. 13072 instruct tailjmpInd(iRegPdstNoScratch jump_target, rarg1RegP ex_oop) %{ 13073 match(TailJump jump_target ex_oop); 13074 ins_cost(CALL_COST); 13075 13076 format %{ "LD R4_ARG2 = LR\n\t" 13077 "MTCTR $jump_target\n\t" 13078 "BCTR \t// TailJump, exception oop: $ex_oop" %} 13079 size(12); 13080 ins_encode %{ 13081 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13082 __ ld(R4_ARG2/* issuing pc */, _abi(lr), R1_SP); 13083 __ mtctr($jump_target$$Register); 13084 __ bctr(); 13085 %} 13086 ins_pipe(pipe_class_call); 13087 %} 13088 13089 // Create exception oop: created by stack-crawling runtime code. 13090 // Created exception is now available to this handler, and is setup 13091 // just prior to jumping to this handler. No code emitted. 13092 instruct CreateException(rarg1RegP ex_oop) %{ 13093 match(Set ex_oop (CreateEx)); 13094 ins_cost(0); 13095 13096 format %{ " -- \t// exception oop; no code emitted" %} 13097 size(0); 13098 ins_encode( /*empty*/ ); 13099 ins_pipe(pipe_class_default); 13100 %} 13101 13102 // Rethrow exception: The exception oop will come in the first 13103 // argument position. Then JUMP (not call) to the rethrow stub code. 13104 instruct RethrowException() %{ 13105 match(Rethrow); 13106 ins_cost(CALL_COST); 13107 13108 format %{ "Jmp rethrow_stub" %} 13109 ins_encode %{ 13110 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13111 cbuf.set_insts_mark(); 13112 __ b64_patchable((address)OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type); 13113 %} 13114 ins_pipe(pipe_class_call); 13115 %} 13116 13117 // Die now. 13118 instruct ShouldNotReachHere() %{ 13119 match(Halt); 13120 ins_cost(CALL_COST); 13121 13122 format %{ "ShouldNotReachHere" %} 13123 size(4); 13124 ins_encode %{ 13125 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 13126 __ trap_should_not_reach_here(); 13127 %} 13128 ins_pipe(pipe_class_default); 13129 %} 13130 13131 // This name is KNOWN by the ADLC and cannot be changed. The ADLC 13132 // forces a 'TypeRawPtr::BOTTOM' output type for this guy. 13133 // Get a DEF on threadRegP, no costs, no encoding, use 13134 // 'ins_should_rematerialize(true)' to avoid spilling. 13135 instruct tlsLoadP(threadRegP dst) %{ 13136 match(Set dst (ThreadLocal)); 13137 ins_cost(0); 13138 13139 ins_should_rematerialize(true); 13140 13141 format %{ " -- \t// $dst=Thread::current(), empty" %} 13142 size(0); 13143 ins_encode( /*empty*/ ); 13144 ins_pipe(pipe_class_empty); 13145 %} 13146 13147 //---Some PPC specific nodes--------------------------------------------------- 13148 13149 // Stop a group. 13150 instruct endGroup() %{ 13151 ins_cost(0); 13152 13153 ins_is_nop(true); 13154 13155 format %{ "End Bundle (ori r1, r1, 0)" %} 13156 size(4); 13157 ins_encode %{ 13158 // TODO: PPC port $archOpcode(ppc64Opcode_endgroup); 13159 __ endgroup(); 13160 %} 13161 ins_pipe(pipe_class_default); 13162 %} 13163 13164 // Nop instructions 13165 13166 instruct fxNop() %{ 13167 ins_cost(0); 13168 13169 ins_is_nop(true); 13170 13171 format %{ "fxNop" %} 13172 size(4); 13173 ins_encode %{ 13174 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 13175 __ nop(); 13176 %} 13177 ins_pipe(pipe_class_default); 13178 %} 13179 13180 instruct fpNop0() %{ 13181 ins_cost(0); 13182 13183 ins_is_nop(true); 13184 13185 format %{ "fpNop0" %} 13186 size(4); 13187 ins_encode %{ 13188 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 13189 __ fpnop0(); 13190 %} 13191 ins_pipe(pipe_class_default); 13192 %} 13193 13194 instruct fpNop1() %{ 13195 ins_cost(0); 13196 13197 ins_is_nop(true); 13198 13199 format %{ "fpNop1" %} 13200 size(4); 13201 ins_encode %{ 13202 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 13203 __ fpnop1(); 13204 %} 13205 ins_pipe(pipe_class_default); 13206 %} 13207 13208 instruct brNop0() %{ 13209 ins_cost(0); 13210 size(4); 13211 format %{ "brNop0" %} 13212 ins_encode %{ 13213 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 13214 __ brnop0(); 13215 %} 13216 ins_is_nop(true); 13217 ins_pipe(pipe_class_default); 13218 %} 13219 13220 instruct brNop1() %{ 13221 ins_cost(0); 13222 13223 ins_is_nop(true); 13224 13225 format %{ "brNop1" %} 13226 size(4); 13227 ins_encode %{ 13228 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 13229 __ brnop1(); 13230 %} 13231 ins_pipe(pipe_class_default); 13232 %} 13233 13234 instruct brNop2() %{ 13235 ins_cost(0); 13236 13237 ins_is_nop(true); 13238 13239 format %{ "brNop2" %} 13240 size(4); 13241 ins_encode %{ 13242 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 13243 __ brnop2(); 13244 %} 13245 ins_pipe(pipe_class_default); 13246 %} 13247 13248 //----------PEEPHOLE RULES----------------------------------------------------- 13249 // These must follow all instruction definitions as they use the names 13250 // defined in the instructions definitions. 13251 // 13252 // peepmatch ( root_instr_name [preceeding_instruction]* ); 13253 // 13254 // peepconstraint %{ 13255 // (instruction_number.operand_name relational_op instruction_number.operand_name 13256 // [, ...] ); 13257 // // instruction numbers are zero-based using left to right order in peepmatch 13258 // 13259 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 13260 // // provide an instruction_number.operand_name for each operand that appears 13261 // // in the replacement instruction's match rule 13262 // 13263 // ---------VM FLAGS--------------------------------------------------------- 13264 // 13265 // All peephole optimizations can be turned off using -XX:-OptoPeephole 13266 // 13267 // Each peephole rule is given an identifying number starting with zero and 13268 // increasing by one in the order seen by the parser. An individual peephole 13269 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 13270 // on the command-line. 13271 // 13272 // ---------CURRENT LIMITATIONS---------------------------------------------- 13273 // 13274 // Only match adjacent instructions in same basic block 13275 // Only equality constraints 13276 // Only constraints between operands, not (0.dest_reg == EAX_enc) 13277 // Only one replacement instruction 13278 // 13279 // ---------EXAMPLE---------------------------------------------------------- 13280 // 13281 // // pertinent parts of existing instructions in architecture description 13282 // instruct movI(eRegI dst, eRegI src) %{ 13283 // match(Set dst (CopyI src)); 13284 // %} 13285 // 13286 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{ 13287 // match(Set dst (AddI dst src)); 13288 // effect(KILL cr); 13289 // %} 13290 // 13291 // // Change (inc mov) to lea 13292 // peephole %{ 13293 // // increment preceeded by register-register move 13294 // peepmatch ( incI_eReg movI ); 13295 // // require that the destination register of the increment 13296 // // match the destination register of the move 13297 // peepconstraint ( 0.dst == 1.dst ); 13298 // // construct a replacement instruction that sets 13299 // // the destination to ( move's source register + one ) 13300 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 13301 // %} 13302 // 13303 // Implementation no longer uses movX instructions since 13304 // machine-independent system no longer uses CopyX nodes. 13305 // 13306 // peephole %{ 13307 // peepmatch ( incI_eReg movI ); 13308 // peepconstraint ( 0.dst == 1.dst ); 13309 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 13310 // %} 13311 // 13312 // peephole %{ 13313 // peepmatch ( decI_eReg movI ); 13314 // peepconstraint ( 0.dst == 1.dst ); 13315 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 13316 // %} 13317 // 13318 // peephole %{ 13319 // peepmatch ( addI_eReg_imm movI ); 13320 // peepconstraint ( 0.dst == 1.dst ); 13321 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 13322 // %} 13323 // 13324 // peephole %{ 13325 // peepmatch ( addP_eReg_imm movP ); 13326 // peepconstraint ( 0.dst == 1.dst ); 13327 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) ); 13328 // %} 13329 13330 // // Change load of spilled value to only a spill 13331 // instruct storeI(memory mem, eRegI src) %{ 13332 // match(Set mem (StoreI mem src)); 13333 // %} 13334 // 13335 // instruct loadI(eRegI dst, memory mem) %{ 13336 // match(Set dst (LoadI mem)); 13337 // %} 13338 // 13339 peephole %{ 13340 peepmatch ( loadI storeI ); 13341 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 13342 peepreplace ( storeI( 1.mem 1.mem 1.src ) ); 13343 %} 13344 13345 peephole %{ 13346 peepmatch ( loadL storeL ); 13347 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 13348 peepreplace ( storeL( 1.mem 1.mem 1.src ) ); 13349 %} 13350 13351 peephole %{ 13352 peepmatch ( loadP storeP ); 13353 peepconstraint ( 1.src == 0.dst, 1.dst == 0.mem ); 13354 peepreplace ( storeP( 1.dst 1.dst 1.src ) ); 13355 %} 13356 13357 //----------SMARTSPILL RULES--------------------------------------------------- 13358 // These must follow all instruction definitions as they use the names 13359 // defined in the instructions definitions.