1 // 2 // Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. 3 // Copyright (c) 2012, 2017 SAP SE. All rights reserved. 4 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 // 6 // This code is free software; you can redistribute it and/or modify it 7 // under the terms of the GNU General Public License version 2 only, as 8 // published by the Free Software Foundation. 9 // 10 // This code is distributed in the hope that it will be useful, but WITHOUT 11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 // version 2 for more details (a copy is included in the LICENSE file that 14 // accompanied this code). 15 // 16 // You should have received a copy of the GNU General Public License version 17 // 2 along with this work; if not, write to the Free Software Foundation, 18 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 // 20 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 // or visit www.oracle.com if you need additional information or have any 22 // questions. 23 // 24 // 25 26 // 27 // PPC64 Architecture Description File 28 // 29 30 //----------REGISTER DEFINITION BLOCK------------------------------------------ 31 // This information is used by the matcher and the register allocator to 32 // describe individual registers and classes of registers within the target 33 // architecture. 34 register %{ 35 //----------Architecture Description Register Definitions---------------------- 36 // General Registers 37 // "reg_def" name (register save type, C convention save type, 38 // ideal register type, encoding); 39 // 40 // Register Save Types: 41 // 42 // NS = No-Save: The register allocator assumes that these registers 43 // can be used without saving upon entry to the method, & 44 // that they do not need to be saved at call sites. 45 // 46 // SOC = Save-On-Call: The register allocator assumes that these registers 47 // can be used without saving upon entry to the method, 48 // but that they must be saved at call sites. 49 // These are called "volatiles" on ppc. 50 // 51 // SOE = Save-On-Entry: The register allocator assumes that these registers 52 // must be saved before using them upon entry to the 53 // method, but they do not need to be saved at call 54 // sites. 55 // These are called "nonvolatiles" on ppc. 56 // 57 // AS = Always-Save: The register allocator assumes that these registers 58 // must be saved before using them upon entry to the 59 // method, & that they must be saved at call sites. 60 // 61 // Ideal Register Type is used to determine how to save & restore a 62 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get 63 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI. 64 // 65 // The encoding number is the actual bit-pattern placed into the opcodes. 66 // 67 // PPC64 register definitions, based on the 64-bit PowerPC ELF ABI 68 // Supplement Version 1.7 as of 2003-10-29. 69 // 70 // For each 64-bit register we must define two registers: the register 71 // itself, e.g. R3, and a corresponding virtual other (32-bit-)'half', 72 // e.g. R3_H, which is needed by the allocator, but is not used 73 // for stores, loads, etc. 74 75 // ---------------------------- 76 // Integer/Long Registers 77 // ---------------------------- 78 79 // PPC64 has 32 64-bit integer registers. 80 81 // types: v = volatile, nv = non-volatile, s = system 82 reg_def R0 ( SOC, SOC, Op_RegI, 0, R0->as_VMReg() ); // v used in prologs 83 reg_def R0_H ( SOC, SOC, Op_RegI, 99, R0->as_VMReg()->next() ); 84 reg_def R1 ( NS, NS, Op_RegI, 1, R1->as_VMReg() ); // s SP 85 reg_def R1_H ( NS, NS, Op_RegI, 99, R1->as_VMReg()->next() ); 86 reg_def R2 ( SOC, SOC, Op_RegI, 2, R2->as_VMReg() ); // v TOC 87 reg_def R2_H ( SOC, SOC, Op_RegI, 99, R2->as_VMReg()->next() ); 88 reg_def R3 ( SOC, SOC, Op_RegI, 3, R3->as_VMReg() ); // v iarg1 & iret 89 reg_def R3_H ( SOC, SOC, Op_RegI, 99, R3->as_VMReg()->next() ); 90 reg_def R4 ( SOC, SOC, Op_RegI, 4, R4->as_VMReg() ); // iarg2 91 reg_def R4_H ( SOC, SOC, Op_RegI, 99, R4->as_VMReg()->next() ); 92 reg_def R5 ( SOC, SOC, Op_RegI, 5, R5->as_VMReg() ); // v iarg3 93 reg_def R5_H ( SOC, SOC, Op_RegI, 99, R5->as_VMReg()->next() ); 94 reg_def R6 ( SOC, SOC, Op_RegI, 6, R6->as_VMReg() ); // v iarg4 95 reg_def R6_H ( SOC, SOC, Op_RegI, 99, R6->as_VMReg()->next() ); 96 reg_def R7 ( SOC, SOC, Op_RegI, 7, R7->as_VMReg() ); // v iarg5 97 reg_def R7_H ( SOC, SOC, Op_RegI, 99, R7->as_VMReg()->next() ); 98 reg_def R8 ( SOC, SOC, Op_RegI, 8, R8->as_VMReg() ); // v iarg6 99 reg_def R8_H ( SOC, SOC, Op_RegI, 99, R8->as_VMReg()->next() ); 100 reg_def R9 ( SOC, SOC, Op_RegI, 9, R9->as_VMReg() ); // v iarg7 101 reg_def R9_H ( SOC, SOC, Op_RegI, 99, R9->as_VMReg()->next() ); 102 reg_def R10 ( SOC, SOC, Op_RegI, 10, R10->as_VMReg() ); // v iarg8 103 reg_def R10_H( SOC, SOC, Op_RegI, 99, R10->as_VMReg()->next()); 104 reg_def R11 ( SOC, SOC, Op_RegI, 11, R11->as_VMReg() ); // v ENV / scratch 105 reg_def R11_H( SOC, SOC, Op_RegI, 99, R11->as_VMReg()->next()); 106 reg_def R12 ( SOC, SOC, Op_RegI, 12, R12->as_VMReg() ); // v scratch 107 reg_def R12_H( SOC, SOC, Op_RegI, 99, R12->as_VMReg()->next()); 108 reg_def R13 ( NS, NS, Op_RegI, 13, R13->as_VMReg() ); // s system thread id 109 reg_def R13_H( NS, NS, Op_RegI, 99, R13->as_VMReg()->next()); 110 reg_def R14 ( SOC, SOE, Op_RegI, 14, R14->as_VMReg() ); // nv 111 reg_def R14_H( SOC, SOE, Op_RegI, 99, R14->as_VMReg()->next()); 112 reg_def R15 ( SOC, SOE, Op_RegI, 15, R15->as_VMReg() ); // nv 113 reg_def R15_H( SOC, SOE, Op_RegI, 99, R15->as_VMReg()->next()); 114 reg_def R16 ( SOC, SOE, Op_RegI, 16, R16->as_VMReg() ); // nv 115 reg_def R16_H( SOC, SOE, Op_RegI, 99, R16->as_VMReg()->next()); 116 reg_def R17 ( SOC, SOE, Op_RegI, 17, R17->as_VMReg() ); // nv 117 reg_def R17_H( SOC, SOE, Op_RegI, 99, R17->as_VMReg()->next()); 118 reg_def R18 ( SOC, SOE, Op_RegI, 18, R18->as_VMReg() ); // nv 119 reg_def R18_H( SOC, SOE, Op_RegI, 99, R18->as_VMReg()->next()); 120 reg_def R19 ( SOC, SOE, Op_RegI, 19, R19->as_VMReg() ); // nv 121 reg_def R19_H( SOC, SOE, Op_RegI, 99, R19->as_VMReg()->next()); 122 reg_def R20 ( SOC, SOE, Op_RegI, 20, R20->as_VMReg() ); // nv 123 reg_def R20_H( SOC, SOE, Op_RegI, 99, R20->as_VMReg()->next()); 124 reg_def R21 ( SOC, SOE, Op_RegI, 21, R21->as_VMReg() ); // nv 125 reg_def R21_H( SOC, SOE, Op_RegI, 99, R21->as_VMReg()->next()); 126 reg_def R22 ( SOC, SOE, Op_RegI, 22, R22->as_VMReg() ); // nv 127 reg_def R22_H( SOC, SOE, Op_RegI, 99, R22->as_VMReg()->next()); 128 reg_def R23 ( SOC, SOE, Op_RegI, 23, R23->as_VMReg() ); // nv 129 reg_def R23_H( SOC, SOE, Op_RegI, 99, R23->as_VMReg()->next()); 130 reg_def R24 ( SOC, SOE, Op_RegI, 24, R24->as_VMReg() ); // nv 131 reg_def R24_H( SOC, SOE, Op_RegI, 99, R24->as_VMReg()->next()); 132 reg_def R25 ( SOC, SOE, Op_RegI, 25, R25->as_VMReg() ); // nv 133 reg_def R25_H( SOC, SOE, Op_RegI, 99, R25->as_VMReg()->next()); 134 reg_def R26 ( SOC, SOE, Op_RegI, 26, R26->as_VMReg() ); // nv 135 reg_def R26_H( SOC, SOE, Op_RegI, 99, R26->as_VMReg()->next()); 136 reg_def R27 ( SOC, SOE, Op_RegI, 27, R27->as_VMReg() ); // nv 137 reg_def R27_H( SOC, SOE, Op_RegI, 99, R27->as_VMReg()->next()); 138 reg_def R28 ( SOC, SOE, Op_RegI, 28, R28->as_VMReg() ); // nv 139 reg_def R28_H( SOC, SOE, Op_RegI, 99, R28->as_VMReg()->next()); 140 reg_def R29 ( SOC, SOE, Op_RegI, 29, R29->as_VMReg() ); // nv 141 reg_def R29_H( SOC, SOE, Op_RegI, 99, R29->as_VMReg()->next()); 142 reg_def R30 ( SOC, SOE, Op_RegI, 30, R30->as_VMReg() ); // nv 143 reg_def R30_H( SOC, SOE, Op_RegI, 99, R30->as_VMReg()->next()); 144 reg_def R31 ( SOC, SOE, Op_RegI, 31, R31->as_VMReg() ); // nv 145 reg_def R31_H( SOC, SOE, Op_RegI, 99, R31->as_VMReg()->next()); 146 147 148 // ---------------------------- 149 // Float/Double Registers 150 // ---------------------------- 151 152 // Double Registers 153 // The rules of ADL require that double registers be defined in pairs. 154 // Each pair must be two 32-bit values, but not necessarily a pair of 155 // single float registers. In each pair, ADLC-assigned register numbers 156 // must be adjacent, with the lower number even. Finally, when the 157 // CPU stores such a register pair to memory, the word associated with 158 // the lower ADLC-assigned number must be stored to the lower address. 159 160 // PPC64 has 32 64-bit floating-point registers. Each can store a single 161 // or double precision floating-point value. 162 163 // types: v = volatile, nv = non-volatile, s = system 164 reg_def F0 ( SOC, SOC, Op_RegF, 0, F0->as_VMReg() ); // v scratch 165 reg_def F0_H ( SOC, SOC, Op_RegF, 99, F0->as_VMReg()->next() ); 166 reg_def F1 ( SOC, SOC, Op_RegF, 1, F1->as_VMReg() ); // v farg1 & fret 167 reg_def F1_H ( SOC, SOC, Op_RegF, 99, F1->as_VMReg()->next() ); 168 reg_def F2 ( SOC, SOC, Op_RegF, 2, F2->as_VMReg() ); // v farg2 169 reg_def F2_H ( SOC, SOC, Op_RegF, 99, F2->as_VMReg()->next() ); 170 reg_def F3 ( SOC, SOC, Op_RegF, 3, F3->as_VMReg() ); // v farg3 171 reg_def F3_H ( SOC, SOC, Op_RegF, 99, F3->as_VMReg()->next() ); 172 reg_def F4 ( SOC, SOC, Op_RegF, 4, F4->as_VMReg() ); // v farg4 173 reg_def F4_H ( SOC, SOC, Op_RegF, 99, F4->as_VMReg()->next() ); 174 reg_def F5 ( SOC, SOC, Op_RegF, 5, F5->as_VMReg() ); // v farg5 175 reg_def F5_H ( SOC, SOC, Op_RegF, 99, F5->as_VMReg()->next() ); 176 reg_def F6 ( SOC, SOC, Op_RegF, 6, F6->as_VMReg() ); // v farg6 177 reg_def F6_H ( SOC, SOC, Op_RegF, 99, F6->as_VMReg()->next() ); 178 reg_def F7 ( SOC, SOC, Op_RegF, 7, F7->as_VMReg() ); // v farg7 179 reg_def F7_H ( SOC, SOC, Op_RegF, 99, F7->as_VMReg()->next() ); 180 reg_def F8 ( SOC, SOC, Op_RegF, 8, F8->as_VMReg() ); // v farg8 181 reg_def F8_H ( SOC, SOC, Op_RegF, 99, F8->as_VMReg()->next() ); 182 reg_def F9 ( SOC, SOC, Op_RegF, 9, F9->as_VMReg() ); // v farg9 183 reg_def F9_H ( SOC, SOC, Op_RegF, 99, F9->as_VMReg()->next() ); 184 reg_def F10 ( SOC, SOC, Op_RegF, 10, F10->as_VMReg() ); // v farg10 185 reg_def F10_H( SOC, SOC, Op_RegF, 99, F10->as_VMReg()->next()); 186 reg_def F11 ( SOC, SOC, Op_RegF, 11, F11->as_VMReg() ); // v farg11 187 reg_def F11_H( SOC, SOC, Op_RegF, 99, F11->as_VMReg()->next()); 188 reg_def F12 ( SOC, SOC, Op_RegF, 12, F12->as_VMReg() ); // v farg12 189 reg_def F12_H( SOC, SOC, Op_RegF, 99, F12->as_VMReg()->next()); 190 reg_def F13 ( SOC, SOC, Op_RegF, 13, F13->as_VMReg() ); // v farg13 191 reg_def F13_H( SOC, SOC, Op_RegF, 99, F13->as_VMReg()->next()); 192 reg_def F14 ( SOC, SOE, Op_RegF, 14, F14->as_VMReg() ); // nv 193 reg_def F14_H( SOC, SOE, Op_RegF, 99, F14->as_VMReg()->next()); 194 reg_def F15 ( SOC, SOE, Op_RegF, 15, F15->as_VMReg() ); // nv 195 reg_def F15_H( SOC, SOE, Op_RegF, 99, F15->as_VMReg()->next()); 196 reg_def F16 ( SOC, SOE, Op_RegF, 16, F16->as_VMReg() ); // nv 197 reg_def F16_H( SOC, SOE, Op_RegF, 99, F16->as_VMReg()->next()); 198 reg_def F17 ( SOC, SOE, Op_RegF, 17, F17->as_VMReg() ); // nv 199 reg_def F17_H( SOC, SOE, Op_RegF, 99, F17->as_VMReg()->next()); 200 reg_def F18 ( SOC, SOE, Op_RegF, 18, F18->as_VMReg() ); // nv 201 reg_def F18_H( SOC, SOE, Op_RegF, 99, F18->as_VMReg()->next()); 202 reg_def F19 ( SOC, SOE, Op_RegF, 19, F19->as_VMReg() ); // nv 203 reg_def F19_H( SOC, SOE, Op_RegF, 99, F19->as_VMReg()->next()); 204 reg_def F20 ( SOC, SOE, Op_RegF, 20, F20->as_VMReg() ); // nv 205 reg_def F20_H( SOC, SOE, Op_RegF, 99, F20->as_VMReg()->next()); 206 reg_def F21 ( SOC, SOE, Op_RegF, 21, F21->as_VMReg() ); // nv 207 reg_def F21_H( SOC, SOE, Op_RegF, 99, F21->as_VMReg()->next()); 208 reg_def F22 ( SOC, SOE, Op_RegF, 22, F22->as_VMReg() ); // nv 209 reg_def F22_H( SOC, SOE, Op_RegF, 99, F22->as_VMReg()->next()); 210 reg_def F23 ( SOC, SOE, Op_RegF, 23, F23->as_VMReg() ); // nv 211 reg_def F23_H( SOC, SOE, Op_RegF, 99, F23->as_VMReg()->next()); 212 reg_def F24 ( SOC, SOE, Op_RegF, 24, F24->as_VMReg() ); // nv 213 reg_def F24_H( SOC, SOE, Op_RegF, 99, F24->as_VMReg()->next()); 214 reg_def F25 ( SOC, SOE, Op_RegF, 25, F25->as_VMReg() ); // nv 215 reg_def F25_H( SOC, SOE, Op_RegF, 99, F25->as_VMReg()->next()); 216 reg_def F26 ( SOC, SOE, Op_RegF, 26, F26->as_VMReg() ); // nv 217 reg_def F26_H( SOC, SOE, Op_RegF, 99, F26->as_VMReg()->next()); 218 reg_def F27 ( SOC, SOE, Op_RegF, 27, F27->as_VMReg() ); // nv 219 reg_def F27_H( SOC, SOE, Op_RegF, 99, F27->as_VMReg()->next()); 220 reg_def F28 ( SOC, SOE, Op_RegF, 28, F28->as_VMReg() ); // nv 221 reg_def F28_H( SOC, SOE, Op_RegF, 99, F28->as_VMReg()->next()); 222 reg_def F29 ( SOC, SOE, Op_RegF, 29, F29->as_VMReg() ); // nv 223 reg_def F29_H( SOC, SOE, Op_RegF, 99, F29->as_VMReg()->next()); 224 reg_def F30 ( SOC, SOE, Op_RegF, 30, F30->as_VMReg() ); // nv 225 reg_def F30_H( SOC, SOE, Op_RegF, 99, F30->as_VMReg()->next()); 226 reg_def F31 ( SOC, SOE, Op_RegF, 31, F31->as_VMReg() ); // nv 227 reg_def F31_H( SOC, SOE, Op_RegF, 99, F31->as_VMReg()->next()); 228 229 // ---------------------------- 230 // Special Registers 231 // ---------------------------- 232 233 // Condition Codes Flag Registers 234 235 // PPC64 has 8 condition code "registers" which are all contained 236 // in the CR register. 237 238 // types: v = volatile, nv = non-volatile, s = system 239 reg_def CCR0(SOC, SOC, Op_RegFlags, 0, CCR0->as_VMReg()); // v 240 reg_def CCR1(SOC, SOC, Op_RegFlags, 1, CCR1->as_VMReg()); // v 241 reg_def CCR2(SOC, SOC, Op_RegFlags, 2, CCR2->as_VMReg()); // nv 242 reg_def CCR3(SOC, SOC, Op_RegFlags, 3, CCR3->as_VMReg()); // nv 243 reg_def CCR4(SOC, SOC, Op_RegFlags, 4, CCR4->as_VMReg()); // nv 244 reg_def CCR5(SOC, SOC, Op_RegFlags, 5, CCR5->as_VMReg()); // v 245 reg_def CCR6(SOC, SOC, Op_RegFlags, 6, CCR6->as_VMReg()); // v 246 reg_def CCR7(SOC, SOC, Op_RegFlags, 7, CCR7->as_VMReg()); // v 247 248 // Special registers of PPC64 249 250 reg_def SR_XER( SOC, SOC, Op_RegP, 0, SR_XER->as_VMReg()); // v 251 reg_def SR_LR( SOC, SOC, Op_RegP, 1, SR_LR->as_VMReg()); // v 252 reg_def SR_CTR( SOC, SOC, Op_RegP, 2, SR_CTR->as_VMReg()); // v 253 reg_def SR_VRSAVE( SOC, SOC, Op_RegP, 3, SR_VRSAVE->as_VMReg()); // v 254 reg_def SR_SPEFSCR(SOC, SOC, Op_RegP, 4, SR_SPEFSCR->as_VMReg()); // v 255 reg_def SR_PPR( SOC, SOC, Op_RegP, 5, SR_PPR->as_VMReg()); // v 256 257 258 // ---------------------------- 259 // Specify priority of register selection within phases of register 260 // allocation. Highest priority is first. A useful heuristic is to 261 // give registers a low priority when they are required by machine 262 // instructions, like EAX and EDX on I486, and choose no-save registers 263 // before save-on-call, & save-on-call before save-on-entry. Registers 264 // which participate in fixed calling sequences should come last. 265 // Registers which are used as pairs must fall on an even boundary. 266 267 // It's worth about 1% on SPEC geomean to get this right. 268 269 // Chunk0, chunk1, and chunk2 form the MachRegisterNumbers enumeration 270 // in adGlobals_ppc.hpp which defines the <register>_num values, e.g. 271 // R3_num. Therefore, R3_num may not be (and in reality is not) 272 // the same as R3->encoding()! Furthermore, we cannot make any 273 // assumptions on ordering, e.g. R3_num may be less than R2_num. 274 // Additionally, the function 275 // static enum RC rc_class(OptoReg::Name reg ) 276 // maps a given <register>_num value to its chunk type (except for flags) 277 // and its current implementation relies on chunk0 and chunk1 having a 278 // size of 64 each. 279 280 // If you change this allocation class, please have a look at the 281 // default values for the parameters RoundRobinIntegerRegIntervalStart 282 // and RoundRobinFloatRegIntervalStart 283 284 alloc_class chunk0 ( 285 // Chunk0 contains *all* 64 integer registers halves. 286 287 // "non-volatile" registers 288 R14, R14_H, 289 R15, R15_H, 290 R17, R17_H, 291 R18, R18_H, 292 R19, R19_H, 293 R20, R20_H, 294 R21, R21_H, 295 R22, R22_H, 296 R23, R23_H, 297 R24, R24_H, 298 R25, R25_H, 299 R26, R26_H, 300 R27, R27_H, 301 R28, R28_H, 302 R29, R29_H, 303 R30, R30_H, 304 R31, R31_H, 305 306 // scratch/special registers 307 R11, R11_H, 308 R12, R12_H, 309 310 // argument registers 311 R10, R10_H, 312 R9, R9_H, 313 R8, R8_H, 314 R7, R7_H, 315 R6, R6_H, 316 R5, R5_H, 317 R4, R4_H, 318 R3, R3_H, 319 320 // special registers, not available for allocation 321 R16, R16_H, // R16_thread 322 R13, R13_H, // system thread id 323 R2, R2_H, // may be used for TOC 324 R1, R1_H, // SP 325 R0, R0_H // R0 (scratch) 326 ); 327 328 // If you change this allocation class, please have a look at the 329 // default values for the parameters RoundRobinIntegerRegIntervalStart 330 // and RoundRobinFloatRegIntervalStart 331 332 alloc_class chunk1 ( 333 // Chunk1 contains *all* 64 floating-point registers halves. 334 335 // scratch register 336 F0, F0_H, 337 338 // argument registers 339 F13, F13_H, 340 F12, F12_H, 341 F11, F11_H, 342 F10, F10_H, 343 F9, F9_H, 344 F8, F8_H, 345 F7, F7_H, 346 F6, F6_H, 347 F5, F5_H, 348 F4, F4_H, 349 F3, F3_H, 350 F2, F2_H, 351 F1, F1_H, 352 353 // non-volatile registers 354 F14, F14_H, 355 F15, F15_H, 356 F16, F16_H, 357 F17, F17_H, 358 F18, F18_H, 359 F19, F19_H, 360 F20, F20_H, 361 F21, F21_H, 362 F22, F22_H, 363 F23, F23_H, 364 F24, F24_H, 365 F25, F25_H, 366 F26, F26_H, 367 F27, F27_H, 368 F28, F28_H, 369 F29, F29_H, 370 F30, F30_H, 371 F31, F31_H 372 ); 373 374 alloc_class chunk2 ( 375 // Chunk2 contains *all* 8 condition code registers. 376 377 CCR0, 378 CCR1, 379 CCR2, 380 CCR3, 381 CCR4, 382 CCR5, 383 CCR6, 384 CCR7 385 ); 386 387 alloc_class chunk3 ( 388 // special registers 389 // These registers are not allocated, but used for nodes generated by postalloc expand. 390 SR_XER, 391 SR_LR, 392 SR_CTR, 393 SR_VRSAVE, 394 SR_SPEFSCR, 395 SR_PPR 396 ); 397 398 //-------Architecture Description Register Classes----------------------- 399 400 // Several register classes are automatically defined based upon 401 // information in this architecture description. 402 403 // 1) reg_class inline_cache_reg ( as defined in frame section ) 404 // 2) reg_class compiler_method_oop_reg ( as defined in frame section ) 405 // 2) reg_class interpreter_method_oop_reg ( as defined in frame section ) 406 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 407 // 408 409 // ---------------------------- 410 // 32 Bit Register Classes 411 // ---------------------------- 412 413 // We specify registers twice, once as read/write, and once read-only. 414 // We use the read-only registers for source operands. With this, we 415 // can include preset read only registers in this class, as a hard-coded 416 // '0'-register. (We used to simulate this on ppc.) 417 418 // 32 bit registers that can be read and written i.e. these registers 419 // can be dest (or src) of normal instructions. 420 reg_class bits32_reg_rw( 421 /*R0*/ // R0 422 /*R1*/ // SP 423 R2, // TOC 424 R3, 425 R4, 426 R5, 427 R6, 428 R7, 429 R8, 430 R9, 431 R10, 432 R11, 433 R12, 434 /*R13*/ // system thread id 435 R14, 436 R15, 437 /*R16*/ // R16_thread 438 R17, 439 R18, 440 R19, 441 R20, 442 R21, 443 R22, 444 R23, 445 R24, 446 R25, 447 R26, 448 R27, 449 R28, 450 /*R29,*/ // global TOC 451 R30, 452 R31 453 ); 454 455 // 32 bit registers that can only be read i.e. these registers can 456 // only be src of all instructions. 457 reg_class bits32_reg_ro( 458 /*R0*/ // R0 459 /*R1*/ // SP 460 R2 // TOC 461 R3, 462 R4, 463 R5, 464 R6, 465 R7, 466 R8, 467 R9, 468 R10, 469 R11, 470 R12, 471 /*R13*/ // system thread id 472 R14, 473 R15, 474 /*R16*/ // R16_thread 475 R17, 476 R18, 477 R19, 478 R20, 479 R21, 480 R22, 481 R23, 482 R24, 483 R25, 484 R26, 485 R27, 486 R28, 487 /*R29,*/ 488 R30, 489 R31 490 ); 491 492 reg_class rscratch1_bits32_reg(R11); 493 reg_class rscratch2_bits32_reg(R12); 494 reg_class rarg1_bits32_reg(R3); 495 reg_class rarg2_bits32_reg(R4); 496 reg_class rarg3_bits32_reg(R5); 497 reg_class rarg4_bits32_reg(R6); 498 499 // ---------------------------- 500 // 64 Bit Register Classes 501 // ---------------------------- 502 // 64-bit build means 64-bit pointers means hi/lo pairs 503 504 reg_class rscratch1_bits64_reg(R11_H, R11); 505 reg_class rscratch2_bits64_reg(R12_H, R12); 506 reg_class rarg1_bits64_reg(R3_H, R3); 507 reg_class rarg2_bits64_reg(R4_H, R4); 508 reg_class rarg3_bits64_reg(R5_H, R5); 509 reg_class rarg4_bits64_reg(R6_H, R6); 510 // Thread register, 'written' by tlsLoadP, see there. 511 reg_class thread_bits64_reg(R16_H, R16); 512 513 reg_class r19_bits64_reg(R19_H, R19); 514 515 // 64 bit registers that can be read and written i.e. these registers 516 // can be dest (or src) of normal instructions. 517 reg_class bits64_reg_rw( 518 /*R0_H, R0*/ // R0 519 /*R1_H, R1*/ // SP 520 R2_H, R2, // TOC 521 R3_H, R3, 522 R4_H, R4, 523 R5_H, R5, 524 R6_H, R6, 525 R7_H, R7, 526 R8_H, R8, 527 R9_H, R9, 528 R10_H, R10, 529 R11_H, R11, 530 R12_H, R12, 531 /*R13_H, R13*/ // system thread id 532 R14_H, R14, 533 R15_H, R15, 534 /*R16_H, R16*/ // R16_thread 535 R17_H, R17, 536 R18_H, R18, 537 R19_H, R19, 538 R20_H, R20, 539 R21_H, R21, 540 R22_H, R22, 541 R23_H, R23, 542 R24_H, R24, 543 R25_H, R25, 544 R26_H, R26, 545 R27_H, R27, 546 R28_H, R28, 547 /*R29_H, R29,*/ 548 R30_H, R30, 549 R31_H, R31 550 ); 551 552 // 64 bit registers used excluding r2, r11 and r12 553 // Used to hold the TOC to avoid collisions with expanded LeafCall which uses 554 // r2, r11 and r12 internally. 555 reg_class bits64_reg_leaf_call( 556 /*R0_H, R0*/ // R0 557 /*R1_H, R1*/ // SP 558 /*R2_H, R2*/ // TOC 559 R3_H, R3, 560 R4_H, R4, 561 R5_H, R5, 562 R6_H, R6, 563 R7_H, R7, 564 R8_H, R8, 565 R9_H, R9, 566 R10_H, R10, 567 /*R11_H, R11*/ 568 /*R12_H, R12*/ 569 /*R13_H, R13*/ // system thread id 570 R14_H, R14, 571 R15_H, R15, 572 /*R16_H, R16*/ // R16_thread 573 R17_H, R17, 574 R18_H, R18, 575 R19_H, R19, 576 R20_H, R20, 577 R21_H, R21, 578 R22_H, R22, 579 R23_H, R23, 580 R24_H, R24, 581 R25_H, R25, 582 R26_H, R26, 583 R27_H, R27, 584 R28_H, R28, 585 /*R29_H, R29,*/ 586 R30_H, R30, 587 R31_H, R31 588 ); 589 590 // Used to hold the TOC to avoid collisions with expanded DynamicCall 591 // which uses r19 as inline cache internally and expanded LeafCall which uses 592 // r2, r11 and r12 internally. 593 reg_class bits64_constant_table_base( 594 /*R0_H, R0*/ // R0 595 /*R1_H, R1*/ // SP 596 /*R2_H, R2*/ // TOC 597 R3_H, R3, 598 R4_H, R4, 599 R5_H, R5, 600 R6_H, R6, 601 R7_H, R7, 602 R8_H, R8, 603 R9_H, R9, 604 R10_H, R10, 605 /*R11_H, R11*/ 606 /*R12_H, R12*/ 607 /*R13_H, R13*/ // system thread id 608 R14_H, R14, 609 R15_H, R15, 610 /*R16_H, R16*/ // R16_thread 611 R17_H, R17, 612 R18_H, R18, 613 /*R19_H, R19*/ 614 R20_H, R20, 615 R21_H, R21, 616 R22_H, R22, 617 R23_H, R23, 618 R24_H, R24, 619 R25_H, R25, 620 R26_H, R26, 621 R27_H, R27, 622 R28_H, R28, 623 /*R29_H, R29,*/ 624 R30_H, R30, 625 R31_H, R31 626 ); 627 628 // 64 bit registers that can only be read i.e. these registers can 629 // only be src of all instructions. 630 reg_class bits64_reg_ro( 631 /*R0_H, R0*/ // R0 632 R1_H, R1, 633 R2_H, R2, // TOC 634 R3_H, R3, 635 R4_H, R4, 636 R5_H, R5, 637 R6_H, R6, 638 R7_H, R7, 639 R8_H, R8, 640 R9_H, R9, 641 R10_H, R10, 642 R11_H, R11, 643 R12_H, R12, 644 /*R13_H, R13*/ // system thread id 645 R14_H, R14, 646 R15_H, R15, 647 R16_H, R16, // R16_thread 648 R17_H, R17, 649 R18_H, R18, 650 R19_H, R19, 651 R20_H, R20, 652 R21_H, R21, 653 R22_H, R22, 654 R23_H, R23, 655 R24_H, R24, 656 R25_H, R25, 657 R26_H, R26, 658 R27_H, R27, 659 R28_H, R28, 660 /*R29_H, R29,*/ // TODO: let allocator handle TOC!! 661 R30_H, R30, 662 R31_H, R31 663 ); 664 665 666 // ---------------------------- 667 // Special Class for Condition Code Flags Register 668 669 reg_class int_flags( 670 /*CCR0*/ // scratch 671 /*CCR1*/ // scratch 672 /*CCR2*/ // nv! 673 /*CCR3*/ // nv! 674 /*CCR4*/ // nv! 675 CCR5, 676 CCR6, 677 CCR7 678 ); 679 680 reg_class int_flags_ro( 681 CCR0, 682 CCR1, 683 CCR2, 684 CCR3, 685 CCR4, 686 CCR5, 687 CCR6, 688 CCR7 689 ); 690 691 reg_class int_flags_CR0(CCR0); 692 reg_class int_flags_CR1(CCR1); 693 reg_class int_flags_CR6(CCR6); 694 reg_class ctr_reg(SR_CTR); 695 696 // ---------------------------- 697 // Float Register Classes 698 // ---------------------------- 699 700 reg_class flt_reg( 701 F0, 702 F1, 703 F2, 704 F3, 705 F4, 706 F5, 707 F6, 708 F7, 709 F8, 710 F9, 711 F10, 712 F11, 713 F12, 714 F13, 715 F14, // nv! 716 F15, // nv! 717 F16, // nv! 718 F17, // nv! 719 F18, // nv! 720 F19, // nv! 721 F20, // nv! 722 F21, // nv! 723 F22, // nv! 724 F23, // nv! 725 F24, // nv! 726 F25, // nv! 727 F26, // nv! 728 F27, // nv! 729 F28, // nv! 730 F29, // nv! 731 F30, // nv! 732 F31 // nv! 733 ); 734 735 // Double precision float registers have virtual `high halves' that 736 // are needed by the allocator. 737 reg_class dbl_reg( 738 F0, F0_H, 739 F1, F1_H, 740 F2, F2_H, 741 F3, F3_H, 742 F4, F4_H, 743 F5, F5_H, 744 F6, F6_H, 745 F7, F7_H, 746 F8, F8_H, 747 F9, F9_H, 748 F10, F10_H, 749 F11, F11_H, 750 F12, F12_H, 751 F13, F13_H, 752 F14, F14_H, // nv! 753 F15, F15_H, // nv! 754 F16, F16_H, // nv! 755 F17, F17_H, // nv! 756 F18, F18_H, // nv! 757 F19, F19_H, // nv! 758 F20, F20_H, // nv! 759 F21, F21_H, // nv! 760 F22, F22_H, // nv! 761 F23, F23_H, // nv! 762 F24, F24_H, // nv! 763 F25, F25_H, // nv! 764 F26, F26_H, // nv! 765 F27, F27_H, // nv! 766 F28, F28_H, // nv! 767 F29, F29_H, // nv! 768 F30, F30_H, // nv! 769 F31, F31_H // nv! 770 ); 771 772 %} 773 774 //----------DEFINITION BLOCK--------------------------------------------------- 775 // Define name --> value mappings to inform the ADLC of an integer valued name 776 // Current support includes integer values in the range [0, 0x7FFFFFFF] 777 // Format: 778 // int_def <name> ( <int_value>, <expression>); 779 // Generated Code in ad_<arch>.hpp 780 // #define <name> (<expression>) 781 // // value == <int_value> 782 // Generated code in ad_<arch>.cpp adlc_verification() 783 // assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>"); 784 // 785 definitions %{ 786 // The default cost (of an ALU instruction). 787 int_def DEFAULT_COST_LOW ( 30, 30); 788 int_def DEFAULT_COST ( 100, 100); 789 int_def HUGE_COST (1000000, 1000000); 790 791 // Memory refs 792 int_def MEMORY_REF_COST_LOW ( 200, DEFAULT_COST * 2); 793 int_def MEMORY_REF_COST ( 300, DEFAULT_COST * 3); 794 795 // Branches are even more expensive. 796 int_def BRANCH_COST ( 900, DEFAULT_COST * 9); 797 int_def CALL_COST ( 1300, DEFAULT_COST * 13); 798 %} 799 800 801 //----------SOURCE BLOCK------------------------------------------------------- 802 // This is a block of C++ code which provides values, functions, and 803 // definitions necessary in the rest of the architecture description. 804 source_hpp %{ 805 // Header information of the source block. 806 // Method declarations/definitions which are used outside 807 // the ad-scope can conveniently be defined here. 808 // 809 // To keep related declarations/definitions/uses close together, 810 // we switch between source %{ }% and source_hpp %{ }% freely as needed. 811 812 // Returns true if Node n is followed by a MemBar node that 813 // will do an acquire. If so, this node must not do the acquire 814 // operation. 815 bool followed_by_acquire(const Node *n); 816 %} 817 818 source %{ 819 820 // Should the Matcher clone shifts on addressing modes, expecting them 821 // to be subsumed into complex addressing expressions or compute them 822 // into registers? 823 bool Matcher::clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { 824 return clone_base_plus_offset_address(m, mstack, address_visited); 825 } 826 827 void Compile::reshape_address(AddPNode* addp) { 828 } 829 830 // Optimize load-acquire. 831 // 832 // Check if acquire is unnecessary due to following operation that does 833 // acquire anyways. 834 // Walk the pattern: 835 // 836 // n: Load.acq 837 // | 838 // MemBarAcquire 839 // | | 840 // Proj(ctrl) Proj(mem) 841 // | | 842 // MemBarRelease/Volatile 843 // 844 bool followed_by_acquire(const Node *load) { 845 assert(load->is_Load(), "So far implemented only for loads."); 846 847 // Find MemBarAcquire. 848 const Node *mba = NULL; 849 for (DUIterator_Fast imax, i = load->fast_outs(imax); i < imax; i++) { 850 const Node *out = load->fast_out(i); 851 if (out->Opcode() == Op_MemBarAcquire) { 852 if (out->in(0) == load) continue; // Skip control edge, membar should be found via precedence edge. 853 mba = out; 854 break; 855 } 856 } 857 if (!mba) return false; 858 859 // Find following MemBar node. 860 // 861 // The following node must be reachable by control AND memory 862 // edge to assure no other operations are in between the two nodes. 863 // 864 // So first get the Proj node, mem_proj, to use it to iterate forward. 865 Node *mem_proj = NULL; 866 for (DUIterator_Fast imax, i = mba->fast_outs(imax); i < imax; i++) { 867 mem_proj = mba->fast_out(i); // Throw out-of-bounds if proj not found 868 assert(mem_proj->is_Proj(), "only projections here"); 869 ProjNode *proj = mem_proj->as_Proj(); 870 if (proj->_con == TypeFunc::Memory && 871 !Compile::current()->node_arena()->contains(mem_proj)) // Unmatched old-space only 872 break; 873 } 874 assert(mem_proj->as_Proj()->_con == TypeFunc::Memory, "Graph broken"); 875 876 // Search MemBar behind Proj. If there are other memory operations 877 // behind the Proj we lost. 878 for (DUIterator_Fast jmax, j = mem_proj->fast_outs(jmax); j < jmax; j++) { 879 Node *x = mem_proj->fast_out(j); 880 // Proj might have an edge to a store or load node which precedes the membar. 881 if (x->is_Mem()) return false; 882 883 // On PPC64 release and volatile are implemented by an instruction 884 // that also has acquire semantics. I.e. there is no need for an 885 // acquire before these. 886 int xop = x->Opcode(); 887 if (xop == Op_MemBarRelease || xop == Op_MemBarVolatile) { 888 // Make sure we're not missing Call/Phi/MergeMem by checking 889 // control edges. The control edge must directly lead back 890 // to the MemBarAcquire 891 Node *ctrl_proj = x->in(0); 892 if (ctrl_proj->is_Proj() && ctrl_proj->in(0) == mba) { 893 return true; 894 } 895 } 896 } 897 898 return false; 899 } 900 901 #define __ _masm. 902 903 // Tertiary op of a LoadP or StoreP encoding. 904 #define REGP_OP true 905 906 // **************************************************************************** 907 908 // REQUIRED FUNCTIONALITY 909 910 // !!!!! Special hack to get all type of calls to specify the byte offset 911 // from the start of the call to the point where the return address 912 // will point. 913 914 // PPC port: Removed use of lazy constant construct. 915 916 int MachCallStaticJavaNode::ret_addr_offset() { 917 // It's only a single branch-and-link instruction. 918 return 4; 919 } 920 921 int MachCallDynamicJavaNode::ret_addr_offset() { 922 // Offset is 4 with postalloc expanded calls (bl is one instruction). We use 923 // postalloc expanded calls if we use inline caches and do not update method data. 924 if (UseInlineCaches) 925 return 4; 926 927 int vtable_index = this->_vtable_index; 928 if (vtable_index < 0) { 929 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 930 assert(vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 931 return 12; 932 } else { 933 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 934 return 24; 935 } 936 } 937 938 int MachCallRuntimeNode::ret_addr_offset() { 939 #if defined(ABI_ELFv2) 940 return 28; 941 #else 942 return 40; 943 #endif 944 } 945 946 //============================================================================= 947 948 // condition code conversions 949 950 static int cc_to_boint(int cc) { 951 return Assembler::bcondCRbiIs0 | (cc & 8); 952 } 953 954 static int cc_to_inverse_boint(int cc) { 955 return Assembler::bcondCRbiIs0 | (8-(cc & 8)); 956 } 957 958 static int cc_to_biint(int cc, int flags_reg) { 959 return (flags_reg << 2) | (cc & 3); 960 } 961 962 //============================================================================= 963 964 // Compute padding required for nodes which need alignment. The padding 965 // is the number of bytes (not instructions) which will be inserted before 966 // the instruction. The padding must match the size of a NOP instruction. 967 968 // Currently not used on this platform. 969 970 //============================================================================= 971 972 // Indicate if the safepoint node needs the polling page as an input. 973 bool SafePointNode::needs_polling_address_input() { 974 // The address is loaded from thread by a seperate node. 975 return true; 976 } 977 978 //============================================================================= 979 980 // Emit an interrupt that is caught by the debugger (for debugging compiler). 981 void emit_break(CodeBuffer &cbuf) { 982 MacroAssembler _masm(&cbuf); 983 __ illtrap(); 984 } 985 986 #ifndef PRODUCT 987 void MachBreakpointNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 988 st->print("BREAKPOINT"); 989 } 990 #endif 991 992 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 993 emit_break(cbuf); 994 } 995 996 uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const { 997 return MachNode::size(ra_); 998 } 999 1000 //============================================================================= 1001 1002 void emit_nop(CodeBuffer &cbuf) { 1003 MacroAssembler _masm(&cbuf); 1004 __ nop(); 1005 } 1006 1007 static inline void emit_long(CodeBuffer &cbuf, int value) { 1008 *((int*)(cbuf.insts_end())) = value; 1009 cbuf.set_insts_end(cbuf.insts_end() + BytesPerInstWord); 1010 } 1011 1012 //============================================================================= 1013 1014 %} // interrupt source 1015 1016 source_hpp %{ // Header information of the source block. 1017 1018 //-------------------------------------------------------------- 1019 //---< Used for optimization in Compile::Shorten_branches >--- 1020 //-------------------------------------------------------------- 1021 1022 class CallStubImpl { 1023 1024 public: 1025 1026 // Emit call stub, compiled java to interpreter. 1027 static void emit_trampoline_stub(MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset); 1028 1029 // Size of call trampoline stub. 1030 // This doesn't need to be accurate to the byte, but it 1031 // must be larger than or equal to the real size of the stub. 1032 static uint size_call_trampoline() { 1033 return MacroAssembler::trampoline_stub_size; 1034 } 1035 1036 // number of relocations needed by a call trampoline stub 1037 static uint reloc_call_trampoline() { 1038 return 5; 1039 } 1040 1041 }; 1042 1043 %} // end source_hpp 1044 1045 source %{ 1046 1047 // Emit a trampoline stub for a call to a target which is too far away. 1048 // 1049 // code sequences: 1050 // 1051 // call-site: 1052 // branch-and-link to <destination> or <trampoline stub> 1053 // 1054 // Related trampoline stub for this call-site in the stub section: 1055 // load the call target from the constant pool 1056 // branch via CTR (LR/link still points to the call-site above) 1057 1058 void CallStubImpl::emit_trampoline_stub(MacroAssembler &_masm, int destination_toc_offset, int insts_call_instruction_offset) { 1059 address stub = __ emit_trampoline_stub(destination_toc_offset, insts_call_instruction_offset); 1060 if (stub == NULL) { 1061 ciEnv::current()->record_out_of_memory_failure(); 1062 } 1063 } 1064 1065 //============================================================================= 1066 1067 // Emit an inline branch-and-link call and a related trampoline stub. 1068 // 1069 // code sequences: 1070 // 1071 // call-site: 1072 // branch-and-link to <destination> or <trampoline stub> 1073 // 1074 // Related trampoline stub for this call-site in the stub section: 1075 // load the call target from the constant pool 1076 // branch via CTR (LR/link still points to the call-site above) 1077 // 1078 1079 typedef struct { 1080 int insts_call_instruction_offset; 1081 int ret_addr_offset; 1082 } EmitCallOffsets; 1083 1084 // Emit a branch-and-link instruction that branches to a trampoline. 1085 // - Remember the offset of the branch-and-link instruction. 1086 // - Add a relocation at the branch-and-link instruction. 1087 // - Emit a branch-and-link. 1088 // - Remember the return pc offset. 1089 EmitCallOffsets emit_call_with_trampoline_stub(MacroAssembler &_masm, address entry_point, relocInfo::relocType rtype) { 1090 EmitCallOffsets offsets = { -1, -1 }; 1091 const int start_offset = __ offset(); 1092 offsets.insts_call_instruction_offset = __ offset(); 1093 1094 // No entry point given, use the current pc. 1095 if (entry_point == NULL) entry_point = __ pc(); 1096 1097 // Put the entry point as a constant into the constant pool. 1098 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 1099 if (entry_point_toc_addr == NULL) { 1100 ciEnv::current()->record_out_of_memory_failure(); 1101 return offsets; 1102 } 1103 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 1104 1105 // Emit the trampoline stub which will be related to the branch-and-link below. 1106 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, offsets.insts_call_instruction_offset); 1107 if (ciEnv::current()->failing()) { return offsets; } // Code cache may be full. 1108 __ relocate(rtype); 1109 1110 // Note: At this point we do not have the address of the trampoline 1111 // stub, and the entry point might be too far away for bl, so __ pc() 1112 // serves as dummy and the bl will be patched later. 1113 __ bl((address) __ pc()); 1114 1115 offsets.ret_addr_offset = __ offset() - start_offset; 1116 1117 return offsets; 1118 } 1119 1120 //============================================================================= 1121 1122 // Factory for creating loadConL* nodes for large/small constant pool. 1123 1124 static inline jlong replicate_immF(float con) { 1125 // Replicate float con 2 times and pack into vector. 1126 int val = *((int*)&con); 1127 jlong lval = val; 1128 lval = (lval << 32) | (lval & 0xFFFFFFFFl); 1129 return lval; 1130 } 1131 1132 //============================================================================= 1133 1134 const RegMask& MachConstantBaseNode::_out_RegMask = BITS64_CONSTANT_TABLE_BASE_mask(); 1135 int Compile::ConstantTable::calculate_table_base_offset() const { 1136 return 0; // absolute addressing, no offset 1137 } 1138 1139 bool MachConstantBaseNode::requires_postalloc_expand() const { return true; } 1140 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 1141 iRegPdstOper *op_dst = new iRegPdstOper(); 1142 MachNode *m1 = new loadToc_hiNode(); 1143 MachNode *m2 = new loadToc_loNode(); 1144 1145 m1->add_req(NULL); 1146 m2->add_req(NULL, m1); 1147 m1->_opnds[0] = op_dst; 1148 m2->_opnds[0] = op_dst; 1149 m2->_opnds[1] = op_dst; 1150 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 1151 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 1152 nodes->push(m1); 1153 nodes->push(m2); 1154 } 1155 1156 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1157 // Is postalloc expanded. 1158 ShouldNotReachHere(); 1159 } 1160 1161 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 1162 return 0; 1163 } 1164 1165 #ifndef PRODUCT 1166 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1167 st->print("-- \t// MachConstantBaseNode (empty encoding)"); 1168 } 1169 #endif 1170 1171 //============================================================================= 1172 1173 #ifndef PRODUCT 1174 void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1175 Compile* C = ra_->C; 1176 const long framesize = C->frame_slots() << LogBytesPerInt; 1177 1178 st->print("PROLOG\n\t"); 1179 if (C->need_stack_bang(framesize)) { 1180 st->print("stack_overflow_check\n\t"); 1181 } 1182 1183 if (!false /* TODO: PPC port C->is_frameless_method()*/) { 1184 st->print("save return pc\n\t"); 1185 st->print("push frame %ld\n\t", -framesize); 1186 } 1187 } 1188 #endif 1189 1190 // Macro used instead of the common __ to emulate the pipes of PPC. 1191 // Instead of e.g. __ ld(...) one hase to write ___(ld) ld(...) This enables the 1192 // micro scheduler to cope with "hand written" assembler like in the prolog. Though 1193 // still no scheduling of this code is possible, the micro scheduler is aware of the 1194 // code and can update its internal data. The following mechanism is used to achieve this: 1195 // The micro scheduler calls size() of each compound node during scheduling. size() does a 1196 // dummy emit and only during this dummy emit C->hb_scheduling() is not NULL. 1197 #if 0 // TODO: PPC port 1198 #define ___(op) if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1199 C->hb_scheduling()->_pdScheduling->PdEmulatePipe(ppc64Opcode_##op); \ 1200 _masm. 1201 #define ___stop if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1202 C->hb_scheduling()->_pdScheduling->PdEmulatePipe(archOpcode_none) 1203 #define ___advance if (UsePower6SchedulerPPC64 && C->hb_scheduling()) \ 1204 C->hb_scheduling()->_pdScheduling->advance_offset 1205 #else 1206 #define ___(op) if (UsePower6SchedulerPPC64) \ 1207 Unimplemented(); \ 1208 _masm. 1209 #define ___stop if (UsePower6SchedulerPPC64) \ 1210 Unimplemented() 1211 #define ___advance if (UsePower6SchedulerPPC64) \ 1212 Unimplemented() 1213 #endif 1214 1215 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1216 Compile* C = ra_->C; 1217 MacroAssembler _masm(&cbuf); 1218 1219 const long framesize = C->frame_size_in_bytes(); 1220 assert(framesize % (2 * wordSize) == 0, "must preserve 2*wordSize alignment"); 1221 1222 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; 1223 1224 const Register return_pc = R20; // Must match return_addr() in frame section. 1225 const Register callers_sp = R21; 1226 const Register push_frame_temp = R22; 1227 const Register toc_temp = R23; 1228 assert_different_registers(R11, return_pc, callers_sp, push_frame_temp, toc_temp); 1229 1230 if (method_is_frameless) { 1231 // Add nop at beginning of all frameless methods to prevent any 1232 // oop instructions from getting overwritten by make_not_entrant 1233 // (patching attempt would fail). 1234 ___(nop) nop(); 1235 } else { 1236 // Get return pc. 1237 ___(mflr) mflr(return_pc); 1238 } 1239 1240 // Calls to C2R adapters often do not accept exceptional returns. 1241 // We require that their callers must bang for them. But be 1242 // careful, because some VM calls (such as call site linkage) can 1243 // use several kilobytes of stack. But the stack safety zone should 1244 // account for that. See bugs 4446381, 4468289, 4497237. 1245 1246 int bangsize = C->bang_size_in_bytes(); 1247 assert(bangsize >= framesize || bangsize <= 0, "stack bang size incorrect"); 1248 if (C->need_stack_bang(bangsize) && UseStackBanging) { 1249 // Unfortunately we cannot use the function provided in 1250 // assembler.cpp as we have to emulate the pipes. So I had to 1251 // insert the code of generate_stack_overflow_check(), see 1252 // assembler.cpp for some illuminative comments. 1253 const int page_size = os::vm_page_size(); 1254 int bang_end = JavaThread::stack_shadow_zone_size(); 1255 1256 // This is how far the previous frame's stack banging extended. 1257 const int bang_end_safe = bang_end; 1258 1259 if (bangsize > page_size) { 1260 bang_end += bangsize; 1261 } 1262 1263 int bang_offset = bang_end_safe; 1264 1265 while (bang_offset <= bang_end) { 1266 // Need at least one stack bang at end of shadow zone. 1267 1268 // Again I had to copy code, this time from assembler_ppc.cpp, 1269 // bang_stack_with_offset - see there for comments. 1270 1271 // Stack grows down, caller passes positive offset. 1272 assert(bang_offset > 0, "must bang with positive offset"); 1273 1274 long stdoffset = -bang_offset; 1275 1276 if (Assembler::is_simm(stdoffset, 16)) { 1277 // Signed 16 bit offset, a simple std is ok. 1278 if (UseLoadInstructionsForStackBangingPPC64) { 1279 ___(ld) ld(R0, (int)(signed short)stdoffset, R1_SP); 1280 } else { 1281 ___(std) std(R0, (int)(signed short)stdoffset, R1_SP); 1282 } 1283 } else if (Assembler::is_simm(stdoffset, 31)) { 1284 // Use largeoffset calculations for addis & ld/std. 1285 const int hi = MacroAssembler::largeoffset_si16_si16_hi(stdoffset); 1286 const int lo = MacroAssembler::largeoffset_si16_si16_lo(stdoffset); 1287 1288 Register tmp = R11; 1289 ___(addis) addis(tmp, R1_SP, hi); 1290 if (UseLoadInstructionsForStackBangingPPC64) { 1291 ___(ld) ld(R0, lo, tmp); 1292 } else { 1293 ___(std) std(R0, lo, tmp); 1294 } 1295 } else { 1296 ShouldNotReachHere(); 1297 } 1298 1299 bang_offset += page_size; 1300 } 1301 // R11 trashed 1302 } // C->need_stack_bang(framesize) && UseStackBanging 1303 1304 unsigned int bytes = (unsigned int)framesize; 1305 long offset = Assembler::align_addr(bytes, frame::alignment_in_bytes); 1306 ciMethod *currMethod = C->method(); 1307 1308 // Optimized version for most common case. 1309 if (UsePower6SchedulerPPC64 && 1310 !method_is_frameless && Assembler::is_simm((int)(-offset), 16) && 1311 !(false /* ConstantsALot TODO: PPC port*/)) { 1312 ___(or) mr(callers_sp, R1_SP); 1313 ___(std) std(return_pc, _abi(lr), R1_SP); 1314 ___(stdu) stdu(R1_SP, -offset, R1_SP); 1315 return; 1316 } 1317 1318 if (!method_is_frameless) { 1319 // Get callers sp. 1320 ___(or) mr(callers_sp, R1_SP); 1321 1322 // Push method's frame, modifies SP. 1323 assert(Assembler::is_uimm(framesize, 32U), "wrong type"); 1324 // The ABI is already accounted for in 'framesize' via the 1325 // 'out_preserve' area. 1326 Register tmp = push_frame_temp; 1327 // Had to insert code of push_frame((unsigned int)framesize, push_frame_temp). 1328 if (Assembler::is_simm(-offset, 16)) { 1329 ___(stdu) stdu(R1_SP, -offset, R1_SP); 1330 } else { 1331 long x = -offset; 1332 // Had to insert load_const(tmp, -offset). 1333 ___(addis) lis( tmp, (int)((signed short)(((x >> 32) & 0xffff0000) >> 16))); 1334 ___(ori) ori( tmp, tmp, ((x >> 32) & 0x0000ffff)); 1335 ___(rldicr) sldi(tmp, tmp, 32); 1336 ___(oris) oris(tmp, tmp, (x & 0xffff0000) >> 16); 1337 ___(ori) ori( tmp, tmp, (x & 0x0000ffff)); 1338 1339 ___(stdux) stdux(R1_SP, R1_SP, tmp); 1340 } 1341 } 1342 #if 0 // TODO: PPC port 1343 // For testing large constant pools, emit a lot of constants to constant pool. 1344 // "Randomize" const_size. 1345 if (ConstantsALot) { 1346 const int num_consts = const_size(); 1347 for (int i = 0; i < num_consts; i++) { 1348 __ long_constant(0xB0B5B00BBABE); 1349 } 1350 } 1351 #endif 1352 if (!method_is_frameless) { 1353 // Save return pc. 1354 ___(std) std(return_pc, _abi(lr), callers_sp); 1355 } 1356 1357 C->set_frame_complete(cbuf.insts_size()); 1358 } 1359 #undef ___ 1360 #undef ___stop 1361 #undef ___advance 1362 1363 uint MachPrologNode::size(PhaseRegAlloc *ra_) const { 1364 // Variable size. determine dynamically. 1365 return MachNode::size(ra_); 1366 } 1367 1368 int MachPrologNode::reloc() const { 1369 // Return number of relocatable values contained in this instruction. 1370 return 1; // 1 reloc entry for load_const(toc). 1371 } 1372 1373 //============================================================================= 1374 1375 #ifndef PRODUCT 1376 void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1377 Compile* C = ra_->C; 1378 1379 st->print("EPILOG\n\t"); 1380 st->print("restore return pc\n\t"); 1381 st->print("pop frame\n\t"); 1382 1383 if (do_polling() && C->is_method_compilation()) { 1384 st->print("touch polling page\n\t"); 1385 } 1386 } 1387 #endif 1388 1389 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1390 Compile* C = ra_->C; 1391 MacroAssembler _masm(&cbuf); 1392 1393 const long framesize = ((long)C->frame_slots()) << LogBytesPerInt; 1394 assert(framesize >= 0, "negative frame-size?"); 1395 1396 const bool method_needs_polling = do_polling() && C->is_method_compilation(); 1397 const bool method_is_frameless = false /* TODO: PPC port C->is_frameless_method()*/; 1398 const Register return_pc = R31; // Must survive C-call to enable_stack_reserved_zone(). 1399 const Register polling_page = R12; 1400 1401 if (!method_is_frameless) { 1402 // Restore return pc relative to callers' sp. 1403 __ ld(return_pc, ((int)framesize) + _abi(lr), R1_SP); 1404 } 1405 1406 if (method_needs_polling) { 1407 if (LoadPollAddressFromThread) { 1408 // TODO: PPC port __ ld(polling_page, in_bytes(JavaThread::poll_address_offset()), R16_thread); 1409 Unimplemented(); 1410 } else { 1411 __ load_const_optimized(polling_page, (long)(address) os::get_polling_page()); // TODO: PPC port: get_standard_polling_page() 1412 } 1413 } 1414 1415 if (!method_is_frameless) { 1416 // Move return pc to LR. 1417 __ mtlr(return_pc); 1418 // Pop frame (fixed frame-size). 1419 __ addi(R1_SP, R1_SP, (int)framesize); 1420 } 1421 1422 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1423 __ reserved_stack_check(return_pc); 1424 } 1425 1426 if (method_needs_polling) { 1427 // We need to mark the code position where the load from the safepoint 1428 // polling page was emitted as relocInfo::poll_return_type here. 1429 __ relocate(relocInfo::poll_return_type); 1430 __ load_from_polling_page(polling_page); 1431 } 1432 } 1433 1434 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 1435 // Variable size. Determine dynamically. 1436 return MachNode::size(ra_); 1437 } 1438 1439 int MachEpilogNode::reloc() const { 1440 // Return number of relocatable values contained in this instruction. 1441 return 1; // 1 for load_from_polling_page. 1442 } 1443 1444 const Pipeline * MachEpilogNode::pipeline() const { 1445 return MachNode::pipeline_class(); 1446 } 1447 1448 // This method seems to be obsolete. It is declared in machnode.hpp 1449 // and defined in all *.ad files, but it is never called. Should we 1450 // get rid of it? 1451 int MachEpilogNode::safepoint_offset() const { 1452 assert(do_polling(), "no return for this epilog node"); 1453 return 0; 1454 } 1455 1456 #if 0 // TODO: PPC port 1457 void MachLoadPollAddrLateNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 1458 MacroAssembler _masm(&cbuf); 1459 if (LoadPollAddressFromThread) { 1460 _masm.ld(R11, in_bytes(JavaThread::poll_address_offset()), R16_thread); 1461 } else { 1462 _masm.nop(); 1463 } 1464 } 1465 1466 uint MachLoadPollAddrLateNode::size(PhaseRegAlloc* ra_) const { 1467 if (LoadPollAddressFromThread) { 1468 return 4; 1469 } else { 1470 return 4; 1471 } 1472 } 1473 1474 #ifndef PRODUCT 1475 void MachLoadPollAddrLateNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 1476 st->print_cr(" LD R11, PollAddressOffset, R16_thread \t// LoadPollAddressFromThread"); 1477 } 1478 #endif 1479 1480 const RegMask &MachLoadPollAddrLateNode::out_RegMask() const { 1481 return RSCRATCH1_BITS64_REG_mask(); 1482 } 1483 #endif // PPC port 1484 1485 // ============================================================================= 1486 1487 // Figure out which register class each belongs in: rc_int, rc_float or 1488 // rc_stack. 1489 enum RC { rc_bad, rc_int, rc_float, rc_stack }; 1490 1491 static enum RC rc_class(OptoReg::Name reg) { 1492 // Return the register class for the given register. The given register 1493 // reg is a <register>_num value, which is an index into the MachRegisterNumbers 1494 // enumeration in adGlobals_ppc.hpp. 1495 1496 if (reg == OptoReg::Bad) return rc_bad; 1497 1498 // We have 64 integer register halves, starting at index 0. 1499 if (reg < 64) return rc_int; 1500 1501 // We have 64 floating-point register halves, starting at index 64. 1502 if (reg < 64+64) return rc_float; 1503 1504 // Between float regs & stack are the flags regs. 1505 assert(OptoReg::is_stack(reg), "blow up if spilling flags"); 1506 1507 return rc_stack; 1508 } 1509 1510 static int ld_st_helper(CodeBuffer *cbuf, const char *op_str, uint opcode, int reg, int offset, 1511 bool do_print, Compile* C, outputStream *st) { 1512 1513 assert(opcode == Assembler::LD_OPCODE || 1514 opcode == Assembler::STD_OPCODE || 1515 opcode == Assembler::LWZ_OPCODE || 1516 opcode == Assembler::STW_OPCODE || 1517 opcode == Assembler::LFD_OPCODE || 1518 opcode == Assembler::STFD_OPCODE || 1519 opcode == Assembler::LFS_OPCODE || 1520 opcode == Assembler::STFS_OPCODE, 1521 "opcode not supported"); 1522 1523 if (cbuf) { 1524 int d = 1525 (Assembler::LD_OPCODE == opcode || Assembler::STD_OPCODE == opcode) ? 1526 Assembler::ds(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/) 1527 : Assembler::d1(offset+0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); // Makes no difference in opt build. 1528 emit_long(*cbuf, opcode | Assembler::rt(Matcher::_regEncode[reg]) | d | Assembler::ra(R1_SP)); 1529 } 1530 #ifndef PRODUCT 1531 else if (do_print) { 1532 st->print("%-7s %s, [R1_SP + #%d+%d] \t// spill copy", 1533 op_str, 1534 Matcher::regName[reg], 1535 offset, 0 /* TODO: PPC port C->frame_slots_sp_bias_in_bytes()*/); 1536 } 1537 #endif 1538 return 4; // size 1539 } 1540 1541 uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream *st) const { 1542 Compile* C = ra_->C; 1543 1544 // Get registers to move. 1545 OptoReg::Name src_hi = ra_->get_reg_second(in(1)); 1546 OptoReg::Name src_lo = ra_->get_reg_first(in(1)); 1547 OptoReg::Name dst_hi = ra_->get_reg_second(this); 1548 OptoReg::Name dst_lo = ra_->get_reg_first(this); 1549 1550 enum RC src_hi_rc = rc_class(src_hi); 1551 enum RC src_lo_rc = rc_class(src_lo); 1552 enum RC dst_hi_rc = rc_class(dst_hi); 1553 enum RC dst_lo_rc = rc_class(dst_lo); 1554 1555 assert(src_lo != OptoReg::Bad && dst_lo != OptoReg::Bad, "must move at least 1 register"); 1556 if (src_hi != OptoReg::Bad) 1557 assert((src_lo&1)==0 && src_lo+1==src_hi && 1558 (dst_lo&1)==0 && dst_lo+1==dst_hi, 1559 "expected aligned-adjacent pairs"); 1560 // Generate spill code! 1561 int size = 0; 1562 1563 if (src_lo == dst_lo && src_hi == dst_hi) 1564 return size; // Self copy, no move. 1565 1566 // -------------------------------------- 1567 // Memory->Memory Spill. Use R0 to hold the value. 1568 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1569 int src_offset = ra_->reg2offset(src_lo); 1570 int dst_offset = ra_->reg2offset(dst_lo); 1571 if (src_hi != OptoReg::Bad) { 1572 assert(src_hi_rc==rc_stack && dst_hi_rc==rc_stack, 1573 "expected same type of move for high parts"); 1574 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, R0_num, src_offset, !do_size, C, st); 1575 if (!cbuf && !do_size) st->print("\n\t"); 1576 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, R0_num, dst_offset, !do_size, C, st); 1577 } else { 1578 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, R0_num, src_offset, !do_size, C, st); 1579 if (!cbuf && !do_size) st->print("\n\t"); 1580 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, R0_num, dst_offset, !do_size, C, st); 1581 } 1582 return size; 1583 } 1584 1585 // -------------------------------------- 1586 // Check for float->int copy; requires a trip through memory. 1587 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) { 1588 Unimplemented(); 1589 } 1590 1591 // -------------------------------------- 1592 // Check for integer reg-reg copy. 1593 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) { 1594 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]); 1595 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]); 1596 size = (Rsrc != Rdst) ? 4 : 0; 1597 1598 if (cbuf) { 1599 MacroAssembler _masm(cbuf); 1600 if (size) { 1601 __ mr(Rdst, Rsrc); 1602 } 1603 } 1604 #ifndef PRODUCT 1605 else if (!do_size) { 1606 if (size) { 1607 st->print("%-7s %s, %s \t// spill copy", "MR", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1608 } else { 1609 st->print("%-7s %s, %s \t// spill copy", "MR-NOP", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1610 } 1611 } 1612 #endif 1613 return size; 1614 } 1615 1616 // Check for integer store. 1617 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) { 1618 int dst_offset = ra_->reg2offset(dst_lo); 1619 if (src_hi != OptoReg::Bad) { 1620 assert(src_hi_rc==rc_int && dst_hi_rc==rc_stack, 1621 "expected same type of move for high parts"); 1622 size += ld_st_helper(cbuf, "STD ", Assembler::STD_OPCODE, src_lo, dst_offset, !do_size, C, st); 1623 } else { 1624 size += ld_st_helper(cbuf, "STW ", Assembler::STW_OPCODE, src_lo, dst_offset, !do_size, C, st); 1625 } 1626 return size; 1627 } 1628 1629 // Check for integer load. 1630 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) { 1631 int src_offset = ra_->reg2offset(src_lo); 1632 if (src_hi != OptoReg::Bad) { 1633 assert(dst_hi_rc==rc_int && src_hi_rc==rc_stack, 1634 "expected same type of move for high parts"); 1635 size += ld_st_helper(cbuf, "LD ", Assembler::LD_OPCODE, dst_lo, src_offset, !do_size, C, st); 1636 } else { 1637 size += ld_st_helper(cbuf, "LWZ ", Assembler::LWZ_OPCODE, dst_lo, src_offset, !do_size, C, st); 1638 } 1639 return size; 1640 } 1641 1642 // Check for float reg-reg copy. 1643 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1644 if (cbuf) { 1645 MacroAssembler _masm(cbuf); 1646 FloatRegister Rsrc = as_FloatRegister(Matcher::_regEncode[src_lo]); 1647 FloatRegister Rdst = as_FloatRegister(Matcher::_regEncode[dst_lo]); 1648 __ fmr(Rdst, Rsrc); 1649 } 1650 #ifndef PRODUCT 1651 else if (!do_size) { 1652 st->print("%-7s %s, %s \t// spill copy", "FMR", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 1653 } 1654 #endif 1655 return 4; 1656 } 1657 1658 // Check for float store. 1659 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1660 int dst_offset = ra_->reg2offset(dst_lo); 1661 if (src_hi != OptoReg::Bad) { 1662 assert(src_hi_rc==rc_float && dst_hi_rc==rc_stack, 1663 "expected same type of move for high parts"); 1664 size += ld_st_helper(cbuf, "STFD", Assembler::STFD_OPCODE, src_lo, dst_offset, !do_size, C, st); 1665 } else { 1666 size += ld_st_helper(cbuf, "STFS", Assembler::STFS_OPCODE, src_lo, dst_offset, !do_size, C, st); 1667 } 1668 return size; 1669 } 1670 1671 // Check for float load. 1672 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) { 1673 int src_offset = ra_->reg2offset(src_lo); 1674 if (src_hi != OptoReg::Bad) { 1675 assert(dst_hi_rc==rc_float && src_hi_rc==rc_stack, 1676 "expected same type of move for high parts"); 1677 size += ld_st_helper(cbuf, "LFD ", Assembler::LFD_OPCODE, dst_lo, src_offset, !do_size, C, st); 1678 } else { 1679 size += ld_st_helper(cbuf, "LFS ", Assembler::LFS_OPCODE, dst_lo, src_offset, !do_size, C, st); 1680 } 1681 return size; 1682 } 1683 1684 // -------------------------------------------------------------------- 1685 // Check for hi bits still needing moving. Only happens for misaligned 1686 // arguments to native calls. 1687 if (src_hi == dst_hi) 1688 return size; // Self copy; no move. 1689 1690 assert(src_hi_rc != rc_bad && dst_hi_rc != rc_bad, "src_hi & dst_hi cannot be Bad"); 1691 ShouldNotReachHere(); // Unimplemented 1692 return 0; 1693 } 1694 1695 #ifndef PRODUCT 1696 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1697 if (!ra_) 1698 st->print("N%d = SpillCopy(N%d)", _idx, in(1)->_idx); 1699 else 1700 implementation(NULL, ra_, false, st); 1701 } 1702 #endif 1703 1704 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1705 implementation(&cbuf, ra_, false, NULL); 1706 } 1707 1708 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1709 return implementation(NULL, ra_, true, NULL); 1710 } 1711 1712 #if 0 // TODO: PPC port 1713 ArchOpcode MachSpillCopyNode_archOpcode(MachSpillCopyNode *n, PhaseRegAlloc *ra_) { 1714 #ifndef PRODUCT 1715 if (ra_->node_regs_max_index() == 0) return archOpcode_undefined; 1716 #endif 1717 assert(ra_->node_regs_max_index() != 0, ""); 1718 1719 // Get registers to move. 1720 OptoReg::Name src_hi = ra_->get_reg_second(n->in(1)); 1721 OptoReg::Name src_lo = ra_->get_reg_first(n->in(1)); 1722 OptoReg::Name dst_hi = ra_->get_reg_second(n); 1723 OptoReg::Name dst_lo = ra_->get_reg_first(n); 1724 1725 enum RC src_lo_rc = rc_class(src_lo); 1726 enum RC dst_lo_rc = rc_class(dst_lo); 1727 1728 if (src_lo == dst_lo && src_hi == dst_hi) 1729 return ppc64Opcode_none; // Self copy, no move. 1730 1731 // -------------------------------------- 1732 // Memory->Memory Spill. Use R0 to hold the value. 1733 if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { 1734 return ppc64Opcode_compound; 1735 } 1736 1737 // -------------------------------------- 1738 // Check for float->int copy; requires a trip through memory. 1739 if (src_lo_rc == rc_float && dst_lo_rc == rc_int) { 1740 Unimplemented(); 1741 } 1742 1743 // -------------------------------------- 1744 // Check for integer reg-reg copy. 1745 if (src_lo_rc == rc_int && dst_lo_rc == rc_int) { 1746 Register Rsrc = as_Register(Matcher::_regEncode[src_lo]); 1747 Register Rdst = as_Register(Matcher::_regEncode[dst_lo]); 1748 if (Rsrc == Rdst) { 1749 return ppc64Opcode_none; 1750 } else { 1751 return ppc64Opcode_or; 1752 } 1753 } 1754 1755 // Check for integer store. 1756 if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) { 1757 if (src_hi != OptoReg::Bad) { 1758 return ppc64Opcode_std; 1759 } else { 1760 return ppc64Opcode_stw; 1761 } 1762 } 1763 1764 // Check for integer load. 1765 if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) { 1766 if (src_hi != OptoReg::Bad) { 1767 return ppc64Opcode_ld; 1768 } else { 1769 return ppc64Opcode_lwz; 1770 } 1771 } 1772 1773 // Check for float reg-reg copy. 1774 if (src_lo_rc == rc_float && dst_lo_rc == rc_float) { 1775 return ppc64Opcode_fmr; 1776 } 1777 1778 // Check for float store. 1779 if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) { 1780 if (src_hi != OptoReg::Bad) { 1781 return ppc64Opcode_stfd; 1782 } else { 1783 return ppc64Opcode_stfs; 1784 } 1785 } 1786 1787 // Check for float load. 1788 if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) { 1789 if (src_hi != OptoReg::Bad) { 1790 return ppc64Opcode_lfd; 1791 } else { 1792 return ppc64Opcode_lfs; 1793 } 1794 } 1795 1796 // -------------------------------------------------------------------- 1797 // Check for hi bits still needing moving. Only happens for misaligned 1798 // arguments to native calls. 1799 if (src_hi == dst_hi) { 1800 return ppc64Opcode_none; // Self copy; no move. 1801 } 1802 1803 ShouldNotReachHere(); 1804 return ppc64Opcode_undefined; 1805 } 1806 #endif // PPC port 1807 1808 #ifndef PRODUCT 1809 void MachNopNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1810 st->print("NOP \t// %d nops to pad for loops.", _count); 1811 } 1812 #endif 1813 1814 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *) const { 1815 MacroAssembler _masm(&cbuf); 1816 // _count contains the number of nops needed for padding. 1817 for (int i = 0; i < _count; i++) { 1818 __ nop(); 1819 } 1820 } 1821 1822 uint MachNopNode::size(PhaseRegAlloc *ra_) const { 1823 return _count * 4; 1824 } 1825 1826 #ifndef PRODUCT 1827 void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1828 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1829 char reg_str[128]; 1830 ra_->dump_register(this, reg_str); 1831 st->print("ADDI %s, SP, %d \t// box node", reg_str, offset); 1832 } 1833 #endif 1834 1835 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1836 MacroAssembler _masm(&cbuf); 1837 1838 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1839 int reg = ra_->get_encode(this); 1840 1841 if (Assembler::is_simm(offset, 16)) { 1842 __ addi(as_Register(reg), R1, offset); 1843 } else { 1844 ShouldNotReachHere(); 1845 } 1846 } 1847 1848 uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 1849 // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_). 1850 return 4; 1851 } 1852 1853 #ifndef PRODUCT 1854 void MachUEPNode::format(PhaseRegAlloc *ra_, outputStream *st) const { 1855 st->print_cr("---- MachUEPNode ----"); 1856 st->print_cr("..."); 1857 } 1858 #endif 1859 1860 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1861 // This is the unverified entry point. 1862 MacroAssembler _masm(&cbuf); 1863 1864 // Inline_cache contains a klass. 1865 Register ic_klass = as_Register(Matcher::inline_cache_reg_encode()); 1866 Register receiver_klass = R12_scratch2; // tmp 1867 1868 assert_different_registers(ic_klass, receiver_klass, R11_scratch1, R3_ARG1); 1869 assert(R11_scratch1 == R11, "need prologue scratch register"); 1870 1871 // Check for NULL argument if we don't have implicit null checks. 1872 if (!ImplicitNullChecks || !os::zero_page_read_protected()) { 1873 if (TrapBasedNullChecks) { 1874 __ trap_null_check(R3_ARG1); 1875 } else { 1876 Label valid; 1877 __ cmpdi(CCR0, R3_ARG1, 0); 1878 __ bne_predict_taken(CCR0, valid); 1879 // We have a null argument, branch to ic_miss_stub. 1880 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), 1881 relocInfo::runtime_call_type); 1882 __ bind(valid); 1883 } 1884 } 1885 // Assume argument is not NULL, load klass from receiver. 1886 __ load_klass(receiver_klass, R3_ARG1); 1887 1888 if (TrapBasedICMissChecks) { 1889 __ trap_ic_miss_check(receiver_klass, ic_klass); 1890 } else { 1891 Label valid; 1892 __ cmpd(CCR0, receiver_klass, ic_klass); 1893 __ beq_predict_taken(CCR0, valid); 1894 // We have an unexpected klass, branch to ic_miss_stub. 1895 __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), 1896 relocInfo::runtime_call_type); 1897 __ bind(valid); 1898 } 1899 1900 // Argument is valid and klass is as expected, continue. 1901 } 1902 1903 #if 0 // TODO: PPC port 1904 // Optimize UEP code on z (save a load_const() call in main path). 1905 int MachUEPNode::ep_offset() { 1906 return 0; 1907 } 1908 #endif 1909 1910 uint MachUEPNode::size(PhaseRegAlloc *ra_) const { 1911 // Variable size. Determine dynamically. 1912 return MachNode::size(ra_); 1913 } 1914 1915 //============================================================================= 1916 1917 %} // interrupt source 1918 1919 source_hpp %{ // Header information of the source block. 1920 1921 class HandlerImpl { 1922 1923 public: 1924 1925 static int emit_exception_handler(CodeBuffer &cbuf); 1926 static int emit_deopt_handler(CodeBuffer& cbuf); 1927 1928 static uint size_exception_handler() { 1929 // The exception_handler is a b64_patchable. 1930 return MacroAssembler::b64_patchable_size; 1931 } 1932 1933 static uint size_deopt_handler() { 1934 // The deopt_handler is a bl64_patchable. 1935 return MacroAssembler::bl64_patchable_size; 1936 } 1937 1938 }; 1939 1940 %} // end source_hpp 1941 1942 source %{ 1943 1944 int HandlerImpl::emit_exception_handler(CodeBuffer &cbuf) { 1945 MacroAssembler _masm(&cbuf); 1946 1947 address base = __ start_a_stub(size_exception_handler()); 1948 if (base == NULL) return 0; // CodeBuffer::expand failed 1949 1950 int offset = __ offset(); 1951 __ b64_patchable((address)OptoRuntime::exception_blob()->content_begin(), 1952 relocInfo::runtime_call_type); 1953 assert(__ offset() - offset == (int)size_exception_handler(), "must be fixed size"); 1954 __ end_a_stub(); 1955 1956 return offset; 1957 } 1958 1959 // The deopt_handler is like the exception handler, but it calls to 1960 // the deoptimization blob instead of jumping to the exception blob. 1961 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) { 1962 MacroAssembler _masm(&cbuf); 1963 1964 address base = __ start_a_stub(size_deopt_handler()); 1965 if (base == NULL) return 0; // CodeBuffer::expand failed 1966 1967 int offset = __ offset(); 1968 __ bl64_patchable((address)SharedRuntime::deopt_blob()->unpack(), 1969 relocInfo::runtime_call_type); 1970 assert(__ offset() - offset == (int) size_deopt_handler(), "must be fixed size"); 1971 __ end_a_stub(); 1972 1973 return offset; 1974 } 1975 1976 //============================================================================= 1977 1978 // Use a frame slots bias for frameless methods if accessing the stack. 1979 static int frame_slots_bias(int reg_enc, PhaseRegAlloc* ra_) { 1980 if (as_Register(reg_enc) == R1_SP) { 1981 return 0; // TODO: PPC port ra_->C->frame_slots_sp_bias_in_bytes(); 1982 } 1983 return 0; 1984 } 1985 1986 const bool Matcher::match_rule_supported(int opcode) { 1987 if (!has_match_rule(opcode)) 1988 return false; 1989 1990 switch (opcode) { 1991 case Op_SqrtD: 1992 return VM_Version::has_fsqrt(); 1993 case Op_CountLeadingZerosI: 1994 case Op_CountLeadingZerosL: 1995 case Op_CountTrailingZerosI: 1996 case Op_CountTrailingZerosL: 1997 if (!UseCountLeadingZerosInstructionsPPC64) 1998 return false; 1999 break; 2000 2001 case Op_PopCountI: 2002 case Op_PopCountL: 2003 return (UsePopCountInstruction && VM_Version::has_popcntw()); 2004 2005 case Op_StrComp: 2006 return SpecialStringCompareTo; 2007 case Op_StrEquals: 2008 return SpecialStringEquals; 2009 case Op_StrIndexOf: 2010 return SpecialStringIndexOf; 2011 case Op_StrIndexOfChar: 2012 return SpecialStringIndexOf; 2013 } 2014 2015 return true; // Per default match rules are supported. 2016 } 2017 2018 const bool Matcher::match_rule_supported_vector(int opcode, int vlen) { 2019 2020 // TODO 2021 // identify extra cases that we might want to provide match rules for 2022 // e.g. Op_ vector nodes and other intrinsics while guarding with vlen 2023 bool ret_value = match_rule_supported(opcode); 2024 // Add rules here. 2025 2026 return ret_value; // Per default match rules are supported. 2027 } 2028 2029 const bool Matcher::has_predicated_vectors(void) { 2030 return false; 2031 } 2032 2033 const int Matcher::float_pressure(int default_pressure_threshold) { 2034 return default_pressure_threshold; 2035 } 2036 2037 int Matcher::regnum_to_fpu_offset(int regnum) { 2038 // No user for this method? 2039 Unimplemented(); 2040 return 999; 2041 } 2042 2043 const bool Matcher::convL2FSupported(void) { 2044 // fcfids can do the conversion (>= Power7). 2045 // fcfid + frsp showed rounding problem when result should be 0x3f800001. 2046 return VM_Version::has_fcfids(); // False means that conversion is done by runtime call. 2047 } 2048 2049 // Vector width in bytes. 2050 const int Matcher::vector_width_in_bytes(BasicType bt) { 2051 assert(MaxVectorSize == 8, ""); 2052 return 8; 2053 } 2054 2055 // Vector ideal reg. 2056 const uint Matcher::vector_ideal_reg(int size) { 2057 assert(MaxVectorSize == 8 && size == 8, ""); 2058 return Op_RegL; 2059 } 2060 2061 const uint Matcher::vector_shift_count_ideal_reg(int size) { 2062 fatal("vector shift is not supported"); 2063 return Node::NotAMachineReg; 2064 } 2065 2066 // Limits on vector size (number of elements) loaded into vector. 2067 const int Matcher::max_vector_size(const BasicType bt) { 2068 assert(is_java_primitive(bt), "only primitive type vectors"); 2069 return vector_width_in_bytes(bt)/type2aelembytes(bt); 2070 } 2071 2072 const int Matcher::min_vector_size(const BasicType bt) { 2073 return max_vector_size(bt); // Same as max. 2074 } 2075 2076 // PPC doesn't support misaligned vectors store/load. 2077 const bool Matcher::misaligned_vectors_ok() { 2078 return false; 2079 } 2080 2081 // PPC AES support not yet implemented 2082 const bool Matcher::pass_original_key_for_aes() { 2083 return false; 2084 } 2085 2086 // RETURNS: whether this branch offset is short enough that a short 2087 // branch can be used. 2088 // 2089 // If the platform does not provide any short branch variants, then 2090 // this method should return `false' for offset 0. 2091 // 2092 // `Compile::Fill_buffer' will decide on basis of this information 2093 // whether to do the pass `Compile::Shorten_branches' at all. 2094 // 2095 // And `Compile::Shorten_branches' will decide on basis of this 2096 // information whether to replace particular branch sites by short 2097 // ones. 2098 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 2099 // Is the offset within the range of a ppc64 pc relative branch? 2100 bool b; 2101 2102 const int safety_zone = 3 * BytesPerInstWord; 2103 b = Assembler::is_simm((offset<0 ? offset-safety_zone : offset+safety_zone), 2104 29 - 16 + 1 + 2); 2105 return b; 2106 } 2107 2108 const bool Matcher::isSimpleConstant64(jlong value) { 2109 // Probably always true, even if a temp register is required. 2110 return true; 2111 } 2112 /* TODO: PPC port 2113 // Make a new machine dependent decode node (with its operands). 2114 MachTypeNode *Matcher::make_decode_node() { 2115 assert(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0, 2116 "This method is only implemented for unscaled cOops mode so far"); 2117 MachTypeNode *decode = new decodeN_unscaledNode(); 2118 decode->set_opnd_array(0, new iRegPdstOper()); 2119 decode->set_opnd_array(1, new iRegNsrcOper()); 2120 return decode; 2121 } 2122 */ 2123 2124 // false => size gets scaled to BytesPerLong, ok. 2125 const bool Matcher::init_array_count_is_in_bytes = false; 2126 2127 // Use conditional move (CMOVL) on Power7. 2128 const int Matcher::long_cmove_cost() { return 0; } // this only makes long cmoves more expensive than int cmoves 2129 2130 // Suppress CMOVF. Conditional move available (sort of) on PPC64 only from P7 onwards. Not exploited yet. 2131 // fsel doesn't accept a condition register as input, so this would be slightly different. 2132 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 2133 2134 // Power6 requires postalloc expand (see block.cpp for description of postalloc expand). 2135 const bool Matcher::require_postalloc_expand = true; 2136 2137 // Do we need to mask the count passed to shift instructions or does 2138 // the cpu only look at the lower 5/6 bits anyway? 2139 // PowerPC requires masked shift counts. 2140 const bool Matcher::need_masked_shift_count = true; 2141 2142 // This affects two different things: 2143 // - how Decode nodes are matched 2144 // - how ImplicitNullCheck opportunities are recognized 2145 // If true, the matcher will try to remove all Decodes and match them 2146 // (as operands) into nodes. NullChecks are not prepared to deal with 2147 // Decodes by final_graph_reshaping(). 2148 // If false, final_graph_reshaping() forces the decode behind the Cmp 2149 // for a NullCheck. The matcher matches the Decode node into a register. 2150 // Implicit_null_check optimization moves the Decode along with the 2151 // memory operation back up before the NullCheck. 2152 bool Matcher::narrow_oop_use_complex_address() { 2153 // TODO: PPC port if (MatchDecodeNodes) return true; 2154 return false; 2155 } 2156 2157 bool Matcher::narrow_klass_use_complex_address() { 2158 NOT_LP64(ShouldNotCallThis()); 2159 assert(UseCompressedClassPointers, "only for compressed klass code"); 2160 // TODO: PPC port if (MatchDecodeNodes) return true; 2161 return false; 2162 } 2163 2164 bool Matcher::const_oop_prefer_decode() { 2165 // Prefer ConN+DecodeN over ConP in simple compressed oops mode. 2166 return Universe::narrow_oop_base() == NULL; 2167 } 2168 2169 bool Matcher::const_klass_prefer_decode() { 2170 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 2171 return Universe::narrow_klass_base() == NULL; 2172 } 2173 2174 // Is it better to copy float constants, or load them directly from memory? 2175 // Intel can load a float constant from a direct address, requiring no 2176 // extra registers. Most RISCs will have to materialize an address into a 2177 // register first, so they would do better to copy the constant from stack. 2178 const bool Matcher::rematerialize_float_constants = false; 2179 2180 // If CPU can load and store mis-aligned doubles directly then no fixup is 2181 // needed. Else we split the double into 2 integer pieces and move it 2182 // piece-by-piece. Only happens when passing doubles into C code as the 2183 // Java calling convention forces doubles to be aligned. 2184 const bool Matcher::misaligned_doubles_ok = true; 2185 2186 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) { 2187 Unimplemented(); 2188 } 2189 2190 // Advertise here if the CPU requires explicit rounding operations 2191 // to implement the UseStrictFP mode. 2192 const bool Matcher::strict_fp_requires_explicit_rounding = false; 2193 2194 // Do floats take an entire double register or just half? 2195 // 2196 // A float occupies a ppc64 double register. For the allocator, a 2197 // ppc64 double register appears as a pair of float registers. 2198 bool Matcher::float_in_double() { return true; } 2199 2200 // Do ints take an entire long register or just half? 2201 // The relevant question is how the int is callee-saved: 2202 // the whole long is written but de-opt'ing will have to extract 2203 // the relevant 32 bits. 2204 const bool Matcher::int_in_long = true; 2205 2206 // Constants for c2c and c calling conventions. 2207 2208 const MachRegisterNumbers iarg_reg[8] = { 2209 R3_num, R4_num, R5_num, R6_num, 2210 R7_num, R8_num, R9_num, R10_num 2211 }; 2212 2213 const MachRegisterNumbers farg_reg[13] = { 2214 F1_num, F2_num, F3_num, F4_num, 2215 F5_num, F6_num, F7_num, F8_num, 2216 F9_num, F10_num, F11_num, F12_num, 2217 F13_num 2218 }; 2219 2220 const int num_iarg_registers = sizeof(iarg_reg) / sizeof(iarg_reg[0]); 2221 2222 const int num_farg_registers = sizeof(farg_reg) / sizeof(farg_reg[0]); 2223 2224 // Return whether or not this register is ever used as an argument. This 2225 // function is used on startup to build the trampoline stubs in generateOptoStub. 2226 // Registers not mentioned will be killed by the VM call in the trampoline, and 2227 // arguments in those registers not be available to the callee. 2228 bool Matcher::can_be_java_arg(int reg) { 2229 // We return true for all registers contained in iarg_reg[] and 2230 // farg_reg[] and their virtual halves. 2231 // We must include the virtual halves in order to get STDs and LDs 2232 // instead of STWs and LWs in the trampoline stubs. 2233 2234 if ( reg == R3_num || reg == R3_H_num 2235 || reg == R4_num || reg == R4_H_num 2236 || reg == R5_num || reg == R5_H_num 2237 || reg == R6_num || reg == R6_H_num 2238 || reg == R7_num || reg == R7_H_num 2239 || reg == R8_num || reg == R8_H_num 2240 || reg == R9_num || reg == R9_H_num 2241 || reg == R10_num || reg == R10_H_num) 2242 return true; 2243 2244 if ( reg == F1_num || reg == F1_H_num 2245 || reg == F2_num || reg == F2_H_num 2246 || reg == F3_num || reg == F3_H_num 2247 || reg == F4_num || reg == F4_H_num 2248 || reg == F5_num || reg == F5_H_num 2249 || reg == F6_num || reg == F6_H_num 2250 || reg == F7_num || reg == F7_H_num 2251 || reg == F8_num || reg == F8_H_num 2252 || reg == F9_num || reg == F9_H_num 2253 || reg == F10_num || reg == F10_H_num 2254 || reg == F11_num || reg == F11_H_num 2255 || reg == F12_num || reg == F12_H_num 2256 || reg == F13_num || reg == F13_H_num) 2257 return true; 2258 2259 return false; 2260 } 2261 2262 bool Matcher::is_spillable_arg(int reg) { 2263 return can_be_java_arg(reg); 2264 } 2265 2266 bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) { 2267 return false; 2268 } 2269 2270 // Register for DIVI projection of divmodI. 2271 RegMask Matcher::divI_proj_mask() { 2272 ShouldNotReachHere(); 2273 return RegMask(); 2274 } 2275 2276 // Register for MODI projection of divmodI. 2277 RegMask Matcher::modI_proj_mask() { 2278 ShouldNotReachHere(); 2279 return RegMask(); 2280 } 2281 2282 // Register for DIVL projection of divmodL. 2283 RegMask Matcher::divL_proj_mask() { 2284 ShouldNotReachHere(); 2285 return RegMask(); 2286 } 2287 2288 // Register for MODL projection of divmodL. 2289 RegMask Matcher::modL_proj_mask() { 2290 ShouldNotReachHere(); 2291 return RegMask(); 2292 } 2293 2294 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 2295 return RegMask(); 2296 } 2297 2298 const bool Matcher::convi2l_type_required = true; 2299 2300 %} 2301 2302 //----------ENCODING BLOCK----------------------------------------------------- 2303 // This block specifies the encoding classes used by the compiler to output 2304 // byte streams. Encoding classes are parameterized macros used by 2305 // Machine Instruction Nodes in order to generate the bit encoding of the 2306 // instruction. Operands specify their base encoding interface with the 2307 // interface keyword. There are currently supported four interfaces, 2308 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an 2309 // operand to generate a function which returns its register number when 2310 // queried. CONST_INTER causes an operand to generate a function which 2311 // returns the value of the constant when queried. MEMORY_INTER causes an 2312 // operand to generate four functions which return the Base Register, the 2313 // Index Register, the Scale Value, and the Offset Value of the operand when 2314 // queried. COND_INTER causes an operand to generate six functions which 2315 // return the encoding code (ie - encoding bits for the instruction) 2316 // associated with each basic boolean condition for a conditional instruction. 2317 // 2318 // Instructions specify two basic values for encoding. Again, a function 2319 // is available to check if the constant displacement is an oop. They use the 2320 // ins_encode keyword to specify their encoding classes (which must be 2321 // a sequence of enc_class names, and their parameters, specified in 2322 // the encoding block), and they use the 2323 // opcode keyword to specify, in order, their primary, secondary, and 2324 // tertiary opcode. Only the opcode sections which a particular instruction 2325 // needs for encoding need to be specified. 2326 encode %{ 2327 enc_class enc_unimplemented %{ 2328 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2329 MacroAssembler _masm(&cbuf); 2330 __ unimplemented("Unimplemented mach node encoding in AD file.", 13); 2331 %} 2332 2333 enc_class enc_untested %{ 2334 #ifdef ASSERT 2335 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2336 MacroAssembler _masm(&cbuf); 2337 __ untested("Untested mach node encoding in AD file."); 2338 #else 2339 // TODO: PPC port $archOpcode(ppc64Opcode_none); 2340 #endif 2341 %} 2342 2343 enc_class enc_lbz(iRegIdst dst, memory mem) %{ 2344 // TODO: PPC port $archOpcode(ppc64Opcode_lbz); 2345 MacroAssembler _masm(&cbuf); 2346 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2347 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2348 %} 2349 2350 // Load acquire. 2351 enc_class enc_lbz_ac(iRegIdst dst, memory mem) %{ 2352 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2353 MacroAssembler _masm(&cbuf); 2354 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2355 __ lbz($dst$$Register, Idisp, $mem$$base$$Register); 2356 __ twi_0($dst$$Register); 2357 __ isync(); 2358 %} 2359 2360 enc_class enc_lhz(iRegIdst dst, memory mem) %{ 2361 // TODO: PPC port $archOpcode(ppc64Opcode_lhz); 2362 2363 MacroAssembler _masm(&cbuf); 2364 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2365 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2366 %} 2367 2368 // Load acquire. 2369 enc_class enc_lhz_ac(iRegIdst dst, memory mem) %{ 2370 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2371 2372 MacroAssembler _masm(&cbuf); 2373 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2374 __ lhz($dst$$Register, Idisp, $mem$$base$$Register); 2375 __ twi_0($dst$$Register); 2376 __ isync(); 2377 %} 2378 2379 enc_class enc_lwz(iRegIdst dst, memory mem) %{ 2380 // TODO: PPC port $archOpcode(ppc64Opcode_lwz); 2381 2382 MacroAssembler _masm(&cbuf); 2383 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2384 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2385 %} 2386 2387 // Load acquire. 2388 enc_class enc_lwz_ac(iRegIdst dst, memory mem) %{ 2389 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2390 2391 MacroAssembler _masm(&cbuf); 2392 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2393 __ lwz($dst$$Register, Idisp, $mem$$base$$Register); 2394 __ twi_0($dst$$Register); 2395 __ isync(); 2396 %} 2397 2398 enc_class enc_ld(iRegLdst dst, memoryAlg4 mem) %{ 2399 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2400 MacroAssembler _masm(&cbuf); 2401 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2402 // Operand 'ds' requires 4-alignment. 2403 assert((Idisp & 0x3) == 0, "unaligned offset"); 2404 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2405 %} 2406 2407 // Load acquire. 2408 enc_class enc_ld_ac(iRegLdst dst, memoryAlg4 mem) %{ 2409 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2410 MacroAssembler _masm(&cbuf); 2411 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2412 // Operand 'ds' requires 4-alignment. 2413 assert((Idisp & 0x3) == 0, "unaligned offset"); 2414 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 2415 __ twi_0($dst$$Register); 2416 __ isync(); 2417 %} 2418 2419 enc_class enc_lfd(RegF dst, memory mem) %{ 2420 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 2421 MacroAssembler _masm(&cbuf); 2422 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2423 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 2424 %} 2425 2426 enc_class enc_load_long_constL(iRegLdst dst, immL src, iRegLdst toc) %{ 2427 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2428 2429 MacroAssembler _masm(&cbuf); 2430 int toc_offset = 0; 2431 2432 address const_toc_addr; 2433 // Create a non-oop constant, no relocation needed. 2434 // If it is an IC, it has a virtual_call_Relocation. 2435 const_toc_addr = __ long_constant((jlong)$src$$constant); 2436 if (const_toc_addr == NULL) { 2437 ciEnv::current()->record_out_of_memory_failure(); 2438 return; 2439 } 2440 2441 // Get the constant's TOC offset. 2442 toc_offset = __ offset_to_method_toc(const_toc_addr); 2443 2444 // Keep the current instruction offset in mind. 2445 ((loadConLNode*)this)->_cbuf_insts_offset = __ offset(); 2446 2447 __ ld($dst$$Register, toc_offset, $toc$$Register); 2448 %} 2449 2450 enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{ 2451 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 2452 2453 MacroAssembler _masm(&cbuf); 2454 2455 if (!ra_->C->in_scratch_emit_size()) { 2456 address const_toc_addr; 2457 // Create a non-oop constant, no relocation needed. 2458 // If it is an IC, it has a virtual_call_Relocation. 2459 const_toc_addr = __ long_constant((jlong)$src$$constant); 2460 if (const_toc_addr == NULL) { 2461 ciEnv::current()->record_out_of_memory_failure(); 2462 return; 2463 } 2464 2465 // Get the constant's TOC offset. 2466 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 2467 // Store the toc offset of the constant. 2468 ((loadConL_hiNode*)this)->_const_toc_offset = toc_offset; 2469 2470 // Also keep the current instruction offset in mind. 2471 ((loadConL_hiNode*)this)->_cbuf_insts_offset = __ offset(); 2472 } 2473 2474 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 2475 %} 2476 2477 %} // encode 2478 2479 source %{ 2480 2481 typedef struct { 2482 loadConL_hiNode *_large_hi; 2483 loadConL_loNode *_large_lo; 2484 loadConLNode *_small; 2485 MachNode *_last; 2486 } loadConLNodesTuple; 2487 2488 loadConLNodesTuple loadConLNodesTuple_create(PhaseRegAlloc *ra_, Node *toc, immLOper *immSrc, 2489 OptoReg::Name reg_second, OptoReg::Name reg_first) { 2490 loadConLNodesTuple nodes; 2491 2492 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2493 if (large_constant_pool) { 2494 // Create new nodes. 2495 loadConL_hiNode *m1 = new loadConL_hiNode(); 2496 loadConL_loNode *m2 = new loadConL_loNode(); 2497 2498 // inputs for new nodes 2499 m1->add_req(NULL, toc); 2500 m2->add_req(NULL, m1); 2501 2502 // operands for new nodes 2503 m1->_opnds[0] = new iRegLdstOper(); // dst 2504 m1->_opnds[1] = immSrc; // src 2505 m1->_opnds[2] = new iRegPdstOper(); // toc 2506 m2->_opnds[0] = new iRegLdstOper(); // dst 2507 m2->_opnds[1] = immSrc; // src 2508 m2->_opnds[2] = new iRegLdstOper(); // base 2509 2510 // Initialize ins_attrib TOC fields. 2511 m1->_const_toc_offset = -1; 2512 m2->_const_toc_offset_hi_node = m1; 2513 2514 // Initialize ins_attrib instruction offset. 2515 m1->_cbuf_insts_offset = -1; 2516 2517 // register allocation for new nodes 2518 ra_->set_pair(m1->_idx, reg_second, reg_first); 2519 ra_->set_pair(m2->_idx, reg_second, reg_first); 2520 2521 // Create result. 2522 nodes._large_hi = m1; 2523 nodes._large_lo = m2; 2524 nodes._small = NULL; 2525 nodes._last = nodes._large_lo; 2526 assert(m2->bottom_type()->isa_long(), "must be long"); 2527 } else { 2528 loadConLNode *m2 = new loadConLNode(); 2529 2530 // inputs for new nodes 2531 m2->add_req(NULL, toc); 2532 2533 // operands for new nodes 2534 m2->_opnds[0] = new iRegLdstOper(); // dst 2535 m2->_opnds[1] = immSrc; // src 2536 m2->_opnds[2] = new iRegPdstOper(); // toc 2537 2538 // Initialize ins_attrib instruction offset. 2539 m2->_cbuf_insts_offset = -1; 2540 2541 // register allocation for new nodes 2542 ra_->set_pair(m2->_idx, reg_second, reg_first); 2543 2544 // Create result. 2545 nodes._large_hi = NULL; 2546 nodes._large_lo = NULL; 2547 nodes._small = m2; 2548 nodes._last = nodes._small; 2549 assert(m2->bottom_type()->isa_long(), "must be long"); 2550 } 2551 2552 return nodes; 2553 } 2554 2555 %} // source 2556 2557 encode %{ 2558 // Postalloc expand emitter for loading a long constant from the method's TOC. 2559 // Enc_class needed as consttanttablebase is not supported by postalloc 2560 // expand. 2561 enc_class postalloc_expand_load_long_constant(iRegLdst dst, immL src, iRegLdst toc) %{ 2562 // Create new nodes. 2563 loadConLNodesTuple loadConLNodes = 2564 loadConLNodesTuple_create(ra_, n_toc, op_src, 2565 ra_->get_reg_second(this), ra_->get_reg_first(this)); 2566 2567 // Push new nodes. 2568 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 2569 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 2570 2571 // some asserts 2572 assert(nodes->length() >= 1, "must have created at least 1 node"); 2573 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 2574 %} 2575 2576 enc_class enc_load_long_constP(iRegLdst dst, immP src, iRegLdst toc) %{ 2577 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 2578 2579 MacroAssembler _masm(&cbuf); 2580 int toc_offset = 0; 2581 2582 intptr_t val = $src$$constant; 2583 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 2584 address const_toc_addr; 2585 if (constant_reloc == relocInfo::oop_type) { 2586 // Create an oop constant and a corresponding relocation. 2587 AddressLiteral a = __ allocate_oop_address((jobject)val); 2588 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2589 __ relocate(a.rspec()); 2590 } else if (constant_reloc == relocInfo::metadata_type) { 2591 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 2592 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2593 __ relocate(a.rspec()); 2594 } else { 2595 // Create a non-oop constant, no relocation needed. 2596 const_toc_addr = __ long_constant((jlong)$src$$constant); 2597 } 2598 2599 if (const_toc_addr == NULL) { 2600 ciEnv::current()->record_out_of_memory_failure(); 2601 return; 2602 } 2603 // Get the constant's TOC offset. 2604 toc_offset = __ offset_to_method_toc(const_toc_addr); 2605 2606 __ ld($dst$$Register, toc_offset, $toc$$Register); 2607 %} 2608 2609 enc_class enc_load_long_constP_hi(iRegLdst dst, immP src, iRegLdst toc) %{ 2610 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 2611 2612 MacroAssembler _masm(&cbuf); 2613 if (!ra_->C->in_scratch_emit_size()) { 2614 intptr_t val = $src$$constant; 2615 relocInfo::relocType constant_reloc = $src->constant_reloc(); // src 2616 address const_toc_addr; 2617 if (constant_reloc == relocInfo::oop_type) { 2618 // Create an oop constant and a corresponding relocation. 2619 AddressLiteral a = __ allocate_oop_address((jobject)val); 2620 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2621 __ relocate(a.rspec()); 2622 } else if (constant_reloc == relocInfo::metadata_type) { 2623 AddressLiteral a = __ constant_metadata_address((Metadata *)val); 2624 const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none); 2625 __ relocate(a.rspec()); 2626 } else { // non-oop pointers, e.g. card mark base, heap top 2627 // Create a non-oop constant, no relocation needed. 2628 const_toc_addr = __ long_constant((jlong)$src$$constant); 2629 } 2630 2631 if (const_toc_addr == NULL) { 2632 ciEnv::current()->record_out_of_memory_failure(); 2633 return; 2634 } 2635 // Get the constant's TOC offset. 2636 const int toc_offset = __ offset_to_method_toc(const_toc_addr); 2637 // Store the toc offset of the constant. 2638 ((loadConP_hiNode*)this)->_const_toc_offset = toc_offset; 2639 } 2640 2641 __ addis($dst$$Register, $toc$$Register, MacroAssembler::largeoffset_si16_si16_hi(_const_toc_offset)); 2642 %} 2643 2644 // Postalloc expand emitter for loading a ptr constant from the method's TOC. 2645 // Enc_class needed as consttanttablebase is not supported by postalloc 2646 // expand. 2647 enc_class postalloc_expand_load_ptr_constant(iRegPdst dst, immP src, iRegLdst toc) %{ 2648 const bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2649 if (large_constant_pool) { 2650 // Create new nodes. 2651 loadConP_hiNode *m1 = new loadConP_hiNode(); 2652 loadConP_loNode *m2 = new loadConP_loNode(); 2653 2654 // inputs for new nodes 2655 m1->add_req(NULL, n_toc); 2656 m2->add_req(NULL, m1); 2657 2658 // operands for new nodes 2659 m1->_opnds[0] = new iRegPdstOper(); // dst 2660 m1->_opnds[1] = op_src; // src 2661 m1->_opnds[2] = new iRegPdstOper(); // toc 2662 m2->_opnds[0] = new iRegPdstOper(); // dst 2663 m2->_opnds[1] = op_src; // src 2664 m2->_opnds[2] = new iRegLdstOper(); // base 2665 2666 // Initialize ins_attrib TOC fields. 2667 m1->_const_toc_offset = -1; 2668 m2->_const_toc_offset_hi_node = m1; 2669 2670 // Register allocation for new nodes. 2671 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2672 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2673 2674 nodes->push(m1); 2675 nodes->push(m2); 2676 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 2677 } else { 2678 loadConPNode *m2 = new loadConPNode(); 2679 2680 // inputs for new nodes 2681 m2->add_req(NULL, n_toc); 2682 2683 // operands for new nodes 2684 m2->_opnds[0] = new iRegPdstOper(); // dst 2685 m2->_opnds[1] = op_src; // src 2686 m2->_opnds[2] = new iRegPdstOper(); // toc 2687 2688 // Register allocation for new nodes. 2689 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2690 2691 nodes->push(m2); 2692 assert(m2->bottom_type()->isa_ptr(), "must be ptr"); 2693 } 2694 %} 2695 2696 // Enc_class needed as consttanttablebase is not supported by postalloc 2697 // expand. 2698 enc_class postalloc_expand_load_float_constant(regF dst, immF src, iRegLdst toc) %{ 2699 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2700 2701 MachNode *m2; 2702 if (large_constant_pool) { 2703 m2 = new loadConFCompNode(); 2704 } else { 2705 m2 = new loadConFNode(); 2706 } 2707 // inputs for new nodes 2708 m2->add_req(NULL, n_toc); 2709 2710 // operands for new nodes 2711 m2->_opnds[0] = op_dst; 2712 m2->_opnds[1] = op_src; 2713 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 2714 2715 // register allocation for new nodes 2716 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2717 nodes->push(m2); 2718 %} 2719 2720 // Enc_class needed as consttanttablebase is not supported by postalloc 2721 // expand. 2722 enc_class postalloc_expand_load_double_constant(regD dst, immD src, iRegLdst toc) %{ 2723 bool large_constant_pool = true; // TODO: PPC port C->cfg()->_consts_size > 4000; 2724 2725 MachNode *m2; 2726 if (large_constant_pool) { 2727 m2 = new loadConDCompNode(); 2728 } else { 2729 m2 = new loadConDNode(); 2730 } 2731 // inputs for new nodes 2732 m2->add_req(NULL, n_toc); 2733 2734 // operands for new nodes 2735 m2->_opnds[0] = op_dst; 2736 m2->_opnds[1] = op_src; 2737 m2->_opnds[2] = new iRegPdstOper(); // constanttablebase 2738 2739 // register allocation for new nodes 2740 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2741 nodes->push(m2); 2742 %} 2743 2744 enc_class enc_stw(iRegIsrc src, memory mem) %{ 2745 // TODO: PPC port $archOpcode(ppc64Opcode_stw); 2746 MacroAssembler _masm(&cbuf); 2747 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2748 __ stw($src$$Register, Idisp, $mem$$base$$Register); 2749 %} 2750 2751 enc_class enc_std(iRegIsrc src, memoryAlg4 mem) %{ 2752 // TODO: PPC port $archOpcode(ppc64Opcode_std); 2753 MacroAssembler _masm(&cbuf); 2754 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2755 // Operand 'ds' requires 4-alignment. 2756 assert((Idisp & 0x3) == 0, "unaligned offset"); 2757 __ std($src$$Register, Idisp, $mem$$base$$Register); 2758 %} 2759 2760 enc_class enc_stfs(RegF src, memory mem) %{ 2761 // TODO: PPC port $archOpcode(ppc64Opcode_stfs); 2762 MacroAssembler _masm(&cbuf); 2763 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2764 __ stfs($src$$FloatRegister, Idisp, $mem$$base$$Register); 2765 %} 2766 2767 enc_class enc_stfd(RegF src, memory mem) %{ 2768 // TODO: PPC port $archOpcode(ppc64Opcode_stfd); 2769 MacroAssembler _masm(&cbuf); 2770 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 2771 __ stfd($src$$FloatRegister, Idisp, $mem$$base$$Register); 2772 %} 2773 2774 // Use release_store for card-marking to ensure that previous 2775 // oop-stores are visible before the card-mark change. 2776 enc_class enc_cms_card_mark(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 2777 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 2778 // FIXME: Implement this as a cmove and use a fixed condition code 2779 // register which is written on every transition to compiled code, 2780 // e.g. in call-stub and when returning from runtime stubs. 2781 // 2782 // Proposed code sequence for the cmove implementation: 2783 // 2784 // Label skip_release; 2785 // __ beq(CCRfixed, skip_release); 2786 // __ release(); 2787 // __ bind(skip_release); 2788 // __ stb(card mark); 2789 2790 MacroAssembler _masm(&cbuf); 2791 Label skip_storestore; 2792 2793 #if 0 // TODO: PPC port 2794 // Check CMSCollectorCardTableModRefBSExt::_requires_release and do the 2795 // StoreStore barrier conditionally. 2796 __ lwz(R0, 0, $releaseFieldAddr$$Register); 2797 __ cmpwi($crx$$CondRegister, R0, 0); 2798 __ beq_predict_taken($crx$$CondRegister, skip_storestore); 2799 #endif 2800 __ li(R0, 0); 2801 __ membar(Assembler::StoreStore); 2802 #if 0 // TODO: PPC port 2803 __ bind(skip_storestore); 2804 #endif 2805 2806 // Do the store. 2807 if ($mem$$index == 0) { 2808 __ stb(R0, $mem$$disp, $mem$$base$$Register); 2809 } else { 2810 assert(0 == $mem$$disp, "no displacement possible with indexed load/stores on ppc"); 2811 __ stbx(R0, $mem$$base$$Register, $mem$$index$$Register); 2812 } 2813 %} 2814 2815 enc_class postalloc_expand_encode_oop(iRegNdst dst, iRegPdst src, flagsReg crx) %{ 2816 2817 if (VM_Version::has_isel()) { 2818 // use isel instruction with Power 7 2819 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 2820 encodeP_subNode *n_sub_base = new encodeP_subNode(); 2821 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 2822 cond_set_0_oopNode *n_cond_set = new cond_set_0_oopNode(); 2823 2824 n_compare->add_req(n_region, n_src); 2825 n_compare->_opnds[0] = op_crx; 2826 n_compare->_opnds[1] = op_src; 2827 n_compare->_opnds[2] = new immL16Oper(0); 2828 2829 n_sub_base->add_req(n_region, n_src); 2830 n_sub_base->_opnds[0] = op_dst; 2831 n_sub_base->_opnds[1] = op_src; 2832 n_sub_base->_bottom_type = _bottom_type; 2833 2834 n_shift->add_req(n_region, n_sub_base); 2835 n_shift->_opnds[0] = op_dst; 2836 n_shift->_opnds[1] = op_dst; 2837 n_shift->_bottom_type = _bottom_type; 2838 2839 n_cond_set->add_req(n_region, n_compare, n_shift); 2840 n_cond_set->_opnds[0] = op_dst; 2841 n_cond_set->_opnds[1] = op_crx; 2842 n_cond_set->_opnds[2] = op_dst; 2843 n_cond_set->_bottom_type = _bottom_type; 2844 2845 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 2846 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2847 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2848 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2849 2850 nodes->push(n_compare); 2851 nodes->push(n_sub_base); 2852 nodes->push(n_shift); 2853 nodes->push(n_cond_set); 2854 2855 } else { 2856 // before Power 7 2857 moveRegNode *n_move = new moveRegNode(); 2858 cmpP_reg_imm16Node *n_compare = new cmpP_reg_imm16Node(); 2859 encodeP_shiftNode *n_shift = new encodeP_shiftNode(); 2860 cond_sub_baseNode *n_sub_base = new cond_sub_baseNode(); 2861 2862 n_move->add_req(n_region, n_src); 2863 n_move->_opnds[0] = op_dst; 2864 n_move->_opnds[1] = op_src; 2865 ra_->set_oop(n_move, true); // Until here, 'n_move' still produces an oop. 2866 2867 n_compare->add_req(n_region, n_src); 2868 n_compare->add_prec(n_move); 2869 2870 n_compare->_opnds[0] = op_crx; 2871 n_compare->_opnds[1] = op_src; 2872 n_compare->_opnds[2] = new immL16Oper(0); 2873 2874 n_sub_base->add_req(n_region, n_compare, n_src); 2875 n_sub_base->_opnds[0] = op_dst; 2876 n_sub_base->_opnds[1] = op_crx; 2877 n_sub_base->_opnds[2] = op_src; 2878 n_sub_base->_bottom_type = _bottom_type; 2879 2880 n_shift->add_req(n_region, n_sub_base); 2881 n_shift->_opnds[0] = op_dst; 2882 n_shift->_opnds[1] = op_dst; 2883 n_shift->_bottom_type = _bottom_type; 2884 2885 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2886 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 2887 ra_->set_pair(n_sub_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2888 ra_->set_pair(n_move->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2889 2890 nodes->push(n_move); 2891 nodes->push(n_compare); 2892 nodes->push(n_sub_base); 2893 nodes->push(n_shift); 2894 } 2895 2896 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 2897 %} 2898 2899 enc_class postalloc_expand_encode_oop_not_null(iRegNdst dst, iRegPdst src) %{ 2900 2901 encodeP_subNode *n1 = new encodeP_subNode(); 2902 n1->add_req(n_region, n_src); 2903 n1->_opnds[0] = op_dst; 2904 n1->_opnds[1] = op_src; 2905 n1->_bottom_type = _bottom_type; 2906 2907 encodeP_shiftNode *n2 = new encodeP_shiftNode(); 2908 n2->add_req(n_region, n1); 2909 n2->_opnds[0] = op_dst; 2910 n2->_opnds[1] = op_dst; 2911 n2->_bottom_type = _bottom_type; 2912 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2913 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2914 2915 nodes->push(n1); 2916 nodes->push(n2); 2917 assert(!(ra_->is_oop(this)), "sanity"); // This is not supposed to be GC'ed. 2918 %} 2919 2920 enc_class postalloc_expand_decode_oop(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 2921 decodeN_shiftNode *n_shift = new decodeN_shiftNode(); 2922 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 2923 2924 n_compare->add_req(n_region, n_src); 2925 n_compare->_opnds[0] = op_crx; 2926 n_compare->_opnds[1] = op_src; 2927 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 2928 2929 n_shift->add_req(n_region, n_src); 2930 n_shift->_opnds[0] = op_dst; 2931 n_shift->_opnds[1] = op_src; 2932 n_shift->_bottom_type = _bottom_type; 2933 2934 if (VM_Version::has_isel()) { 2935 // use isel instruction with Power 7 2936 2937 decodeN_addNode *n_add_base = new decodeN_addNode(); 2938 n_add_base->add_req(n_region, n_shift); 2939 n_add_base->_opnds[0] = op_dst; 2940 n_add_base->_opnds[1] = op_dst; 2941 n_add_base->_bottom_type = _bottom_type; 2942 2943 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 2944 n_cond_set->add_req(n_region, n_compare, n_add_base); 2945 n_cond_set->_opnds[0] = op_dst; 2946 n_cond_set->_opnds[1] = op_crx; 2947 n_cond_set->_opnds[2] = op_dst; 2948 n_cond_set->_bottom_type = _bottom_type; 2949 2950 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 2951 ra_->set_oop(n_cond_set, true); 2952 2953 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2954 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 2955 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2956 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2957 2958 nodes->push(n_compare); 2959 nodes->push(n_shift); 2960 nodes->push(n_add_base); 2961 nodes->push(n_cond_set); 2962 2963 } else { 2964 // before Power 7 2965 cond_add_baseNode *n_add_base = new cond_add_baseNode(); 2966 2967 n_add_base->add_req(n_region, n_compare, n_shift); 2968 n_add_base->_opnds[0] = op_dst; 2969 n_add_base->_opnds[1] = op_crx; 2970 n_add_base->_opnds[2] = op_dst; 2971 n_add_base->_bottom_type = _bottom_type; 2972 2973 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 2974 ra_->set_oop(n_add_base, true); 2975 2976 ra_->set_pair(n_shift->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2977 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 2978 ra_->set_pair(n_add_base->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2979 2980 nodes->push(n_compare); 2981 nodes->push(n_shift); 2982 nodes->push(n_add_base); 2983 } 2984 %} 2985 2986 enc_class postalloc_expand_decode_oop_not_null(iRegPdst dst, iRegNsrc src) %{ 2987 decodeN_shiftNode *n1 = new decodeN_shiftNode(); 2988 n1->add_req(n_region, n_src); 2989 n1->_opnds[0] = op_dst; 2990 n1->_opnds[1] = op_src; 2991 n1->_bottom_type = _bottom_type; 2992 2993 decodeN_addNode *n2 = new decodeN_addNode(); 2994 n2->add_req(n_region, n1); 2995 n2->_opnds[0] = op_dst; 2996 n2->_opnds[1] = op_dst; 2997 n2->_bottom_type = _bottom_type; 2998 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 2999 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 3000 3001 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 3002 ra_->set_oop(n2, true); 3003 3004 nodes->push(n1); 3005 nodes->push(n2); 3006 %} 3007 3008 enc_class enc_cmove_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src, cmpOp cmp) %{ 3009 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3010 3011 MacroAssembler _masm(&cbuf); 3012 int cc = $cmp$$cmpcode; 3013 int flags_reg = $crx$$reg; 3014 Label done; 3015 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3016 // Branch if not (cmp crx). 3017 __ bc(cc_to_inverse_boint(cc), cc_to_biint(cc, flags_reg), done); 3018 __ mr($dst$$Register, $src$$Register); 3019 // TODO PPC port __ endgroup_if_needed(_size == 12); 3020 __ bind(done); 3021 %} 3022 3023 enc_class enc_cmove_imm(iRegIdst dst, flagsRegSrc crx, immI16 src, cmpOp cmp) %{ 3024 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3025 3026 MacroAssembler _masm(&cbuf); 3027 Label done; 3028 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3029 // Branch if not (cmp crx). 3030 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 3031 __ li($dst$$Register, $src$$constant); 3032 // TODO PPC port __ endgroup_if_needed(_size == 12); 3033 __ bind(done); 3034 %} 3035 3036 // This enc_class is needed so that scheduler gets proper 3037 // input mapping for latency computation. 3038 enc_class enc_andc(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 3039 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 3040 MacroAssembler _masm(&cbuf); 3041 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 3042 %} 3043 3044 enc_class enc_convI2B_regI__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3045 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3046 3047 MacroAssembler _masm(&cbuf); 3048 3049 Label done; 3050 __ cmpwi($crx$$CondRegister, $src$$Register, 0); 3051 __ li($dst$$Register, $zero$$constant); 3052 __ beq($crx$$CondRegister, done); 3053 __ li($dst$$Register, $notzero$$constant); 3054 __ bind(done); 3055 %} 3056 3057 enc_class enc_convP2B_regP__cmove(iRegIdst dst, iRegPsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{ 3058 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3059 3060 MacroAssembler _masm(&cbuf); 3061 3062 Label done; 3063 __ cmpdi($crx$$CondRegister, $src$$Register, 0); 3064 __ li($dst$$Register, $zero$$constant); 3065 __ beq($crx$$CondRegister, done); 3066 __ li($dst$$Register, $notzero$$constant); 3067 __ bind(done); 3068 %} 3069 3070 enc_class enc_cmove_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL mem ) %{ 3071 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 3072 3073 MacroAssembler _masm(&cbuf); 3074 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 3075 Label done; 3076 __ bso($crx$$CondRegister, done); 3077 __ ld($dst$$Register, Idisp, $mem$$base$$Register); 3078 // TODO PPC port __ endgroup_if_needed(_size == 12); 3079 __ bind(done); 3080 %} 3081 3082 enc_class enc_bc(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3083 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3084 3085 MacroAssembler _masm(&cbuf); 3086 Label d; // dummy 3087 __ bind(d); 3088 Label* p = ($lbl$$label); 3089 // `p' is `NULL' when this encoding class is used only to 3090 // determine the size of the encoded instruction. 3091 Label& l = (NULL == p)? d : *(p); 3092 int cc = $cmp$$cmpcode; 3093 int flags_reg = $crx$$reg; 3094 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 3095 int bhint = Assembler::bhintNoHint; 3096 3097 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3098 if (_prob <= PROB_NEVER) { 3099 bhint = Assembler::bhintIsNotTaken; 3100 } else if (_prob >= PROB_ALWAYS) { 3101 bhint = Assembler::bhintIsTaken; 3102 } 3103 } 3104 3105 __ bc(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3106 cc_to_biint(cc, flags_reg), 3107 l); 3108 %} 3109 3110 enc_class enc_bc_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3111 // The scheduler doesn't know about branch shortening, so we set the opcode 3112 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3113 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3114 3115 MacroAssembler _masm(&cbuf); 3116 Label d; // dummy 3117 __ bind(d); 3118 Label* p = ($lbl$$label); 3119 // `p' is `NULL' when this encoding class is used only to 3120 // determine the size of the encoded instruction. 3121 Label& l = (NULL == p)? d : *(p); 3122 int cc = $cmp$$cmpcode; 3123 int flags_reg = $crx$$reg; 3124 int bhint = Assembler::bhintNoHint; 3125 3126 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3127 if (_prob <= PROB_NEVER) { 3128 bhint = Assembler::bhintIsNotTaken; 3129 } else if (_prob >= PROB_ALWAYS) { 3130 bhint = Assembler::bhintIsTaken; 3131 } 3132 } 3133 3134 // Tell the conditional far branch to optimize itself when being relocated. 3135 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3136 cc_to_biint(cc, flags_reg), 3137 l, 3138 MacroAssembler::bc_far_optimize_on_relocate); 3139 %} 3140 3141 // Branch used with Power6 scheduling (can be shortened without changing the node). 3142 enc_class enc_bc_short_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{ 3143 // The scheduler doesn't know about branch shortening, so we set the opcode 3144 // to ppc64Opcode_bc in order to hide this detail from the scheduler. 3145 // TODO: PPC port $archOpcode(ppc64Opcode_bc); 3146 3147 MacroAssembler _masm(&cbuf); 3148 Label d; // dummy 3149 __ bind(d); 3150 Label* p = ($lbl$$label); 3151 // `p' is `NULL' when this encoding class is used only to 3152 // determine the size of the encoded instruction. 3153 Label& l = (NULL == p)? d : *(p); 3154 int cc = $cmp$$cmpcode; 3155 int flags_reg = $crx$$reg; 3156 int bhint = Assembler::bhintNoHint; 3157 3158 if (UseStaticBranchPredictionForUncommonPathsPPC64) { 3159 if (_prob <= PROB_NEVER) { 3160 bhint = Assembler::bhintIsNotTaken; 3161 } else if (_prob >= PROB_ALWAYS) { 3162 bhint = Assembler::bhintIsTaken; 3163 } 3164 } 3165 3166 #if 0 // TODO: PPC port 3167 if (_size == 8) { 3168 // Tell the conditional far branch to optimize itself when being relocated. 3169 __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3170 cc_to_biint(cc, flags_reg), 3171 l, 3172 MacroAssembler::bc_far_optimize_on_relocate); 3173 } else { 3174 __ bc (Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)), 3175 cc_to_biint(cc, flags_reg), 3176 l); 3177 } 3178 #endif 3179 Unimplemented(); 3180 %} 3181 3182 // Postalloc expand emitter for loading a replicatef float constant from 3183 // the method's TOC. 3184 // Enc_class needed as consttanttablebase is not supported by postalloc 3185 // expand. 3186 enc_class postalloc_expand_load_replF_constant(iRegLdst dst, immF src, iRegLdst toc) %{ 3187 // Create new nodes. 3188 3189 // Make an operand with the bit pattern to load as float. 3190 immLOper *op_repl = new immLOper((jlong)replicate_immF(op_src->constantF())); 3191 3192 loadConLNodesTuple loadConLNodes = 3193 loadConLNodesTuple_create(ra_, n_toc, op_repl, 3194 ra_->get_reg_second(this), ra_->get_reg_first(this)); 3195 3196 // Push new nodes. 3197 if (loadConLNodes._large_hi) nodes->push(loadConLNodes._large_hi); 3198 if (loadConLNodes._last) nodes->push(loadConLNodes._last); 3199 3200 assert(nodes->length() >= 1, "must have created at least 1 node"); 3201 assert(loadConLNodes._last->bottom_type()->isa_long(), "must be long"); 3202 %} 3203 3204 // This enc_class is needed so that scheduler gets proper 3205 // input mapping for latency computation. 3206 enc_class enc_poll(immI dst, iRegLdst poll) %{ 3207 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 3208 // Fake operand dst needed for PPC scheduler. 3209 assert($dst$$constant == 0x0, "dst must be 0x0"); 3210 3211 MacroAssembler _masm(&cbuf); 3212 // Mark the code position where the load from the safepoint 3213 // polling page was emitted as relocInfo::poll_type. 3214 __ relocate(relocInfo::poll_type); 3215 __ load_from_polling_page($poll$$Register); 3216 %} 3217 3218 // A Java static call or a runtime call. 3219 // 3220 // Branch-and-link relative to a trampoline. 3221 // The trampoline loads the target address and does a long branch to there. 3222 // In case we call java, the trampoline branches to a interpreter_stub 3223 // which loads the inline cache and the real call target from the constant pool. 3224 // 3225 // This basically looks like this: 3226 // 3227 // >>>> consts -+ -+ 3228 // | |- offset1 3229 // [call target1] | <-+ 3230 // [IC cache] |- offset2 3231 // [call target2] <--+ 3232 // 3233 // <<<< consts 3234 // >>>> insts 3235 // 3236 // bl offset16 -+ -+ ??? // How many bits available? 3237 // | | 3238 // <<<< insts | | 3239 // >>>> stubs | | 3240 // | |- trampoline_stub_Reloc 3241 // trampoline stub: | <-+ 3242 // r2 = toc | 3243 // r2 = [r2 + offset1] | // Load call target1 from const section 3244 // mtctr r2 | 3245 // bctr |- static_stub_Reloc 3246 // comp_to_interp_stub: <---+ 3247 // r1 = toc 3248 // ICreg = [r1 + IC_offset] // Load IC from const section 3249 // r1 = [r1 + offset2] // Load call target2 from const section 3250 // mtctr r1 3251 // bctr 3252 // 3253 // <<<< stubs 3254 // 3255 // The call instruction in the code either 3256 // - Branches directly to a compiled method if the offset is encodable in instruction. 3257 // - Branches to the trampoline stub if the offset to the compiled method is not encodable. 3258 // - Branches to the compiled_to_interp stub if the target is interpreted. 3259 // 3260 // Further there are three relocations from the loads to the constants in 3261 // the constant section. 3262 // 3263 // Usage of r1 and r2 in the stubs allows to distinguish them. 3264 enc_class enc_java_static_call(method meth) %{ 3265 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3266 3267 MacroAssembler _masm(&cbuf); 3268 address entry_point = (address)$meth$$method; 3269 3270 if (!_method) { 3271 // A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap. 3272 emit_call_with_trampoline_stub(_masm, entry_point, relocInfo::runtime_call_type); 3273 } else { 3274 // Remember the offset not the address. 3275 const int start_offset = __ offset(); 3276 3277 // The trampoline stub. 3278 // No entry point given, use the current pc. 3279 // Make sure branch fits into 3280 if (entry_point == 0) entry_point = __ pc(); 3281 3282 // Put the entry point as a constant into the constant pool. 3283 const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none); 3284 if (entry_point_toc_addr == NULL) { 3285 ciEnv::current()->record_out_of_memory_failure(); 3286 return; 3287 } 3288 const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr); 3289 3290 // Emit the trampoline stub which will be related to the branch-and-link below. 3291 CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset); 3292 if (ciEnv::current()->failing()) { return; } // Code cache may be full. 3293 int method_index = resolved_method_index(cbuf); 3294 __ relocate(_optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 3295 : static_call_Relocation::spec(method_index)); 3296 3297 // The real call. 3298 // Note: At this point we do not have the address of the trampoline 3299 // stub, and the entry point might be too far away for bl, so __ pc() 3300 // serves as dummy and the bl will be patched later. 3301 cbuf.set_insts_mark(); 3302 __ bl(__ pc()); // Emits a relocation. 3303 3304 // The stub for call to interpreter. 3305 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf); 3306 if (stub == NULL) { 3307 ciEnv::current()->record_failure("CodeCache is full"); 3308 return; 3309 } 3310 } 3311 %} 3312 3313 // Second node of expanded dynamic call - the call. 3314 enc_class enc_java_dynamic_call_sched(method meth) %{ 3315 // TODO: PPC port $archOpcode(ppc64Opcode_bl); 3316 3317 MacroAssembler _masm(&cbuf); 3318 3319 if (!ra_->C->in_scratch_emit_size()) { 3320 // Create a call trampoline stub for the given method. 3321 const address entry_point = !($meth$$method) ? 0 : (address)$meth$$method; 3322 const address entry_point_const = __ address_constant(entry_point, RelocationHolder::none); 3323 if (entry_point_const == NULL) { 3324 ciEnv::current()->record_out_of_memory_failure(); 3325 return; 3326 } 3327 const int entry_point_const_toc_offset = __ offset_to_method_toc(entry_point_const); 3328 CallStubImpl::emit_trampoline_stub(_masm, entry_point_const_toc_offset, __ offset()); 3329 if (ra_->C->env()->failing()) { return; } // Code cache may be full. 3330 3331 // Build relocation at call site with ic position as data. 3332 assert((_load_ic_hi_node != NULL && _load_ic_node == NULL) || 3333 (_load_ic_hi_node == NULL && _load_ic_node != NULL), 3334 "must have one, but can't have both"); 3335 assert((_load_ic_hi_node != NULL && _load_ic_hi_node->_cbuf_insts_offset != -1) || 3336 (_load_ic_node != NULL && _load_ic_node->_cbuf_insts_offset != -1), 3337 "must contain instruction offset"); 3338 const int virtual_call_oop_addr_offset = _load_ic_hi_node != NULL 3339 ? _load_ic_hi_node->_cbuf_insts_offset 3340 : _load_ic_node->_cbuf_insts_offset; 3341 const address virtual_call_oop_addr = __ addr_at(virtual_call_oop_addr_offset); 3342 assert(MacroAssembler::is_load_const_from_method_toc_at(virtual_call_oop_addr), 3343 "should be load from TOC"); 3344 int method_index = resolved_method_index(cbuf); 3345 __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr, method_index)); 3346 } 3347 3348 // At this point I do not have the address of the trampoline stub, 3349 // and the entry point might be too far away for bl. Pc() serves 3350 // as dummy and bl will be patched later. 3351 __ bl((address) __ pc()); 3352 %} 3353 3354 // postalloc expand emitter for virtual calls. 3355 enc_class postalloc_expand_java_dynamic_call_sched(method meth, iRegLdst toc) %{ 3356 3357 // Create the nodes for loading the IC from the TOC. 3358 loadConLNodesTuple loadConLNodes_IC = 3359 loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong)Universe::non_oop_word()), 3360 OptoReg::Name(R19_H_num), OptoReg::Name(R19_num)); 3361 3362 // Create the call node. 3363 CallDynamicJavaDirectSchedNode *call = new CallDynamicJavaDirectSchedNode(); 3364 call->_method_handle_invoke = _method_handle_invoke; 3365 call->_vtable_index = _vtable_index; 3366 call->_method = _method; 3367 call->_bci = _bci; 3368 call->_optimized_virtual = _optimized_virtual; 3369 call->_tf = _tf; 3370 call->_entry_point = _entry_point; 3371 call->_cnt = _cnt; 3372 call->_argsize = _argsize; 3373 call->_oop_map = _oop_map; 3374 call->_jvms = _jvms; 3375 call->_jvmadj = _jvmadj; 3376 call->_in_rms = _in_rms; 3377 call->_nesting = _nesting; 3378 call->_override_symbolic_info = _override_symbolic_info; 3379 3380 // New call needs all inputs of old call. 3381 // Req... 3382 for (uint i = 0; i < req(); ++i) { 3383 // The expanded node does not need toc any more. 3384 // Add the inline cache constant here instead. This expresses the 3385 // register of the inline cache must be live at the call. 3386 // Else we would have to adapt JVMState by -1. 3387 if (i == mach_constant_base_node_input()) { 3388 call->add_req(loadConLNodes_IC._last); 3389 } else { 3390 call->add_req(in(i)); 3391 } 3392 } 3393 // ...as well as prec 3394 for (uint i = req(); i < len(); ++i) { 3395 call->add_prec(in(i)); 3396 } 3397 3398 // Remember nodes loading the inline cache into r19. 3399 call->_load_ic_hi_node = loadConLNodes_IC._large_hi; 3400 call->_load_ic_node = loadConLNodes_IC._small; 3401 3402 // Operands for new nodes. 3403 call->_opnds[0] = _opnds[0]; 3404 call->_opnds[1] = _opnds[1]; 3405 3406 // Only the inline cache is associated with a register. 3407 assert(Matcher::inline_cache_reg() == OptoReg::Name(R19_num), "ic reg should be R19"); 3408 3409 // Push new nodes. 3410 if (loadConLNodes_IC._large_hi) nodes->push(loadConLNodes_IC._large_hi); 3411 if (loadConLNodes_IC._last) nodes->push(loadConLNodes_IC._last); 3412 nodes->push(call); 3413 %} 3414 3415 // Compound version of call dynamic 3416 // Toc is only passed so that it can be used in ins_encode statement. 3417 // In the code we have to use $constanttablebase. 3418 enc_class enc_java_dynamic_call(method meth, iRegLdst toc) %{ 3419 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3420 MacroAssembler _masm(&cbuf); 3421 int start_offset = __ offset(); 3422 3423 Register Rtoc = (ra_) ? $constanttablebase : R2_TOC; 3424 #if 0 3425 int vtable_index = this->_vtable_index; 3426 if (_vtable_index < 0) { 3427 // Must be invalid_vtable_index, not nonvirtual_vtable_index. 3428 assert(_vtable_index == Method::invalid_vtable_index, "correct sentinel value"); 3429 Register ic_reg = as_Register(Matcher::inline_cache_reg_encode()); 3430 3431 // Virtual call relocation will point to ic load. 3432 address virtual_call_meta_addr = __ pc(); 3433 // Load a clear inline cache. 3434 AddressLiteral empty_ic((address) Universe::non_oop_word()); 3435 bool success = __ load_const_from_method_toc(ic_reg, empty_ic, Rtoc, /*fixed_size*/ true); 3436 if (!success) { 3437 ciEnv::current()->record_out_of_memory_failure(); 3438 return; 3439 } 3440 // CALL to fixup routine. Fixup routine uses ScopeDesc info 3441 // to determine who we intended to call. 3442 __ relocate(virtual_call_Relocation::spec(virtual_call_meta_addr)); 3443 emit_call_with_trampoline_stub(_masm, (address)$meth$$method, relocInfo::none); 3444 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3445 "Fix constant in ret_addr_offset()"); 3446 } else { 3447 assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); 3448 // Go thru the vtable. Get receiver klass. Receiver already 3449 // checked for non-null. If we'll go thru a C2I adapter, the 3450 // interpreter expects method in R19_method. 3451 3452 __ load_klass(R11_scratch1, R3); 3453 3454 int entry_offset = in_bytes(Klass::vtable_start_offset()) + _vtable_index * vtableEntry::size_in_bytes(); 3455 int v_off = entry_offset + vtableEntry::method_offset_in_bytes(); 3456 __ li(R19_method, v_off); 3457 __ ldx(R19_method/*method oop*/, R19_method/*method offset*/, R11_scratch1/*class*/); 3458 // NOTE: for vtable dispatches, the vtable entry will never be 3459 // null. However it may very well end up in handle_wrong_method 3460 // if the method is abstract for the particular class. 3461 __ ld(R11_scratch1, in_bytes(Method::from_compiled_offset()), R19_method); 3462 // Call target. Either compiled code or C2I adapter. 3463 __ mtctr(R11_scratch1); 3464 __ bctrl(); 3465 if (((MachCallDynamicJavaNode*)this)->ret_addr_offset() != __ offset() - start_offset) { 3466 tty->print(" %d, %d\n", ((MachCallDynamicJavaNode*)this)->ret_addr_offset(),__ offset() - start_offset); 3467 } 3468 assert(((MachCallDynamicJavaNode*)this)->ret_addr_offset() == __ offset() - start_offset, 3469 "Fix constant in ret_addr_offset()"); 3470 } 3471 #endif 3472 Unimplemented(); // ret_addr_offset not yet fixed. Depends on compressed oops (load klass!). 3473 %} 3474 3475 // a runtime call 3476 enc_class enc_java_to_runtime_call (method meth) %{ 3477 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 3478 3479 MacroAssembler _masm(&cbuf); 3480 const address start_pc = __ pc(); 3481 3482 #if defined(ABI_ELFv2) 3483 address entry= !($meth$$method) ? NULL : (address)$meth$$method; 3484 __ call_c(entry, relocInfo::runtime_call_type); 3485 #else 3486 // The function we're going to call. 3487 FunctionDescriptor fdtemp; 3488 const FunctionDescriptor* fd = !($meth$$method) ? &fdtemp : (FunctionDescriptor*)$meth$$method; 3489 3490 Register Rtoc = R12_scratch2; 3491 // Calculate the method's TOC. 3492 __ calculate_address_from_global_toc(Rtoc, __ method_toc()); 3493 // Put entry, env, toc into the constant pool, this needs up to 3 constant 3494 // pool entries; call_c_using_toc will optimize the call. 3495 bool success = __ call_c_using_toc(fd, relocInfo::runtime_call_type, Rtoc); 3496 if (!success) { 3497 ciEnv::current()->record_out_of_memory_failure(); 3498 return; 3499 } 3500 #endif 3501 3502 // Check the ret_addr_offset. 3503 assert(((MachCallRuntimeNode*)this)->ret_addr_offset() == __ last_calls_return_pc() - start_pc, 3504 "Fix constant in ret_addr_offset()"); 3505 %} 3506 3507 // Move to ctr for leaf call. 3508 // This enc_class is needed so that scheduler gets proper 3509 // input mapping for latency computation. 3510 enc_class enc_leaf_call_mtctr(iRegLsrc src) %{ 3511 // TODO: PPC port $archOpcode(ppc64Opcode_mtctr); 3512 MacroAssembler _masm(&cbuf); 3513 __ mtctr($src$$Register); 3514 %} 3515 3516 // Postalloc expand emitter for runtime leaf calls. 3517 enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{ 3518 loadConLNodesTuple loadConLNodes_Entry; 3519 #if defined(ABI_ELFv2) 3520 jlong entry_address = (jlong) this->entry_point(); 3521 assert(entry_address, "need address here"); 3522 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3523 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3524 #else 3525 // Get the struct that describes the function we are about to call. 3526 FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point(); 3527 assert(fd, "need fd here"); 3528 jlong entry_address = (jlong) fd->entry(); 3529 // new nodes 3530 loadConLNodesTuple loadConLNodes_Env; 3531 loadConLNodesTuple loadConLNodes_Toc; 3532 3533 // Create nodes and operands for loading the entry point. 3534 loadConLNodes_Entry = loadConLNodesTuple_create(ra_, n_toc, new immLOper(entry_address), 3535 OptoReg::Name(R12_H_num), OptoReg::Name(R12_num)); 3536 3537 3538 // Create nodes and operands for loading the env pointer. 3539 if (fd->env() != NULL) { 3540 loadConLNodes_Env = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->env()), 3541 OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3542 } else { 3543 loadConLNodes_Env._large_hi = NULL; 3544 loadConLNodes_Env._large_lo = NULL; 3545 loadConLNodes_Env._small = NULL; 3546 loadConLNodes_Env._last = new loadConL16Node(); 3547 loadConLNodes_Env._last->_opnds[0] = new iRegLdstOper(); 3548 loadConLNodes_Env._last->_opnds[1] = new immL16Oper(0); 3549 ra_->set_pair(loadConLNodes_Env._last->_idx, OptoReg::Name(R11_H_num), OptoReg::Name(R11_num)); 3550 } 3551 3552 // Create nodes and operands for loading the Toc point. 3553 loadConLNodes_Toc = loadConLNodesTuple_create(ra_, n_toc, new immLOper((jlong) fd->toc()), 3554 OptoReg::Name(R2_H_num), OptoReg::Name(R2_num)); 3555 #endif // ABI_ELFv2 3556 // mtctr node 3557 MachNode *mtctr = new CallLeafDirect_mtctrNode(); 3558 3559 assert(loadConLNodes_Entry._last != NULL, "entry must exist"); 3560 mtctr->add_req(0, loadConLNodes_Entry._last); 3561 3562 mtctr->_opnds[0] = new iRegLdstOper(); 3563 mtctr->_opnds[1] = new iRegLdstOper(); 3564 3565 // call node 3566 MachCallLeafNode *call = new CallLeafDirectNode(); 3567 3568 call->_opnds[0] = _opnds[0]; 3569 call->_opnds[1] = new methodOper((intptr_t) entry_address); // May get set later. 3570 3571 // Make the new call node look like the old one. 3572 call->_name = _name; 3573 call->_tf = _tf; 3574 call->_entry_point = _entry_point; 3575 call->_cnt = _cnt; 3576 call->_argsize = _argsize; 3577 call->_oop_map = _oop_map; 3578 guarantee(!_jvms, "You must clone the jvms and adapt the offsets by fix_jvms()."); 3579 call->_jvms = NULL; 3580 call->_jvmadj = _jvmadj; 3581 call->_in_rms = _in_rms; 3582 call->_nesting = _nesting; 3583 3584 3585 // New call needs all inputs of old call. 3586 // Req... 3587 for (uint i = 0; i < req(); ++i) { 3588 if (i != mach_constant_base_node_input()) { 3589 call->add_req(in(i)); 3590 } 3591 } 3592 3593 // These must be reqired edges, as the registers are live up to 3594 // the call. Else the constants are handled as kills. 3595 call->add_req(mtctr); 3596 #if !defined(ABI_ELFv2) 3597 call->add_req(loadConLNodes_Env._last); 3598 call->add_req(loadConLNodes_Toc._last); 3599 #endif 3600 3601 // ...as well as prec 3602 for (uint i = req(); i < len(); ++i) { 3603 call->add_prec(in(i)); 3604 } 3605 3606 // registers 3607 ra_->set1(mtctr->_idx, OptoReg::Name(SR_CTR_num)); 3608 3609 // Insert the new nodes. 3610 if (loadConLNodes_Entry._large_hi) nodes->push(loadConLNodes_Entry._large_hi); 3611 if (loadConLNodes_Entry._last) nodes->push(loadConLNodes_Entry._last); 3612 #if !defined(ABI_ELFv2) 3613 if (loadConLNodes_Env._large_hi) nodes->push(loadConLNodes_Env._large_hi); 3614 if (loadConLNodes_Env._last) nodes->push(loadConLNodes_Env._last); 3615 if (loadConLNodes_Toc._large_hi) nodes->push(loadConLNodes_Toc._large_hi); 3616 if (loadConLNodes_Toc._last) nodes->push(loadConLNodes_Toc._last); 3617 #endif 3618 nodes->push(mtctr); 3619 nodes->push(call); 3620 %} 3621 %} 3622 3623 //----------FRAME-------------------------------------------------------------- 3624 // Definition of frame structure and management information. 3625 3626 frame %{ 3627 // What direction does stack grow in (assumed to be same for native & Java). 3628 stack_direction(TOWARDS_LOW); 3629 3630 // These two registers define part of the calling convention between 3631 // compiled code and the interpreter. 3632 3633 // Inline Cache Register or method for I2C. 3634 inline_cache_reg(R19); // R19_method 3635 3636 // Method Oop Register when calling interpreter. 3637 interpreter_method_oop_reg(R19); // R19_method 3638 3639 // Optional: name the operand used by cisc-spilling to access 3640 // [stack_pointer + offset]. 3641 cisc_spilling_operand_name(indOffset); 3642 3643 // Number of stack slots consumed by a Monitor enter. 3644 sync_stack_slots((frame::jit_monitor_size / VMRegImpl::stack_slot_size)); 3645 3646 // Compiled code's Frame Pointer. 3647 frame_pointer(R1); // R1_SP 3648 3649 // Interpreter stores its frame pointer in a register which is 3650 // stored to the stack by I2CAdaptors. I2CAdaptors convert from 3651 // interpreted java to compiled java. 3652 // 3653 // R14_state holds pointer to caller's cInterpreter. 3654 interpreter_frame_pointer(R14); // R14_state 3655 3656 stack_alignment(frame::alignment_in_bytes); 3657 3658 in_preserve_stack_slots((frame::jit_in_preserve_size / VMRegImpl::stack_slot_size)); 3659 3660 // Number of outgoing stack slots killed above the 3661 // out_preserve_stack_slots for calls to C. Supports the var-args 3662 // backing area for register parms. 3663 // 3664 varargs_C_out_slots_killed(((frame::abi_reg_args_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size)); 3665 3666 // The after-PROLOG location of the return address. Location of 3667 // return address specifies a type (REG or STACK) and a number 3668 // representing the register number (i.e. - use a register name) or 3669 // stack slot. 3670 // 3671 // A: Link register is stored in stack slot ... 3672 // M: ... but it's in the caller's frame according to PPC-64 ABI. 3673 // J: Therefore, we make sure that the link register is also in R11_scratch1 3674 // at the end of the prolog. 3675 // B: We use R20, now. 3676 //return_addr(REG R20); 3677 3678 // G: After reading the comments made by all the luminaries on their 3679 // failure to tell the compiler where the return address really is, 3680 // I hardly dare to try myself. However, I'm convinced it's in slot 3681 // 4 what apparently works and saves us some spills. 3682 return_addr(STACK 4); 3683 3684 // This is the body of the function 3685 // 3686 // void Matcher::calling_convention(OptoRegPair* sig, // array of ideal regs 3687 // uint length, // length of array 3688 // bool is_outgoing) 3689 // 3690 // The `sig' array is to be updated. sig[j] represents the location 3691 // of the j-th argument, either a register or a stack slot. 3692 3693 // Comment taken from i486.ad: 3694 // Body of function which returns an integer array locating 3695 // arguments either in registers or in stack slots. Passed an array 3696 // of ideal registers called "sig" and a "length" count. Stack-slot 3697 // offsets are based on outgoing arguments, i.e. a CALLER setting up 3698 // arguments for a CALLEE. Incoming stack arguments are 3699 // automatically biased by the preserve_stack_slots field above. 3700 calling_convention %{ 3701 // No difference between ingoing/outgoing. Just pass false. 3702 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 3703 %} 3704 3705 // Comment taken from i486.ad: 3706 // Body of function which returns an integer array locating 3707 // arguments either in registers or in stack slots. Passed an array 3708 // of ideal registers called "sig" and a "length" count. Stack-slot 3709 // offsets are based on outgoing arguments, i.e. a CALLER setting up 3710 // arguments for a CALLEE. Incoming stack arguments are 3711 // automatically biased by the preserve_stack_slots field above. 3712 c_calling_convention %{ 3713 // This is obviously always outgoing. 3714 // C argument in register AND stack slot. 3715 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 3716 %} 3717 3718 // Location of native (C/C++) and interpreter return values. This 3719 // is specified to be the same as Java. In the 32-bit VM, long 3720 // values are actually returned from native calls in O0:O1 and 3721 // returned to the interpreter in I0:I1. The copying to and from 3722 // the register pairs is done by the appropriate call and epilog 3723 // opcodes. This simplifies the register allocator. 3724 c_return_value %{ 3725 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 3726 (ideal_reg == Op_RegN && Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0), 3727 "only return normal values"); 3728 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 3729 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 3730 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 3731 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 3732 %} 3733 3734 // Location of compiled Java return values. Same as C 3735 return_value %{ 3736 assert((ideal_reg >= Op_RegI && ideal_reg <= Op_RegL) || 3737 (ideal_reg == Op_RegN && Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0), 3738 "only return normal values"); 3739 // enum names from opcodes.hpp: Op_Node Op_Set Op_RegN Op_RegI Op_RegP Op_RegF Op_RegD Op_RegL 3740 static int typeToRegLo[Op_RegL+1] = { 0, 0, R3_num, R3_num, R3_num, F1_num, F1_num, R3_num }; 3741 static int typeToRegHi[Op_RegL+1] = { 0, 0, OptoReg::Bad, R3_H_num, R3_H_num, OptoReg::Bad, F1_H_num, R3_H_num }; 3742 return OptoRegPair(typeToRegHi[ideal_reg], typeToRegLo[ideal_reg]); 3743 %} 3744 %} 3745 3746 3747 //----------ATTRIBUTES--------------------------------------------------------- 3748 3749 //----------Operand Attributes------------------------------------------------- 3750 op_attrib op_cost(1); // Required cost attribute. 3751 3752 //----------Instruction Attributes--------------------------------------------- 3753 3754 // Cost attribute. required. 3755 ins_attrib ins_cost(DEFAULT_COST); 3756 3757 // Is this instruction a non-matching short branch variant of some 3758 // long branch? Not required. 3759 ins_attrib ins_short_branch(0); 3760 3761 ins_attrib ins_is_TrapBasedCheckNode(true); 3762 3763 // Number of constants. 3764 // This instruction uses the given number of constants 3765 // (optional attribute). 3766 // This is needed to determine in time whether the constant pool will 3767 // exceed 4000 entries. Before postalloc_expand the overall number of constants 3768 // is determined. It's also used to compute the constant pool size 3769 // in Output(). 3770 ins_attrib ins_num_consts(0); 3771 3772 // Required alignment attribute (must be a power of 2) specifies the 3773 // alignment that some part of the instruction (not necessarily the 3774 // start) requires. If > 1, a compute_padding() function must be 3775 // provided for the instruction. 3776 ins_attrib ins_alignment(1); 3777 3778 // Enforce/prohibit rematerializations. 3779 // - If an instruction is attributed with 'ins_cannot_rematerialize(true)' 3780 // then rematerialization of that instruction is prohibited and the 3781 // instruction's value will be spilled if necessary. 3782 // Causes that MachNode::rematerialize() returns false. 3783 // - If an instruction is attributed with 'ins_should_rematerialize(true)' 3784 // then rematerialization should be enforced and a copy of the instruction 3785 // should be inserted if possible; rematerialization is not guaranteed. 3786 // Note: this may result in rematerializations in front of every use. 3787 // Causes that MachNode::rematerialize() can return true. 3788 // (optional attribute) 3789 ins_attrib ins_cannot_rematerialize(false); 3790 ins_attrib ins_should_rematerialize(false); 3791 3792 // Instruction has variable size depending on alignment. 3793 ins_attrib ins_variable_size_depending_on_alignment(false); 3794 3795 // Instruction is a nop. 3796 ins_attrib ins_is_nop(false); 3797 3798 // Instruction is mapped to a MachIfFastLock node (instead of MachFastLock). 3799 ins_attrib ins_use_mach_if_fast_lock_node(false); 3800 3801 // Field for the toc offset of a constant. 3802 // 3803 // This is needed if the toc offset is not encodable as an immediate in 3804 // the PPC load instruction. If so, the upper (hi) bits of the offset are 3805 // added to the toc, and from this a load with immediate is performed. 3806 // With postalloc expand, we get two nodes that require the same offset 3807 // but which don't know about each other. The offset is only known 3808 // when the constant is added to the constant pool during emitting. 3809 // It is generated in the 'hi'-node adding the upper bits, and saved 3810 // in this node. The 'lo'-node has a link to the 'hi'-node and reads 3811 // the offset from there when it gets encoded. 3812 ins_attrib ins_field_const_toc_offset(0); 3813 ins_attrib ins_field_const_toc_offset_hi_node(0); 3814 3815 // A field that can hold the instructions offset in the code buffer. 3816 // Set in the nodes emitter. 3817 ins_attrib ins_field_cbuf_insts_offset(-1); 3818 3819 // Fields for referencing a call's load-IC-node. 3820 // If the toc offset can not be encoded as an immediate in a load, we 3821 // use two nodes. 3822 ins_attrib ins_field_load_ic_hi_node(0); 3823 ins_attrib ins_field_load_ic_node(0); 3824 3825 //----------OPERANDS----------------------------------------------------------- 3826 // Operand definitions must precede instruction definitions for correct 3827 // parsing in the ADLC because operands constitute user defined types 3828 // which are used in instruction definitions. 3829 // 3830 // Formats are generated automatically for constants and base registers. 3831 3832 //----------Simple Operands---------------------------------------------------- 3833 // Immediate Operands 3834 3835 // Integer Immediate: 32-bit 3836 operand immI() %{ 3837 match(ConI); 3838 op_cost(40); 3839 format %{ %} 3840 interface(CONST_INTER); 3841 %} 3842 3843 operand immI8() %{ 3844 predicate(Assembler::is_simm(n->get_int(), 8)); 3845 op_cost(0); 3846 match(ConI); 3847 format %{ %} 3848 interface(CONST_INTER); 3849 %} 3850 3851 // Integer Immediate: 16-bit 3852 operand immI16() %{ 3853 predicate(Assembler::is_simm(n->get_int(), 16)); 3854 op_cost(0); 3855 match(ConI); 3856 format %{ %} 3857 interface(CONST_INTER); 3858 %} 3859 3860 // Integer Immediate: 32-bit, where lowest 16 bits are 0x0000. 3861 operand immIhi16() %{ 3862 predicate(((n->get_int() & 0xffff0000) != 0) && ((n->get_int() & 0xffff) == 0)); 3863 match(ConI); 3864 op_cost(0); 3865 format %{ %} 3866 interface(CONST_INTER); 3867 %} 3868 3869 operand immInegpow2() %{ 3870 predicate(is_power_of_2_long((jlong) (julong) (juint) (-(n->get_int())))); 3871 match(ConI); 3872 op_cost(0); 3873 format %{ %} 3874 interface(CONST_INTER); 3875 %} 3876 3877 operand immIpow2minus1() %{ 3878 predicate(is_power_of_2_long((((jlong) (n->get_int()))+1))); 3879 match(ConI); 3880 op_cost(0); 3881 format %{ %} 3882 interface(CONST_INTER); 3883 %} 3884 3885 operand immIpowerOf2() %{ 3886 predicate(is_power_of_2_long((((jlong) (julong) (juint) (n->get_int()))))); 3887 match(ConI); 3888 op_cost(0); 3889 format %{ %} 3890 interface(CONST_INTER); 3891 %} 3892 3893 // Unsigned Integer Immediate: the values 0-31 3894 operand uimmI5() %{ 3895 predicate(Assembler::is_uimm(n->get_int(), 5)); 3896 match(ConI); 3897 op_cost(0); 3898 format %{ %} 3899 interface(CONST_INTER); 3900 %} 3901 3902 // Unsigned Integer Immediate: 6-bit 3903 operand uimmI6() %{ 3904 predicate(Assembler::is_uimm(n->get_int(), 6)); 3905 match(ConI); 3906 op_cost(0); 3907 format %{ %} 3908 interface(CONST_INTER); 3909 %} 3910 3911 // Unsigned Integer Immediate: 6-bit int, greater than 32 3912 operand uimmI6_ge32() %{ 3913 predicate(Assembler::is_uimm(n->get_int(), 6) && n->get_int() >= 32); 3914 match(ConI); 3915 op_cost(0); 3916 format %{ %} 3917 interface(CONST_INTER); 3918 %} 3919 3920 // Unsigned Integer Immediate: 15-bit 3921 operand uimmI15() %{ 3922 predicate(Assembler::is_uimm(n->get_int(), 15)); 3923 match(ConI); 3924 op_cost(0); 3925 format %{ %} 3926 interface(CONST_INTER); 3927 %} 3928 3929 // Unsigned Integer Immediate: 16-bit 3930 operand uimmI16() %{ 3931 predicate(Assembler::is_uimm(n->get_int(), 16)); 3932 match(ConI); 3933 op_cost(0); 3934 format %{ %} 3935 interface(CONST_INTER); 3936 %} 3937 3938 // constant 'int 0'. 3939 operand immI_0() %{ 3940 predicate(n->get_int() == 0); 3941 match(ConI); 3942 op_cost(0); 3943 format %{ %} 3944 interface(CONST_INTER); 3945 %} 3946 3947 // constant 'int 1'. 3948 operand immI_1() %{ 3949 predicate(n->get_int() == 1); 3950 match(ConI); 3951 op_cost(0); 3952 format %{ %} 3953 interface(CONST_INTER); 3954 %} 3955 3956 // constant 'int -1'. 3957 operand immI_minus1() %{ 3958 predicate(n->get_int() == -1); 3959 match(ConI); 3960 op_cost(0); 3961 format %{ %} 3962 interface(CONST_INTER); 3963 %} 3964 3965 // int value 16. 3966 operand immI_16() %{ 3967 predicate(n->get_int() == 16); 3968 match(ConI); 3969 op_cost(0); 3970 format %{ %} 3971 interface(CONST_INTER); 3972 %} 3973 3974 // int value 24. 3975 operand immI_24() %{ 3976 predicate(n->get_int() == 24); 3977 match(ConI); 3978 op_cost(0); 3979 format %{ %} 3980 interface(CONST_INTER); 3981 %} 3982 3983 // Compressed oops constants 3984 // Pointer Immediate 3985 operand immN() %{ 3986 match(ConN); 3987 3988 op_cost(10); 3989 format %{ %} 3990 interface(CONST_INTER); 3991 %} 3992 3993 // NULL Pointer Immediate 3994 operand immN_0() %{ 3995 predicate(n->get_narrowcon() == 0); 3996 match(ConN); 3997 3998 op_cost(0); 3999 format %{ %} 4000 interface(CONST_INTER); 4001 %} 4002 4003 // Compressed klass constants 4004 operand immNKlass() %{ 4005 match(ConNKlass); 4006 4007 op_cost(0); 4008 format %{ %} 4009 interface(CONST_INTER); 4010 %} 4011 4012 // This operand can be used to avoid matching of an instruct 4013 // with chain rule. 4014 operand immNKlass_NM() %{ 4015 match(ConNKlass); 4016 predicate(false); 4017 op_cost(0); 4018 format %{ %} 4019 interface(CONST_INTER); 4020 %} 4021 4022 // Pointer Immediate: 64-bit 4023 operand immP() %{ 4024 match(ConP); 4025 op_cost(0); 4026 format %{ %} 4027 interface(CONST_INTER); 4028 %} 4029 4030 // Operand to avoid match of loadConP. 4031 // This operand can be used to avoid matching of an instruct 4032 // with chain rule. 4033 operand immP_NM() %{ 4034 match(ConP); 4035 predicate(false); 4036 op_cost(0); 4037 format %{ %} 4038 interface(CONST_INTER); 4039 %} 4040 4041 // costant 'pointer 0'. 4042 operand immP_0() %{ 4043 predicate(n->get_ptr() == 0); 4044 match(ConP); 4045 op_cost(0); 4046 format %{ %} 4047 interface(CONST_INTER); 4048 %} 4049 4050 // pointer 0x0 or 0x1 4051 operand immP_0or1() %{ 4052 predicate((n->get_ptr() == 0) || (n->get_ptr() == 1)); 4053 match(ConP); 4054 op_cost(0); 4055 format %{ %} 4056 interface(CONST_INTER); 4057 %} 4058 4059 operand immL() %{ 4060 match(ConL); 4061 op_cost(40); 4062 format %{ %} 4063 interface(CONST_INTER); 4064 %} 4065 4066 operand immLmax30() %{ 4067 predicate((n->get_long() <= 30)); 4068 match(ConL); 4069 op_cost(0); 4070 format %{ %} 4071 interface(CONST_INTER); 4072 %} 4073 4074 // Long Immediate: 16-bit 4075 operand immL16() %{ 4076 predicate(Assembler::is_simm(n->get_long(), 16)); 4077 match(ConL); 4078 op_cost(0); 4079 format %{ %} 4080 interface(CONST_INTER); 4081 %} 4082 4083 // Long Immediate: 16-bit, 4-aligned 4084 operand immL16Alg4() %{ 4085 predicate(Assembler::is_simm(n->get_long(), 16) && ((n->get_long() & 0x3) == 0)); 4086 match(ConL); 4087 op_cost(0); 4088 format %{ %} 4089 interface(CONST_INTER); 4090 %} 4091 4092 // Long Immediate: 32-bit, where lowest 16 bits are 0x0000. 4093 operand immL32hi16() %{ 4094 predicate(Assembler::is_simm(n->get_long(), 32) && ((n->get_long() & 0xffffL) == 0L)); 4095 match(ConL); 4096 op_cost(0); 4097 format %{ %} 4098 interface(CONST_INTER); 4099 %} 4100 4101 // Long Immediate: 32-bit 4102 operand immL32() %{ 4103 predicate(Assembler::is_simm(n->get_long(), 32)); 4104 match(ConL); 4105 op_cost(0); 4106 format %{ %} 4107 interface(CONST_INTER); 4108 %} 4109 4110 // Long Immediate: 64-bit, where highest 16 bits are not 0x0000. 4111 operand immLhighest16() %{ 4112 predicate((n->get_long() & 0xffff000000000000L) != 0L && (n->get_long() & 0x0000ffffffffffffL) == 0L); 4113 match(ConL); 4114 op_cost(0); 4115 format %{ %} 4116 interface(CONST_INTER); 4117 %} 4118 4119 operand immLnegpow2() %{ 4120 predicate(is_power_of_2_long((jlong)-(n->get_long()))); 4121 match(ConL); 4122 op_cost(0); 4123 format %{ %} 4124 interface(CONST_INTER); 4125 %} 4126 4127 operand immLpow2minus1() %{ 4128 predicate(is_power_of_2_long((((jlong) (n->get_long()))+1)) && 4129 (n->get_long() != (jlong)0xffffffffffffffffL)); 4130 match(ConL); 4131 op_cost(0); 4132 format %{ %} 4133 interface(CONST_INTER); 4134 %} 4135 4136 // constant 'long 0'. 4137 operand immL_0() %{ 4138 predicate(n->get_long() == 0L); 4139 match(ConL); 4140 op_cost(0); 4141 format %{ %} 4142 interface(CONST_INTER); 4143 %} 4144 4145 // constat ' long -1'. 4146 operand immL_minus1() %{ 4147 predicate(n->get_long() == -1L); 4148 match(ConL); 4149 op_cost(0); 4150 format %{ %} 4151 interface(CONST_INTER); 4152 %} 4153 4154 // Long Immediate: low 32-bit mask 4155 operand immL_32bits() %{ 4156 predicate(n->get_long() == 0xFFFFFFFFL); 4157 match(ConL); 4158 op_cost(0); 4159 format %{ %} 4160 interface(CONST_INTER); 4161 %} 4162 4163 // Unsigned Long Immediate: 16-bit 4164 operand uimmL16() %{ 4165 predicate(Assembler::is_uimm(n->get_long(), 16)); 4166 match(ConL); 4167 op_cost(0); 4168 format %{ %} 4169 interface(CONST_INTER); 4170 %} 4171 4172 // Float Immediate 4173 operand immF() %{ 4174 match(ConF); 4175 op_cost(40); 4176 format %{ %} 4177 interface(CONST_INTER); 4178 %} 4179 4180 // Float Immediate: +0.0f. 4181 operand immF_0() %{ 4182 predicate(jint_cast(n->getf()) == 0); 4183 match(ConF); 4184 4185 op_cost(0); 4186 format %{ %} 4187 interface(CONST_INTER); 4188 %} 4189 4190 // Double Immediate 4191 operand immD() %{ 4192 match(ConD); 4193 op_cost(40); 4194 format %{ %} 4195 interface(CONST_INTER); 4196 %} 4197 4198 // Integer Register Operands 4199 // Integer Destination Register 4200 // See definition of reg_class bits32_reg_rw. 4201 operand iRegIdst() %{ 4202 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4203 match(RegI); 4204 match(rscratch1RegI); 4205 match(rscratch2RegI); 4206 match(rarg1RegI); 4207 match(rarg2RegI); 4208 match(rarg3RegI); 4209 match(rarg4RegI); 4210 format %{ %} 4211 interface(REG_INTER); 4212 %} 4213 4214 // Integer Source Register 4215 // See definition of reg_class bits32_reg_ro. 4216 operand iRegIsrc() %{ 4217 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4218 match(RegI); 4219 match(rscratch1RegI); 4220 match(rscratch2RegI); 4221 match(rarg1RegI); 4222 match(rarg2RegI); 4223 match(rarg3RegI); 4224 match(rarg4RegI); 4225 format %{ %} 4226 interface(REG_INTER); 4227 %} 4228 4229 operand rscratch1RegI() %{ 4230 constraint(ALLOC_IN_RC(rscratch1_bits32_reg)); 4231 match(iRegIdst); 4232 format %{ %} 4233 interface(REG_INTER); 4234 %} 4235 4236 operand rscratch2RegI() %{ 4237 constraint(ALLOC_IN_RC(rscratch2_bits32_reg)); 4238 match(iRegIdst); 4239 format %{ %} 4240 interface(REG_INTER); 4241 %} 4242 4243 operand rarg1RegI() %{ 4244 constraint(ALLOC_IN_RC(rarg1_bits32_reg)); 4245 match(iRegIdst); 4246 format %{ %} 4247 interface(REG_INTER); 4248 %} 4249 4250 operand rarg2RegI() %{ 4251 constraint(ALLOC_IN_RC(rarg2_bits32_reg)); 4252 match(iRegIdst); 4253 format %{ %} 4254 interface(REG_INTER); 4255 %} 4256 4257 operand rarg3RegI() %{ 4258 constraint(ALLOC_IN_RC(rarg3_bits32_reg)); 4259 match(iRegIdst); 4260 format %{ %} 4261 interface(REG_INTER); 4262 %} 4263 4264 operand rarg4RegI() %{ 4265 constraint(ALLOC_IN_RC(rarg4_bits32_reg)); 4266 match(iRegIdst); 4267 format %{ %} 4268 interface(REG_INTER); 4269 %} 4270 4271 operand rarg1RegL() %{ 4272 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4273 match(iRegLdst); 4274 format %{ %} 4275 interface(REG_INTER); 4276 %} 4277 4278 operand rarg2RegL() %{ 4279 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4280 match(iRegLdst); 4281 format %{ %} 4282 interface(REG_INTER); 4283 %} 4284 4285 operand rarg3RegL() %{ 4286 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4287 match(iRegLdst); 4288 format %{ %} 4289 interface(REG_INTER); 4290 %} 4291 4292 operand rarg4RegL() %{ 4293 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4294 match(iRegLdst); 4295 format %{ %} 4296 interface(REG_INTER); 4297 %} 4298 4299 // Pointer Destination Register 4300 // See definition of reg_class bits64_reg_rw. 4301 operand iRegPdst() %{ 4302 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4303 match(RegP); 4304 match(rscratch1RegP); 4305 match(rscratch2RegP); 4306 match(rarg1RegP); 4307 match(rarg2RegP); 4308 match(rarg3RegP); 4309 match(rarg4RegP); 4310 format %{ %} 4311 interface(REG_INTER); 4312 %} 4313 4314 // Pointer Destination Register 4315 // Operand not using r11 and r12 (killed in epilog). 4316 operand iRegPdstNoScratch() %{ 4317 constraint(ALLOC_IN_RC(bits64_reg_leaf_call)); 4318 match(RegP); 4319 match(rarg1RegP); 4320 match(rarg2RegP); 4321 match(rarg3RegP); 4322 match(rarg4RegP); 4323 format %{ %} 4324 interface(REG_INTER); 4325 %} 4326 4327 // Pointer Source Register 4328 // See definition of reg_class bits64_reg_ro. 4329 operand iRegPsrc() %{ 4330 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4331 match(RegP); 4332 match(iRegPdst); 4333 match(rscratch1RegP); 4334 match(rscratch2RegP); 4335 match(rarg1RegP); 4336 match(rarg2RegP); 4337 match(rarg3RegP); 4338 match(rarg4RegP); 4339 match(threadRegP); 4340 format %{ %} 4341 interface(REG_INTER); 4342 %} 4343 4344 // Thread operand. 4345 operand threadRegP() %{ 4346 constraint(ALLOC_IN_RC(thread_bits64_reg)); 4347 match(iRegPdst); 4348 format %{ "R16" %} 4349 interface(REG_INTER); 4350 %} 4351 4352 operand rscratch1RegP() %{ 4353 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4354 match(iRegPdst); 4355 format %{ "R11" %} 4356 interface(REG_INTER); 4357 %} 4358 4359 operand rscratch2RegP() %{ 4360 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4361 match(iRegPdst); 4362 format %{ %} 4363 interface(REG_INTER); 4364 %} 4365 4366 operand rarg1RegP() %{ 4367 constraint(ALLOC_IN_RC(rarg1_bits64_reg)); 4368 match(iRegPdst); 4369 format %{ %} 4370 interface(REG_INTER); 4371 %} 4372 4373 operand rarg2RegP() %{ 4374 constraint(ALLOC_IN_RC(rarg2_bits64_reg)); 4375 match(iRegPdst); 4376 format %{ %} 4377 interface(REG_INTER); 4378 %} 4379 4380 operand rarg3RegP() %{ 4381 constraint(ALLOC_IN_RC(rarg3_bits64_reg)); 4382 match(iRegPdst); 4383 format %{ %} 4384 interface(REG_INTER); 4385 %} 4386 4387 operand rarg4RegP() %{ 4388 constraint(ALLOC_IN_RC(rarg4_bits64_reg)); 4389 match(iRegPdst); 4390 format %{ %} 4391 interface(REG_INTER); 4392 %} 4393 4394 operand iRegNsrc() %{ 4395 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4396 match(RegN); 4397 match(iRegNdst); 4398 4399 format %{ %} 4400 interface(REG_INTER); 4401 %} 4402 4403 operand iRegNdst() %{ 4404 constraint(ALLOC_IN_RC(bits32_reg_rw)); 4405 match(RegN); 4406 4407 format %{ %} 4408 interface(REG_INTER); 4409 %} 4410 4411 // Long Destination Register 4412 // See definition of reg_class bits64_reg_rw. 4413 operand iRegLdst() %{ 4414 constraint(ALLOC_IN_RC(bits64_reg_rw)); 4415 match(RegL); 4416 match(rscratch1RegL); 4417 match(rscratch2RegL); 4418 format %{ %} 4419 interface(REG_INTER); 4420 %} 4421 4422 // Long Source Register 4423 // See definition of reg_class bits64_reg_ro. 4424 operand iRegLsrc() %{ 4425 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4426 match(RegL); 4427 match(iRegLdst); 4428 match(rscratch1RegL); 4429 match(rscratch2RegL); 4430 format %{ %} 4431 interface(REG_INTER); 4432 %} 4433 4434 // Special operand for ConvL2I. 4435 operand iRegL2Isrc(iRegLsrc reg) %{ 4436 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4437 match(ConvL2I reg); 4438 format %{ "ConvL2I($reg)" %} 4439 interface(REG_INTER) 4440 %} 4441 4442 operand rscratch1RegL() %{ 4443 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); 4444 match(RegL); 4445 format %{ %} 4446 interface(REG_INTER); 4447 %} 4448 4449 operand rscratch2RegL() %{ 4450 constraint(ALLOC_IN_RC(rscratch2_bits64_reg)); 4451 match(RegL); 4452 format %{ %} 4453 interface(REG_INTER); 4454 %} 4455 4456 // Condition Code Flag Registers 4457 operand flagsReg() %{ 4458 constraint(ALLOC_IN_RC(int_flags)); 4459 match(RegFlags); 4460 format %{ %} 4461 interface(REG_INTER); 4462 %} 4463 4464 operand flagsRegSrc() %{ 4465 constraint(ALLOC_IN_RC(int_flags_ro)); 4466 match(RegFlags); 4467 match(flagsReg); 4468 match(flagsRegCR0); 4469 format %{ %} 4470 interface(REG_INTER); 4471 %} 4472 4473 // Condition Code Flag Register CR0 4474 operand flagsRegCR0() %{ 4475 constraint(ALLOC_IN_RC(int_flags_CR0)); 4476 match(RegFlags); 4477 format %{ "CR0" %} 4478 interface(REG_INTER); 4479 %} 4480 4481 operand flagsRegCR1() %{ 4482 constraint(ALLOC_IN_RC(int_flags_CR1)); 4483 match(RegFlags); 4484 format %{ "CR1" %} 4485 interface(REG_INTER); 4486 %} 4487 4488 operand flagsRegCR6() %{ 4489 constraint(ALLOC_IN_RC(int_flags_CR6)); 4490 match(RegFlags); 4491 format %{ "CR6" %} 4492 interface(REG_INTER); 4493 %} 4494 4495 operand regCTR() %{ 4496 constraint(ALLOC_IN_RC(ctr_reg)); 4497 // RegFlags should work. Introducing a RegSpecial type would cause a 4498 // lot of changes. 4499 match(RegFlags); 4500 format %{"SR_CTR" %} 4501 interface(REG_INTER); 4502 %} 4503 4504 operand regD() %{ 4505 constraint(ALLOC_IN_RC(dbl_reg)); 4506 match(RegD); 4507 format %{ %} 4508 interface(REG_INTER); 4509 %} 4510 4511 operand regF() %{ 4512 constraint(ALLOC_IN_RC(flt_reg)); 4513 match(RegF); 4514 format %{ %} 4515 interface(REG_INTER); 4516 %} 4517 4518 // Special Registers 4519 4520 // Method Register 4521 operand inline_cache_regP(iRegPdst reg) %{ 4522 constraint(ALLOC_IN_RC(r19_bits64_reg)); // inline_cache_reg 4523 match(reg); 4524 format %{ %} 4525 interface(REG_INTER); 4526 %} 4527 4528 operand compiler_method_oop_regP(iRegPdst reg) %{ 4529 constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); // compiler_method_oop_reg 4530 match(reg); 4531 format %{ %} 4532 interface(REG_INTER); 4533 %} 4534 4535 operand interpreter_method_oop_regP(iRegPdst reg) %{ 4536 constraint(ALLOC_IN_RC(r19_bits64_reg)); // interpreter_method_oop_reg 4537 match(reg); 4538 format %{ %} 4539 interface(REG_INTER); 4540 %} 4541 4542 // Operands to remove register moves in unscaled mode. 4543 // Match read/write registers with an EncodeP node if neither shift nor add are required. 4544 operand iRegP2N(iRegPsrc reg) %{ 4545 predicate(false /* TODO: PPC port MatchDecodeNodes*/&& Universe::narrow_oop_shift() == 0); 4546 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4547 match(EncodeP reg); 4548 format %{ "$reg" %} 4549 interface(REG_INTER) 4550 %} 4551 4552 operand iRegN2P(iRegNsrc reg) %{ 4553 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4554 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4555 match(DecodeN reg); 4556 format %{ "$reg" %} 4557 interface(REG_INTER) 4558 %} 4559 4560 operand iRegN2P_klass(iRegNsrc reg) %{ 4561 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 4562 constraint(ALLOC_IN_RC(bits32_reg_ro)); 4563 match(DecodeNKlass reg); 4564 format %{ "$reg" %} 4565 interface(REG_INTER) 4566 %} 4567 4568 //----------Complex Operands--------------------------------------------------- 4569 // Indirect Memory Reference 4570 operand indirect(iRegPsrc reg) %{ 4571 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4572 match(reg); 4573 op_cost(100); 4574 format %{ "[$reg]" %} 4575 interface(MEMORY_INTER) %{ 4576 base($reg); 4577 index(0x0); 4578 scale(0x0); 4579 disp(0x0); 4580 %} 4581 %} 4582 4583 // Indirect with Offset 4584 operand indOffset16(iRegPsrc reg, immL16 offset) %{ 4585 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4586 match(AddP reg offset); 4587 op_cost(100); 4588 format %{ "[$reg + $offset]" %} 4589 interface(MEMORY_INTER) %{ 4590 base($reg); 4591 index(0x0); 4592 scale(0x0); 4593 disp($offset); 4594 %} 4595 %} 4596 4597 // Indirect with 4-aligned Offset 4598 operand indOffset16Alg4(iRegPsrc reg, immL16Alg4 offset) %{ 4599 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4600 match(AddP reg offset); 4601 op_cost(100); 4602 format %{ "[$reg + $offset]" %} 4603 interface(MEMORY_INTER) %{ 4604 base($reg); 4605 index(0x0); 4606 scale(0x0); 4607 disp($offset); 4608 %} 4609 %} 4610 4611 //----------Complex Operands for Compressed OOPs------------------------------- 4612 // Compressed OOPs with narrow_oop_shift == 0. 4613 4614 // Indirect Memory Reference, compressed OOP 4615 operand indirectNarrow(iRegNsrc reg) %{ 4616 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4617 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4618 match(DecodeN reg); 4619 op_cost(100); 4620 format %{ "[$reg]" %} 4621 interface(MEMORY_INTER) %{ 4622 base($reg); 4623 index(0x0); 4624 scale(0x0); 4625 disp(0x0); 4626 %} 4627 %} 4628 4629 operand indirectNarrow_klass(iRegNsrc reg) %{ 4630 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 4631 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4632 match(DecodeNKlass reg); 4633 op_cost(100); 4634 format %{ "[$reg]" %} 4635 interface(MEMORY_INTER) %{ 4636 base($reg); 4637 index(0x0); 4638 scale(0x0); 4639 disp(0x0); 4640 %} 4641 %} 4642 4643 // Indirect with Offset, compressed OOP 4644 operand indOffset16Narrow(iRegNsrc reg, immL16 offset) %{ 4645 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4646 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4647 match(AddP (DecodeN reg) offset); 4648 op_cost(100); 4649 format %{ "[$reg + $offset]" %} 4650 interface(MEMORY_INTER) %{ 4651 base($reg); 4652 index(0x0); 4653 scale(0x0); 4654 disp($offset); 4655 %} 4656 %} 4657 4658 operand indOffset16Narrow_klass(iRegNsrc reg, immL16 offset) %{ 4659 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 4660 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4661 match(AddP (DecodeNKlass reg) offset); 4662 op_cost(100); 4663 format %{ "[$reg + $offset]" %} 4664 interface(MEMORY_INTER) %{ 4665 base($reg); 4666 index(0x0); 4667 scale(0x0); 4668 disp($offset); 4669 %} 4670 %} 4671 4672 // Indirect with 4-aligned Offset, compressed OOP 4673 operand indOffset16NarrowAlg4(iRegNsrc reg, immL16Alg4 offset) %{ 4674 predicate(false /* TODO: PPC port MatchDecodeNodes*/); 4675 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4676 match(AddP (DecodeN reg) offset); 4677 op_cost(100); 4678 format %{ "[$reg + $offset]" %} 4679 interface(MEMORY_INTER) %{ 4680 base($reg); 4681 index(0x0); 4682 scale(0x0); 4683 disp($offset); 4684 %} 4685 %} 4686 4687 operand indOffset16NarrowAlg4_klass(iRegNsrc reg, immL16Alg4 offset) %{ 4688 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0); 4689 constraint(ALLOC_IN_RC(bits64_reg_ro)); 4690 match(AddP (DecodeNKlass reg) offset); 4691 op_cost(100); 4692 format %{ "[$reg + $offset]" %} 4693 interface(MEMORY_INTER) %{ 4694 base($reg); 4695 index(0x0); 4696 scale(0x0); 4697 disp($offset); 4698 %} 4699 %} 4700 4701 //----------Special Memory Operands-------------------------------------------- 4702 // Stack Slot Operand 4703 // 4704 // This operand is used for loading and storing temporary values on 4705 // the stack where a match requires a value to flow through memory. 4706 operand stackSlotI(sRegI reg) %{ 4707 constraint(ALLOC_IN_RC(stack_slots)); 4708 op_cost(100); 4709 //match(RegI); 4710 format %{ "[sp+$reg]" %} 4711 interface(MEMORY_INTER) %{ 4712 base(0x1); // R1_SP 4713 index(0x0); 4714 scale(0x0); 4715 disp($reg); // Stack Offset 4716 %} 4717 %} 4718 4719 operand stackSlotL(sRegL reg) %{ 4720 constraint(ALLOC_IN_RC(stack_slots)); 4721 op_cost(100); 4722 //match(RegL); 4723 format %{ "[sp+$reg]" %} 4724 interface(MEMORY_INTER) %{ 4725 base(0x1); // R1_SP 4726 index(0x0); 4727 scale(0x0); 4728 disp($reg); // Stack Offset 4729 %} 4730 %} 4731 4732 operand stackSlotP(sRegP reg) %{ 4733 constraint(ALLOC_IN_RC(stack_slots)); 4734 op_cost(100); 4735 //match(RegP); 4736 format %{ "[sp+$reg]" %} 4737 interface(MEMORY_INTER) %{ 4738 base(0x1); // R1_SP 4739 index(0x0); 4740 scale(0x0); 4741 disp($reg); // Stack Offset 4742 %} 4743 %} 4744 4745 operand stackSlotF(sRegF reg) %{ 4746 constraint(ALLOC_IN_RC(stack_slots)); 4747 op_cost(100); 4748 //match(RegF); 4749 format %{ "[sp+$reg]" %} 4750 interface(MEMORY_INTER) %{ 4751 base(0x1); // R1_SP 4752 index(0x0); 4753 scale(0x0); 4754 disp($reg); // Stack Offset 4755 %} 4756 %} 4757 4758 operand stackSlotD(sRegD reg) %{ 4759 constraint(ALLOC_IN_RC(stack_slots)); 4760 op_cost(100); 4761 //match(RegD); 4762 format %{ "[sp+$reg]" %} 4763 interface(MEMORY_INTER) %{ 4764 base(0x1); // R1_SP 4765 index(0x0); 4766 scale(0x0); 4767 disp($reg); // Stack Offset 4768 %} 4769 %} 4770 4771 // Operands for expressing Control Flow 4772 // NOTE: Label is a predefined operand which should not be redefined in 4773 // the AD file. It is generically handled within the ADLC. 4774 4775 //----------Conditional Branch Operands---------------------------------------- 4776 // Comparison Op 4777 // 4778 // This is the operation of the comparison, and is limited to the 4779 // following set of codes: L (<), LE (<=), G (>), GE (>=), E (==), NE 4780 // (!=). 4781 // 4782 // Other attributes of the comparison, such as unsignedness, are specified 4783 // by the comparison instruction that sets a condition code flags register. 4784 // That result is represented by a flags operand whose subtype is appropriate 4785 // to the unsignedness (etc.) of the comparison. 4786 // 4787 // Later, the instruction which matches both the Comparison Op (a Bool) and 4788 // the flags (produced by the Cmp) specifies the coding of the comparison op 4789 // by matching a specific subtype of Bool operand below. 4790 4791 // When used for floating point comparisons: unordered same as less. 4792 operand cmpOp() %{ 4793 match(Bool); 4794 format %{ "" %} 4795 interface(COND_INTER) %{ 4796 // BO only encodes bit 4 of bcondCRbiIsX, as bits 1-3 are always '100'. 4797 // BO & BI 4798 equal(0xA); // 10 10: bcondCRbiIs1 & Condition::equal 4799 not_equal(0x2); // 00 10: bcondCRbiIs0 & Condition::equal 4800 less(0x8); // 10 00: bcondCRbiIs1 & Condition::less 4801 greater_equal(0x0); // 00 00: bcondCRbiIs0 & Condition::less 4802 less_equal(0x1); // 00 01: bcondCRbiIs0 & Condition::greater 4803 greater(0x9); // 10 01: bcondCRbiIs1 & Condition::greater 4804 overflow(0xB); // 10 11: bcondCRbiIs1 & Condition::summary_overflow 4805 no_overflow(0x3); // 00 11: bcondCRbiIs0 & Condition::summary_overflow 4806 %} 4807 %} 4808 4809 //----------OPERAND CLASSES---------------------------------------------------- 4810 // Operand Classes are groups of operands that are used to simplify 4811 // instruction definitions by not requiring the AD writer to specify 4812 // seperate instructions for every form of operand when the 4813 // instruction accepts multiple operand types with the same basic 4814 // encoding and format. The classic case of this is memory operands. 4815 // Indirect is not included since its use is limited to Compare & Swap. 4816 4817 opclass memory(indirect, indOffset16 /*, indIndex, tlsReference*/, indirectNarrow, indirectNarrow_klass, indOffset16Narrow, indOffset16Narrow_klass); 4818 // Memory operand where offsets are 4-aligned. Required for ld, std. 4819 opclass memoryAlg4(indirect, indOffset16Alg4, indirectNarrow, indOffset16NarrowAlg4, indOffset16NarrowAlg4_klass); 4820 opclass indirectMemory(indirect, indirectNarrow); 4821 4822 // Special opclass for I and ConvL2I. 4823 opclass iRegIsrc_iRegL2Isrc(iRegIsrc, iRegL2Isrc); 4824 4825 // Operand classes to match encode and decode. iRegN_P2N is only used 4826 // for storeN. I have never seen an encode node elsewhere. 4827 opclass iRegN_P2N(iRegNsrc, iRegP2N); 4828 opclass iRegP_N2P(iRegPsrc, iRegN2P, iRegN2P_klass); 4829 4830 //----------PIPELINE----------------------------------------------------------- 4831 4832 pipeline %{ 4833 4834 // See J.M.Tendler et al. "Power4 system microarchitecture", IBM 4835 // J. Res. & Dev., No. 1, Jan. 2002. 4836 4837 //----------ATTRIBUTES--------------------------------------------------------- 4838 attributes %{ 4839 4840 // Power4 instructions are of fixed length. 4841 fixed_size_instructions; 4842 4843 // TODO: if `bundle' means number of instructions fetched 4844 // per cycle, this is 8. If `bundle' means Power4 `group', that is 4845 // max instructions issued per cycle, this is 5. 4846 max_instructions_per_bundle = 8; 4847 4848 // A Power4 instruction is 4 bytes long. 4849 instruction_unit_size = 4; 4850 4851 // The Power4 processor fetches 64 bytes... 4852 instruction_fetch_unit_size = 64; 4853 4854 // ...in one line 4855 instruction_fetch_units = 1 4856 4857 // Unused, list one so that array generated by adlc is not empty. 4858 // Aix compiler chokes if _nop_count = 0. 4859 nops(fxNop); 4860 %} 4861 4862 //----------RESOURCES---------------------------------------------------------- 4863 // Resources are the functional units available to the machine 4864 resources( 4865 PPC_BR, // branch unit 4866 PPC_CR, // condition unit 4867 PPC_FX1, // integer arithmetic unit 1 4868 PPC_FX2, // integer arithmetic unit 2 4869 PPC_LDST1, // load/store unit 1 4870 PPC_LDST2, // load/store unit 2 4871 PPC_FP1, // float arithmetic unit 1 4872 PPC_FP2, // float arithmetic unit 2 4873 PPC_LDST = PPC_LDST1 | PPC_LDST2, 4874 PPC_FX = PPC_FX1 | PPC_FX2, 4875 PPC_FP = PPC_FP1 | PPC_FP2 4876 ); 4877 4878 //----------PIPELINE DESCRIPTION----------------------------------------------- 4879 // Pipeline Description specifies the stages in the machine's pipeline 4880 pipe_desc( 4881 // Power4 longest pipeline path 4882 PPC_IF, // instruction fetch 4883 PPC_IC, 4884 //PPC_BP, // branch prediction 4885 PPC_D0, // decode 4886 PPC_D1, // decode 4887 PPC_D2, // decode 4888 PPC_D3, // decode 4889 PPC_Xfer1, 4890 PPC_GD, // group definition 4891 PPC_MP, // map 4892 PPC_ISS, // issue 4893 PPC_RF, // resource fetch 4894 PPC_EX1, // execute (all units) 4895 PPC_EX2, // execute (FP, LDST) 4896 PPC_EX3, // execute (FP, LDST) 4897 PPC_EX4, // execute (FP) 4898 PPC_EX5, // execute (FP) 4899 PPC_EX6, // execute (FP) 4900 PPC_WB, // write back 4901 PPC_Xfer2, 4902 PPC_CP 4903 ); 4904 4905 //----------PIPELINE CLASSES--------------------------------------------------- 4906 // Pipeline Classes describe the stages in which input and output are 4907 // referenced by the hardware pipeline. 4908 4909 // Simple pipeline classes. 4910 4911 // Default pipeline class. 4912 pipe_class pipe_class_default() %{ 4913 single_instruction; 4914 fixed_latency(2); 4915 %} 4916 4917 // Pipeline class for empty instructions. 4918 pipe_class pipe_class_empty() %{ 4919 single_instruction; 4920 fixed_latency(0); 4921 %} 4922 4923 // Pipeline class for compares. 4924 pipe_class pipe_class_compare() %{ 4925 single_instruction; 4926 fixed_latency(16); 4927 %} 4928 4929 // Pipeline class for traps. 4930 pipe_class pipe_class_trap() %{ 4931 single_instruction; 4932 fixed_latency(100); 4933 %} 4934 4935 // Pipeline class for memory operations. 4936 pipe_class pipe_class_memory() %{ 4937 single_instruction; 4938 fixed_latency(16); 4939 %} 4940 4941 // Pipeline class for call. 4942 pipe_class pipe_class_call() %{ 4943 single_instruction; 4944 fixed_latency(100); 4945 %} 4946 4947 // Define the class for the Nop node. 4948 define %{ 4949 MachNop = pipe_class_default; 4950 %} 4951 4952 %} 4953 4954 //----------INSTRUCTIONS------------------------------------------------------- 4955 4956 // Naming of instructions: 4957 // opA_operB / opA_operB_operC: 4958 // Operation 'op' with one or two source operands 'oper'. Result 4959 // type is A, source operand types are B and C. 4960 // Iff A == B == C, B and C are left out. 4961 // 4962 // The instructions are ordered according to the following scheme: 4963 // - loads 4964 // - load constants 4965 // - prefetch 4966 // - store 4967 // - encode/decode 4968 // - membar 4969 // - conditional moves 4970 // - compare & swap 4971 // - arithmetic and logic operations 4972 // * int: Add, Sub, Mul, Div, Mod 4973 // * int: lShift, arShift, urShift, rot 4974 // * float: Add, Sub, Mul, Div 4975 // * and, or, xor ... 4976 // - register moves: float <-> int, reg <-> stack, repl 4977 // - cast (high level type cast, XtoP, castPP, castII, not_null etc. 4978 // - conv (low level type cast requiring bit changes (sign extend etc) 4979 // - compares, range & zero checks. 4980 // - branches 4981 // - complex operations, intrinsics, min, max, replicate 4982 // - lock 4983 // - Calls 4984 // 4985 // If there are similar instructions with different types they are sorted: 4986 // int before float 4987 // small before big 4988 // signed before unsigned 4989 // e.g., loadS before loadUS before loadI before loadF. 4990 4991 4992 //----------Load/Store Instructions-------------------------------------------- 4993 4994 //----------Load Instructions-------------------------------------------------- 4995 4996 // Converts byte to int. 4997 // As convB2I_reg, but without match rule. The match rule of convB2I_reg 4998 // reuses the 'amount' operand, but adlc expects that operand specification 4999 // and operands in match rule are equivalent. 5000 instruct convB2I_reg_2(iRegIdst dst, iRegIsrc src) %{ 5001 effect(DEF dst, USE src); 5002 format %{ "EXTSB $dst, $src \t// byte->int" %} 5003 size(4); 5004 ins_encode %{ 5005 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 5006 __ extsb($dst$$Register, $src$$Register); 5007 %} 5008 ins_pipe(pipe_class_default); 5009 %} 5010 5011 instruct loadUB_indirect(iRegIdst dst, indirectMemory mem) %{ 5012 // match-rule, false predicate 5013 match(Set dst (LoadB mem)); 5014 predicate(false); 5015 5016 format %{ "LBZ $dst, $mem" %} 5017 size(4); 5018 ins_encode( enc_lbz(dst, mem) ); 5019 ins_pipe(pipe_class_memory); 5020 %} 5021 5022 instruct loadUB_indirect_ac(iRegIdst dst, indirectMemory mem) %{ 5023 // match-rule, false predicate 5024 match(Set dst (LoadB mem)); 5025 predicate(false); 5026 5027 format %{ "LBZ $dst, $mem\n\t" 5028 "TWI $dst\n\t" 5029 "ISYNC" %} 5030 size(12); 5031 ins_encode( enc_lbz_ac(dst, mem) ); 5032 ins_pipe(pipe_class_memory); 5033 %} 5034 5035 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5036 instruct loadB_indirect_Ex(iRegIdst dst, indirectMemory mem) %{ 5037 match(Set dst (LoadB mem)); 5038 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5039 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5040 expand %{ 5041 iRegIdst tmp; 5042 loadUB_indirect(tmp, mem); 5043 convB2I_reg_2(dst, tmp); 5044 %} 5045 %} 5046 5047 instruct loadB_indirect_ac_Ex(iRegIdst dst, indirectMemory mem) %{ 5048 match(Set dst (LoadB mem)); 5049 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5050 expand %{ 5051 iRegIdst tmp; 5052 loadUB_indirect_ac(tmp, mem); 5053 convB2I_reg_2(dst, tmp); 5054 %} 5055 %} 5056 5057 instruct loadUB_indOffset16(iRegIdst dst, indOffset16 mem) %{ 5058 // match-rule, false predicate 5059 match(Set dst (LoadB mem)); 5060 predicate(false); 5061 5062 format %{ "LBZ $dst, $mem" %} 5063 size(4); 5064 ins_encode( enc_lbz(dst, mem) ); 5065 ins_pipe(pipe_class_memory); 5066 %} 5067 5068 instruct loadUB_indOffset16_ac(iRegIdst dst, indOffset16 mem) %{ 5069 // match-rule, false predicate 5070 match(Set dst (LoadB mem)); 5071 predicate(false); 5072 5073 format %{ "LBZ $dst, $mem\n\t" 5074 "TWI $dst\n\t" 5075 "ISYNC" %} 5076 size(12); 5077 ins_encode( enc_lbz_ac(dst, mem) ); 5078 ins_pipe(pipe_class_memory); 5079 %} 5080 5081 // Load Byte (8bit signed). LoadB = LoadUB + ConvUB2B. 5082 instruct loadB_indOffset16_Ex(iRegIdst dst, indOffset16 mem) %{ 5083 match(Set dst (LoadB mem)); 5084 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5085 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 5086 5087 expand %{ 5088 iRegIdst tmp; 5089 loadUB_indOffset16(tmp, mem); 5090 convB2I_reg_2(dst, tmp); 5091 %} 5092 %} 5093 5094 instruct loadB_indOffset16_ac_Ex(iRegIdst dst, indOffset16 mem) %{ 5095 match(Set dst (LoadB mem)); 5096 ins_cost(3*MEMORY_REF_COST + DEFAULT_COST); 5097 5098 expand %{ 5099 iRegIdst tmp; 5100 loadUB_indOffset16_ac(tmp, mem); 5101 convB2I_reg_2(dst, tmp); 5102 %} 5103 %} 5104 5105 // Load Unsigned Byte (8bit UNsigned) into an int reg. 5106 instruct loadUB(iRegIdst dst, memory mem) %{ 5107 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5108 match(Set dst (LoadUB mem)); 5109 ins_cost(MEMORY_REF_COST); 5110 5111 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int" %} 5112 size(4); 5113 ins_encode( enc_lbz(dst, mem) ); 5114 ins_pipe(pipe_class_memory); 5115 %} 5116 5117 // Load Unsigned Byte (8bit UNsigned) acquire. 5118 instruct loadUB_ac(iRegIdst dst, memory mem) %{ 5119 match(Set dst (LoadUB mem)); 5120 ins_cost(3*MEMORY_REF_COST); 5121 5122 format %{ "LBZ $dst, $mem \t// byte, zero-extend to int, acquire\n\t" 5123 "TWI $dst\n\t" 5124 "ISYNC" %} 5125 size(12); 5126 ins_encode( enc_lbz_ac(dst, mem) ); 5127 ins_pipe(pipe_class_memory); 5128 %} 5129 5130 // Load Unsigned Byte (8bit UNsigned) into a Long Register. 5131 instruct loadUB2L(iRegLdst dst, memory mem) %{ 5132 match(Set dst (ConvI2L (LoadUB mem))); 5133 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5134 ins_cost(MEMORY_REF_COST); 5135 5136 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long" %} 5137 size(4); 5138 ins_encode( enc_lbz(dst, mem) ); 5139 ins_pipe(pipe_class_memory); 5140 %} 5141 5142 instruct loadUB2L_ac(iRegLdst dst, memory mem) %{ 5143 match(Set dst (ConvI2L (LoadUB mem))); 5144 ins_cost(3*MEMORY_REF_COST); 5145 5146 format %{ "LBZ $dst, $mem \t// byte, zero-extend to long, acquire\n\t" 5147 "TWI $dst\n\t" 5148 "ISYNC" %} 5149 size(12); 5150 ins_encode( enc_lbz_ac(dst, mem) ); 5151 ins_pipe(pipe_class_memory); 5152 %} 5153 5154 // Load Short (16bit signed) 5155 instruct loadS(iRegIdst dst, memory mem) %{ 5156 match(Set dst (LoadS mem)); 5157 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5158 ins_cost(MEMORY_REF_COST); 5159 5160 format %{ "LHA $dst, $mem" %} 5161 size(4); 5162 ins_encode %{ 5163 // TODO: PPC port $archOpcode(ppc64Opcode_lha); 5164 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5165 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5166 %} 5167 ins_pipe(pipe_class_memory); 5168 %} 5169 5170 // Load Short (16bit signed) acquire. 5171 instruct loadS_ac(iRegIdst dst, memory mem) %{ 5172 match(Set dst (LoadS mem)); 5173 ins_cost(3*MEMORY_REF_COST); 5174 5175 format %{ "LHA $dst, $mem\t acquire\n\t" 5176 "TWI $dst\n\t" 5177 "ISYNC" %} 5178 size(12); 5179 ins_encode %{ 5180 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5181 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5182 __ lha($dst$$Register, Idisp, $mem$$base$$Register); 5183 __ twi_0($dst$$Register); 5184 __ isync(); 5185 %} 5186 ins_pipe(pipe_class_memory); 5187 %} 5188 5189 // Load Char (16bit unsigned) 5190 instruct loadUS(iRegIdst dst, memory mem) %{ 5191 match(Set dst (LoadUS mem)); 5192 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5193 ins_cost(MEMORY_REF_COST); 5194 5195 format %{ "LHZ $dst, $mem" %} 5196 size(4); 5197 ins_encode( enc_lhz(dst, mem) ); 5198 ins_pipe(pipe_class_memory); 5199 %} 5200 5201 // Load Char (16bit unsigned) acquire. 5202 instruct loadUS_ac(iRegIdst dst, memory mem) %{ 5203 match(Set dst (LoadUS mem)); 5204 ins_cost(3*MEMORY_REF_COST); 5205 5206 format %{ "LHZ $dst, $mem \t// acquire\n\t" 5207 "TWI $dst\n\t" 5208 "ISYNC" %} 5209 size(12); 5210 ins_encode( enc_lhz_ac(dst, mem) ); 5211 ins_pipe(pipe_class_memory); 5212 %} 5213 5214 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register. 5215 instruct loadUS2L(iRegLdst dst, memory mem) %{ 5216 match(Set dst (ConvI2L (LoadUS mem))); 5217 predicate(_kids[0]->_leaf->as_Load()->is_unordered() || followed_by_acquire(_kids[0]->_leaf)); 5218 ins_cost(MEMORY_REF_COST); 5219 5220 format %{ "LHZ $dst, $mem \t// short, zero-extend to long" %} 5221 size(4); 5222 ins_encode( enc_lhz(dst, mem) ); 5223 ins_pipe(pipe_class_memory); 5224 %} 5225 5226 // Load Unsigned Short/Char (16bit UNsigned) into a Long Register acquire. 5227 instruct loadUS2L_ac(iRegLdst dst, memory mem) %{ 5228 match(Set dst (ConvI2L (LoadUS mem))); 5229 ins_cost(3*MEMORY_REF_COST); 5230 5231 format %{ "LHZ $dst, $mem \t// short, zero-extend to long, acquire\n\t" 5232 "TWI $dst\n\t" 5233 "ISYNC" %} 5234 size(12); 5235 ins_encode( enc_lhz_ac(dst, mem) ); 5236 ins_pipe(pipe_class_memory); 5237 %} 5238 5239 // Load Integer. 5240 instruct loadI(iRegIdst dst, memory mem) %{ 5241 match(Set dst (LoadI mem)); 5242 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5243 ins_cost(MEMORY_REF_COST); 5244 5245 format %{ "LWZ $dst, $mem" %} 5246 size(4); 5247 ins_encode( enc_lwz(dst, mem) ); 5248 ins_pipe(pipe_class_memory); 5249 %} 5250 5251 // Load Integer acquire. 5252 instruct loadI_ac(iRegIdst dst, memory mem) %{ 5253 match(Set dst (LoadI mem)); 5254 ins_cost(3*MEMORY_REF_COST); 5255 5256 format %{ "LWZ $dst, $mem \t// load acquire\n\t" 5257 "TWI $dst\n\t" 5258 "ISYNC" %} 5259 size(12); 5260 ins_encode( enc_lwz_ac(dst, mem) ); 5261 ins_pipe(pipe_class_memory); 5262 %} 5263 5264 // Match loading integer and casting it to unsigned int in 5265 // long register. 5266 // LoadI + ConvI2L + AndL 0xffffffff. 5267 instruct loadUI2L(iRegLdst dst, memory mem, immL_32bits mask) %{ 5268 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5269 predicate(_kids[0]->_kids[0]->_leaf->as_Load()->is_unordered()); 5270 ins_cost(MEMORY_REF_COST); 5271 5272 format %{ "LWZ $dst, $mem \t// zero-extend to long" %} 5273 size(4); 5274 ins_encode( enc_lwz(dst, mem) ); 5275 ins_pipe(pipe_class_memory); 5276 %} 5277 5278 // Match loading integer and casting it to long. 5279 instruct loadI2L(iRegLdst dst, memoryAlg4 mem) %{ 5280 match(Set dst (ConvI2L (LoadI mem))); 5281 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5282 ins_cost(MEMORY_REF_COST); 5283 5284 format %{ "LWA $dst, $mem \t// loadI2L" %} 5285 size(4); 5286 ins_encode %{ 5287 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5288 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5289 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5290 %} 5291 ins_pipe(pipe_class_memory); 5292 %} 5293 5294 // Match loading integer and casting it to long - acquire. 5295 instruct loadI2L_ac(iRegLdst dst, memoryAlg4 mem) %{ 5296 match(Set dst (ConvI2L (LoadI mem))); 5297 ins_cost(3*MEMORY_REF_COST); 5298 5299 format %{ "LWA $dst, $mem \t// loadI2L acquire" 5300 "TWI $dst\n\t" 5301 "ISYNC" %} 5302 size(12); 5303 ins_encode %{ 5304 // TODO: PPC port $archOpcode(ppc64Opcode_lwa); 5305 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5306 __ lwa($dst$$Register, Idisp, $mem$$base$$Register); 5307 __ twi_0($dst$$Register); 5308 __ isync(); 5309 %} 5310 ins_pipe(pipe_class_memory); 5311 %} 5312 5313 // Load Long - aligned 5314 instruct loadL(iRegLdst dst, memoryAlg4 mem) %{ 5315 match(Set dst (LoadL mem)); 5316 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5317 ins_cost(MEMORY_REF_COST); 5318 5319 format %{ "LD $dst, $mem \t// long" %} 5320 size(4); 5321 ins_encode( enc_ld(dst, mem) ); 5322 ins_pipe(pipe_class_memory); 5323 %} 5324 5325 // Load Long - aligned acquire. 5326 instruct loadL_ac(iRegLdst dst, memoryAlg4 mem) %{ 5327 match(Set dst (LoadL mem)); 5328 ins_cost(3*MEMORY_REF_COST); 5329 5330 format %{ "LD $dst, $mem \t// long acquire\n\t" 5331 "TWI $dst\n\t" 5332 "ISYNC" %} 5333 size(12); 5334 ins_encode( enc_ld_ac(dst, mem) ); 5335 ins_pipe(pipe_class_memory); 5336 %} 5337 5338 // Load Long - UNaligned 5339 instruct loadL_unaligned(iRegLdst dst, memoryAlg4 mem) %{ 5340 match(Set dst (LoadL_unaligned mem)); 5341 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 5342 ins_cost(MEMORY_REF_COST); 5343 5344 format %{ "LD $dst, $mem \t// unaligned long" %} 5345 size(4); 5346 ins_encode( enc_ld(dst, mem) ); 5347 ins_pipe(pipe_class_memory); 5348 %} 5349 5350 // Load nodes for superwords 5351 5352 // Load Aligned Packed Byte 5353 instruct loadV8(iRegLdst dst, memoryAlg4 mem) %{ 5354 predicate(n->as_LoadVector()->memory_size() == 8); 5355 match(Set dst (LoadVector mem)); 5356 ins_cost(MEMORY_REF_COST); 5357 5358 format %{ "LD $dst, $mem \t// load 8-byte Vector" %} 5359 size(4); 5360 ins_encode( enc_ld(dst, mem) ); 5361 ins_pipe(pipe_class_memory); 5362 %} 5363 5364 // Load Range, range = array length (=jint) 5365 instruct loadRange(iRegIdst dst, memory mem) %{ 5366 match(Set dst (LoadRange mem)); 5367 ins_cost(MEMORY_REF_COST); 5368 5369 format %{ "LWZ $dst, $mem \t// range" %} 5370 size(4); 5371 ins_encode( enc_lwz(dst, mem) ); 5372 ins_pipe(pipe_class_memory); 5373 %} 5374 5375 // Load Compressed Pointer 5376 instruct loadN(iRegNdst dst, memory mem) %{ 5377 match(Set dst (LoadN mem)); 5378 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5379 ins_cost(MEMORY_REF_COST); 5380 5381 format %{ "LWZ $dst, $mem \t// load compressed ptr" %} 5382 size(4); 5383 ins_encode( enc_lwz(dst, mem) ); 5384 ins_pipe(pipe_class_memory); 5385 %} 5386 5387 // Load Compressed Pointer acquire. 5388 instruct loadN_ac(iRegNdst dst, memory mem) %{ 5389 match(Set dst (LoadN mem)); 5390 ins_cost(3*MEMORY_REF_COST); 5391 5392 format %{ "LWZ $dst, $mem \t// load acquire compressed ptr\n\t" 5393 "TWI $dst\n\t" 5394 "ISYNC" %} 5395 size(12); 5396 ins_encode( enc_lwz_ac(dst, mem) ); 5397 ins_pipe(pipe_class_memory); 5398 %} 5399 5400 // Load Compressed Pointer and decode it if narrow_oop_shift == 0. 5401 instruct loadN2P_unscaled(iRegPdst dst, memory mem) %{ 5402 match(Set dst (DecodeN (LoadN mem))); 5403 predicate(_kids[0]->_leaf->as_Load()->is_unordered() && Universe::narrow_oop_shift() == 0); 5404 ins_cost(MEMORY_REF_COST); 5405 5406 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5407 size(4); 5408 ins_encode( enc_lwz(dst, mem) ); 5409 ins_pipe(pipe_class_memory); 5410 %} 5411 5412 instruct loadN2P_klass_unscaled(iRegPdst dst, memory mem) %{ 5413 match(Set dst (DecodeNKlass (LoadNKlass mem))); 5414 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0 && 5415 _kids[0]->_leaf->as_Load()->is_unordered()); 5416 ins_cost(MEMORY_REF_COST); 5417 5418 format %{ "LWZ $dst, $mem \t// DecodeN (unscaled)" %} 5419 size(4); 5420 ins_encode( enc_lwz(dst, mem) ); 5421 ins_pipe(pipe_class_memory); 5422 %} 5423 5424 // Load Pointer 5425 instruct loadP(iRegPdst dst, memoryAlg4 mem) %{ 5426 match(Set dst (LoadP mem)); 5427 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5428 ins_cost(MEMORY_REF_COST); 5429 5430 format %{ "LD $dst, $mem \t// ptr" %} 5431 size(4); 5432 ins_encode( enc_ld(dst, mem) ); 5433 ins_pipe(pipe_class_memory); 5434 %} 5435 5436 // Load Pointer acquire. 5437 instruct loadP_ac(iRegPdst dst, memoryAlg4 mem) %{ 5438 match(Set dst (LoadP mem)); 5439 ins_cost(3*MEMORY_REF_COST); 5440 5441 format %{ "LD $dst, $mem \t// ptr acquire\n\t" 5442 "TWI $dst\n\t" 5443 "ISYNC" %} 5444 size(12); 5445 ins_encode( enc_ld_ac(dst, mem) ); 5446 ins_pipe(pipe_class_memory); 5447 %} 5448 5449 // LoadP + CastP2L 5450 instruct loadP2X(iRegLdst dst, memoryAlg4 mem) %{ 5451 match(Set dst (CastP2X (LoadP mem))); 5452 predicate(_kids[0]->_leaf->as_Load()->is_unordered()); 5453 ins_cost(MEMORY_REF_COST); 5454 5455 format %{ "LD $dst, $mem \t// ptr + p2x" %} 5456 size(4); 5457 ins_encode( enc_ld(dst, mem) ); 5458 ins_pipe(pipe_class_memory); 5459 %} 5460 5461 // Load compressed klass pointer. 5462 instruct loadNKlass(iRegNdst dst, memory mem) %{ 5463 match(Set dst (LoadNKlass mem)); 5464 ins_cost(MEMORY_REF_COST); 5465 5466 format %{ "LWZ $dst, $mem \t// compressed klass ptr" %} 5467 size(4); 5468 ins_encode( enc_lwz(dst, mem) ); 5469 ins_pipe(pipe_class_memory); 5470 %} 5471 5472 // Load Klass Pointer 5473 instruct loadKlass(iRegPdst dst, memoryAlg4 mem) %{ 5474 match(Set dst (LoadKlass mem)); 5475 ins_cost(MEMORY_REF_COST); 5476 5477 format %{ "LD $dst, $mem \t// klass ptr" %} 5478 size(4); 5479 ins_encode( enc_ld(dst, mem) ); 5480 ins_pipe(pipe_class_memory); 5481 %} 5482 5483 // Load Float 5484 instruct loadF(regF dst, memory mem) %{ 5485 match(Set dst (LoadF mem)); 5486 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5487 ins_cost(MEMORY_REF_COST); 5488 5489 format %{ "LFS $dst, $mem" %} 5490 size(4); 5491 ins_encode %{ 5492 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 5493 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5494 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5495 %} 5496 ins_pipe(pipe_class_memory); 5497 %} 5498 5499 // Load Float acquire. 5500 instruct loadF_ac(regF dst, memory mem, flagsRegCR0 cr0) %{ 5501 match(Set dst (LoadF mem)); 5502 effect(TEMP cr0); 5503 ins_cost(3*MEMORY_REF_COST); 5504 5505 format %{ "LFS $dst, $mem \t// acquire\n\t" 5506 "FCMPU cr0, $dst, $dst\n\t" 5507 "BNE cr0, next\n" 5508 "next:\n\t" 5509 "ISYNC" %} 5510 size(16); 5511 ins_encode %{ 5512 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5513 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5514 Label next; 5515 __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5516 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 5517 __ bne(CCR0, next); 5518 __ bind(next); 5519 __ isync(); 5520 %} 5521 ins_pipe(pipe_class_memory); 5522 %} 5523 5524 // Load Double - aligned 5525 instruct loadD(regD dst, memory mem) %{ 5526 match(Set dst (LoadD mem)); 5527 predicate(n->as_Load()->is_unordered() || followed_by_acquire(n)); 5528 ins_cost(MEMORY_REF_COST); 5529 5530 format %{ "LFD $dst, $mem" %} 5531 size(4); 5532 ins_encode( enc_lfd(dst, mem) ); 5533 ins_pipe(pipe_class_memory); 5534 %} 5535 5536 // Load Double - aligned acquire. 5537 instruct loadD_ac(regD dst, memory mem, flagsRegCR0 cr0) %{ 5538 match(Set dst (LoadD mem)); 5539 effect(TEMP cr0); 5540 ins_cost(3*MEMORY_REF_COST); 5541 5542 format %{ "LFD $dst, $mem \t// acquire\n\t" 5543 "FCMPU cr0, $dst, $dst\n\t" 5544 "BNE cr0, next\n" 5545 "next:\n\t" 5546 "ISYNC" %} 5547 size(16); 5548 ins_encode %{ 5549 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5550 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 5551 Label next; 5552 __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register); 5553 __ fcmpu(CCR0, $dst$$FloatRegister, $dst$$FloatRegister); 5554 __ bne(CCR0, next); 5555 __ bind(next); 5556 __ isync(); 5557 %} 5558 ins_pipe(pipe_class_memory); 5559 %} 5560 5561 // Load Double - UNaligned 5562 instruct loadD_unaligned(regD dst, memory mem) %{ 5563 match(Set dst (LoadD_unaligned mem)); 5564 // predicate(...) // Unaligned_ac is not needed (and wouldn't make sense). 5565 ins_cost(MEMORY_REF_COST); 5566 5567 format %{ "LFD $dst, $mem" %} 5568 size(4); 5569 ins_encode( enc_lfd(dst, mem) ); 5570 ins_pipe(pipe_class_memory); 5571 %} 5572 5573 //----------Constants-------------------------------------------------------- 5574 5575 // Load MachConstantTableBase: add hi offset to global toc. 5576 // TODO: Handle hidden register r29 in bundler! 5577 instruct loadToc_hi(iRegLdst dst) %{ 5578 effect(DEF dst); 5579 ins_cost(DEFAULT_COST); 5580 5581 format %{ "ADDIS $dst, R29, DISP.hi \t// load TOC hi" %} 5582 size(4); 5583 ins_encode %{ 5584 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 5585 __ calculate_address_from_global_toc_hi16only($dst$$Register, __ method_toc()); 5586 %} 5587 ins_pipe(pipe_class_default); 5588 %} 5589 5590 // Load MachConstantTableBase: add lo offset to global toc. 5591 instruct loadToc_lo(iRegLdst dst, iRegLdst src) %{ 5592 effect(DEF dst, USE src); 5593 ins_cost(DEFAULT_COST); 5594 5595 format %{ "ADDI $dst, $src, DISP.lo \t// load TOC lo" %} 5596 size(4); 5597 ins_encode %{ 5598 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 5599 __ calculate_address_from_global_toc_lo16only($dst$$Register, __ method_toc()); 5600 %} 5601 ins_pipe(pipe_class_default); 5602 %} 5603 5604 // Load 16-bit integer constant 0xssss???? 5605 instruct loadConI16(iRegIdst dst, immI16 src) %{ 5606 match(Set dst src); 5607 5608 format %{ "LI $dst, $src" %} 5609 size(4); 5610 ins_encode %{ 5611 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 5612 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 5613 %} 5614 ins_pipe(pipe_class_default); 5615 %} 5616 5617 // Load integer constant 0x????0000 5618 instruct loadConIhi16(iRegIdst dst, immIhi16 src) %{ 5619 match(Set dst src); 5620 ins_cost(DEFAULT_COST); 5621 5622 format %{ "LIS $dst, $src.hi" %} 5623 size(4); 5624 ins_encode %{ 5625 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 5626 // Lis sign extends 16-bit src then shifts it 16 bit to the left. 5627 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 5628 %} 5629 ins_pipe(pipe_class_default); 5630 %} 5631 5632 // Part 2 of loading 32 bit constant: hi16 is is src1 (properly shifted 5633 // and sign extended), this adds the low 16 bits. 5634 instruct loadConI32_lo16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 5635 // no match-rule, false predicate 5636 effect(DEF dst, USE src1, USE src2); 5637 predicate(false); 5638 5639 format %{ "ORI $dst, $src1.hi, $src2.lo" %} 5640 size(4); 5641 ins_encode %{ 5642 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 5643 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 5644 %} 5645 ins_pipe(pipe_class_default); 5646 %} 5647 5648 instruct loadConI_Ex(iRegIdst dst, immI src) %{ 5649 match(Set dst src); 5650 ins_cost(DEFAULT_COST*2); 5651 5652 expand %{ 5653 // Would like to use $src$$constant. 5654 immI16 srcLo %{ _opnds[1]->constant() %} 5655 // srcHi can be 0000 if srcLo sign-extends to a negative number. 5656 immIhi16 srcHi %{ _opnds[1]->constant() %} 5657 iRegIdst tmpI; 5658 loadConIhi16(tmpI, srcHi); 5659 loadConI32_lo16(dst, tmpI, srcLo); 5660 %} 5661 %} 5662 5663 // No constant pool entries required. 5664 instruct loadConL16(iRegLdst dst, immL16 src) %{ 5665 match(Set dst src); 5666 5667 format %{ "LI $dst, $src \t// long" %} 5668 size(4); 5669 ins_encode %{ 5670 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 5671 __ li($dst$$Register, (int)((short) ($src$$constant & 0xFFFF))); 5672 %} 5673 ins_pipe(pipe_class_default); 5674 %} 5675 5676 // Load long constant 0xssssssss????0000 5677 instruct loadConL32hi16(iRegLdst dst, immL32hi16 src) %{ 5678 match(Set dst src); 5679 ins_cost(DEFAULT_COST); 5680 5681 format %{ "LIS $dst, $src.hi \t// long" %} 5682 size(4); 5683 ins_encode %{ 5684 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 5685 __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16))); 5686 %} 5687 ins_pipe(pipe_class_default); 5688 %} 5689 5690 // To load a 32 bit constant: merge lower 16 bits into already loaded 5691 // high 16 bits. 5692 instruct loadConL32_lo16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 5693 // no match-rule, false predicate 5694 effect(DEF dst, USE src1, USE src2); 5695 predicate(false); 5696 5697 format %{ "ORI $dst, $src1, $src2.lo" %} 5698 size(4); 5699 ins_encode %{ 5700 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 5701 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 5702 %} 5703 ins_pipe(pipe_class_default); 5704 %} 5705 5706 // Load 32-bit long constant 5707 instruct loadConL32_Ex(iRegLdst dst, immL32 src) %{ 5708 match(Set dst src); 5709 ins_cost(DEFAULT_COST*2); 5710 5711 expand %{ 5712 // Would like to use $src$$constant. 5713 immL16 srcLo %{ _opnds[1]->constant() /*& 0x0000FFFFL */%} 5714 // srcHi can be 0000 if srcLo sign-extends to a negative number. 5715 immL32hi16 srcHi %{ _opnds[1]->constant() /*& 0xFFFF0000L */%} 5716 iRegLdst tmpL; 5717 loadConL32hi16(tmpL, srcHi); 5718 loadConL32_lo16(dst, tmpL, srcLo); 5719 %} 5720 %} 5721 5722 // Load long constant 0x????000000000000. 5723 instruct loadConLhighest16_Ex(iRegLdst dst, immLhighest16 src) %{ 5724 match(Set dst src); 5725 ins_cost(DEFAULT_COST); 5726 5727 expand %{ 5728 immL32hi16 srcHi %{ _opnds[1]->constant() >> 32 /*& 0xFFFF0000L */%} 5729 immI shift32 %{ 32 %} 5730 iRegLdst tmpL; 5731 loadConL32hi16(tmpL, srcHi); 5732 lshiftL_regL_immI(dst, tmpL, shift32); 5733 %} 5734 %} 5735 5736 // Expand node for constant pool load: small offset. 5737 instruct loadConL(iRegLdst dst, immL src, iRegLdst toc) %{ 5738 effect(DEF dst, USE src, USE toc); 5739 ins_cost(MEMORY_REF_COST); 5740 5741 ins_num_consts(1); 5742 // Needed so that CallDynamicJavaDirect can compute the address of this 5743 // instruction for relocation. 5744 ins_field_cbuf_insts_offset(int); 5745 5746 format %{ "LD $dst, offset, $toc \t// load long $src from TOC" %} 5747 size(4); 5748 ins_encode( enc_load_long_constL(dst, src, toc) ); 5749 ins_pipe(pipe_class_memory); 5750 %} 5751 5752 // Expand node for constant pool load: large offset. 5753 instruct loadConL_hi(iRegLdst dst, immL src, iRegLdst toc) %{ 5754 effect(DEF dst, USE src, USE toc); 5755 predicate(false); 5756 5757 ins_num_consts(1); 5758 ins_field_const_toc_offset(int); 5759 // Needed so that CallDynamicJavaDirect can compute the address of this 5760 // instruction for relocation. 5761 ins_field_cbuf_insts_offset(int); 5762 5763 format %{ "ADDIS $dst, $toc, offset \t// load long $src from TOC (hi)" %} 5764 size(4); 5765 ins_encode( enc_load_long_constL_hi(dst, toc, src) ); 5766 ins_pipe(pipe_class_default); 5767 %} 5768 5769 // Expand node for constant pool load: large offset. 5770 // No constant pool entries required. 5771 instruct loadConL_lo(iRegLdst dst, immL src, iRegLdst base) %{ 5772 effect(DEF dst, USE src, USE base); 5773 predicate(false); 5774 5775 ins_field_const_toc_offset_hi_node(loadConL_hiNode*); 5776 5777 format %{ "LD $dst, offset, $base \t// load long $src from TOC (lo)" %} 5778 size(4); 5779 ins_encode %{ 5780 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 5781 int offset = ra_->C->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 5782 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 5783 %} 5784 ins_pipe(pipe_class_memory); 5785 %} 5786 5787 // Load long constant from constant table. Expand in case of 5788 // offset > 16 bit is needed. 5789 // Adlc adds toc node MachConstantTableBase. 5790 instruct loadConL_Ex(iRegLdst dst, immL src) %{ 5791 match(Set dst src); 5792 ins_cost(MEMORY_REF_COST); 5793 5794 format %{ "LD $dst, offset, $constanttablebase\t// load long $src from table, postalloc expanded" %} 5795 // We can not inline the enc_class for the expand as that does not support constanttablebase. 5796 postalloc_expand( postalloc_expand_load_long_constant(dst, src, constanttablebase) ); 5797 %} 5798 5799 // Load NULL as compressed oop. 5800 instruct loadConN0(iRegNdst dst, immN_0 src) %{ 5801 match(Set dst src); 5802 ins_cost(DEFAULT_COST); 5803 5804 format %{ "LI $dst, $src \t// compressed ptr" %} 5805 size(4); 5806 ins_encode %{ 5807 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 5808 __ li($dst$$Register, 0); 5809 %} 5810 ins_pipe(pipe_class_default); 5811 %} 5812 5813 // Load hi part of compressed oop constant. 5814 instruct loadConN_hi(iRegNdst dst, immN src) %{ 5815 effect(DEF dst, USE src); 5816 ins_cost(DEFAULT_COST); 5817 5818 format %{ "LIS $dst, $src \t// narrow oop hi" %} 5819 size(4); 5820 ins_encode %{ 5821 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 5822 __ lis($dst$$Register, (int)(short)(($src$$constant >> 16) & 0xffff)); 5823 %} 5824 ins_pipe(pipe_class_default); 5825 %} 5826 5827 // Add lo part of compressed oop constant to already loaded hi part. 5828 instruct loadConN_lo(iRegNdst dst, iRegNsrc src1, immN src2) %{ 5829 effect(DEF dst, USE src1, USE src2); 5830 ins_cost(DEFAULT_COST); 5831 5832 format %{ "ORI $dst, $src1, $src2 \t// narrow oop lo" %} 5833 size(4); 5834 ins_encode %{ 5835 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 5836 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 5837 int oop_index = __ oop_recorder()->find_index((jobject)$src2$$constant); 5838 RelocationHolder rspec = oop_Relocation::spec(oop_index); 5839 __ relocate(rspec, 1); 5840 __ ori($dst$$Register, $src1$$Register, $src2$$constant & 0xffff); 5841 %} 5842 ins_pipe(pipe_class_default); 5843 %} 5844 5845 instruct rldicl(iRegLdst dst, iRegLsrc src, immI16 shift, immI16 mask_begin) %{ 5846 effect(DEF dst, USE src, USE shift, USE mask_begin); 5847 5848 size(4); 5849 ins_encode %{ 5850 __ rldicl($dst$$Register, $src$$Register, $shift$$constant, $mask_begin$$constant); 5851 %} 5852 ins_pipe(pipe_class_default); 5853 %} 5854 5855 // Needed to postalloc expand loadConN: ConN is loaded as ConI 5856 // leaving the upper 32 bits with sign-extension bits. 5857 // This clears these bits: dst = src & 0xFFFFFFFF. 5858 // TODO: Eventually call this maskN_regN_FFFFFFFF. 5859 instruct clearMs32b(iRegNdst dst, iRegNsrc src) %{ 5860 effect(DEF dst, USE src); 5861 predicate(false); 5862 5863 format %{ "MASK $dst, $src, 0xFFFFFFFF" %} // mask 5864 size(4); 5865 ins_encode %{ 5866 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 5867 __ clrldi($dst$$Register, $src$$Register, 0x20); 5868 %} 5869 ins_pipe(pipe_class_default); 5870 %} 5871 5872 // Optimize DecodeN for disjoint base. 5873 // Load base of compressed oops into a register 5874 instruct loadBase(iRegLdst dst) %{ 5875 effect(DEF dst); 5876 5877 format %{ "LoadConst $dst, heapbase" %} 5878 ins_encode %{ 5879 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 5880 __ load_const_optimized($dst$$Register, Universe::narrow_oop_base(), R0); 5881 %} 5882 ins_pipe(pipe_class_default); 5883 %} 5884 5885 // Loading ConN must be postalloc expanded so that edges between 5886 // the nodes are safe. They may not interfere with a safepoint. 5887 // GL TODO: This needs three instructions: better put this into the constant pool. 5888 instruct loadConN_Ex(iRegNdst dst, immN src) %{ 5889 match(Set dst src); 5890 ins_cost(DEFAULT_COST*2); 5891 5892 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 5893 postalloc_expand %{ 5894 MachNode *m1 = new loadConN_hiNode(); 5895 MachNode *m2 = new loadConN_loNode(); 5896 MachNode *m3 = new clearMs32bNode(); 5897 m1->add_req(NULL); 5898 m2->add_req(NULL, m1); 5899 m3->add_req(NULL, m2); 5900 m1->_opnds[0] = op_dst; 5901 m1->_opnds[1] = op_src; 5902 m2->_opnds[0] = op_dst; 5903 m2->_opnds[1] = op_dst; 5904 m2->_opnds[2] = op_src; 5905 m3->_opnds[0] = op_dst; 5906 m3->_opnds[1] = op_dst; 5907 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5908 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5909 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5910 nodes->push(m1); 5911 nodes->push(m2); 5912 nodes->push(m3); 5913 %} 5914 %} 5915 5916 // We have seen a safepoint between the hi and lo parts, and this node was handled 5917 // as an oop. Therefore this needs a match rule so that build_oop_map knows this is 5918 // not a narrow oop. 5919 instruct loadConNKlass_hi(iRegNdst dst, immNKlass_NM src) %{ 5920 match(Set dst src); 5921 effect(DEF dst, USE src); 5922 ins_cost(DEFAULT_COST); 5923 5924 format %{ "LIS $dst, $src \t// narrow klass hi" %} 5925 size(4); 5926 ins_encode %{ 5927 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 5928 intptr_t Csrc = Klass::encode_klass((Klass *)$src$$constant); 5929 __ lis($dst$$Register, (int)(short)((Csrc >> 16) & 0xffff)); 5930 %} 5931 ins_pipe(pipe_class_default); 5932 %} 5933 5934 // As loadConNKlass_hi this must be recognized as narrow klass, not oop! 5935 instruct loadConNKlass_mask(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 5936 match(Set dst src1); 5937 effect(TEMP src2); 5938 ins_cost(DEFAULT_COST); 5939 5940 format %{ "MASK $dst, $src2, 0xFFFFFFFF" %} // mask 5941 size(4); 5942 ins_encode %{ 5943 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 5944 __ clrldi($dst$$Register, $src2$$Register, 0x20); 5945 %} 5946 ins_pipe(pipe_class_default); 5947 %} 5948 5949 // This needs a match rule so that build_oop_map knows this is 5950 // not a narrow oop. 5951 instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{ 5952 match(Set dst src1); 5953 effect(TEMP src2); 5954 ins_cost(DEFAULT_COST); 5955 5956 format %{ "ORI $dst, $src1, $src2 \t// narrow klass lo" %} 5957 size(4); 5958 ins_encode %{ 5959 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 5960 intptr_t Csrc = Klass::encode_klass((Klass *)$src1$$constant); 5961 assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder"); 5962 int klass_index = __ oop_recorder()->find_index((Klass *)$src1$$constant); 5963 RelocationHolder rspec = metadata_Relocation::spec(klass_index); 5964 5965 __ relocate(rspec, 1); 5966 __ ori($dst$$Register, $src2$$Register, Csrc & 0xffff); 5967 %} 5968 ins_pipe(pipe_class_default); 5969 %} 5970 5971 // Loading ConNKlass must be postalloc expanded so that edges between 5972 // the nodes are safe. They may not interfere with a safepoint. 5973 instruct loadConNKlass_Ex(iRegNdst dst, immNKlass src) %{ 5974 match(Set dst src); 5975 ins_cost(DEFAULT_COST*2); 5976 5977 format %{ "LoadN $dst, $src \t// postalloc expanded" %} // mask 5978 postalloc_expand %{ 5979 // Load high bits into register. Sign extended. 5980 MachNode *m1 = new loadConNKlass_hiNode(); 5981 m1->add_req(NULL); 5982 m1->_opnds[0] = op_dst; 5983 m1->_opnds[1] = op_src; 5984 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5985 nodes->push(m1); 5986 5987 MachNode *m2 = m1; 5988 if (!Assembler::is_uimm((jlong)Klass::encode_klass((Klass *)op_src->constant()), 31)) { 5989 // Value might be 1-extended. Mask out these bits. 5990 m2 = new loadConNKlass_maskNode(); 5991 m2->add_req(NULL, m1); 5992 m2->_opnds[0] = op_dst; 5993 m2->_opnds[1] = op_src; 5994 m2->_opnds[2] = op_dst; 5995 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 5996 nodes->push(m2); 5997 } 5998 5999 MachNode *m3 = new loadConNKlass_loNode(); 6000 m3->add_req(NULL, m2); 6001 m3->_opnds[0] = op_dst; 6002 m3->_opnds[1] = op_src; 6003 m3->_opnds[2] = op_dst; 6004 ra_->set_pair(m3->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6005 nodes->push(m3); 6006 %} 6007 %} 6008 6009 // 0x1 is used in object initialization (initial object header). 6010 // No constant pool entries required. 6011 instruct loadConP0or1(iRegPdst dst, immP_0or1 src) %{ 6012 match(Set dst src); 6013 6014 format %{ "LI $dst, $src \t// ptr" %} 6015 size(4); 6016 ins_encode %{ 6017 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 6018 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 6019 %} 6020 ins_pipe(pipe_class_default); 6021 %} 6022 6023 // Expand node for constant pool load: small offset. 6024 // The match rule is needed to generate the correct bottom_type(), 6025 // however this node should never match. The use of predicate is not 6026 // possible since ADLC forbids predicates for chain rules. The higher 6027 // costs do not prevent matching in this case. For that reason the 6028 // operand immP_NM with predicate(false) is used. 6029 instruct loadConP(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6030 match(Set dst src); 6031 effect(TEMP toc); 6032 6033 ins_num_consts(1); 6034 6035 format %{ "LD $dst, offset, $toc \t// load ptr $src from TOC" %} 6036 size(4); 6037 ins_encode( enc_load_long_constP(dst, src, toc) ); 6038 ins_pipe(pipe_class_memory); 6039 %} 6040 6041 // Expand node for constant pool load: large offset. 6042 instruct loadConP_hi(iRegPdst dst, immP_NM src, iRegLdst toc) %{ 6043 effect(DEF dst, USE src, USE toc); 6044 predicate(false); 6045 6046 ins_num_consts(1); 6047 ins_field_const_toc_offset(int); 6048 6049 format %{ "ADDIS $dst, $toc, offset \t// load ptr $src from TOC (hi)" %} 6050 size(4); 6051 ins_encode( enc_load_long_constP_hi(dst, src, toc) ); 6052 ins_pipe(pipe_class_default); 6053 %} 6054 6055 // Expand node for constant pool load: large offset. 6056 instruct loadConP_lo(iRegPdst dst, immP_NM src, iRegLdst base) %{ 6057 match(Set dst src); 6058 effect(TEMP base); 6059 6060 ins_field_const_toc_offset_hi_node(loadConP_hiNode*); 6061 6062 format %{ "LD $dst, offset, $base \t// load ptr $src from TOC (lo)" %} 6063 size(4); 6064 ins_encode %{ 6065 // TODO: PPC port $archOpcode(ppc64Opcode_ld); 6066 int offset = ra_->C->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset; 6067 __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register); 6068 %} 6069 ins_pipe(pipe_class_memory); 6070 %} 6071 6072 // Load pointer constant from constant table. Expand in case an 6073 // offset > 16 bit is needed. 6074 // Adlc adds toc node MachConstantTableBase. 6075 instruct loadConP_Ex(iRegPdst dst, immP src) %{ 6076 match(Set dst src); 6077 ins_cost(MEMORY_REF_COST); 6078 6079 // This rule does not use "expand" because then 6080 // the result type is not known to be an Oop. An ADLC 6081 // enhancement will be needed to make that work - not worth it! 6082 6083 // If this instruction rematerializes, it prolongs the live range 6084 // of the toc node, causing illegal graphs. 6085 // assert(edge_from_to(_reg_node[reg_lo],def)) fails in verify_good_schedule(). 6086 ins_cannot_rematerialize(true); 6087 6088 format %{ "LD $dst, offset, $constanttablebase \t// load ptr $src from table, postalloc expanded" %} 6089 postalloc_expand( postalloc_expand_load_ptr_constant(dst, src, constanttablebase) ); 6090 %} 6091 6092 // Expand node for constant pool load: small offset. 6093 instruct loadConF(regF dst, immF src, iRegLdst toc) %{ 6094 effect(DEF dst, USE src, USE toc); 6095 ins_cost(MEMORY_REF_COST); 6096 6097 ins_num_consts(1); 6098 6099 format %{ "LFS $dst, offset, $toc \t// load float $src from TOC" %} 6100 size(4); 6101 ins_encode %{ 6102 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 6103 address float_address = __ float_constant($src$$constant); 6104 if (float_address == NULL) { 6105 ciEnv::current()->record_out_of_memory_failure(); 6106 return; 6107 } 6108 __ lfs($dst$$FloatRegister, __ offset_to_method_toc(float_address), $toc$$Register); 6109 %} 6110 ins_pipe(pipe_class_memory); 6111 %} 6112 6113 // Expand node for constant pool load: large offset. 6114 instruct loadConFComp(regF dst, immF src, iRegLdst toc) %{ 6115 effect(DEF dst, USE src, USE toc); 6116 ins_cost(MEMORY_REF_COST); 6117 6118 ins_num_consts(1); 6119 6120 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6121 "LFS $dst, offset_lo, $toc \t// load float $src from TOC (hi/lo)\n\t" 6122 "ADDIS $toc, $toc, -offset_hi"%} 6123 size(12); 6124 ins_encode %{ 6125 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6126 FloatRegister Rdst = $dst$$FloatRegister; 6127 Register Rtoc = $toc$$Register; 6128 address float_address = __ float_constant($src$$constant); 6129 if (float_address == NULL) { 6130 ciEnv::current()->record_out_of_memory_failure(); 6131 return; 6132 } 6133 int offset = __ offset_to_method_toc(float_address); 6134 int hi = (offset + (1<<15))>>16; 6135 int lo = offset - hi * (1<<16); 6136 6137 __ addis(Rtoc, Rtoc, hi); 6138 __ lfs(Rdst, lo, Rtoc); 6139 __ addis(Rtoc, Rtoc, -hi); 6140 %} 6141 ins_pipe(pipe_class_memory); 6142 %} 6143 6144 // Adlc adds toc node MachConstantTableBase. 6145 instruct loadConF_Ex(regF dst, immF src) %{ 6146 match(Set dst src); 6147 ins_cost(MEMORY_REF_COST); 6148 6149 // See loadConP. 6150 ins_cannot_rematerialize(true); 6151 6152 format %{ "LFS $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6153 postalloc_expand( postalloc_expand_load_float_constant(dst, src, constanttablebase) ); 6154 %} 6155 6156 // Expand node for constant pool load: small offset. 6157 instruct loadConD(regD dst, immD src, iRegLdst toc) %{ 6158 effect(DEF dst, USE src, USE toc); 6159 ins_cost(MEMORY_REF_COST); 6160 6161 ins_num_consts(1); 6162 6163 format %{ "LFD $dst, offset, $toc \t// load double $src from TOC" %} 6164 size(4); 6165 ins_encode %{ 6166 // TODO: PPC port $archOpcode(ppc64Opcode_lfd); 6167 address float_address = __ double_constant($src$$constant); 6168 if (float_address == NULL) { 6169 ciEnv::current()->record_out_of_memory_failure(); 6170 return; 6171 } 6172 int offset = __ offset_to_method_toc(float_address); 6173 __ lfd($dst$$FloatRegister, offset, $toc$$Register); 6174 %} 6175 ins_pipe(pipe_class_memory); 6176 %} 6177 6178 // Expand node for constant pool load: large offset. 6179 instruct loadConDComp(regD dst, immD src, iRegLdst toc) %{ 6180 effect(DEF dst, USE src, USE toc); 6181 ins_cost(MEMORY_REF_COST); 6182 6183 ins_num_consts(1); 6184 6185 format %{ "ADDIS $toc, $toc, offset_hi\n\t" 6186 "LFD $dst, offset_lo, $toc \t// load double $src from TOC (hi/lo)\n\t" 6187 "ADDIS $toc, $toc, -offset_hi" %} 6188 size(12); 6189 ins_encode %{ 6190 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6191 FloatRegister Rdst = $dst$$FloatRegister; 6192 Register Rtoc = $toc$$Register; 6193 address float_address = __ double_constant($src$$constant); 6194 if (float_address == NULL) { 6195 ciEnv::current()->record_out_of_memory_failure(); 6196 return; 6197 } 6198 int offset = __ offset_to_method_toc(float_address); 6199 int hi = (offset + (1<<15))>>16; 6200 int lo = offset - hi * (1<<16); 6201 6202 __ addis(Rtoc, Rtoc, hi); 6203 __ lfd(Rdst, lo, Rtoc); 6204 __ addis(Rtoc, Rtoc, -hi); 6205 %} 6206 ins_pipe(pipe_class_memory); 6207 %} 6208 6209 // Adlc adds toc node MachConstantTableBase. 6210 instruct loadConD_Ex(regD dst, immD src) %{ 6211 match(Set dst src); 6212 ins_cost(MEMORY_REF_COST); 6213 6214 // See loadConP. 6215 ins_cannot_rematerialize(true); 6216 6217 format %{ "ConD $dst, offset, $constanttablebase \t// load $src from table, postalloc expanded" %} 6218 postalloc_expand( postalloc_expand_load_double_constant(dst, src, constanttablebase) ); 6219 %} 6220 6221 // Prefetch instructions. 6222 // Must be safe to execute with invalid address (cannot fault). 6223 6224 // Special prefetch versions which use the dcbz instruction. 6225 instruct prefetch_alloc_zero(indirectMemory mem, iRegLsrc src) %{ 6226 match(PrefetchAllocation (AddP mem src)); 6227 predicate(AllocatePrefetchStyle == 3); 6228 ins_cost(MEMORY_REF_COST); 6229 6230 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many with zero" %} 6231 size(4); 6232 ins_encode %{ 6233 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6234 __ dcbz($src$$Register, $mem$$base$$Register); 6235 %} 6236 ins_pipe(pipe_class_memory); 6237 %} 6238 6239 instruct prefetch_alloc_zero_no_offset(indirectMemory mem) %{ 6240 match(PrefetchAllocation mem); 6241 predicate(AllocatePrefetchStyle == 3); 6242 ins_cost(MEMORY_REF_COST); 6243 6244 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many with zero" %} 6245 size(4); 6246 ins_encode %{ 6247 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6248 __ dcbz($mem$$base$$Register); 6249 %} 6250 ins_pipe(pipe_class_memory); 6251 %} 6252 6253 instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{ 6254 match(PrefetchAllocation (AddP mem src)); 6255 predicate(AllocatePrefetchStyle != 3); 6256 ins_cost(MEMORY_REF_COST); 6257 6258 format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many" %} 6259 size(4); 6260 ins_encode %{ 6261 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6262 __ dcbtst($src$$Register, $mem$$base$$Register); 6263 %} 6264 ins_pipe(pipe_class_memory); 6265 %} 6266 6267 instruct prefetch_alloc_no_offset(indirectMemory mem) %{ 6268 match(PrefetchAllocation mem); 6269 predicate(AllocatePrefetchStyle != 3); 6270 ins_cost(MEMORY_REF_COST); 6271 6272 format %{ "PREFETCH $mem, 2 \t// Prefetch write-many" %} 6273 size(4); 6274 ins_encode %{ 6275 // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst); 6276 __ dcbtst($mem$$base$$Register); 6277 %} 6278 ins_pipe(pipe_class_memory); 6279 %} 6280 6281 //----------Store Instructions------------------------------------------------- 6282 6283 // Store Byte 6284 instruct storeB(memory mem, iRegIsrc src) %{ 6285 match(Set mem (StoreB mem src)); 6286 ins_cost(MEMORY_REF_COST); 6287 6288 format %{ "STB $src, $mem \t// byte" %} 6289 size(4); 6290 ins_encode %{ 6291 // TODO: PPC port $archOpcode(ppc64Opcode_stb); 6292 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6293 __ stb($src$$Register, Idisp, $mem$$base$$Register); 6294 %} 6295 ins_pipe(pipe_class_memory); 6296 %} 6297 6298 // Store Char/Short 6299 instruct storeC(memory mem, iRegIsrc src) %{ 6300 match(Set mem (StoreC mem src)); 6301 ins_cost(MEMORY_REF_COST); 6302 6303 format %{ "STH $src, $mem \t// short" %} 6304 size(4); 6305 ins_encode %{ 6306 // TODO: PPC port $archOpcode(ppc64Opcode_sth); 6307 int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_); 6308 __ sth($src$$Register, Idisp, $mem$$base$$Register); 6309 %} 6310 ins_pipe(pipe_class_memory); 6311 %} 6312 6313 // Store Integer 6314 instruct storeI(memory mem, iRegIsrc src) %{ 6315 match(Set mem (StoreI mem src)); 6316 ins_cost(MEMORY_REF_COST); 6317 6318 format %{ "STW $src, $mem" %} 6319 size(4); 6320 ins_encode( enc_stw(src, mem) ); 6321 ins_pipe(pipe_class_memory); 6322 %} 6323 6324 // ConvL2I + StoreI. 6325 instruct storeI_convL2I(memory mem, iRegLsrc src) %{ 6326 match(Set mem (StoreI mem (ConvL2I src))); 6327 ins_cost(MEMORY_REF_COST); 6328 6329 format %{ "STW l2i($src), $mem" %} 6330 size(4); 6331 ins_encode( enc_stw(src, mem) ); 6332 ins_pipe(pipe_class_memory); 6333 %} 6334 6335 // Store Long 6336 instruct storeL(memoryAlg4 mem, iRegLsrc src) %{ 6337 match(Set mem (StoreL mem src)); 6338 ins_cost(MEMORY_REF_COST); 6339 6340 format %{ "STD $src, $mem \t// long" %} 6341 size(4); 6342 ins_encode( enc_std(src, mem) ); 6343 ins_pipe(pipe_class_memory); 6344 %} 6345 6346 // Store super word nodes. 6347 6348 // Store Aligned Packed Byte long register to memory 6349 instruct storeA8B(memoryAlg4 mem, iRegLsrc src) %{ 6350 predicate(n->as_StoreVector()->memory_size() == 8); 6351 match(Set mem (StoreVector mem src)); 6352 ins_cost(MEMORY_REF_COST); 6353 6354 format %{ "STD $mem, $src \t// packed8B" %} 6355 size(4); 6356 ins_encode( enc_std(src, mem) ); 6357 ins_pipe(pipe_class_memory); 6358 %} 6359 6360 // Store Compressed Oop 6361 instruct storeN(memory dst, iRegN_P2N src) %{ 6362 match(Set dst (StoreN dst src)); 6363 ins_cost(MEMORY_REF_COST); 6364 6365 format %{ "STW $src, $dst \t// compressed oop" %} 6366 size(4); 6367 ins_encode( enc_stw(src, dst) ); 6368 ins_pipe(pipe_class_memory); 6369 %} 6370 6371 // Store Compressed KLass 6372 instruct storeNKlass(memory dst, iRegN_P2N src) %{ 6373 match(Set dst (StoreNKlass dst src)); 6374 ins_cost(MEMORY_REF_COST); 6375 6376 format %{ "STW $src, $dst \t// compressed klass" %} 6377 size(4); 6378 ins_encode( enc_stw(src, dst) ); 6379 ins_pipe(pipe_class_memory); 6380 %} 6381 6382 // Store Pointer 6383 instruct storeP(memoryAlg4 dst, iRegPsrc src) %{ 6384 match(Set dst (StoreP dst src)); 6385 ins_cost(MEMORY_REF_COST); 6386 6387 format %{ "STD $src, $dst \t// ptr" %} 6388 size(4); 6389 ins_encode( enc_std(src, dst) ); 6390 ins_pipe(pipe_class_memory); 6391 %} 6392 6393 // Store Float 6394 instruct storeF(memory mem, regF src) %{ 6395 match(Set mem (StoreF mem src)); 6396 ins_cost(MEMORY_REF_COST); 6397 6398 format %{ "STFS $src, $mem" %} 6399 size(4); 6400 ins_encode( enc_stfs(src, mem) ); 6401 ins_pipe(pipe_class_memory); 6402 %} 6403 6404 // Store Double 6405 instruct storeD(memory mem, regD src) %{ 6406 match(Set mem (StoreD mem src)); 6407 ins_cost(MEMORY_REF_COST); 6408 6409 format %{ "STFD $src, $mem" %} 6410 size(4); 6411 ins_encode( enc_stfd(src, mem) ); 6412 ins_pipe(pipe_class_memory); 6413 %} 6414 6415 //----------Store Instructions With Zeros-------------------------------------- 6416 6417 // Card-mark for CMS garbage collection. 6418 // This cardmark does an optimization so that it must not always 6419 // do a releasing store. For this, it gets the address of 6420 // CMSCollectorCardTableModRefBSExt::_requires_release as input. 6421 // (Using releaseFieldAddr in the match rule is a hack.) 6422 instruct storeCM_CMS(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{ 6423 match(Set mem (StoreCM mem releaseFieldAddr)); 6424 effect(TEMP crx); 6425 predicate(false); 6426 ins_cost(MEMORY_REF_COST); 6427 6428 // See loadConP. 6429 ins_cannot_rematerialize(true); 6430 6431 format %{ "STB #0, $mem \t// CMS card-mark byte (must be 0!), checking requires_release in [$releaseFieldAddr]" %} 6432 ins_encode( enc_cms_card_mark(mem, releaseFieldAddr, crx) ); 6433 ins_pipe(pipe_class_memory); 6434 %} 6435 6436 // Card-mark for CMS garbage collection. 6437 // This cardmark does an optimization so that it must not always 6438 // do a releasing store. For this, it needs the constant address of 6439 // CMSCollectorCardTableModRefBSExt::_requires_release. 6440 // This constant address is split off here by expand so we can use 6441 // adlc / matcher functionality to load it from the constant section. 6442 instruct storeCM_CMS_ExEx(memory mem, immI_0 zero) %{ 6443 match(Set mem (StoreCM mem zero)); 6444 predicate(UseConcMarkSweepGC); 6445 6446 expand %{ 6447 immL baseImm %{ 0 /* TODO: PPC port (jlong)CMSCollectorCardTableModRefBSExt::requires_release_address() */ %} 6448 iRegLdst releaseFieldAddress; 6449 flagsReg crx; 6450 loadConL_Ex(releaseFieldAddress, baseImm); 6451 storeCM_CMS(mem, releaseFieldAddress, crx); 6452 %} 6453 %} 6454 6455 instruct storeCM_G1(memory mem, immI_0 zero) %{ 6456 match(Set mem (StoreCM mem zero)); 6457 predicate(UseG1GC); 6458 ins_cost(MEMORY_REF_COST); 6459 6460 ins_cannot_rematerialize(true); 6461 6462 format %{ "STB #0, $mem \t// CMS card-mark byte store (G1)" %} 6463 size(8); 6464 ins_encode %{ 6465 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6466 __ li(R0, 0); 6467 //__ release(); // G1: oops are allowed to get visible after dirty marking 6468 guarantee($mem$$base$$Register != R1_SP, "use frame_slots_bias"); 6469 __ stb(R0, $mem$$disp, $mem$$base$$Register); 6470 %} 6471 ins_pipe(pipe_class_memory); 6472 %} 6473 6474 // Convert oop pointer into compressed form. 6475 6476 // Nodes for postalloc expand. 6477 6478 // Shift node for expand. 6479 instruct encodeP_shift(iRegNdst dst, iRegNsrc src) %{ 6480 // The match rule is needed to make it a 'MachTypeNode'! 6481 match(Set dst (EncodeP src)); 6482 predicate(false); 6483 6484 format %{ "SRDI $dst, $src, 3 \t// encode" %} 6485 size(4); 6486 ins_encode %{ 6487 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6488 __ srdi($dst$$Register, $src$$Register, Universe::narrow_oop_shift() & 0x3f); 6489 %} 6490 ins_pipe(pipe_class_default); 6491 %} 6492 6493 // Add node for expand. 6494 instruct encodeP_sub(iRegPdst dst, iRegPdst src) %{ 6495 // The match rule is needed to make it a 'MachTypeNode'! 6496 match(Set dst (EncodeP src)); 6497 predicate(false); 6498 6499 format %{ "SUB $dst, $src, oop_base \t// encode" %} 6500 ins_encode %{ 6501 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6502 __ sub_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 6503 %} 6504 ins_pipe(pipe_class_default); 6505 %} 6506 6507 // Conditional sub base. 6508 instruct cond_sub_base(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6509 // The match rule is needed to make it a 'MachTypeNode'! 6510 match(Set dst (EncodeP (Binary crx src1))); 6511 predicate(false); 6512 6513 format %{ "BEQ $crx, done\n\t" 6514 "SUB $dst, $src1, heapbase \t// encode: subtract base if != NULL\n" 6515 "done:" %} 6516 ins_encode %{ 6517 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6518 Label done; 6519 __ beq($crx$$CondRegister, done); 6520 __ sub_const_optimized($dst$$Register, $src1$$Register, Universe::narrow_oop_base(), R0); 6521 __ bind(done); 6522 %} 6523 ins_pipe(pipe_class_default); 6524 %} 6525 6526 // Power 7 can use isel instruction 6527 instruct cond_set_0_oop(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6528 // The match rule is needed to make it a 'MachTypeNode'! 6529 match(Set dst (EncodeP (Binary crx src1))); 6530 predicate(false); 6531 6532 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// encode: preserve 0" %} 6533 size(4); 6534 ins_encode %{ 6535 // This is a Power7 instruction for which no machine description exists. 6536 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6537 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 6538 %} 6539 ins_pipe(pipe_class_default); 6540 %} 6541 6542 // Disjoint narrow oop base. 6543 instruct encodeP_Disjoint(iRegNdst dst, iRegPsrc src) %{ 6544 match(Set dst (EncodeP src)); 6545 predicate(Universe::narrow_oop_base_disjoint()); 6546 6547 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 6548 size(4); 6549 ins_encode %{ 6550 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6551 __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_oop_shift(), 32); 6552 %} 6553 ins_pipe(pipe_class_default); 6554 %} 6555 6556 // shift != 0, base != 0 6557 instruct encodeP_Ex(iRegNdst dst, flagsReg crx, iRegPsrc src) %{ 6558 match(Set dst (EncodeP src)); 6559 effect(TEMP crx); 6560 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull && 6561 Universe::narrow_oop_shift() != 0 && 6562 Universe::narrow_oop_base_overlaps()); 6563 6564 format %{ "EncodeP $dst, $crx, $src \t// postalloc expanded" %} 6565 postalloc_expand( postalloc_expand_encode_oop(dst, src, crx)); 6566 %} 6567 6568 // shift != 0, base != 0 6569 instruct encodeP_not_null_Ex(iRegNdst dst, iRegPsrc src) %{ 6570 match(Set dst (EncodeP src)); 6571 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull && 6572 Universe::narrow_oop_shift() != 0 && 6573 Universe::narrow_oop_base_overlaps()); 6574 6575 format %{ "EncodeP $dst, $src\t// $src != Null, postalloc expanded" %} 6576 postalloc_expand( postalloc_expand_encode_oop_not_null(dst, src) ); 6577 %} 6578 6579 // shift != 0, base == 0 6580 // TODO: This is the same as encodeP_shift. Merge! 6581 instruct encodeP_not_null_base_null(iRegNdst dst, iRegPsrc src) %{ 6582 match(Set dst (EncodeP src)); 6583 predicate(Universe::narrow_oop_shift() != 0 && 6584 Universe::narrow_oop_base() ==0); 6585 6586 format %{ "SRDI $dst, $src, #3 \t// encodeP, $src != NULL" %} 6587 size(4); 6588 ins_encode %{ 6589 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6590 __ srdi($dst$$Register, $src$$Register, Universe::narrow_oop_shift() & 0x3f); 6591 %} 6592 ins_pipe(pipe_class_default); 6593 %} 6594 6595 // Compressed OOPs with narrow_oop_shift == 0. 6596 // shift == 0, base == 0 6597 instruct encodeP_narrow_oop_shift_0(iRegNdst dst, iRegPsrc src) %{ 6598 match(Set dst (EncodeP src)); 6599 predicate(Universe::narrow_oop_shift() == 0); 6600 6601 format %{ "MR $dst, $src \t// Ptr->Narrow" %} 6602 // variable size, 0 or 4. 6603 ins_encode %{ 6604 // TODO: PPC port $archOpcode(ppc64Opcode_or); 6605 __ mr_if_needed($dst$$Register, $src$$Register); 6606 %} 6607 ins_pipe(pipe_class_default); 6608 %} 6609 6610 // Decode nodes. 6611 6612 // Shift node for expand. 6613 instruct decodeN_shift(iRegPdst dst, iRegPsrc src) %{ 6614 // The match rule is needed to make it a 'MachTypeNode'! 6615 match(Set dst (DecodeN src)); 6616 predicate(false); 6617 6618 format %{ "SLDI $dst, $src, #3 \t// DecodeN" %} 6619 size(4); 6620 ins_encode %{ 6621 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 6622 __ sldi($dst$$Register, $src$$Register, Universe::narrow_oop_shift()); 6623 %} 6624 ins_pipe(pipe_class_default); 6625 %} 6626 6627 // Add node for expand. 6628 instruct decodeN_add(iRegPdst dst, iRegPdst src) %{ 6629 // The match rule is needed to make it a 'MachTypeNode'! 6630 match(Set dst (DecodeN src)); 6631 predicate(false); 6632 6633 format %{ "ADD $dst, $src, heapbase \t// DecodeN, add oop base" %} 6634 ins_encode %{ 6635 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6636 __ add_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 6637 %} 6638 ins_pipe(pipe_class_default); 6639 %} 6640 6641 // conditianal add base for expand 6642 instruct cond_add_base(iRegPdst dst, flagsRegSrc crx, iRegPsrc src) %{ 6643 // The match rule is needed to make it a 'MachTypeNode'! 6644 // NOTICE that the rule is nonsense - we just have to make sure that: 6645 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 6646 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 6647 match(Set dst (DecodeN (Binary crx src))); 6648 predicate(false); 6649 6650 format %{ "BEQ $crx, done\n\t" 6651 "ADD $dst, $src, heapbase \t// DecodeN: add oop base if $src != NULL\n" 6652 "done:" %} 6653 ins_encode %{ 6654 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6655 Label done; 6656 __ beq($crx$$CondRegister, done); 6657 __ add_const_optimized($dst$$Register, $src$$Register, Universe::narrow_oop_base(), R0); 6658 __ bind(done); 6659 %} 6660 ins_pipe(pipe_class_default); 6661 %} 6662 6663 instruct cond_set_0_ptr(iRegPdst dst, flagsRegSrc crx, iRegPsrc src1) %{ 6664 // The match rule is needed to make it a 'MachTypeNode'! 6665 // NOTICE that the rule is nonsense - we just have to make sure that: 6666 // - _matrule->_rChild->_opType == "DecodeN" (see InstructForm::captures_bottom_type() in formssel.cpp) 6667 // - we have to match 'crx' to avoid an "illegal USE of non-input: flagsReg crx" error in ADLC. 6668 match(Set dst (DecodeN (Binary crx src1))); 6669 predicate(false); 6670 6671 format %{ "CMOVE $dst, $crx eq, 0, $src1 \t// decode: preserve 0" %} 6672 size(4); 6673 ins_encode %{ 6674 // This is a Power7 instruction for which no machine description exists. 6675 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 6676 __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register); 6677 %} 6678 ins_pipe(pipe_class_default); 6679 %} 6680 6681 // shift != 0, base != 0 6682 instruct decodeN_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 6683 match(Set dst (DecodeN src)); 6684 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 6685 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 6686 Universe::narrow_oop_shift() != 0 && 6687 Universe::narrow_oop_base() != 0); 6688 ins_cost(4 * DEFAULT_COST); // Should be more expensive than decodeN_Disjoint_isel_Ex. 6689 effect(TEMP crx); 6690 6691 format %{ "DecodeN $dst, $src \t// Kills $crx, postalloc expanded" %} 6692 postalloc_expand( postalloc_expand_decode_oop(dst, src, crx) ); 6693 %} 6694 6695 // shift != 0, base == 0 6696 instruct decodeN_nullBase(iRegPdst dst, iRegNsrc src) %{ 6697 match(Set dst (DecodeN src)); 6698 predicate(Universe::narrow_oop_shift() != 0 && 6699 Universe::narrow_oop_base() == 0); 6700 6701 format %{ "SLDI $dst, $src, #3 \t// DecodeN (zerobased)" %} 6702 size(4); 6703 ins_encode %{ 6704 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 6705 __ sldi($dst$$Register, $src$$Register, Universe::narrow_oop_shift()); 6706 %} 6707 ins_pipe(pipe_class_default); 6708 %} 6709 6710 // Optimize DecodeN for disjoint base. 6711 // Shift narrow oop and or it into register that already contains the heap base. 6712 // Base == dst must hold, and is assured by construction in postaloc_expand. 6713 instruct decodeN_mergeDisjoint(iRegPdst dst, iRegNsrc src, iRegLsrc base) %{ 6714 match(Set dst (DecodeN src)); 6715 effect(TEMP base); 6716 predicate(false); 6717 6718 format %{ "RLDIMI $dst, $src, shift, 32-shift \t// DecodeN (disjoint base)" %} 6719 size(4); 6720 ins_encode %{ 6721 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 6722 __ rldimi($dst$$Register, $src$$Register, Universe::narrow_oop_shift(), 32-Universe::narrow_oop_shift()); 6723 %} 6724 ins_pipe(pipe_class_default); 6725 %} 6726 6727 // Optimize DecodeN for disjoint base. 6728 // This node requires only one cycle on the critical path. 6729 // We must postalloc_expand as we can not express use_def effects where 6730 // the used register is L and the def'ed register P. 6731 instruct decodeN_Disjoint_notNull_Ex(iRegPdst dst, iRegNsrc src) %{ 6732 match(Set dst (DecodeN src)); 6733 effect(TEMP_DEF dst); 6734 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 6735 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 6736 Universe::narrow_oop_base_disjoint()); 6737 ins_cost(DEFAULT_COST); 6738 6739 format %{ "MOV $dst, heapbase \t\n" 6740 "RLDIMI $dst, $src, shift, 32-shift \t// decode with disjoint base" %} 6741 postalloc_expand %{ 6742 loadBaseNode *n1 = new loadBaseNode(); 6743 n1->add_req(NULL); 6744 n1->_opnds[0] = op_dst; 6745 6746 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 6747 n2->add_req(n_region, n_src, n1); 6748 n2->_opnds[0] = op_dst; 6749 n2->_opnds[1] = op_src; 6750 n2->_opnds[2] = op_dst; 6751 n2->_bottom_type = _bottom_type; 6752 6753 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6754 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6755 6756 nodes->push(n1); 6757 nodes->push(n2); 6758 %} 6759 %} 6760 6761 instruct decodeN_Disjoint_isel_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ 6762 match(Set dst (DecodeN src)); 6763 effect(TEMP_DEF dst, TEMP crx); 6764 predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 6765 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && 6766 Universe::narrow_oop_base_disjoint() && VM_Version::has_isel()); 6767 ins_cost(3 * DEFAULT_COST); 6768 6769 format %{ "DecodeN $dst, $src \t// decode with disjoint base using isel" %} 6770 postalloc_expand %{ 6771 loadBaseNode *n1 = new loadBaseNode(); 6772 n1->add_req(NULL); 6773 n1->_opnds[0] = op_dst; 6774 6775 cmpN_reg_imm0Node *n_compare = new cmpN_reg_imm0Node(); 6776 n_compare->add_req(n_region, n_src); 6777 n_compare->_opnds[0] = op_crx; 6778 n_compare->_opnds[1] = op_src; 6779 n_compare->_opnds[2] = new immN_0Oper(TypeNarrowOop::NULL_PTR); 6780 6781 decodeN_mergeDisjointNode *n2 = new decodeN_mergeDisjointNode(); 6782 n2->add_req(n_region, n_src, n1); 6783 n2->_opnds[0] = op_dst; 6784 n2->_opnds[1] = op_src; 6785 n2->_opnds[2] = op_dst; 6786 n2->_bottom_type = _bottom_type; 6787 6788 cond_set_0_ptrNode *n_cond_set = new cond_set_0_ptrNode(); 6789 n_cond_set->add_req(n_region, n_compare, n2); 6790 n_cond_set->_opnds[0] = op_dst; 6791 n_cond_set->_opnds[1] = op_crx; 6792 n_cond_set->_opnds[2] = op_dst; 6793 n_cond_set->_bottom_type = _bottom_type; 6794 6795 assert(ra_->is_oop(this) == true, "A decodeN node must produce an oop!"); 6796 ra_->set_oop(n_cond_set, true); 6797 6798 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6799 ra_->set_pair(n_compare->_idx, ra_->get_reg_second(n_crx), ra_->get_reg_first(n_crx)); 6800 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6801 ra_->set_pair(n_cond_set->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6802 6803 nodes->push(n1); 6804 nodes->push(n_compare); 6805 nodes->push(n2); 6806 nodes->push(n_cond_set); 6807 %} 6808 %} 6809 6810 // src != 0, shift != 0, base != 0 6811 instruct decodeN_notNull_addBase_Ex(iRegPdst dst, iRegNsrc src) %{ 6812 match(Set dst (DecodeN src)); 6813 predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 6814 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && 6815 Universe::narrow_oop_shift() != 0 && 6816 Universe::narrow_oop_base() != 0); 6817 ins_cost(2 * DEFAULT_COST); 6818 6819 format %{ "DecodeN $dst, $src \t// $src != NULL, postalloc expanded" %} 6820 postalloc_expand( postalloc_expand_decode_oop_not_null(dst, src)); 6821 %} 6822 6823 // Compressed OOPs with narrow_oop_shift == 0. 6824 instruct decodeN_unscaled(iRegPdst dst, iRegNsrc src) %{ 6825 match(Set dst (DecodeN src)); 6826 predicate(Universe::narrow_oop_shift() == 0); 6827 ins_cost(DEFAULT_COST); 6828 6829 format %{ "MR $dst, $src \t// DecodeN (unscaled)" %} 6830 // variable size, 0 or 4. 6831 ins_encode %{ 6832 // TODO: PPC port $archOpcode(ppc64Opcode_or); 6833 __ mr_if_needed($dst$$Register, $src$$Register); 6834 %} 6835 ins_pipe(pipe_class_default); 6836 %} 6837 6838 // Convert compressed oop into int for vectors alignment masking. 6839 instruct decodeN2I_unscaled(iRegIdst dst, iRegNsrc src) %{ 6840 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6841 predicate(Universe::narrow_oop_shift() == 0); 6842 ins_cost(DEFAULT_COST); 6843 6844 format %{ "MR $dst, $src \t// (int)DecodeN (unscaled)" %} 6845 // variable size, 0 or 4. 6846 ins_encode %{ 6847 // TODO: PPC port $archOpcode(ppc64Opcode_or); 6848 __ mr_if_needed($dst$$Register, $src$$Register); 6849 %} 6850 ins_pipe(pipe_class_default); 6851 %} 6852 6853 // Convert klass pointer into compressed form. 6854 6855 // Nodes for postalloc expand. 6856 6857 // Shift node for expand. 6858 instruct encodePKlass_shift(iRegNdst dst, iRegNsrc src) %{ 6859 // The match rule is needed to make it a 'MachTypeNode'! 6860 match(Set dst (EncodePKlass src)); 6861 predicate(false); 6862 6863 format %{ "SRDI $dst, $src, 3 \t// encode" %} 6864 size(4); 6865 ins_encode %{ 6866 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6867 __ srdi($dst$$Register, $src$$Register, Universe::narrow_klass_shift()); 6868 %} 6869 ins_pipe(pipe_class_default); 6870 %} 6871 6872 // Add node for expand. 6873 instruct encodePKlass_sub_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 6874 // The match rule is needed to make it a 'MachTypeNode'! 6875 match(Set dst (EncodePKlass (Binary base src))); 6876 predicate(false); 6877 6878 format %{ "SUB $dst, $base, $src \t// encode" %} 6879 size(4); 6880 ins_encode %{ 6881 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 6882 __ subf($dst$$Register, $base$$Register, $src$$Register); 6883 %} 6884 ins_pipe(pipe_class_default); 6885 %} 6886 6887 // Disjoint narrow oop base. 6888 instruct encodePKlass_Disjoint(iRegNdst dst, iRegPsrc src) %{ 6889 match(Set dst (EncodePKlass src)); 6890 predicate(false /* TODO: PPC port Universe::narrow_klass_base_disjoint()*/); 6891 6892 format %{ "EXTRDI $dst, $src, #32, #3 \t// encode with disjoint base" %} 6893 size(4); 6894 ins_encode %{ 6895 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 6896 __ rldicl($dst$$Register, $src$$Register, 64-Universe::narrow_klass_shift(), 32); 6897 %} 6898 ins_pipe(pipe_class_default); 6899 %} 6900 6901 // shift != 0, base != 0 6902 instruct encodePKlass_not_null_Ex(iRegNdst dst, iRegLsrc base, iRegPsrc src) %{ 6903 match(Set dst (EncodePKlass (Binary base src))); 6904 predicate(false); 6905 6906 format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 6907 postalloc_expand %{ 6908 encodePKlass_sub_baseNode *n1 = new encodePKlass_sub_baseNode(); 6909 n1->add_req(n_region, n_base, n_src); 6910 n1->_opnds[0] = op_dst; 6911 n1->_opnds[1] = op_base; 6912 n1->_opnds[2] = op_src; 6913 n1->_bottom_type = _bottom_type; 6914 6915 encodePKlass_shiftNode *n2 = new encodePKlass_shiftNode(); 6916 n2->add_req(n_region, n1); 6917 n2->_opnds[0] = op_dst; 6918 n2->_opnds[1] = op_dst; 6919 n2->_bottom_type = _bottom_type; 6920 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6921 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6922 6923 nodes->push(n1); 6924 nodes->push(n2); 6925 %} 6926 %} 6927 6928 // shift != 0, base != 0 6929 instruct encodePKlass_not_null_ExEx(iRegNdst dst, iRegPsrc src) %{ 6930 match(Set dst (EncodePKlass src)); 6931 //predicate(Universe::narrow_klass_shift() != 0 && 6932 // true /* TODO: PPC port Universe::narrow_klass_base_overlaps()*/); 6933 6934 //format %{ "EncodePKlass $dst, $src\t// $src != Null, postalloc expanded" %} 6935 ins_cost(DEFAULT_COST*2); // Don't count constant. 6936 expand %{ 6937 immL baseImm %{ (jlong)(intptr_t)Universe::narrow_klass_base() %} 6938 iRegLdst base; 6939 loadConL_Ex(base, baseImm); 6940 encodePKlass_not_null_Ex(dst, base, src); 6941 %} 6942 %} 6943 6944 // Decode nodes. 6945 6946 // Shift node for expand. 6947 instruct decodeNKlass_shift(iRegPdst dst, iRegPsrc src) %{ 6948 // The match rule is needed to make it a 'MachTypeNode'! 6949 match(Set dst (DecodeNKlass src)); 6950 predicate(false); 6951 6952 format %{ "SLDI $dst, $src, #3 \t// DecodeNKlass" %} 6953 size(4); 6954 ins_encode %{ 6955 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 6956 __ sldi($dst$$Register, $src$$Register, Universe::narrow_klass_shift()); 6957 %} 6958 ins_pipe(pipe_class_default); 6959 %} 6960 6961 // Add node for expand. 6962 6963 instruct decodeNKlass_add_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{ 6964 // The match rule is needed to make it a 'MachTypeNode'! 6965 match(Set dst (DecodeNKlass (Binary base src))); 6966 predicate(false); 6967 6968 format %{ "ADD $dst, $base, $src \t// DecodeNKlass, add klass base" %} 6969 size(4); 6970 ins_encode %{ 6971 // TODO: PPC port $archOpcode(ppc64Opcode_add); 6972 __ add($dst$$Register, $base$$Register, $src$$Register); 6973 %} 6974 ins_pipe(pipe_class_default); 6975 %} 6976 6977 // src != 0, shift != 0, base != 0 6978 instruct decodeNKlass_notNull_addBase_Ex(iRegPdst dst, iRegLsrc base, iRegNsrc src) %{ 6979 match(Set dst (DecodeNKlass (Binary base src))); 6980 //effect(kill src); // We need a register for the immediate result after shifting. 6981 predicate(false); 6982 6983 format %{ "DecodeNKlass $dst = $base + ($src << 3) \t// $src != NULL, postalloc expanded" %} 6984 postalloc_expand %{ 6985 decodeNKlass_add_baseNode *n1 = new decodeNKlass_add_baseNode(); 6986 n1->add_req(n_region, n_base, n_src); 6987 n1->_opnds[0] = op_dst; 6988 n1->_opnds[1] = op_base; 6989 n1->_opnds[2] = op_src; 6990 n1->_bottom_type = _bottom_type; 6991 6992 decodeNKlass_shiftNode *n2 = new decodeNKlass_shiftNode(); 6993 n2->add_req(n_region, n1); 6994 n2->_opnds[0] = op_dst; 6995 n2->_opnds[1] = op_dst; 6996 n2->_bottom_type = _bottom_type; 6997 6998 ra_->set_pair(n1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 6999 ra_->set_pair(n2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); 7000 7001 nodes->push(n1); 7002 nodes->push(n2); 7003 %} 7004 %} 7005 7006 // src != 0, shift != 0, base != 0 7007 instruct decodeNKlass_notNull_addBase_ExEx(iRegPdst dst, iRegNsrc src) %{ 7008 match(Set dst (DecodeNKlass src)); 7009 // predicate(Universe::narrow_klass_shift() != 0 && 7010 // Universe::narrow_klass_base() != 0); 7011 7012 //format %{ "DecodeNKlass $dst, $src \t// $src != NULL, expanded" %} 7013 7014 ins_cost(DEFAULT_COST*2); // Don't count constant. 7015 expand %{ 7016 // We add first, then we shift. Like this, we can get along with one register less. 7017 // But we have to load the base pre-shifted. 7018 immL baseImm %{ (jlong)((intptr_t)Universe::narrow_klass_base() >> Universe::narrow_klass_shift()) %} 7019 iRegLdst base; 7020 loadConL_Ex(base, baseImm); 7021 decodeNKlass_notNull_addBase_Ex(dst, base, src); 7022 %} 7023 %} 7024 7025 //----------MemBar Instructions----------------------------------------------- 7026 // Memory barrier flavors 7027 7028 instruct membar_acquire() %{ 7029 match(LoadFence); 7030 ins_cost(4*MEMORY_REF_COST); 7031 7032 format %{ "MEMBAR-acquire" %} 7033 size(4); 7034 ins_encode %{ 7035 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7036 __ acquire(); 7037 %} 7038 ins_pipe(pipe_class_default); 7039 %} 7040 7041 instruct unnecessary_membar_acquire() %{ 7042 match(MemBarAcquire); 7043 ins_cost(0); 7044 7045 format %{ " -- \t// redundant MEMBAR-acquire - empty" %} 7046 size(0); 7047 ins_encode( /*empty*/ ); 7048 ins_pipe(pipe_class_default); 7049 %} 7050 7051 instruct membar_acquire_lock() %{ 7052 match(MemBarAcquireLock); 7053 ins_cost(0); 7054 7055 format %{ " -- \t// redundant MEMBAR-acquire - empty (acquire as part of CAS in prior FastLock)" %} 7056 size(0); 7057 ins_encode( /*empty*/ ); 7058 ins_pipe(pipe_class_default); 7059 %} 7060 7061 instruct membar_release() %{ 7062 match(MemBarRelease); 7063 match(StoreFence); 7064 ins_cost(4*MEMORY_REF_COST); 7065 7066 format %{ "MEMBAR-release" %} 7067 size(4); 7068 ins_encode %{ 7069 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7070 __ release(); 7071 %} 7072 ins_pipe(pipe_class_default); 7073 %} 7074 7075 instruct membar_storestore() %{ 7076 match(MemBarStoreStore); 7077 ins_cost(4*MEMORY_REF_COST); 7078 7079 format %{ "MEMBAR-store-store" %} 7080 size(4); 7081 ins_encode %{ 7082 // TODO: PPC port $archOpcode(ppc64Opcode_lwsync); 7083 __ membar(Assembler::StoreStore); 7084 %} 7085 ins_pipe(pipe_class_default); 7086 %} 7087 7088 instruct membar_release_lock() %{ 7089 match(MemBarReleaseLock); 7090 ins_cost(0); 7091 7092 format %{ " -- \t// redundant MEMBAR-release - empty (release in FastUnlock)" %} 7093 size(0); 7094 ins_encode( /*empty*/ ); 7095 ins_pipe(pipe_class_default); 7096 %} 7097 7098 instruct membar_volatile() %{ 7099 match(MemBarVolatile); 7100 ins_cost(4*MEMORY_REF_COST); 7101 7102 format %{ "MEMBAR-volatile" %} 7103 size(4); 7104 ins_encode %{ 7105 // TODO: PPC port $archOpcode(ppc64Opcode_sync); 7106 __ fence(); 7107 %} 7108 ins_pipe(pipe_class_default); 7109 %} 7110 7111 // This optimization is wrong on PPC. The following pattern is not supported: 7112 // MemBarVolatile 7113 // ^ ^ 7114 // | | 7115 // CtrlProj MemProj 7116 // ^ ^ 7117 // | | 7118 // | Load 7119 // | 7120 // MemBarVolatile 7121 // 7122 // The first MemBarVolatile could get optimized out! According to 7123 // Vladimir, this pattern can not occur on Oracle platforms. 7124 // However, it does occur on PPC64 (because of membars in 7125 // inline_unsafe_load_store). 7126 // 7127 // Add this node again if we found a good solution for inline_unsafe_load_store(). 7128 // Don't forget to look at the implementation of post_store_load_barrier again, 7129 // we did other fixes in that method. 7130 //instruct unnecessary_membar_volatile() %{ 7131 // match(MemBarVolatile); 7132 // predicate(Matcher::post_store_load_barrier(n)); 7133 // ins_cost(0); 7134 // 7135 // format %{ " -- \t// redundant MEMBAR-volatile - empty" %} 7136 // size(0); 7137 // ins_encode( /*empty*/ ); 7138 // ins_pipe(pipe_class_default); 7139 //%} 7140 7141 instruct membar_CPUOrder() %{ 7142 match(MemBarCPUOrder); 7143 ins_cost(0); 7144 7145 format %{ " -- \t// MEMBAR-CPUOrder - empty: PPC64 processors are self-consistent." %} 7146 size(0); 7147 ins_encode( /*empty*/ ); 7148 ins_pipe(pipe_class_default); 7149 %} 7150 7151 //----------Conditional Move--------------------------------------------------- 7152 7153 // Cmove using isel. 7154 instruct cmovI_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7155 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7156 predicate(VM_Version::has_isel()); 7157 ins_cost(DEFAULT_COST); 7158 7159 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7160 size(4); 7161 ins_encode %{ 7162 // This is a Power7 instruction for which no machine description 7163 // exists. Anyways, the scheduler should be off on Power7. 7164 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7165 int cc = $cmp$$cmpcode; 7166 __ isel($dst$$Register, $crx$$CondRegister, 7167 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7168 %} 7169 ins_pipe(pipe_class_default); 7170 %} 7171 7172 instruct cmovI_reg(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{ 7173 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7174 predicate(!VM_Version::has_isel()); 7175 ins_cost(DEFAULT_COST+BRANCH_COST); 7176 7177 ins_variable_size_depending_on_alignment(true); 7178 7179 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7180 // Worst case is branch + move + stop, no stop without scheduler 7181 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7182 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7183 ins_pipe(pipe_class_default); 7184 %} 7185 7186 instruct cmovI_imm(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, immI16 src) %{ 7187 match(Set dst (CMoveI (Binary cmp crx) (Binary dst src))); 7188 ins_cost(DEFAULT_COST+BRANCH_COST); 7189 7190 ins_variable_size_depending_on_alignment(true); 7191 7192 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7193 // Worst case is branch + move + stop, no stop without scheduler 7194 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7195 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7196 ins_pipe(pipe_class_default); 7197 %} 7198 7199 // Cmove using isel. 7200 instruct cmovL_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7201 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7202 predicate(VM_Version::has_isel()); 7203 ins_cost(DEFAULT_COST); 7204 7205 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7206 size(4); 7207 ins_encode %{ 7208 // This is a Power7 instruction for which no machine description 7209 // exists. Anyways, the scheduler should be off on Power7. 7210 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7211 int cc = $cmp$$cmpcode; 7212 __ isel($dst$$Register, $crx$$CondRegister, 7213 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7214 %} 7215 ins_pipe(pipe_class_default); 7216 %} 7217 7218 instruct cmovL_reg(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{ 7219 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7220 predicate(!VM_Version::has_isel()); 7221 ins_cost(DEFAULT_COST+BRANCH_COST); 7222 7223 ins_variable_size_depending_on_alignment(true); 7224 7225 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7226 // Worst case is branch + move + stop, no stop without scheduler. 7227 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7228 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7229 ins_pipe(pipe_class_default); 7230 %} 7231 7232 instruct cmovL_imm(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, immL16 src) %{ 7233 match(Set dst (CMoveL (Binary cmp crx) (Binary dst src))); 7234 ins_cost(DEFAULT_COST+BRANCH_COST); 7235 7236 ins_variable_size_depending_on_alignment(true); 7237 7238 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7239 // Worst case is branch + move + stop, no stop without scheduler. 7240 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7241 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7242 ins_pipe(pipe_class_default); 7243 %} 7244 7245 // Cmove using isel. 7246 instruct cmovN_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7247 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7248 predicate(VM_Version::has_isel()); 7249 ins_cost(DEFAULT_COST); 7250 7251 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7252 size(4); 7253 ins_encode %{ 7254 // This is a Power7 instruction for which no machine description 7255 // exists. Anyways, the scheduler should be off on Power7. 7256 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7257 int cc = $cmp$$cmpcode; 7258 __ isel($dst$$Register, $crx$$CondRegister, 7259 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7260 %} 7261 ins_pipe(pipe_class_default); 7262 %} 7263 7264 // Conditional move for RegN. Only cmov(reg, reg). 7265 instruct cmovN_reg(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{ 7266 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7267 predicate(!VM_Version::has_isel()); 7268 ins_cost(DEFAULT_COST+BRANCH_COST); 7269 7270 ins_variable_size_depending_on_alignment(true); 7271 7272 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7273 // Worst case is branch + move + stop, no stop without scheduler. 7274 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7275 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7276 ins_pipe(pipe_class_default); 7277 %} 7278 7279 instruct cmovN_imm(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, immN_0 src) %{ 7280 match(Set dst (CMoveN (Binary cmp crx) (Binary dst src))); 7281 ins_cost(DEFAULT_COST+BRANCH_COST); 7282 7283 ins_variable_size_depending_on_alignment(true); 7284 7285 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7286 // Worst case is branch + move + stop, no stop without scheduler. 7287 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7288 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7289 ins_pipe(pipe_class_default); 7290 %} 7291 7292 // Cmove using isel. 7293 instruct cmovP_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegPsrc src) %{ 7294 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7295 predicate(VM_Version::has_isel()); 7296 ins_cost(DEFAULT_COST); 7297 7298 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7299 size(4); 7300 ins_encode %{ 7301 // This is a Power7 instruction for which no machine description 7302 // exists. Anyways, the scheduler should be off on Power7. 7303 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7304 int cc = $cmp$$cmpcode; 7305 __ isel($dst$$Register, $crx$$CondRegister, 7306 (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register); 7307 %} 7308 ins_pipe(pipe_class_default); 7309 %} 7310 7311 instruct cmovP_reg(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegP_N2P src) %{ 7312 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7313 predicate(!VM_Version::has_isel()); 7314 ins_cost(DEFAULT_COST+BRANCH_COST); 7315 7316 ins_variable_size_depending_on_alignment(true); 7317 7318 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7319 // Worst case is branch + move + stop, no stop without scheduler. 7320 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7321 ins_encode( enc_cmove_reg(dst, crx, src, cmp) ); 7322 ins_pipe(pipe_class_default); 7323 %} 7324 7325 instruct cmovP_imm(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, immP_0 src) %{ 7326 match(Set dst (CMoveP (Binary cmp crx) (Binary dst src))); 7327 ins_cost(DEFAULT_COST+BRANCH_COST); 7328 7329 ins_variable_size_depending_on_alignment(true); 7330 7331 format %{ "CMOVE $cmp, $crx, $dst, $src\n\t" %} 7332 // Worst case is branch + move + stop, no stop without scheduler. 7333 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 7334 ins_encode( enc_cmove_imm(dst, crx, src, cmp) ); 7335 ins_pipe(pipe_class_default); 7336 %} 7337 7338 instruct cmovF_reg(cmpOp cmp, flagsRegSrc crx, regF dst, regF src) %{ 7339 match(Set dst (CMoveF (Binary cmp crx) (Binary dst src))); 7340 ins_cost(DEFAULT_COST+BRANCH_COST); 7341 7342 ins_variable_size_depending_on_alignment(true); 7343 7344 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7345 // Worst case is branch + move + stop, no stop without scheduler. 7346 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 7347 ins_encode %{ 7348 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7349 Label done; 7350 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7351 // Branch if not (cmp crx). 7352 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7353 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7354 // TODO PPC port __ endgroup_if_needed(_size == 12); 7355 __ bind(done); 7356 %} 7357 ins_pipe(pipe_class_default); 7358 %} 7359 7360 instruct cmovD_reg(cmpOp cmp, flagsRegSrc crx, regD dst, regD src) %{ 7361 match(Set dst (CMoveD (Binary cmp crx) (Binary dst src))); 7362 ins_cost(DEFAULT_COST+BRANCH_COST); 7363 7364 ins_variable_size_depending_on_alignment(true); 7365 7366 format %{ "CMOVEF $cmp, $crx, $dst, $src\n\t" %} 7367 // Worst case is branch + move + stop, no stop without scheduler. 7368 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 7369 ins_encode %{ 7370 // TODO: PPC port $archOpcode(ppc64Opcode_cmovef); 7371 Label done; 7372 assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding"); 7373 // Branch if not (cmp crx). 7374 __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done); 7375 __ fmr($dst$$FloatRegister, $src$$FloatRegister); 7376 // TODO PPC port __ endgroup_if_needed(_size == 12); 7377 __ bind(done); 7378 %} 7379 ins_pipe(pipe_class_default); 7380 %} 7381 7382 //----------Conditional_store-------------------------------------------------- 7383 // Conditional-store of the updated heap-top. 7384 // Used during allocation of the shared heap. 7385 // Sets flags (EQ) on success. Implemented with a CASA on Sparc. 7386 7387 // As compareAndSwapL, but return flag register instead of boolean value in 7388 // int register. 7389 // Used by sun/misc/AtomicLongCSImpl.java. 7390 // Mem_ptr must be a memory operand, else this node does not get 7391 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7392 // can be rematerialized which leads to errors. 7393 instruct storeLConditional_regP_regL_regL(flagsReg crx, indirect mem_ptr, iRegLsrc oldVal, iRegLsrc newVal, flagsRegCR0 cr0) %{ 7394 match(Set crx (StoreLConditional mem_ptr (Binary oldVal newVal))); 7395 effect(TEMP cr0); 7396 format %{ "CMPXCHGD if ($crx = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7397 ins_encode %{ 7398 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7399 __ cmpxchgd($crx$$CondRegister, R0, $oldVal$$Register, $newVal$$Register, $mem_ptr$$Register, 7400 MacroAssembler::MemBarAcq, MacroAssembler::cmpxchgx_hint_atomic_update(), 7401 noreg, NULL, true); 7402 %} 7403 ins_pipe(pipe_class_default); 7404 %} 7405 7406 // As compareAndSwapP, but return flag register instead of boolean value in 7407 // int register. 7408 // This instruction is matched if UseTLAB is off. 7409 // Mem_ptr must be a memory operand, else this node does not get 7410 // Flag_needs_anti_dependence_check set by adlc. If this is not set this node 7411 // can be rematerialized which leads to errors. 7412 instruct storePConditional_regP_regP_regP(flagsRegCR0 cr0, indirect mem_ptr, iRegPsrc oldVal, iRegPsrc newVal) %{ 7413 match(Set cr0 (StorePConditional mem_ptr (Binary oldVal newVal))); 7414 ins_cost(2*MEMORY_REF_COST); 7415 7416 format %{ "STDCX_ if ($cr0 = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %} 7417 ins_encode %{ 7418 // TODO: PPC port $archOpcode(ppc64Opcode_stdcx_); 7419 __ stdcx_($newVal$$Register, $mem_ptr$$Register); 7420 %} 7421 ins_pipe(pipe_class_memory); 7422 %} 7423 7424 // Implement LoadPLocked. Must be ordered against changes of the memory location 7425 // by storePConditional. 7426 // Don't know whether this is ever used. 7427 instruct loadPLocked(iRegPdst dst, memory mem) %{ 7428 match(Set dst (LoadPLocked mem)); 7429 ins_cost(2*MEMORY_REF_COST); 7430 7431 format %{ "LDARX $dst, $mem \t// loadPLocked\n\t" %} 7432 size(4); 7433 ins_encode %{ 7434 // TODO: PPC port $archOpcode(ppc64Opcode_ldarx); 7435 __ ldarx($dst$$Register, $mem$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 7436 %} 7437 ins_pipe(pipe_class_memory); 7438 %} 7439 7440 //----------Compare-And-Swap--------------------------------------------------- 7441 7442 // CompareAndSwap{P,I,L} have more than one output, therefore "CmpI 7443 // (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be 7444 // matched. 7445 7446 // Strong versions: 7447 7448 instruct compareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7449 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7450 predicate(VM_Version::has_lqarx()); 7451 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7452 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7453 ins_encode %{ 7454 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7455 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7456 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7457 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7458 $res$$Register, true); 7459 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7460 __ isync(); 7461 } else { 7462 __ sync(); 7463 } 7464 %} 7465 ins_pipe(pipe_class_default); 7466 %} 7467 7468 instruct compareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7469 match(Set res (CompareAndSwapB mem_ptr (Binary src1 src2))); 7470 predicate(!VM_Version::has_lqarx()); 7471 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7472 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7473 ins_encode %{ 7474 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7475 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7476 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7477 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7478 $res$$Register, true); 7479 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7480 __ isync(); 7481 } else { 7482 __ sync(); 7483 } 7484 %} 7485 ins_pipe(pipe_class_default); 7486 %} 7487 7488 instruct compareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7489 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7490 predicate(VM_Version::has_lqarx()); 7491 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7492 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7493 ins_encode %{ 7494 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7495 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7496 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7497 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7498 $res$$Register, true); 7499 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7500 __ isync(); 7501 } else { 7502 __ sync(); 7503 } 7504 %} 7505 ins_pipe(pipe_class_default); 7506 %} 7507 7508 instruct compareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7509 match(Set res (CompareAndSwapS mem_ptr (Binary src1 src2))); 7510 predicate(!VM_Version::has_lqarx()); 7511 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7512 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7513 ins_encode %{ 7514 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7515 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7516 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7517 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7518 $res$$Register, true); 7519 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7520 __ isync(); 7521 } else { 7522 __ sync(); 7523 } 7524 %} 7525 ins_pipe(pipe_class_default); 7526 %} 7527 7528 instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7529 match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2))); 7530 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7531 format %{ "CMPXCHGW $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 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 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 compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 7548 match(Set res (CompareAndSwapN mem_ptr (Binary src1 src2))); 7549 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7550 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7551 ins_encode %{ 7552 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7553 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7554 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7555 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7556 $res$$Register, true); 7557 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7558 __ isync(); 7559 } else { 7560 __ sync(); 7561 } 7562 %} 7563 ins_pipe(pipe_class_default); 7564 %} 7565 7566 instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 7567 match(Set res (CompareAndSwapL mem_ptr (Binary src1 src2))); 7568 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7569 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 7570 ins_encode %{ 7571 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7572 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7573 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7574 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7575 $res$$Register, NULL, true); 7576 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7577 __ isync(); 7578 } else { 7579 __ sync(); 7580 } 7581 %} 7582 ins_pipe(pipe_class_default); 7583 %} 7584 7585 instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 7586 match(Set res (CompareAndSwapP mem_ptr (Binary src1 src2))); 7587 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7588 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 7589 ins_encode %{ 7590 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7591 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7592 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7593 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7594 $res$$Register, NULL, true); 7595 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7596 __ isync(); 7597 } else { 7598 __ sync(); 7599 } 7600 %} 7601 ins_pipe(pipe_class_default); 7602 %} 7603 7604 // Weak versions: 7605 7606 instruct weakCompareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7607 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7608 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7609 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7610 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7611 ins_encode %{ 7612 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7613 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7614 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7615 MacroAssembler::MemBarNone, 7616 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7617 %} 7618 ins_pipe(pipe_class_default); 7619 %} 7620 7621 instruct weakCompareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7622 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7623 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 7624 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7625 format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %} 7626 ins_encode %{ 7627 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7628 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7629 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7630 MacroAssembler::MemBarNone, 7631 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7632 %} 7633 ins_pipe(pipe_class_default); 7634 %} 7635 7636 instruct weakCompareAndSwapB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7637 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7638 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 7639 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7640 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 7641 ins_encode %{ 7642 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7643 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7644 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7645 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7646 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7647 %} 7648 ins_pipe(pipe_class_default); 7649 %} 7650 7651 instruct weakCompareAndSwapB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7652 match(Set res (WeakCompareAndSwapB mem_ptr (Binary src1 src2))); 7653 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 7654 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7655 format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %} 7656 ins_encode %{ 7657 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7658 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7659 __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7660 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7661 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7662 %} 7663 ins_pipe(pipe_class_default); 7664 %} 7665 7666 instruct weakCompareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7667 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 7668 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7669 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7670 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7671 ins_encode %{ 7672 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7673 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7674 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7675 MacroAssembler::MemBarNone, 7676 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7677 %} 7678 ins_pipe(pipe_class_default); 7679 %} 7680 7681 instruct weakCompareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7682 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 7683 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 7684 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7685 format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %} 7686 ins_encode %{ 7687 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7688 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7689 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7690 MacroAssembler::MemBarNone, 7691 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7692 %} 7693 ins_pipe(pipe_class_default); 7694 %} 7695 7696 instruct weakCompareAndSwapS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7697 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 7698 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 7699 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7700 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 7701 ins_encode %{ 7702 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7703 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7704 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7705 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7706 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7707 %} 7708 ins_pipe(pipe_class_default); 7709 %} 7710 7711 instruct weakCompareAndSwapS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, iRegIdst tmp2, flagsRegCR0 cr0) %{ 7712 match(Set res (WeakCompareAndSwapS mem_ptr (Binary src1 src2))); 7713 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 7714 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump 7715 format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %} 7716 ins_encode %{ 7717 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7718 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7719 __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register, 7720 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7721 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7722 %} 7723 ins_pipe(pipe_class_default); 7724 %} 7725 7726 instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7727 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 7728 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7729 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7730 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7731 ins_encode %{ 7732 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7733 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7734 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7735 MacroAssembler::MemBarNone, 7736 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7737 %} 7738 ins_pipe(pipe_class_default); 7739 %} 7740 7741 instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7742 match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2))); 7743 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 7744 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7745 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 7746 ins_encode %{ 7747 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7748 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7749 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 7750 // value is never passed to caller. 7751 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7752 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7753 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7754 %} 7755 ins_pipe(pipe_class_default); 7756 %} 7757 7758 instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 7759 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 7760 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7761 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7762 format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %} 7763 ins_encode %{ 7764 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7765 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7766 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7767 MacroAssembler::MemBarNone, 7768 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7769 %} 7770 ins_pipe(pipe_class_default); 7771 %} 7772 7773 instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 7774 match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2))); 7775 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 7776 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7777 format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %} 7778 ins_encode %{ 7779 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7780 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7781 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 7782 // value is never passed to caller. 7783 __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7784 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7785 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true); 7786 %} 7787 ins_pipe(pipe_class_default); 7788 %} 7789 7790 instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 7791 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 7792 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7793 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7794 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %} 7795 ins_encode %{ 7796 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7797 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7798 // value is never passed to caller. 7799 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7800 MacroAssembler::MemBarNone, 7801 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 7802 %} 7803 ins_pipe(pipe_class_default); 7804 %} 7805 7806 instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 7807 match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2))); 7808 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 7809 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7810 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %} 7811 ins_encode %{ 7812 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7813 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7814 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 7815 // value is never passed to caller. 7816 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7817 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7818 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 7819 %} 7820 ins_pipe(pipe_class_default); 7821 %} 7822 7823 instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 7824 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 7825 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 7826 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7827 format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 7828 ins_encode %{ 7829 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7830 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7831 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7832 MacroAssembler::MemBarNone, 7833 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 7834 %} 7835 ins_pipe(pipe_class_default); 7836 %} 7837 7838 instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 7839 match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2))); 7840 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 7841 effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump 7842 format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %} 7843 ins_encode %{ 7844 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7845 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7846 // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and 7847 // value is never passed to caller. 7848 __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 7849 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter, 7850 MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true); 7851 %} 7852 ins_pipe(pipe_class_default); 7853 %} 7854 7855 // CompareAndExchange 7856 7857 instruct compareAndExchangeB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7858 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 7859 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7860 effect(TEMP_DEF res, TEMP cr0); 7861 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 7862 ins_encode %{ 7863 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7864 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7865 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7866 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7867 noreg, true); 7868 %} 7869 ins_pipe(pipe_class_default); 7870 %} 7871 7872 instruct compareAndExchangeB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 7873 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 7874 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 7875 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 7876 format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %} 7877 ins_encode %{ 7878 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7879 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7880 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 7881 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7882 noreg, true); 7883 %} 7884 ins_pipe(pipe_class_default); 7885 %} 7886 7887 instruct compareAndExchangeB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7888 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 7889 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 7890 effect(TEMP_DEF res, TEMP cr0); 7891 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 7892 ins_encode %{ 7893 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7894 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7895 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7896 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7897 noreg, true); 7898 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7899 __ isync(); 7900 } else { 7901 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 7902 __ sync(); 7903 } 7904 %} 7905 ins_pipe(pipe_class_default); 7906 %} 7907 7908 instruct compareAndExchangeB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 7909 match(Set res (CompareAndExchangeB mem_ptr (Binary src1 src2))); 7910 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 7911 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 7912 format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %} 7913 ins_encode %{ 7914 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7915 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7916 __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 7917 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7918 noreg, true); 7919 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7920 __ isync(); 7921 } else { 7922 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 7923 __ sync(); 7924 } 7925 %} 7926 ins_pipe(pipe_class_default); 7927 %} 7928 7929 instruct compareAndExchangeS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7930 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 7931 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && VM_Version::has_lqarx()); 7932 effect(TEMP_DEF res, TEMP cr0); 7933 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 7934 ins_encode %{ 7935 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7936 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7937 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7938 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7939 noreg, true); 7940 %} 7941 ins_pipe(pipe_class_default); 7942 %} 7943 7944 instruct compareAndExchangeS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 7945 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 7946 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst && !VM_Version::has_lqarx()); 7947 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 7948 format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %} 7949 ins_encode %{ 7950 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7951 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7952 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 7953 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7954 noreg, true); 7955 %} 7956 ins_pipe(pipe_class_default); 7957 %} 7958 7959 instruct compareAndExchangeS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 7960 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 7961 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && VM_Version::has_lqarx()); 7962 effect(TEMP_DEF res, TEMP cr0); 7963 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 7964 ins_encode %{ 7965 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7966 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7967 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg, 7968 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7969 noreg, true); 7970 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7971 __ isync(); 7972 } else { 7973 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 7974 __ sync(); 7975 } 7976 %} 7977 ins_pipe(pipe_class_default); 7978 %} 7979 7980 instruct compareAndExchangeS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src1, rarg4RegI src2, iRegIdst tmp1, flagsRegCR0 cr0) %{ 7981 match(Set res (CompareAndExchangeS mem_ptr (Binary src1 src2))); 7982 predicate((((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst) && !VM_Version::has_lqarx()); 7983 effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0); 7984 format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %} 7985 ins_encode %{ 7986 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 7987 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 7988 __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0, 7989 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 7990 noreg, true); 7991 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 7992 __ isync(); 7993 } else { 7994 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 7995 __ sync(); 7996 } 7997 %} 7998 ins_pipe(pipe_class_default); 7999 %} 8000 8001 instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8002 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8003 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8004 effect(TEMP_DEF res, TEMP cr0); 8005 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %} 8006 ins_encode %{ 8007 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8008 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8009 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8010 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8011 noreg, true); 8012 %} 8013 ins_pipe(pipe_class_default); 8014 %} 8015 8016 instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 8017 match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2))); 8018 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8019 effect(TEMP_DEF res, TEMP cr0); 8020 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %} 8021 ins_encode %{ 8022 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8023 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8024 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8025 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8026 noreg, true); 8027 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8028 __ isync(); 8029 } else { 8030 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8031 __ sync(); 8032 } 8033 %} 8034 ins_pipe(pipe_class_default); 8035 %} 8036 8037 instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8038 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8039 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8040 effect(TEMP_DEF res, TEMP cr0); 8041 format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8042 ins_encode %{ 8043 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8044 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8045 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8046 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8047 noreg, true); 8048 %} 8049 ins_pipe(pipe_class_default); 8050 %} 8051 8052 instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{ 8053 match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2))); 8054 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8055 effect(TEMP_DEF res, TEMP cr0); 8056 format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %} 8057 ins_encode %{ 8058 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8059 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8060 __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8061 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8062 noreg, true); 8063 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8064 __ isync(); 8065 } else { 8066 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8067 __ sync(); 8068 } 8069 %} 8070 ins_pipe(pipe_class_default); 8071 %} 8072 8073 instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8074 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8075 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8076 effect(TEMP_DEF res, TEMP cr0); 8077 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %} 8078 ins_encode %{ 8079 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8080 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8081 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8082 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8083 noreg, NULL, true); 8084 %} 8085 ins_pipe(pipe_class_default); 8086 %} 8087 8088 instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{ 8089 match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2))); 8090 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8091 effect(TEMP_DEF res, TEMP cr0); 8092 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %} 8093 ins_encode %{ 8094 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8095 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8096 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8097 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8098 noreg, NULL, true); 8099 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8100 __ isync(); 8101 } else { 8102 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8103 __ sync(); 8104 } 8105 %} 8106 ins_pipe(pipe_class_default); 8107 %} 8108 8109 instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8110 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8111 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst); 8112 effect(TEMP_DEF res, TEMP cr0); 8113 format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8114 ins_encode %{ 8115 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8116 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8117 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8118 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8119 noreg, NULL, true); 8120 %} 8121 ins_pipe(pipe_class_default); 8122 %} 8123 8124 instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{ 8125 match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2))); 8126 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst); 8127 effect(TEMP_DEF res, TEMP cr0); 8128 format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %} 8129 ins_encode %{ 8130 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 8131 // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'. 8132 __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, 8133 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), 8134 noreg, NULL, true); 8135 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8136 __ isync(); 8137 } else { 8138 // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that. 8139 __ sync(); 8140 } 8141 %} 8142 ins_pipe(pipe_class_default); 8143 %} 8144 8145 // Special RMW 8146 8147 instruct getAndAddB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8148 match(Set res (GetAndAddB mem_ptr src)); 8149 predicate(VM_Version::has_lqarx()); 8150 effect(TEMP_DEF res, TEMP cr0); 8151 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8152 ins_encode %{ 8153 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8154 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8155 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8156 __ isync(); 8157 } else { 8158 __ sync(); 8159 } 8160 %} 8161 ins_pipe(pipe_class_default); 8162 %} 8163 8164 instruct getAndAddB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8165 match(Set res (GetAndAddB mem_ptr src)); 8166 predicate(!VM_Version::has_lqarx()); 8167 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8168 format %{ "GetAndAddB $res, $mem_ptr, $src" %} 8169 ins_encode %{ 8170 __ getandaddb($res$$Register, $src$$Register, $mem_ptr$$Register, 8171 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8172 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8173 __ isync(); 8174 } else { 8175 __ sync(); 8176 } 8177 %} 8178 ins_pipe(pipe_class_default); 8179 %} 8180 8181 instruct getAndAddS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8182 match(Set res (GetAndAddS mem_ptr src)); 8183 predicate(VM_Version::has_lqarx()); 8184 effect(TEMP_DEF res, TEMP cr0); 8185 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8186 ins_encode %{ 8187 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8188 R0, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8189 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8190 __ isync(); 8191 } else { 8192 __ sync(); 8193 } 8194 %} 8195 ins_pipe(pipe_class_default); 8196 %} 8197 8198 instruct getAndAddS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8199 match(Set res (GetAndAddS mem_ptr src)); 8200 predicate(!VM_Version::has_lqarx()); 8201 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8202 format %{ "GetAndAddS $res, $mem_ptr, $src" %} 8203 ins_encode %{ 8204 __ getandaddh($res$$Register, $src$$Register, $mem_ptr$$Register, 8205 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8206 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8207 __ isync(); 8208 } else { 8209 __ sync(); 8210 } 8211 %} 8212 ins_pipe(pipe_class_default); 8213 %} 8214 8215 instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8216 match(Set res (GetAndAddI mem_ptr src)); 8217 effect(TEMP_DEF res, TEMP cr0); 8218 format %{ "GetAndAddI $res, $mem_ptr, $src" %} 8219 ins_encode %{ 8220 __ getandaddw($res$$Register, $src$$Register, $mem_ptr$$Register, 8221 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8222 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8223 __ isync(); 8224 } else { 8225 __ sync(); 8226 } 8227 %} 8228 ins_pipe(pipe_class_default); 8229 %} 8230 8231 instruct getAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8232 match(Set res (GetAndAddL mem_ptr src)); 8233 effect(TEMP_DEF res, TEMP cr0); 8234 format %{ "GetAndAddL $res, $mem_ptr, $src" %} 8235 ins_encode %{ 8236 __ getandaddd($res$$Register, $src$$Register, $mem_ptr$$Register, 8237 R0, MacroAssembler::cmpxchgx_hint_atomic_update()); 8238 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8239 __ isync(); 8240 } else { 8241 __ sync(); 8242 } 8243 %} 8244 ins_pipe(pipe_class_default); 8245 %} 8246 8247 instruct getAndSetB(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8248 match(Set res (GetAndSetB mem_ptr src)); 8249 predicate(VM_Version::has_lqarx()); 8250 effect(TEMP_DEF res, TEMP cr0); 8251 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8252 ins_encode %{ 8253 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8254 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8255 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8256 __ isync(); 8257 } else { 8258 __ sync(); 8259 } 8260 %} 8261 ins_pipe(pipe_class_default); 8262 %} 8263 8264 instruct getAndSetB4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8265 match(Set res (GetAndSetB mem_ptr src)); 8266 predicate(!VM_Version::has_lqarx()); 8267 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8268 format %{ "GetAndSetB $res, $mem_ptr, $src" %} 8269 ins_encode %{ 8270 __ getandsetb($res$$Register, $src$$Register, $mem_ptr$$Register, 8271 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8272 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8273 __ isync(); 8274 } else { 8275 __ sync(); 8276 } 8277 %} 8278 ins_pipe(pipe_class_default); 8279 %} 8280 8281 instruct getAndSetS(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8282 match(Set res (GetAndSetS mem_ptr src)); 8283 predicate(VM_Version::has_lqarx()); 8284 effect(TEMP_DEF res, TEMP cr0); 8285 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8286 ins_encode %{ 8287 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8288 noreg, noreg, noreg, MacroAssembler::cmpxchgx_hint_atomic_update()); 8289 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8290 __ isync(); 8291 } else { 8292 __ sync(); 8293 } 8294 %} 8295 ins_pipe(pipe_class_default); 8296 %} 8297 8298 instruct getAndSetS4(iRegIdst res, rarg3RegP mem_ptr, iRegIsrc src, iRegIsrc tmp1, iRegIsrc tmp2, flagsRegCR0 cr0) %{ 8299 match(Set res (GetAndSetS mem_ptr src)); 8300 predicate(!VM_Version::has_lqarx()); 8301 effect(TEMP_DEF res, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); 8302 format %{ "GetAndSetS $res, $mem_ptr, $src" %} 8303 ins_encode %{ 8304 __ getandseth($res$$Register, $src$$Register, $mem_ptr$$Register, 8305 R0, $tmp1$$Register, $tmp2$$Register, MacroAssembler::cmpxchgx_hint_atomic_update()); 8306 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8307 __ isync(); 8308 } else { 8309 __ sync(); 8310 } 8311 %} 8312 ins_pipe(pipe_class_default); 8313 %} 8314 8315 instruct getAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{ 8316 match(Set res (GetAndSetI mem_ptr src)); 8317 effect(TEMP_DEF res, TEMP cr0); 8318 format %{ "GetAndSetI $res, $mem_ptr, $src" %} 8319 ins_encode %{ 8320 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8321 MacroAssembler::cmpxchgx_hint_atomic_update()); 8322 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8323 __ isync(); 8324 } else { 8325 __ sync(); 8326 } 8327 %} 8328 ins_pipe(pipe_class_default); 8329 %} 8330 8331 instruct getAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src, flagsRegCR0 cr0) %{ 8332 match(Set res (GetAndSetL mem_ptr src)); 8333 effect(TEMP_DEF res, TEMP cr0); 8334 format %{ "GetAndSetL $res, $mem_ptr, $src" %} 8335 ins_encode %{ 8336 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8337 MacroAssembler::cmpxchgx_hint_atomic_update()); 8338 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8339 __ isync(); 8340 } else { 8341 __ sync(); 8342 } 8343 %} 8344 ins_pipe(pipe_class_default); 8345 %} 8346 8347 instruct getAndSetP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src, flagsRegCR0 cr0) %{ 8348 match(Set res (GetAndSetP mem_ptr src)); 8349 effect(TEMP_DEF res, TEMP cr0); 8350 format %{ "GetAndSetP $res, $mem_ptr, $src" %} 8351 ins_encode %{ 8352 __ getandsetd($res$$Register, $src$$Register, $mem_ptr$$Register, 8353 MacroAssembler::cmpxchgx_hint_atomic_update()); 8354 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8355 __ isync(); 8356 } else { 8357 __ sync(); 8358 } 8359 %} 8360 ins_pipe(pipe_class_default); 8361 %} 8362 8363 instruct getAndSetN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src, flagsRegCR0 cr0) %{ 8364 match(Set res (GetAndSetN mem_ptr src)); 8365 effect(TEMP_DEF res, TEMP cr0); 8366 format %{ "GetAndSetN $res, $mem_ptr, $src" %} 8367 ins_encode %{ 8368 __ getandsetw($res$$Register, $src$$Register, $mem_ptr$$Register, 8369 MacroAssembler::cmpxchgx_hint_atomic_update()); 8370 if (support_IRIW_for_not_multiple_copy_atomic_cpu) { 8371 __ isync(); 8372 } else { 8373 __ sync(); 8374 } 8375 %} 8376 ins_pipe(pipe_class_default); 8377 %} 8378 8379 //----------Arithmetic Instructions-------------------------------------------- 8380 // Addition Instructions 8381 8382 // Register Addition 8383 instruct addI_reg_reg(iRegIdst dst, iRegIsrc_iRegL2Isrc src1, iRegIsrc_iRegL2Isrc src2) %{ 8384 match(Set dst (AddI src1 src2)); 8385 format %{ "ADD $dst, $src1, $src2" %} 8386 size(4); 8387 ins_encode %{ 8388 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8389 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8390 %} 8391 ins_pipe(pipe_class_default); 8392 %} 8393 8394 // Expand does not work with above instruct. (??) 8395 instruct addI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8396 // no match-rule 8397 effect(DEF dst, USE src1, USE src2); 8398 format %{ "ADD $dst, $src1, $src2" %} 8399 size(4); 8400 ins_encode %{ 8401 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8402 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8403 %} 8404 ins_pipe(pipe_class_default); 8405 %} 8406 8407 instruct tree_addI_addI_addI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 8408 match(Set dst (AddI (AddI (AddI src1 src2) src3) src4)); 8409 ins_cost(DEFAULT_COST*3); 8410 8411 expand %{ 8412 // FIXME: we should do this in the ideal world. 8413 iRegIdst tmp1; 8414 iRegIdst tmp2; 8415 addI_reg_reg(tmp1, src1, src2); 8416 addI_reg_reg_2(tmp2, src3, src4); // Adlc complains about addI_reg_reg. 8417 addI_reg_reg(dst, tmp1, tmp2); 8418 %} 8419 %} 8420 8421 // Immediate Addition 8422 instruct addI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 8423 match(Set dst (AddI src1 src2)); 8424 format %{ "ADDI $dst, $src1, $src2" %} 8425 size(4); 8426 ins_encode %{ 8427 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8428 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8429 %} 8430 ins_pipe(pipe_class_default); 8431 %} 8432 8433 // Immediate Addition with 16-bit shifted operand 8434 instruct addI_reg_immhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2) %{ 8435 match(Set dst (AddI src1 src2)); 8436 format %{ "ADDIS $dst, $src1, $src2" %} 8437 size(4); 8438 ins_encode %{ 8439 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8440 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8441 %} 8442 ins_pipe(pipe_class_default); 8443 %} 8444 8445 // Long Addition 8446 instruct addL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8447 match(Set dst (AddL src1 src2)); 8448 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8449 size(4); 8450 ins_encode %{ 8451 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8452 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8453 %} 8454 ins_pipe(pipe_class_default); 8455 %} 8456 8457 // Expand does not work with above instruct. (??) 8458 instruct addL_reg_reg_2(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8459 // no match-rule 8460 effect(DEF dst, USE src1, USE src2); 8461 format %{ "ADD $dst, $src1, $src2 \t// long" %} 8462 size(4); 8463 ins_encode %{ 8464 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8465 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8466 %} 8467 ins_pipe(pipe_class_default); 8468 %} 8469 8470 instruct tree_addL_addL_addL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2, iRegLsrc src3, iRegLsrc src4) %{ 8471 match(Set dst (AddL (AddL (AddL src1 src2) src3) src4)); 8472 ins_cost(DEFAULT_COST*3); 8473 8474 expand %{ 8475 // FIXME: we should do this in the ideal world. 8476 iRegLdst tmp1; 8477 iRegLdst tmp2; 8478 addL_reg_reg(tmp1, src1, src2); 8479 addL_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 8480 addL_reg_reg(dst, tmp1, tmp2); 8481 %} 8482 %} 8483 8484 // AddL + ConvL2I. 8485 instruct addI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8486 match(Set dst (ConvL2I (AddL src1 src2))); 8487 8488 format %{ "ADD $dst, $src1, $src2 \t// long + l2i" %} 8489 size(4); 8490 ins_encode %{ 8491 // TODO: PPC port $archOpcode(ppc64Opcode_add); 8492 __ add($dst$$Register, $src1$$Register, $src2$$Register); 8493 %} 8494 ins_pipe(pipe_class_default); 8495 %} 8496 8497 // No constant pool entries required. 8498 instruct addL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 8499 match(Set dst (AddL src1 src2)); 8500 8501 format %{ "ADDI $dst, $src1, $src2" %} 8502 size(4); 8503 ins_encode %{ 8504 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8505 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8506 %} 8507 ins_pipe(pipe_class_default); 8508 %} 8509 8510 // Long Immediate Addition with 16-bit shifted operand. 8511 // No constant pool entries required. 8512 instruct addL_reg_immhi16(iRegLdst dst, iRegLsrc src1, immL32hi16 src2) %{ 8513 match(Set dst (AddL src1 src2)); 8514 8515 format %{ "ADDIS $dst, $src1, $src2" %} 8516 size(4); 8517 ins_encode %{ 8518 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8519 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8520 %} 8521 ins_pipe(pipe_class_default); 8522 %} 8523 8524 // Pointer Register Addition 8525 instruct addP_reg_reg(iRegPdst dst, iRegP_N2P src1, iRegLsrc src2) %{ 8526 match(Set dst (AddP src1 src2)); 8527 format %{ "ADD $dst, $src1, $src2" %} 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 // Pointer Immediate Addition 8537 // No constant pool entries required. 8538 instruct addP_reg_imm16(iRegPdst dst, iRegP_N2P src1, immL16 src2) %{ 8539 match(Set dst (AddP src1 src2)); 8540 8541 format %{ "ADDI $dst, $src1, $src2" %} 8542 size(4); 8543 ins_encode %{ 8544 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 8545 __ addi($dst$$Register, $src1$$Register, $src2$$constant); 8546 %} 8547 ins_pipe(pipe_class_default); 8548 %} 8549 8550 // Pointer Immediate Addition with 16-bit shifted operand. 8551 // No constant pool entries required. 8552 instruct addP_reg_immhi16(iRegPdst dst, iRegP_N2P src1, immL32hi16 src2) %{ 8553 match(Set dst (AddP src1 src2)); 8554 8555 format %{ "ADDIS $dst, $src1, $src2" %} 8556 size(4); 8557 ins_encode %{ 8558 // TODO: PPC port $archOpcode(ppc64Opcode_addis); 8559 __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16); 8560 %} 8561 ins_pipe(pipe_class_default); 8562 %} 8563 8564 //--------------------- 8565 // Subtraction Instructions 8566 8567 // Register Subtraction 8568 instruct subI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8569 match(Set dst (SubI src1 src2)); 8570 format %{ "SUBF $dst, $src2, $src1" %} 8571 size(4); 8572 ins_encode %{ 8573 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 8574 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 8575 %} 8576 ins_pipe(pipe_class_default); 8577 %} 8578 8579 // Immediate Subtraction 8580 // Immediate Subtraction: The compiler converts "x-c0" into "x+ -c0" (see SubLNode::Ideal), 8581 // Don't try to use addi with - $src2$$constant since it can overflow when $src2$$constant == minI16. 8582 8583 // SubI from constant (using subfic). 8584 instruct subI_imm16_reg(iRegIdst dst, immI16 src1, iRegIsrc src2) %{ 8585 match(Set dst (SubI src1 src2)); 8586 format %{ "SUBI $dst, $src1, $src2" %} 8587 8588 size(4); 8589 ins_encode %{ 8590 // TODO: PPC port $archOpcode(ppc64Opcode_subfic); 8591 __ subfic($dst$$Register, $src2$$Register, $src1$$constant); 8592 %} 8593 ins_pipe(pipe_class_default); 8594 %} 8595 8596 // Turn the sign-bit of an integer into a 32-bit mask, 0x0...0 for 8597 // positive integers and 0xF...F for negative ones. 8598 instruct signmask32I_regI(iRegIdst dst, iRegIsrc src) %{ 8599 // no match-rule, false predicate 8600 effect(DEF dst, USE src); 8601 predicate(false); 8602 8603 format %{ "SRAWI $dst, $src, #31" %} 8604 size(4); 8605 ins_encode %{ 8606 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 8607 __ srawi($dst$$Register, $src$$Register, 0x1f); 8608 %} 8609 ins_pipe(pipe_class_default); 8610 %} 8611 8612 instruct absI_reg_Ex(iRegIdst dst, iRegIsrc src) %{ 8613 match(Set dst (AbsI src)); 8614 ins_cost(DEFAULT_COST*3); 8615 8616 expand %{ 8617 iRegIdst tmp1; 8618 iRegIdst tmp2; 8619 signmask32I_regI(tmp1, src); 8620 xorI_reg_reg(tmp2, tmp1, src); 8621 subI_reg_reg(dst, tmp2, tmp1); 8622 %} 8623 %} 8624 8625 instruct negI_regI(iRegIdst dst, immI_0 zero, iRegIsrc src2) %{ 8626 match(Set dst (SubI zero src2)); 8627 format %{ "NEG $dst, $src2" %} 8628 size(4); 8629 ins_encode %{ 8630 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 8631 __ neg($dst$$Register, $src2$$Register); 8632 %} 8633 ins_pipe(pipe_class_default); 8634 %} 8635 8636 // Long subtraction 8637 instruct subL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8638 match(Set dst (SubL src1 src2)); 8639 format %{ "SUBF $dst, $src2, $src1 \t// long" %} 8640 size(4); 8641 ins_encode %{ 8642 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 8643 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 8644 %} 8645 ins_pipe(pipe_class_default); 8646 %} 8647 8648 // SubL + convL2I. 8649 instruct subI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8650 match(Set dst (ConvL2I (SubL src1 src2))); 8651 8652 format %{ "SUBF $dst, $src2, $src1 \t// long + l2i" %} 8653 size(4); 8654 ins_encode %{ 8655 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 8656 __ subf($dst$$Register, $src2$$Register, $src1$$Register); 8657 %} 8658 ins_pipe(pipe_class_default); 8659 %} 8660 8661 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 8662 // positive longs and 0xF...F for negative ones. 8663 instruct signmask64I_regL(iRegIdst dst, iRegLsrc src) %{ 8664 // no match-rule, false predicate 8665 effect(DEF dst, USE src); 8666 predicate(false); 8667 8668 format %{ "SRADI $dst, $src, #63" %} 8669 size(4); 8670 ins_encode %{ 8671 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 8672 __ sradi($dst$$Register, $src$$Register, 0x3f); 8673 %} 8674 ins_pipe(pipe_class_default); 8675 %} 8676 8677 // Turn the sign-bit of a long into a 64-bit mask, 0x0...0 for 8678 // positive longs and 0xF...F for negative ones. 8679 instruct signmask64L_regL(iRegLdst dst, iRegLsrc src) %{ 8680 // no match-rule, false predicate 8681 effect(DEF dst, USE src); 8682 predicate(false); 8683 8684 format %{ "SRADI $dst, $src, #63" %} 8685 size(4); 8686 ins_encode %{ 8687 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 8688 __ sradi($dst$$Register, $src$$Register, 0x3f); 8689 %} 8690 ins_pipe(pipe_class_default); 8691 %} 8692 8693 // Long negation 8694 instruct negL_reg_reg(iRegLdst dst, immL_0 zero, iRegLsrc src2) %{ 8695 match(Set dst (SubL zero src2)); 8696 format %{ "NEG $dst, $src2 \t// long" %} 8697 size(4); 8698 ins_encode %{ 8699 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 8700 __ neg($dst$$Register, $src2$$Register); 8701 %} 8702 ins_pipe(pipe_class_default); 8703 %} 8704 8705 // NegL + ConvL2I. 8706 instruct negI_con0_regL(iRegIdst dst, immL_0 zero, iRegLsrc src2) %{ 8707 match(Set dst (ConvL2I (SubL zero src2))); 8708 8709 format %{ "NEG $dst, $src2 \t// long + l2i" %} 8710 size(4); 8711 ins_encode %{ 8712 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 8713 __ neg($dst$$Register, $src2$$Register); 8714 %} 8715 ins_pipe(pipe_class_default); 8716 %} 8717 8718 // Multiplication Instructions 8719 // Integer Multiplication 8720 8721 // Register Multiplication 8722 instruct mulI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8723 match(Set dst (MulI src1 src2)); 8724 ins_cost(DEFAULT_COST); 8725 8726 format %{ "MULLW $dst, $src1, $src2" %} 8727 size(4); 8728 ins_encode %{ 8729 // TODO: PPC port $archOpcode(ppc64Opcode_mullw); 8730 __ mullw($dst$$Register, $src1$$Register, $src2$$Register); 8731 %} 8732 ins_pipe(pipe_class_default); 8733 %} 8734 8735 // Immediate Multiplication 8736 instruct mulI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{ 8737 match(Set dst (MulI src1 src2)); 8738 ins_cost(DEFAULT_COST); 8739 8740 format %{ "MULLI $dst, $src1, $src2" %} 8741 size(4); 8742 ins_encode %{ 8743 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 8744 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 8745 %} 8746 ins_pipe(pipe_class_default); 8747 %} 8748 8749 instruct mulL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8750 match(Set dst (MulL src1 src2)); 8751 ins_cost(DEFAULT_COST); 8752 8753 format %{ "MULLD $dst $src1, $src2 \t// long" %} 8754 size(4); 8755 ins_encode %{ 8756 // TODO: PPC port $archOpcode(ppc64Opcode_mulld); 8757 __ mulld($dst$$Register, $src1$$Register, $src2$$Register); 8758 %} 8759 ins_pipe(pipe_class_default); 8760 %} 8761 8762 // Multiply high for optimized long division by constant. 8763 instruct mulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8764 match(Set dst (MulHiL src1 src2)); 8765 ins_cost(DEFAULT_COST); 8766 8767 format %{ "MULHD $dst $src1, $src2 \t// long" %} 8768 size(4); 8769 ins_encode %{ 8770 // TODO: PPC port $archOpcode(ppc64Opcode_mulhd); 8771 __ mulhd($dst$$Register, $src1$$Register, $src2$$Register); 8772 %} 8773 ins_pipe(pipe_class_default); 8774 %} 8775 8776 // Immediate Multiplication 8777 instruct mulL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{ 8778 match(Set dst (MulL src1 src2)); 8779 ins_cost(DEFAULT_COST); 8780 8781 format %{ "MULLI $dst, $src1, $src2" %} 8782 size(4); 8783 ins_encode %{ 8784 // TODO: PPC port $archOpcode(ppc64Opcode_mulli); 8785 __ mulli($dst$$Register, $src1$$Register, $src2$$constant); 8786 %} 8787 ins_pipe(pipe_class_default); 8788 %} 8789 8790 // Integer Division with Immediate -1: Negate. 8791 instruct divI_reg_immIvalueMinus1(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 8792 match(Set dst (DivI src1 src2)); 8793 ins_cost(DEFAULT_COST); 8794 8795 format %{ "NEG $dst, $src1 \t// /-1" %} 8796 size(4); 8797 ins_encode %{ 8798 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 8799 __ neg($dst$$Register, $src1$$Register); 8800 %} 8801 ins_pipe(pipe_class_default); 8802 %} 8803 8804 // Integer Division with constant, but not -1. 8805 // We should be able to improve this by checking the type of src2. 8806 // It might well be that src2 is known to be positive. 8807 instruct divI_reg_regnotMinus1(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8808 match(Set dst (DivI src1 src2)); 8809 predicate(n->in(2)->find_int_con(-1) != -1); // src2 is a constant, but not -1 8810 ins_cost(2*DEFAULT_COST); 8811 8812 format %{ "DIVW $dst, $src1, $src2 \t// /not-1" %} 8813 size(4); 8814 ins_encode %{ 8815 // TODO: PPC port $archOpcode(ppc64Opcode_divw); 8816 __ divw($dst$$Register, $src1$$Register, $src2$$Register); 8817 %} 8818 ins_pipe(pipe_class_default); 8819 %} 8820 8821 instruct cmovI_bne_negI_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src1) %{ 8822 effect(USE_DEF dst, USE src1, USE crx); 8823 predicate(false); 8824 8825 ins_variable_size_depending_on_alignment(true); 8826 8827 format %{ "CMOVE $dst, neg($src1), $crx" %} 8828 // Worst case is branch + move + stop, no stop without scheduler. 8829 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 8830 ins_encode %{ 8831 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 8832 Label done; 8833 __ bne($crx$$CondRegister, done); 8834 __ neg($dst$$Register, $src1$$Register); 8835 // TODO PPC port __ endgroup_if_needed(_size == 12); 8836 __ bind(done); 8837 %} 8838 ins_pipe(pipe_class_default); 8839 %} 8840 8841 // Integer Division with Registers not containing constants. 8842 instruct divI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8843 match(Set dst (DivI src1 src2)); 8844 ins_cost(10*DEFAULT_COST); 8845 8846 expand %{ 8847 immI16 imm %{ (int)-1 %} 8848 flagsReg tmp1; 8849 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 8850 divI_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 8851 cmovI_bne_negI_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 8852 %} 8853 %} 8854 8855 // Long Division with Immediate -1: Negate. 8856 instruct divL_reg_immLvalueMinus1(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 8857 match(Set dst (DivL src1 src2)); 8858 ins_cost(DEFAULT_COST); 8859 8860 format %{ "NEG $dst, $src1 \t// /-1, long" %} 8861 size(4); 8862 ins_encode %{ 8863 // TODO: PPC port $archOpcode(ppc64Opcode_neg); 8864 __ neg($dst$$Register, $src1$$Register); 8865 %} 8866 ins_pipe(pipe_class_default); 8867 %} 8868 8869 // Long Division with constant, but not -1. 8870 instruct divL_reg_regnotMinus1(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8871 match(Set dst (DivL src1 src2)); 8872 predicate(n->in(2)->find_long_con(-1L) != -1L); // Src2 is a constant, but not -1. 8873 ins_cost(2*DEFAULT_COST); 8874 8875 format %{ "DIVD $dst, $src1, $src2 \t// /not-1, long" %} 8876 size(4); 8877 ins_encode %{ 8878 // TODO: PPC port $archOpcode(ppc64Opcode_divd); 8879 __ divd($dst$$Register, $src1$$Register, $src2$$Register); 8880 %} 8881 ins_pipe(pipe_class_default); 8882 %} 8883 8884 instruct cmovL_bne_negL_reg(iRegLdst dst, flagsRegSrc crx, iRegLsrc src1) %{ 8885 effect(USE_DEF dst, USE src1, USE crx); 8886 predicate(false); 8887 8888 ins_variable_size_depending_on_alignment(true); 8889 8890 format %{ "CMOVE $dst, neg($src1), $crx" %} 8891 // Worst case is branch + move + stop, no stop without scheduler. 8892 size(false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 8893 ins_encode %{ 8894 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 8895 Label done; 8896 __ bne($crx$$CondRegister, done); 8897 __ neg($dst$$Register, $src1$$Register); 8898 // TODO PPC port __ endgroup_if_needed(_size == 12); 8899 __ bind(done); 8900 %} 8901 ins_pipe(pipe_class_default); 8902 %} 8903 8904 // Long Division with Registers not containing constants. 8905 instruct divL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8906 match(Set dst (DivL src1 src2)); 8907 ins_cost(10*DEFAULT_COST); 8908 8909 expand %{ 8910 immL16 imm %{ (int)-1 %} 8911 flagsReg tmp1; 8912 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 8913 divL_reg_regnotMinus1(dst, src1, src2); // dst = src1 / src2 8914 cmovL_bne_negL_reg(dst, tmp1, src1); // cmove dst = neg(src1) if src2 == -1 8915 %} 8916 %} 8917 8918 // Integer Remainder with registers. 8919 instruct modI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8920 match(Set dst (ModI src1 src2)); 8921 ins_cost(10*DEFAULT_COST); 8922 8923 expand %{ 8924 immI16 imm %{ (int)-1 %} 8925 flagsReg tmp1; 8926 iRegIdst tmp2; 8927 iRegIdst tmp3; 8928 cmpI_reg_imm16(tmp1, src2, imm); // check src2 == -1 8929 divI_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 8930 cmovI_bne_negI_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 8931 mulI_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 8932 subI_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 8933 %} 8934 %} 8935 8936 // Long Remainder with registers 8937 instruct modL_reg_reg_Ex(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 8938 match(Set dst (ModL src1 src2)); 8939 ins_cost(10*DEFAULT_COST); 8940 8941 expand %{ 8942 immL16 imm %{ (int)-1 %} 8943 flagsReg tmp1; 8944 iRegLdst tmp2; 8945 iRegLdst tmp3; 8946 cmpL_reg_imm16(tmp1, src2, imm); // check src2 == -1 8947 divL_reg_regnotMinus1(tmp2, src1, src2); // tmp2 = src1 / src2 8948 cmovL_bne_negL_reg(tmp2, tmp1, src1); // cmove tmp2 = neg(src1) if src2 == -1 8949 mulL_reg_reg(tmp3, src2, tmp2); // tmp3 = src2 * tmp2 8950 subL_reg_reg(dst, src1, tmp3); // dst = src1 - tmp3 8951 %} 8952 %} 8953 8954 // Integer Shift Instructions 8955 8956 // Register Shift Left 8957 8958 // Clear all but the lowest #mask bits. 8959 // Used to normalize shift amounts in registers. 8960 instruct maskI_reg_imm(iRegIdst dst, iRegIsrc src, uimmI6 mask) %{ 8961 // no match-rule, false predicate 8962 effect(DEF dst, USE src, USE mask); 8963 predicate(false); 8964 8965 format %{ "MASK $dst, $src, $mask \t// clear $mask upper bits" %} 8966 size(4); 8967 ins_encode %{ 8968 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 8969 __ clrldi($dst$$Register, $src$$Register, $mask$$constant); 8970 %} 8971 ins_pipe(pipe_class_default); 8972 %} 8973 8974 instruct lShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8975 // no match-rule, false predicate 8976 effect(DEF dst, USE src1, USE src2); 8977 predicate(false); 8978 8979 format %{ "SLW $dst, $src1, $src2" %} 8980 size(4); 8981 ins_encode %{ 8982 // TODO: PPC port $archOpcode(ppc64Opcode_slw); 8983 __ slw($dst$$Register, $src1$$Register, $src2$$Register); 8984 %} 8985 ins_pipe(pipe_class_default); 8986 %} 8987 8988 instruct lShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 8989 match(Set dst (LShiftI src1 src2)); 8990 ins_cost(DEFAULT_COST*2); 8991 expand %{ 8992 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 8993 iRegIdst tmpI; 8994 maskI_reg_imm(tmpI, src2, mask); 8995 lShiftI_reg_reg(dst, src1, tmpI); 8996 %} 8997 %} 8998 8999 // Register Shift Left Immediate 9000 instruct lShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9001 match(Set dst (LShiftI src1 src2)); 9002 9003 format %{ "SLWI $dst, $src1, ($src2 & 0x1f)" %} 9004 size(4); 9005 ins_encode %{ 9006 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9007 __ slwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9008 %} 9009 ins_pipe(pipe_class_default); 9010 %} 9011 9012 // AndI with negpow2-constant + LShiftI 9013 instruct lShiftI_andI_immInegpow2_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9014 match(Set dst (LShiftI (AndI src1 src2) src3)); 9015 predicate(UseRotateAndMaskInstructionsPPC64); 9016 9017 format %{ "RLWINM $dst, lShiftI(AndI($src1, $src2), $src3)" %} 9018 size(4); 9019 ins_encode %{ 9020 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9021 long src2 = $src2$$constant; 9022 long src3 = $src3$$constant; 9023 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9024 if (maskbits >= 32) { 9025 __ li($dst$$Register, 0); // addi 9026 } else { 9027 __ rlwinm($dst$$Register, $src1$$Register, src3 & 0x1f, 0, (31-maskbits) & 0x1f); 9028 } 9029 %} 9030 ins_pipe(pipe_class_default); 9031 %} 9032 9033 // RShiftI + AndI with negpow2-constant + LShiftI 9034 instruct lShiftI_andI_immInegpow2_rShiftI_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2 src2, uimmI5 src3) %{ 9035 match(Set dst (LShiftI (AndI (RShiftI src1 src3) src2) src3)); 9036 predicate(UseRotateAndMaskInstructionsPPC64); 9037 9038 format %{ "RLWINM $dst, lShiftI(AndI(RShiftI($src1, $src3), $src2), $src3)" %} 9039 size(4); 9040 ins_encode %{ 9041 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi 9042 long src2 = $src2$$constant; 9043 long src3 = $src3$$constant; 9044 long maskbits = src3 + log2_long((jlong) (julong) (juint) -src2); 9045 if (maskbits >= 32) { 9046 __ li($dst$$Register, 0); // addi 9047 } else { 9048 __ rlwinm($dst$$Register, $src1$$Register, 0, 0, (31-maskbits) & 0x1f); 9049 } 9050 %} 9051 ins_pipe(pipe_class_default); 9052 %} 9053 9054 instruct lShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9055 // no match-rule, false predicate 9056 effect(DEF dst, USE src1, USE src2); 9057 predicate(false); 9058 9059 format %{ "SLD $dst, $src1, $src2" %} 9060 size(4); 9061 ins_encode %{ 9062 // TODO: PPC port $archOpcode(ppc64Opcode_sld); 9063 __ sld($dst$$Register, $src1$$Register, $src2$$Register); 9064 %} 9065 ins_pipe(pipe_class_default); 9066 %} 9067 9068 // Register Shift Left 9069 instruct lShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9070 match(Set dst (LShiftL src1 src2)); 9071 ins_cost(DEFAULT_COST*2); 9072 expand %{ 9073 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9074 iRegIdst tmpI; 9075 maskI_reg_imm(tmpI, src2, mask); 9076 lShiftL_regL_regI(dst, src1, tmpI); 9077 %} 9078 %} 9079 9080 // Register Shift Left Immediate 9081 instruct lshiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9082 match(Set dst (LShiftL src1 src2)); 9083 format %{ "SLDI $dst, $src1, ($src2 & 0x3f)" %} 9084 size(4); 9085 ins_encode %{ 9086 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9087 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9088 %} 9089 ins_pipe(pipe_class_default); 9090 %} 9091 9092 // If we shift more than 32 bits, we need not convert I2L. 9093 instruct lShiftL_regI_immGE32(iRegLdst dst, iRegIsrc src1, uimmI6_ge32 src2) %{ 9094 match(Set dst (LShiftL (ConvI2L src1) src2)); 9095 ins_cost(DEFAULT_COST); 9096 9097 size(4); 9098 format %{ "SLDI $dst, i2l($src1), $src2" %} 9099 ins_encode %{ 9100 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9101 __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9102 %} 9103 ins_pipe(pipe_class_default); 9104 %} 9105 9106 // Shift a postivie int to the left. 9107 // Clrlsldi clears the upper 32 bits and shifts. 9108 instruct scaledPositiveI2L_lShiftL_convI2L_reg_imm6(iRegLdst dst, iRegIsrc src1, uimmI6 src2) %{ 9109 match(Set dst (LShiftL (ConvI2L src1) src2)); 9110 predicate(((ConvI2LNode*)(_kids[0]->_leaf))->type()->is_long()->is_positive_int()); 9111 9112 format %{ "SLDI $dst, i2l(positive_int($src1)), $src2" %} 9113 size(4); 9114 ins_encode %{ 9115 // TODO: PPC port $archOpcode(ppc64Opcode_rldic); 9116 __ clrlsldi($dst$$Register, $src1$$Register, 0x20, $src2$$constant); 9117 %} 9118 ins_pipe(pipe_class_default); 9119 %} 9120 9121 instruct arShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9122 // no match-rule, false predicate 9123 effect(DEF dst, USE src1, USE src2); 9124 predicate(false); 9125 9126 format %{ "SRAW $dst, $src1, $src2" %} 9127 size(4); 9128 ins_encode %{ 9129 // TODO: PPC port $archOpcode(ppc64Opcode_sraw); 9130 __ sraw($dst$$Register, $src1$$Register, $src2$$Register); 9131 %} 9132 ins_pipe(pipe_class_default); 9133 %} 9134 9135 // Register Arithmetic Shift Right 9136 instruct arShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9137 match(Set dst (RShiftI src1 src2)); 9138 ins_cost(DEFAULT_COST*2); 9139 expand %{ 9140 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9141 iRegIdst tmpI; 9142 maskI_reg_imm(tmpI, src2, mask); 9143 arShiftI_reg_reg(dst, src1, tmpI); 9144 %} 9145 %} 9146 9147 // Register Arithmetic Shift Right Immediate 9148 instruct arShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9149 match(Set dst (RShiftI src1 src2)); 9150 9151 format %{ "SRAWI $dst, $src1, ($src2 & 0x1f)" %} 9152 size(4); 9153 ins_encode %{ 9154 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 9155 __ srawi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9156 %} 9157 ins_pipe(pipe_class_default); 9158 %} 9159 9160 instruct arShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9161 // no match-rule, false predicate 9162 effect(DEF dst, USE src1, USE src2); 9163 predicate(false); 9164 9165 format %{ "SRAD $dst, $src1, $src2" %} 9166 size(4); 9167 ins_encode %{ 9168 // TODO: PPC port $archOpcode(ppc64Opcode_srad); 9169 __ srad($dst$$Register, $src1$$Register, $src2$$Register); 9170 %} 9171 ins_pipe(pipe_class_default); 9172 %} 9173 9174 // Register Shift Right Arithmetic Long 9175 instruct arShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9176 match(Set dst (RShiftL src1 src2)); 9177 ins_cost(DEFAULT_COST*2); 9178 9179 expand %{ 9180 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9181 iRegIdst tmpI; 9182 maskI_reg_imm(tmpI, src2, mask); 9183 arShiftL_regL_regI(dst, src1, tmpI); 9184 %} 9185 %} 9186 9187 // Register Shift Right Immediate 9188 instruct arShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9189 match(Set dst (RShiftL src1 src2)); 9190 9191 format %{ "SRADI $dst, $src1, ($src2 & 0x3f)" %} 9192 size(4); 9193 ins_encode %{ 9194 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9195 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9196 %} 9197 ins_pipe(pipe_class_default); 9198 %} 9199 9200 // RShiftL + ConvL2I 9201 instruct convL2I_arShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9202 match(Set dst (ConvL2I (RShiftL src1 src2))); 9203 9204 format %{ "SRADI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9205 size(4); 9206 ins_encode %{ 9207 // TODO: PPC port $archOpcode(ppc64Opcode_sradi); 9208 __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9209 %} 9210 ins_pipe(pipe_class_default); 9211 %} 9212 9213 instruct urShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9214 // no match-rule, false predicate 9215 effect(DEF dst, USE src1, USE src2); 9216 predicate(false); 9217 9218 format %{ "SRW $dst, $src1, $src2" %} 9219 size(4); 9220 ins_encode %{ 9221 // TODO: PPC port $archOpcode(ppc64Opcode_srw); 9222 __ srw($dst$$Register, $src1$$Register, $src2$$Register); 9223 %} 9224 ins_pipe(pipe_class_default); 9225 %} 9226 9227 // Register Shift Right 9228 instruct urShiftI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9229 match(Set dst (URShiftI src1 src2)); 9230 ins_cost(DEFAULT_COST*2); 9231 9232 expand %{ 9233 uimmI6 mask %{ 0x3b /* clear 59 bits, keep 5 */ %} 9234 iRegIdst tmpI; 9235 maskI_reg_imm(tmpI, src2, mask); 9236 urShiftI_reg_reg(dst, src1, tmpI); 9237 %} 9238 %} 9239 9240 // Register Shift Right Immediate 9241 instruct urShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{ 9242 match(Set dst (URShiftI src1 src2)); 9243 9244 format %{ "SRWI $dst, $src1, ($src2 & 0x1f)" %} 9245 size(4); 9246 ins_encode %{ 9247 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9248 __ srwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f); 9249 %} 9250 ins_pipe(pipe_class_default); 9251 %} 9252 9253 instruct urShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9254 // no match-rule, false predicate 9255 effect(DEF dst, USE src1, USE src2); 9256 predicate(false); 9257 9258 format %{ "SRD $dst, $src1, $src2" %} 9259 size(4); 9260 ins_encode %{ 9261 // TODO: PPC port $archOpcode(ppc64Opcode_srd); 9262 __ srd($dst$$Register, $src1$$Register, $src2$$Register); 9263 %} 9264 ins_pipe(pipe_class_default); 9265 %} 9266 9267 // Register Shift Right 9268 instruct urShiftL_regL_regI_Ex(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{ 9269 match(Set dst (URShiftL src1 src2)); 9270 ins_cost(DEFAULT_COST*2); 9271 9272 expand %{ 9273 uimmI6 mask %{ 0x3a /* clear 58 bits, keep 6 */ %} 9274 iRegIdst tmpI; 9275 maskI_reg_imm(tmpI, src2, mask); 9276 urShiftL_regL_regI(dst, src1, tmpI); 9277 %} 9278 %} 9279 9280 // Register Shift Right Immediate 9281 instruct urShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{ 9282 match(Set dst (URShiftL src1 src2)); 9283 9284 format %{ "SRDI $dst, $src1, ($src2 & 0x3f)" %} 9285 size(4); 9286 ins_encode %{ 9287 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9288 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9289 %} 9290 ins_pipe(pipe_class_default); 9291 %} 9292 9293 // URShiftL + ConvL2I. 9294 instruct convL2I_urShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{ 9295 match(Set dst (ConvL2I (URShiftL src1 src2))); 9296 9297 format %{ "SRDI $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %} 9298 size(4); 9299 ins_encode %{ 9300 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9301 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9302 %} 9303 ins_pipe(pipe_class_default); 9304 %} 9305 9306 // Register Shift Right Immediate with a CastP2X 9307 instruct shrP_convP2X_reg_imm6(iRegLdst dst, iRegP_N2P src1, uimmI6 src2) %{ 9308 match(Set dst (URShiftL (CastP2X src1) src2)); 9309 9310 format %{ "SRDI $dst, $src1, $src2 \t// Cast ptr $src1 to long and shift" %} 9311 size(4); 9312 ins_encode %{ 9313 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9314 __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f); 9315 %} 9316 ins_pipe(pipe_class_default); 9317 %} 9318 9319 // Bitfield Extract: URShiftI + AndI 9320 instruct andI_urShiftI_regI_immI_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immI src2, immIpow2minus1 src3) %{ 9321 match(Set dst (AndI (URShiftI src1 src2) src3)); 9322 9323 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// int bitfield extract" %} 9324 size(4); 9325 ins_encode %{ 9326 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9327 int rshift = ($src2$$constant) & 0x1f; 9328 int length = log2_long(((jlong) $src3$$constant) + 1); 9329 if (rshift + length > 32) { 9330 // if necessary, adjust mask to omit rotated bits. 9331 length = 32 - rshift; 9332 } 9333 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length)); 9334 %} 9335 ins_pipe(pipe_class_default); 9336 %} 9337 9338 // Bitfield Extract: URShiftL + AndL 9339 instruct andL_urShiftL_regL_immI_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immI src2, immLpow2minus1 src3) %{ 9340 match(Set dst (AndL (URShiftL src1 src2) src3)); 9341 9342 format %{ "EXTRDI $dst, $src1, shift=$src2, mask=$src3 \t// long bitfield extract" %} 9343 size(4); 9344 ins_encode %{ 9345 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9346 int rshift = ($src2$$constant) & 0x3f; 9347 int length = log2_long(((jlong) $src3$$constant) + 1); 9348 if (rshift + length > 64) { 9349 // if necessary, adjust mask to omit rotated bits. 9350 length = 64 - rshift; 9351 } 9352 __ extrdi($dst$$Register, $src1$$Register, length, 64 - (rshift + length)); 9353 %} 9354 ins_pipe(pipe_class_default); 9355 %} 9356 9357 instruct sxtI_reg(iRegIdst dst, iRegIsrc src) %{ 9358 match(Set dst (ConvL2I (ConvI2L src))); 9359 9360 format %{ "EXTSW $dst, $src \t// int->int" %} 9361 size(4); 9362 ins_encode %{ 9363 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 9364 __ extsw($dst$$Register, $src$$Register); 9365 %} 9366 ins_pipe(pipe_class_default); 9367 %} 9368 9369 //----------Rotate Instructions------------------------------------------------ 9370 9371 // Rotate Left by 8-bit immediate 9372 instruct rotlI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 lshift, immI8 rshift) %{ 9373 match(Set dst (OrI (LShiftI src lshift) (URShiftI src rshift))); 9374 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9375 9376 format %{ "ROTLWI $dst, $src, $lshift" %} 9377 size(4); 9378 ins_encode %{ 9379 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9380 __ rotlwi($dst$$Register, $src$$Register, $lshift$$constant); 9381 %} 9382 ins_pipe(pipe_class_default); 9383 %} 9384 9385 // Rotate Right by 8-bit immediate 9386 instruct rotrI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 rshift, immI8 lshift) %{ 9387 match(Set dst (OrI (URShiftI src rshift) (LShiftI src lshift))); 9388 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9389 9390 format %{ "ROTRWI $dst, $rshift" %} 9391 size(4); 9392 ins_encode %{ 9393 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9394 __ rotrwi($dst$$Register, $src$$Register, $rshift$$constant); 9395 %} 9396 ins_pipe(pipe_class_default); 9397 %} 9398 9399 //----------Floating Point Arithmetic Instructions----------------------------- 9400 9401 // Add float single precision 9402 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{ 9403 match(Set dst (AddF src1 src2)); 9404 9405 format %{ "FADDS $dst, $src1, $src2" %} 9406 size(4); 9407 ins_encode %{ 9408 // TODO: PPC port $archOpcode(ppc64Opcode_fadds); 9409 __ fadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9410 %} 9411 ins_pipe(pipe_class_default); 9412 %} 9413 9414 // Add float double precision 9415 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{ 9416 match(Set dst (AddD src1 src2)); 9417 9418 format %{ "FADD $dst, $src1, $src2" %} 9419 size(4); 9420 ins_encode %{ 9421 // TODO: PPC port $archOpcode(ppc64Opcode_fadd); 9422 __ fadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9423 %} 9424 ins_pipe(pipe_class_default); 9425 %} 9426 9427 // Sub float single precision 9428 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{ 9429 match(Set dst (SubF src1 src2)); 9430 9431 format %{ "FSUBS $dst, $src1, $src2" %} 9432 size(4); 9433 ins_encode %{ 9434 // TODO: PPC port $archOpcode(ppc64Opcode_fsubs); 9435 __ fsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9436 %} 9437 ins_pipe(pipe_class_default); 9438 %} 9439 9440 // Sub float double precision 9441 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{ 9442 match(Set dst (SubD src1 src2)); 9443 format %{ "FSUB $dst, $src1, $src2" %} 9444 size(4); 9445 ins_encode %{ 9446 // TODO: PPC port $archOpcode(ppc64Opcode_fsub); 9447 __ fsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9448 %} 9449 ins_pipe(pipe_class_default); 9450 %} 9451 9452 // Mul float single precision 9453 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{ 9454 match(Set dst (MulF src1 src2)); 9455 format %{ "FMULS $dst, $src1, $src2" %} 9456 size(4); 9457 ins_encode %{ 9458 // TODO: PPC port $archOpcode(ppc64Opcode_fmuls); 9459 __ fmuls($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9460 %} 9461 ins_pipe(pipe_class_default); 9462 %} 9463 9464 // Mul float double precision 9465 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{ 9466 match(Set dst (MulD src1 src2)); 9467 format %{ "FMUL $dst, $src1, $src2" %} 9468 size(4); 9469 ins_encode %{ 9470 // TODO: PPC port $archOpcode(ppc64Opcode_fmul); 9471 __ fmul($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9472 %} 9473 ins_pipe(pipe_class_default); 9474 %} 9475 9476 // Div float single precision 9477 instruct divF_reg_reg(regF dst, regF src1, regF src2) %{ 9478 match(Set dst (DivF src1 src2)); 9479 format %{ "FDIVS $dst, $src1, $src2" %} 9480 size(4); 9481 ins_encode %{ 9482 // TODO: PPC port $archOpcode(ppc64Opcode_fdivs); 9483 __ fdivs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9484 %} 9485 ins_pipe(pipe_class_default); 9486 %} 9487 9488 // Div float double precision 9489 instruct divD_reg_reg(regD dst, regD src1, regD src2) %{ 9490 match(Set dst (DivD src1 src2)); 9491 format %{ "FDIV $dst, $src1, $src2" %} 9492 size(4); 9493 ins_encode %{ 9494 // TODO: PPC port $archOpcode(ppc64Opcode_fdiv); 9495 __ fdiv($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister); 9496 %} 9497 ins_pipe(pipe_class_default); 9498 %} 9499 9500 // Absolute float single precision 9501 instruct absF_reg(regF dst, regF src) %{ 9502 match(Set dst (AbsF src)); 9503 format %{ "FABS $dst, $src \t// float" %} 9504 size(4); 9505 ins_encode %{ 9506 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 9507 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9508 %} 9509 ins_pipe(pipe_class_default); 9510 %} 9511 9512 // Absolute float double precision 9513 instruct absD_reg(regD dst, regD src) %{ 9514 match(Set dst (AbsD src)); 9515 format %{ "FABS $dst, $src \t// double" %} 9516 size(4); 9517 ins_encode %{ 9518 // TODO: PPC port $archOpcode(ppc64Opcode_fabs); 9519 __ fabs($dst$$FloatRegister, $src$$FloatRegister); 9520 %} 9521 ins_pipe(pipe_class_default); 9522 %} 9523 9524 instruct negF_reg(regF dst, regF src) %{ 9525 match(Set dst (NegF src)); 9526 format %{ "FNEG $dst, $src \t// float" %} 9527 size(4); 9528 ins_encode %{ 9529 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 9530 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 9531 %} 9532 ins_pipe(pipe_class_default); 9533 %} 9534 9535 instruct negD_reg(regD dst, regD src) %{ 9536 match(Set dst (NegD src)); 9537 format %{ "FNEG $dst, $src \t// double" %} 9538 size(4); 9539 ins_encode %{ 9540 // TODO: PPC port $archOpcode(ppc64Opcode_fneg); 9541 __ fneg($dst$$FloatRegister, $src$$FloatRegister); 9542 %} 9543 ins_pipe(pipe_class_default); 9544 %} 9545 9546 // AbsF + NegF. 9547 instruct negF_absF_reg(regF dst, regF src) %{ 9548 match(Set dst (NegF (AbsF src))); 9549 format %{ "FNABS $dst, $src \t// float" %} 9550 size(4); 9551 ins_encode %{ 9552 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 9553 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 9554 %} 9555 ins_pipe(pipe_class_default); 9556 %} 9557 9558 // AbsD + NegD. 9559 instruct negD_absD_reg(regD dst, regD src) %{ 9560 match(Set dst (NegD (AbsD src))); 9561 format %{ "FNABS $dst, $src \t// double" %} 9562 size(4); 9563 ins_encode %{ 9564 // TODO: PPC port $archOpcode(ppc64Opcode_fnabs); 9565 __ fnabs($dst$$FloatRegister, $src$$FloatRegister); 9566 %} 9567 ins_pipe(pipe_class_default); 9568 %} 9569 9570 // VM_Version::has_fsqrt() decides if this node will be used. 9571 // Sqrt float double precision 9572 instruct sqrtD_reg(regD dst, regD src) %{ 9573 match(Set dst (SqrtD src)); 9574 format %{ "FSQRT $dst, $src" %} 9575 size(4); 9576 ins_encode %{ 9577 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrt); 9578 __ fsqrt($dst$$FloatRegister, $src$$FloatRegister); 9579 %} 9580 ins_pipe(pipe_class_default); 9581 %} 9582 9583 // Single-precision sqrt. 9584 instruct sqrtF_reg(regF dst, regF src) %{ 9585 match(Set dst (ConvD2F (SqrtD (ConvF2D src)))); 9586 predicate(VM_Version::has_fsqrts()); 9587 ins_cost(DEFAULT_COST); 9588 9589 format %{ "FSQRTS $dst, $src" %} 9590 size(4); 9591 ins_encode %{ 9592 // TODO: PPC port $archOpcode(ppc64Opcode_fsqrts); 9593 __ fsqrts($dst$$FloatRegister, $src$$FloatRegister); 9594 %} 9595 ins_pipe(pipe_class_default); 9596 %} 9597 9598 instruct roundDouble_nop(regD dst) %{ 9599 match(Set dst (RoundDouble dst)); 9600 ins_cost(0); 9601 9602 format %{ " -- \t// RoundDouble not needed - empty" %} 9603 size(0); 9604 // PPC results are already "rounded" (i.e., normal-format IEEE). 9605 ins_encode( /*empty*/ ); 9606 ins_pipe(pipe_class_default); 9607 %} 9608 9609 instruct roundFloat_nop(regF dst) %{ 9610 match(Set dst (RoundFloat dst)); 9611 ins_cost(0); 9612 9613 format %{ " -- \t// RoundFloat not needed - empty" %} 9614 size(0); 9615 // PPC results are already "rounded" (i.e., normal-format IEEE). 9616 ins_encode( /*empty*/ ); 9617 ins_pipe(pipe_class_default); 9618 %} 9619 9620 9621 // Multiply-Accumulate 9622 // src1 * src2 + src3 9623 instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 9624 match(Set dst (FmaF src3 (Binary src1 src2))); 9625 9626 format %{ "FMADDS $dst, $src1, $src2, $src3" %} 9627 size(4); 9628 ins_encode %{ 9629 // TODO: PPC port $archOpcode(ppc64Opcode_fmadds); 9630 __ fmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 9631 %} 9632 ins_pipe(pipe_class_default); 9633 %} 9634 9635 // src1 * src2 + src3 9636 instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 9637 match(Set dst (FmaD src3 (Binary src1 src2))); 9638 9639 format %{ "FMADD $dst, $src1, $src2, $src3" %} 9640 size(4); 9641 ins_encode %{ 9642 // TODO: PPC port $archOpcode(ppc64Opcode_fmadd); 9643 __ fmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 9644 %} 9645 ins_pipe(pipe_class_default); 9646 %} 9647 9648 // -src1 * src2 + src3 = -(src1*src2-src3) 9649 instruct mnsubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 9650 match(Set dst (FmaF src3 (Binary (NegF src1) src2))); 9651 match(Set dst (FmaF src3 (Binary src1 (NegF src2)))); 9652 9653 format %{ "FNMSUBS $dst, $src1, $src2, $src3" %} 9654 size(4); 9655 ins_encode %{ 9656 // TODO: PPC port $archOpcode(ppc64Opcode_fnmsubs); 9657 __ fnmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 9658 %} 9659 ins_pipe(pipe_class_default); 9660 %} 9661 9662 // -src1 * src2 + src3 = -(src1*src2-src3) 9663 instruct mnsubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 9664 match(Set dst (FmaD src3 (Binary (NegD src1) src2))); 9665 match(Set dst (FmaD src3 (Binary src1 (NegD src2)))); 9666 9667 format %{ "FNMSUB $dst, $src1, $src2, $src3" %} 9668 size(4); 9669 ins_encode %{ 9670 // TODO: PPC port $archOpcode(ppc64Opcode_fnmsub); 9671 __ fnmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 9672 %} 9673 ins_pipe(pipe_class_default); 9674 %} 9675 9676 // -src1 * src2 - src3 = -(src1*src2+src3) 9677 instruct mnaddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 9678 match(Set dst (FmaF (NegF src3) (Binary (NegF src1) src2))); 9679 match(Set dst (FmaF (NegF src3) (Binary src1 (NegF src2)))); 9680 9681 format %{ "FNMADDS $dst, $src1, $src2, $src3" %} 9682 size(4); 9683 ins_encode %{ 9684 // TODO: PPC port $archOpcode(ppc64Opcode_fnmadds); 9685 __ fnmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 9686 %} 9687 ins_pipe(pipe_class_default); 9688 %} 9689 9690 // -src1 * src2 - src3 = -(src1*src2+src3) 9691 instruct mnaddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 9692 match(Set dst (FmaD (NegD src3) (Binary (NegD src1) src2))); 9693 match(Set dst (FmaD (NegD src3) (Binary src1 (NegD src2)))); 9694 9695 format %{ "FNMADD $dst, $src1, $src2, $src3" %} 9696 size(4); 9697 ins_encode %{ 9698 // TODO: PPC port $archOpcode(ppc64Opcode_fnmadd); 9699 __ fnmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 9700 %} 9701 ins_pipe(pipe_class_default); 9702 %} 9703 9704 // src1 * src2 - src3 9705 instruct msubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{ 9706 match(Set dst (FmaF (NegF src3) (Binary src1 src2))); 9707 9708 format %{ "FMSUBS $dst, $src1, $src2, $src3" %} 9709 size(4); 9710 ins_encode %{ 9711 // TODO: PPC port $archOpcode(ppc64Opcode_fmsubs); 9712 __ fmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 9713 %} 9714 ins_pipe(pipe_class_default); 9715 %} 9716 9717 // src1 * src2 - src3 9718 instruct msubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 9719 match(Set dst (FmaD (NegD src3) (Binary src1 src2))); 9720 9721 format %{ "FMSUB $dst, $src1, $src2, $src3" %} 9722 size(4); 9723 ins_encode %{ 9724 // TODO: PPC port $archOpcode(ppc64Opcode_fmsub); 9725 __ fmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister); 9726 %} 9727 ins_pipe(pipe_class_default); 9728 %} 9729 9730 9731 //----------Logical Instructions----------------------------------------------- 9732 9733 // And Instructions 9734 9735 // Register And 9736 instruct andI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9737 match(Set dst (AndI src1 src2)); 9738 format %{ "AND $dst, $src1, $src2" %} 9739 size(4); 9740 ins_encode %{ 9741 // TODO: PPC port $archOpcode(ppc64Opcode_and); 9742 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 9743 %} 9744 ins_pipe(pipe_class_default); 9745 %} 9746 9747 // Left shifted Immediate And 9748 instruct andI_reg_immIhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2, flagsRegCR0 cr0) %{ 9749 match(Set dst (AndI src1 src2)); 9750 effect(KILL cr0); 9751 format %{ "ANDIS $dst, $src1, $src2.hi" %} 9752 size(4); 9753 ins_encode %{ 9754 // TODO: PPC port $archOpcode(ppc64Opcode_andis_); 9755 __ andis_($dst$$Register, $src1$$Register, (int)((unsigned short)(($src2$$constant & 0xFFFF0000) >> 16))); 9756 %} 9757 ins_pipe(pipe_class_default); 9758 %} 9759 9760 // Immediate And 9761 instruct andI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2, flagsRegCR0 cr0) %{ 9762 match(Set dst (AndI src1 src2)); 9763 effect(KILL cr0); 9764 9765 format %{ "ANDI $dst, $src1, $src2" %} 9766 size(4); 9767 ins_encode %{ 9768 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 9769 // FIXME: avoid andi_ ? 9770 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 9771 %} 9772 ins_pipe(pipe_class_default); 9773 %} 9774 9775 // Immediate And where the immediate is a negative power of 2. 9776 instruct andI_reg_immInegpow2(iRegIdst dst, iRegIsrc src1, immInegpow2 src2) %{ 9777 match(Set dst (AndI src1 src2)); 9778 format %{ "ANDWI $dst, $src1, $src2" %} 9779 size(4); 9780 ins_encode %{ 9781 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9782 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)(julong)(juint)-($src2$$constant))); 9783 %} 9784 ins_pipe(pipe_class_default); 9785 %} 9786 9787 instruct andI_reg_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immIpow2minus1 src2) %{ 9788 match(Set dst (AndI src1 src2)); 9789 format %{ "ANDWI $dst, $src1, $src2" %} 9790 size(4); 9791 ins_encode %{ 9792 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9793 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 9794 %} 9795 ins_pipe(pipe_class_default); 9796 %} 9797 9798 instruct andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src1, immIpowerOf2 src2) %{ 9799 match(Set dst (AndI src1 src2)); 9800 predicate(UseRotateAndMaskInstructionsPPC64); 9801 format %{ "ANDWI $dst, $src1, $src2" %} 9802 size(4); 9803 ins_encode %{ 9804 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 9805 __ rlwinm($dst$$Register, $src1$$Register, 0, 9806 (31-log2_long((jlong) $src2$$constant)) & 0x1f, (31-log2_long((jlong) $src2$$constant)) & 0x1f); 9807 %} 9808 ins_pipe(pipe_class_default); 9809 %} 9810 9811 // Register And Long 9812 instruct andL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9813 match(Set dst (AndL src1 src2)); 9814 ins_cost(DEFAULT_COST); 9815 9816 format %{ "AND $dst, $src1, $src2 \t// long" %} 9817 size(4); 9818 ins_encode %{ 9819 // TODO: PPC port $archOpcode(ppc64Opcode_and); 9820 __ andr($dst$$Register, $src1$$Register, $src2$$Register); 9821 %} 9822 ins_pipe(pipe_class_default); 9823 %} 9824 9825 // Immediate And long 9826 instruct andL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2, flagsRegCR0 cr0) %{ 9827 match(Set dst (AndL src1 src2)); 9828 effect(KILL cr0); 9829 9830 format %{ "ANDI $dst, $src1, $src2 \t// long" %} 9831 size(4); 9832 ins_encode %{ 9833 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 9834 // FIXME: avoid andi_ ? 9835 __ andi_($dst$$Register, $src1$$Register, $src2$$constant); 9836 %} 9837 ins_pipe(pipe_class_default); 9838 %} 9839 9840 // Immediate And Long where the immediate is a negative power of 2. 9841 instruct andL_reg_immLnegpow2(iRegLdst dst, iRegLsrc src1, immLnegpow2 src2) %{ 9842 match(Set dst (AndL src1 src2)); 9843 format %{ "ANDDI $dst, $src1, $src2" %} 9844 size(4); 9845 ins_encode %{ 9846 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 9847 __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)-$src2$$constant)); 9848 %} 9849 ins_pipe(pipe_class_default); 9850 %} 9851 9852 instruct andL_reg_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 9853 match(Set dst (AndL src1 src2)); 9854 format %{ "ANDDI $dst, $src1, $src2" %} 9855 size(4); 9856 ins_encode %{ 9857 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9858 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 9859 %} 9860 ins_pipe(pipe_class_default); 9861 %} 9862 9863 // AndL + ConvL2I. 9864 instruct convL2I_andL_reg_immLpow2minus1(iRegIdst dst, iRegLsrc src1, immLpow2minus1 src2) %{ 9865 match(Set dst (ConvL2I (AndL src1 src2))); 9866 ins_cost(DEFAULT_COST); 9867 9868 format %{ "ANDDI $dst, $src1, $src2 \t// long + l2i" %} 9869 size(4); 9870 ins_encode %{ 9871 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 9872 __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1))); 9873 %} 9874 ins_pipe(pipe_class_default); 9875 %} 9876 9877 // Or Instructions 9878 9879 // Register Or 9880 instruct orI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9881 match(Set dst (OrI src1 src2)); 9882 format %{ "OR $dst, $src1, $src2" %} 9883 size(4); 9884 ins_encode %{ 9885 // TODO: PPC port $archOpcode(ppc64Opcode_or); 9886 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 9887 %} 9888 ins_pipe(pipe_class_default); 9889 %} 9890 9891 // Expand does not work with above instruct. (??) 9892 instruct orI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9893 // no match-rule 9894 effect(DEF dst, USE src1, USE src2); 9895 format %{ "OR $dst, $src1, $src2" %} 9896 size(4); 9897 ins_encode %{ 9898 // TODO: PPC port $archOpcode(ppc64Opcode_or); 9899 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 9900 %} 9901 ins_pipe(pipe_class_default); 9902 %} 9903 9904 instruct tree_orI_orI_orI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 9905 match(Set dst (OrI (OrI (OrI src1 src2) src3) src4)); 9906 ins_cost(DEFAULT_COST*3); 9907 9908 expand %{ 9909 // FIXME: we should do this in the ideal world. 9910 iRegIdst tmp1; 9911 iRegIdst tmp2; 9912 orI_reg_reg(tmp1, src1, src2); 9913 orI_reg_reg_2(tmp2, src3, src4); // Adlc complains about orI_reg_reg. 9914 orI_reg_reg(dst, tmp1, tmp2); 9915 %} 9916 %} 9917 9918 // Immediate Or 9919 instruct orI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 9920 match(Set dst (OrI src1 src2)); 9921 format %{ "ORI $dst, $src1, $src2" %} 9922 size(4); 9923 ins_encode %{ 9924 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 9925 __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF); 9926 %} 9927 ins_pipe(pipe_class_default); 9928 %} 9929 9930 // Register Or Long 9931 instruct orL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9932 match(Set dst (OrL src1 src2)); 9933 ins_cost(DEFAULT_COST); 9934 9935 size(4); 9936 format %{ "OR $dst, $src1, $src2 \t// long" %} 9937 ins_encode %{ 9938 // TODO: PPC port $archOpcode(ppc64Opcode_or); 9939 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 9940 %} 9941 ins_pipe(pipe_class_default); 9942 %} 9943 9944 // OrL + ConvL2I. 9945 instruct orI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 9946 match(Set dst (ConvL2I (OrL src1 src2))); 9947 ins_cost(DEFAULT_COST); 9948 9949 format %{ "OR $dst, $src1, $src2 \t// long + l2i" %} 9950 size(4); 9951 ins_encode %{ 9952 // TODO: PPC port $archOpcode(ppc64Opcode_or); 9953 __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register); 9954 %} 9955 ins_pipe(pipe_class_default); 9956 %} 9957 9958 // Immediate Or long 9959 instruct orL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 con) %{ 9960 match(Set dst (OrL src1 con)); 9961 ins_cost(DEFAULT_COST); 9962 9963 format %{ "ORI $dst, $src1, $con \t// long" %} 9964 size(4); 9965 ins_encode %{ 9966 // TODO: PPC port $archOpcode(ppc64Opcode_ori); 9967 __ ori($dst$$Register, $src1$$Register, ($con$$constant) & 0xFFFF); 9968 %} 9969 ins_pipe(pipe_class_default); 9970 %} 9971 9972 // Xor Instructions 9973 9974 // Register Xor 9975 instruct xorI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9976 match(Set dst (XorI src1 src2)); 9977 format %{ "XOR $dst, $src1, $src2" %} 9978 size(4); 9979 ins_encode %{ 9980 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 9981 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 9982 %} 9983 ins_pipe(pipe_class_default); 9984 %} 9985 9986 // Expand does not work with above instruct. (??) 9987 instruct xorI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 9988 // no match-rule 9989 effect(DEF dst, USE src1, USE src2); 9990 format %{ "XOR $dst, $src1, $src2" %} 9991 size(4); 9992 ins_encode %{ 9993 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 9994 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 9995 %} 9996 ins_pipe(pipe_class_default); 9997 %} 9998 9999 instruct tree_xorI_xorI_xorI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, iRegIsrc src3, iRegIsrc src4) %{ 10000 match(Set dst (XorI (XorI (XorI src1 src2) src3) src4)); 10001 ins_cost(DEFAULT_COST*3); 10002 10003 expand %{ 10004 // FIXME: we should do this in the ideal world. 10005 iRegIdst tmp1; 10006 iRegIdst tmp2; 10007 xorI_reg_reg(tmp1, src1, src2); 10008 xorI_reg_reg_2(tmp2, src3, src4); // Adlc complains about xorI_reg_reg. 10009 xorI_reg_reg(dst, tmp1, tmp2); 10010 %} 10011 %} 10012 10013 // Immediate Xor 10014 instruct xorI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{ 10015 match(Set dst (XorI src1 src2)); 10016 format %{ "XORI $dst, $src1, $src2" %} 10017 size(4); 10018 ins_encode %{ 10019 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 10020 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 10021 %} 10022 ins_pipe(pipe_class_default); 10023 %} 10024 10025 // Register Xor Long 10026 instruct xorL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10027 match(Set dst (XorL src1 src2)); 10028 ins_cost(DEFAULT_COST); 10029 10030 format %{ "XOR $dst, $src1, $src2 \t// long" %} 10031 size(4); 10032 ins_encode %{ 10033 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10034 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10035 %} 10036 ins_pipe(pipe_class_default); 10037 %} 10038 10039 // XorL + ConvL2I. 10040 instruct xorI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10041 match(Set dst (ConvL2I (XorL src1 src2))); 10042 ins_cost(DEFAULT_COST); 10043 10044 format %{ "XOR $dst, $src1, $src2 \t// long + l2i" %} 10045 size(4); 10046 ins_encode %{ 10047 // TODO: PPC port $archOpcode(ppc64Opcode_xor); 10048 __ xorr($dst$$Register, $src1$$Register, $src2$$Register); 10049 %} 10050 ins_pipe(pipe_class_default); 10051 %} 10052 10053 // Immediate Xor Long 10054 instruct xorL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2) %{ 10055 match(Set dst (XorL src1 src2)); 10056 ins_cost(DEFAULT_COST); 10057 10058 format %{ "XORI $dst, $src1, $src2 \t// long" %} 10059 size(4); 10060 ins_encode %{ 10061 // TODO: PPC port $archOpcode(ppc64Opcode_xori); 10062 __ xori($dst$$Register, $src1$$Register, $src2$$constant); 10063 %} 10064 ins_pipe(pipe_class_default); 10065 %} 10066 10067 instruct notI_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{ 10068 match(Set dst (XorI src1 src2)); 10069 ins_cost(DEFAULT_COST); 10070 10071 format %{ "NOT $dst, $src1 ($src2)" %} 10072 size(4); 10073 ins_encode %{ 10074 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 10075 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 10076 %} 10077 ins_pipe(pipe_class_default); 10078 %} 10079 10080 instruct notL_reg(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{ 10081 match(Set dst (XorL src1 src2)); 10082 ins_cost(DEFAULT_COST); 10083 10084 format %{ "NOT $dst, $src1 ($src2) \t// long" %} 10085 size(4); 10086 ins_encode %{ 10087 // TODO: PPC port $archOpcode(ppc64Opcode_nor); 10088 __ nor($dst$$Register, $src1$$Register, $src1$$Register); 10089 %} 10090 ins_pipe(pipe_class_default); 10091 %} 10092 10093 // And-complement 10094 instruct andcI_reg_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2, iRegIsrc src3) %{ 10095 match(Set dst (AndI (XorI src1 src2) src3)); 10096 ins_cost(DEFAULT_COST); 10097 10098 format %{ "ANDW $dst, xori($src1, $src2), $src3" %} 10099 size(4); 10100 ins_encode( enc_andc(dst, src3, src1) ); 10101 ins_pipe(pipe_class_default); 10102 %} 10103 10104 // And-complement 10105 instruct andcL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{ 10106 // no match-rule, false predicate 10107 effect(DEF dst, USE src1, USE src2); 10108 predicate(false); 10109 10110 format %{ "ANDC $dst, $src1, $src2" %} 10111 size(4); 10112 ins_encode %{ 10113 // TODO: PPC port $archOpcode(ppc64Opcode_andc); 10114 __ andc($dst$$Register, $src1$$Register, $src2$$Register); 10115 %} 10116 ins_pipe(pipe_class_default); 10117 %} 10118 10119 //----------Moves between int/long and float/double---------------------------- 10120 // 10121 // The following rules move values from int/long registers/stack-locations 10122 // to float/double registers/stack-locations and vice versa, without doing any 10123 // conversions. These rules are used to implement the bit-conversion methods 10124 // of java.lang.Float etc., e.g. 10125 // int floatToIntBits(float value) 10126 // float intBitsToFloat(int bits) 10127 // 10128 // Notes on the implementation on ppc64: 10129 // We only provide rules which move between a register and a stack-location, 10130 // because we always have to go through memory when moving between a float 10131 // register and an integer register. 10132 10133 //---------- Chain stack slots between similar types -------- 10134 10135 // These are needed so that the rules below can match. 10136 10137 // Load integer from stack slot 10138 instruct stkI_to_regI(iRegIdst dst, stackSlotI src) %{ 10139 match(Set dst src); 10140 ins_cost(MEMORY_REF_COST); 10141 10142 format %{ "LWZ $dst, $src" %} 10143 size(4); 10144 ins_encode( enc_lwz(dst, src) ); 10145 ins_pipe(pipe_class_memory); 10146 %} 10147 10148 // Store integer to stack slot 10149 instruct regI_to_stkI(stackSlotI dst, iRegIsrc src) %{ 10150 match(Set dst src); 10151 ins_cost(MEMORY_REF_COST); 10152 10153 format %{ "STW $src, $dst \t// stk" %} 10154 size(4); 10155 ins_encode( enc_stw(src, dst) ); // rs=rt 10156 ins_pipe(pipe_class_memory); 10157 %} 10158 10159 // Load long from stack slot 10160 instruct stkL_to_regL(iRegLdst dst, stackSlotL src) %{ 10161 match(Set dst src); 10162 ins_cost(MEMORY_REF_COST); 10163 10164 format %{ "LD $dst, $src \t// long" %} 10165 size(4); 10166 ins_encode( enc_ld(dst, src) ); 10167 ins_pipe(pipe_class_memory); 10168 %} 10169 10170 // Store long to stack slot 10171 instruct regL_to_stkL(stackSlotL dst, iRegLsrc src) %{ 10172 match(Set dst src); 10173 ins_cost(MEMORY_REF_COST); 10174 10175 format %{ "STD $src, $dst \t// long" %} 10176 size(4); 10177 ins_encode( enc_std(src, dst) ); // rs=rt 10178 ins_pipe(pipe_class_memory); 10179 %} 10180 10181 //----------Moves between int and float 10182 10183 // Move float value from float stack-location to integer register. 10184 instruct moveF2I_stack_reg(iRegIdst dst, stackSlotF src) %{ 10185 match(Set dst (MoveF2I src)); 10186 ins_cost(MEMORY_REF_COST); 10187 10188 format %{ "LWZ $dst, $src \t// MoveF2I" %} 10189 size(4); 10190 ins_encode( enc_lwz(dst, src) ); 10191 ins_pipe(pipe_class_memory); 10192 %} 10193 10194 // Move float value from float register to integer stack-location. 10195 instruct moveF2I_reg_stack(stackSlotI dst, regF src) %{ 10196 match(Set dst (MoveF2I src)); 10197 ins_cost(MEMORY_REF_COST); 10198 10199 format %{ "STFS $src, $dst \t// MoveF2I" %} 10200 size(4); 10201 ins_encode( enc_stfs(src, dst) ); 10202 ins_pipe(pipe_class_memory); 10203 %} 10204 10205 // Move integer value from integer stack-location to float register. 10206 instruct moveI2F_stack_reg(regF dst, stackSlotI src) %{ 10207 match(Set dst (MoveI2F src)); 10208 ins_cost(MEMORY_REF_COST); 10209 10210 format %{ "LFS $dst, $src \t// MoveI2F" %} 10211 size(4); 10212 ins_encode %{ 10213 // TODO: PPC port $archOpcode(ppc64Opcode_lfs); 10214 int Idisp = $src$$disp + frame_slots_bias($src$$base, ra_); 10215 __ lfs($dst$$FloatRegister, Idisp, $src$$base$$Register); 10216 %} 10217 ins_pipe(pipe_class_memory); 10218 %} 10219 10220 // Move integer value from integer register to float stack-location. 10221 instruct moveI2F_reg_stack(stackSlotF dst, iRegIsrc src) %{ 10222 match(Set dst (MoveI2F src)); 10223 ins_cost(MEMORY_REF_COST); 10224 10225 format %{ "STW $src, $dst \t// MoveI2F" %} 10226 size(4); 10227 ins_encode( enc_stw(src, dst) ); 10228 ins_pipe(pipe_class_memory); 10229 %} 10230 10231 //----------Moves between long and float 10232 10233 instruct moveF2L_reg_stack(stackSlotL dst, regF src) %{ 10234 // no match-rule, false predicate 10235 effect(DEF dst, USE src); 10236 predicate(false); 10237 10238 format %{ "storeD $src, $dst \t// STACK" %} 10239 size(4); 10240 ins_encode( enc_stfd(src, dst) ); 10241 ins_pipe(pipe_class_default); 10242 %} 10243 10244 //----------Moves between long and double 10245 10246 // Move double value from double stack-location to long register. 10247 instruct moveD2L_stack_reg(iRegLdst dst, stackSlotD src) %{ 10248 match(Set dst (MoveD2L src)); 10249 ins_cost(MEMORY_REF_COST); 10250 size(4); 10251 format %{ "LD $dst, $src \t// MoveD2L" %} 10252 ins_encode( enc_ld(dst, src) ); 10253 ins_pipe(pipe_class_memory); 10254 %} 10255 10256 // Move double value from double register to long stack-location. 10257 instruct moveD2L_reg_stack(stackSlotL dst, regD src) %{ 10258 match(Set dst (MoveD2L src)); 10259 effect(DEF dst, USE src); 10260 ins_cost(MEMORY_REF_COST); 10261 10262 format %{ "STFD $src, $dst \t// MoveD2L" %} 10263 size(4); 10264 ins_encode( enc_stfd(src, dst) ); 10265 ins_pipe(pipe_class_memory); 10266 %} 10267 10268 // Move long value from long stack-location to double register. 10269 instruct moveL2D_stack_reg(regD dst, stackSlotL src) %{ 10270 match(Set dst (MoveL2D src)); 10271 ins_cost(MEMORY_REF_COST); 10272 10273 format %{ "LFD $dst, $src \t// MoveL2D" %} 10274 size(4); 10275 ins_encode( enc_lfd(dst, src) ); 10276 ins_pipe(pipe_class_memory); 10277 %} 10278 10279 // Move long value from long register to double stack-location. 10280 instruct moveL2D_reg_stack(stackSlotD dst, iRegLsrc src) %{ 10281 match(Set dst (MoveL2D src)); 10282 ins_cost(MEMORY_REF_COST); 10283 10284 format %{ "STD $src, $dst \t// MoveL2D" %} 10285 size(4); 10286 ins_encode( enc_std(src, dst) ); 10287 ins_pipe(pipe_class_memory); 10288 %} 10289 10290 //----------Register Move Instructions----------------------------------------- 10291 10292 // Replicate for Superword 10293 10294 instruct moveReg(iRegLdst dst, iRegIsrc src) %{ 10295 predicate(false); 10296 effect(DEF dst, USE src); 10297 10298 format %{ "MR $dst, $src \t// replicate " %} 10299 // variable size, 0 or 4. 10300 ins_encode %{ 10301 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10302 __ mr_if_needed($dst$$Register, $src$$Register); 10303 %} 10304 ins_pipe(pipe_class_default); 10305 %} 10306 10307 //----------Cast instructions (Java-level type cast)--------------------------- 10308 10309 // Cast Long to Pointer for unsafe natives. 10310 instruct castX2P(iRegPdst dst, iRegLsrc src) %{ 10311 match(Set dst (CastX2P src)); 10312 10313 format %{ "MR $dst, $src \t// Long->Ptr" %} 10314 // variable size, 0 or 4. 10315 ins_encode %{ 10316 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10317 __ mr_if_needed($dst$$Register, $src$$Register); 10318 %} 10319 ins_pipe(pipe_class_default); 10320 %} 10321 10322 // Cast Pointer to Long for unsafe natives. 10323 instruct castP2X(iRegLdst dst, iRegP_N2P src) %{ 10324 match(Set dst (CastP2X src)); 10325 10326 format %{ "MR $dst, $src \t// Ptr->Long" %} 10327 // variable size, 0 or 4. 10328 ins_encode %{ 10329 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10330 __ mr_if_needed($dst$$Register, $src$$Register); 10331 %} 10332 ins_pipe(pipe_class_default); 10333 %} 10334 10335 instruct castPP(iRegPdst dst) %{ 10336 match(Set dst (CastPP dst)); 10337 format %{ " -- \t// castPP of $dst" %} 10338 size(0); 10339 ins_encode( /*empty*/ ); 10340 ins_pipe(pipe_class_default); 10341 %} 10342 10343 instruct castII(iRegIdst dst) %{ 10344 match(Set dst (CastII dst)); 10345 format %{ " -- \t// castII of $dst" %} 10346 size(0); 10347 ins_encode( /*empty*/ ); 10348 ins_pipe(pipe_class_default); 10349 %} 10350 10351 instruct checkCastPP(iRegPdst dst) %{ 10352 match(Set dst (CheckCastPP dst)); 10353 format %{ " -- \t// checkcastPP of $dst" %} 10354 size(0); 10355 ins_encode( /*empty*/ ); 10356 ins_pipe(pipe_class_default); 10357 %} 10358 10359 //----------Convert instructions----------------------------------------------- 10360 10361 // Convert to boolean. 10362 10363 // int_to_bool(src) : { 1 if src != 0 10364 // { 0 else 10365 // 10366 // strategy: 10367 // 1) Count leading zeros of 32 bit-value src, 10368 // this returns 32 (0b10.0000) iff src == 0 and <32 otherwise. 10369 // 2) Shift 5 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10370 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10371 10372 // convI2Bool 10373 instruct convI2Bool_reg__cntlz_Ex(iRegIdst dst, iRegIsrc src) %{ 10374 match(Set dst (Conv2B src)); 10375 predicate(UseCountLeadingZerosInstructionsPPC64); 10376 ins_cost(DEFAULT_COST); 10377 10378 expand %{ 10379 immI shiftAmount %{ 0x5 %} 10380 uimmI16 mask %{ 0x1 %} 10381 iRegIdst tmp1; 10382 iRegIdst tmp2; 10383 countLeadingZerosI(tmp1, src); 10384 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10385 xorI_reg_uimm16(dst, tmp2, mask); 10386 %} 10387 %} 10388 10389 instruct convI2Bool_reg__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx) %{ 10390 match(Set dst (Conv2B src)); 10391 effect(TEMP crx); 10392 predicate(!UseCountLeadingZerosInstructionsPPC64); 10393 ins_cost(DEFAULT_COST); 10394 10395 format %{ "CMPWI $crx, $src, #0 \t// convI2B" 10396 "LI $dst, #0\n\t" 10397 "BEQ $crx, done\n\t" 10398 "LI $dst, #1\n" 10399 "done:" %} 10400 size(16); 10401 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x0, 0x1) ); 10402 ins_pipe(pipe_class_compare); 10403 %} 10404 10405 // ConvI2B + XorI 10406 instruct xorI_convI2Bool_reg_immIvalue1__cntlz_Ex(iRegIdst dst, iRegIsrc src, immI_1 mask) %{ 10407 match(Set dst (XorI (Conv2B src) mask)); 10408 predicate(UseCountLeadingZerosInstructionsPPC64); 10409 ins_cost(DEFAULT_COST); 10410 10411 expand %{ 10412 immI shiftAmount %{ 0x5 %} 10413 iRegIdst tmp1; 10414 countLeadingZerosI(tmp1, src); 10415 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10416 %} 10417 %} 10418 10419 instruct xorI_convI2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI_1 mask) %{ 10420 match(Set dst (XorI (Conv2B src) mask)); 10421 effect(TEMP crx); 10422 predicate(!UseCountLeadingZerosInstructionsPPC64); 10423 ins_cost(DEFAULT_COST); 10424 10425 format %{ "CMPWI $crx, $src, #0 \t// Xor(convI2B($src), $mask)" 10426 "LI $dst, #1\n\t" 10427 "BEQ $crx, done\n\t" 10428 "LI $dst, #0\n" 10429 "done:" %} 10430 size(16); 10431 ins_encode( enc_convI2B_regI__cmove(dst, src, crx, 0x1, 0x0) ); 10432 ins_pipe(pipe_class_compare); 10433 %} 10434 10435 // AndI 0b0..010..0 + ConvI2B 10436 instruct convI2Bool_andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src, immIpowerOf2 mask) %{ 10437 match(Set dst (Conv2B (AndI src mask))); 10438 predicate(UseRotateAndMaskInstructionsPPC64); 10439 ins_cost(DEFAULT_COST); 10440 10441 format %{ "RLWINM $dst, $src, $mask \t// convI2B(AndI($src, $mask))" %} 10442 size(4); 10443 ins_encode %{ 10444 // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); 10445 __ rlwinm($dst$$Register, $src$$Register, (32-log2_long((jlong)$mask$$constant)) & 0x1f, 31, 31); 10446 %} 10447 ins_pipe(pipe_class_default); 10448 %} 10449 10450 // Convert pointer to boolean. 10451 // 10452 // ptr_to_bool(src) : { 1 if src != 0 10453 // { 0 else 10454 // 10455 // strategy: 10456 // 1) Count leading zeros of 64 bit-value src, 10457 // this returns 64 (0b100.0000) iff src == 0 and <64 otherwise. 10458 // 2) Shift 6 bits to the right, result is 0b1 iff src == 0, 0b0 otherwise. 10459 // 3) Xori the result to get 0b1 if src != 0 and 0b0 if src == 0. 10460 10461 // ConvP2B 10462 instruct convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src) %{ 10463 match(Set dst (Conv2B src)); 10464 predicate(UseCountLeadingZerosInstructionsPPC64); 10465 ins_cost(DEFAULT_COST); 10466 10467 expand %{ 10468 immI shiftAmount %{ 0x6 %} 10469 uimmI16 mask %{ 0x1 %} 10470 iRegIdst tmp1; 10471 iRegIdst tmp2; 10472 countLeadingZerosP(tmp1, src); 10473 urShiftI_reg_imm(tmp2, tmp1, shiftAmount); 10474 xorI_reg_uimm16(dst, tmp2, mask); 10475 %} 10476 %} 10477 10478 instruct convP2Bool_reg__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx) %{ 10479 match(Set dst (Conv2B src)); 10480 effect(TEMP crx); 10481 predicate(!UseCountLeadingZerosInstructionsPPC64); 10482 ins_cost(DEFAULT_COST); 10483 10484 format %{ "CMPDI $crx, $src, #0 \t// convP2B" 10485 "LI $dst, #0\n\t" 10486 "BEQ $crx, done\n\t" 10487 "LI $dst, #1\n" 10488 "done:" %} 10489 size(16); 10490 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x0, 0x1) ); 10491 ins_pipe(pipe_class_compare); 10492 %} 10493 10494 // ConvP2B + XorI 10495 instruct xorI_convP2Bool_reg__cntlz_Ex(iRegIdst dst, iRegP_N2P src, immI_1 mask) %{ 10496 match(Set dst (XorI (Conv2B src) mask)); 10497 predicate(UseCountLeadingZerosInstructionsPPC64); 10498 ins_cost(DEFAULT_COST); 10499 10500 expand %{ 10501 immI shiftAmount %{ 0x6 %} 10502 iRegIdst tmp1; 10503 countLeadingZerosP(tmp1, src); 10504 urShiftI_reg_imm(dst, tmp1, shiftAmount); 10505 %} 10506 %} 10507 10508 instruct xorI_convP2Bool_reg_immIvalue1__cmove(iRegIdst dst, iRegP_N2P src, flagsReg crx, immI_1 mask) %{ 10509 match(Set dst (XorI (Conv2B src) mask)); 10510 effect(TEMP crx); 10511 predicate(!UseCountLeadingZerosInstructionsPPC64); 10512 ins_cost(DEFAULT_COST); 10513 10514 format %{ "CMPDI $crx, $src, #0 \t// XorI(convP2B($src), $mask)" 10515 "LI $dst, #1\n\t" 10516 "BEQ $crx, done\n\t" 10517 "LI $dst, #0\n" 10518 "done:" %} 10519 size(16); 10520 ins_encode( enc_convP2B_regP__cmove(dst, src, crx, 0x1, 0x0) ); 10521 ins_pipe(pipe_class_compare); 10522 %} 10523 10524 // if src1 < src2, return -1 else return 0 10525 instruct cmpLTMask_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 10526 match(Set dst (CmpLTMask src1 src2)); 10527 ins_cost(DEFAULT_COST*4); 10528 10529 expand %{ 10530 iRegLdst src1s; 10531 iRegLdst src2s; 10532 iRegLdst diff; 10533 convI2L_reg(src1s, src1); // Ensure proper sign extension. 10534 convI2L_reg(src2s, src2); // Ensure proper sign extension. 10535 subL_reg_reg(diff, src1s, src2s); 10536 // Need to consider >=33 bit result, therefore we need signmaskL. 10537 signmask64I_regL(dst, diff); 10538 %} 10539 %} 10540 10541 instruct cmpLTMask_reg_immI0(iRegIdst dst, iRegIsrc src1, immI_0 src2) %{ 10542 match(Set dst (CmpLTMask src1 src2)); // if src1 < src2, return -1 else return 0 10543 format %{ "SRAWI $dst, $src1, $src2 \t// CmpLTMask" %} 10544 size(4); 10545 ins_encode %{ 10546 // TODO: PPC port $archOpcode(ppc64Opcode_srawi); 10547 __ srawi($dst$$Register, $src1$$Register, 0x1f); 10548 %} 10549 ins_pipe(pipe_class_default); 10550 %} 10551 10552 //----------Arithmetic Conversion Instructions--------------------------------- 10553 10554 // Convert to Byte -- nop 10555 // Convert to Short -- nop 10556 10557 // Convert to Int 10558 10559 instruct convB2I_reg(iRegIdst dst, iRegIsrc src, immI_24 amount) %{ 10560 match(Set dst (RShiftI (LShiftI src amount) amount)); 10561 format %{ "EXTSB $dst, $src \t// byte->int" %} 10562 size(4); 10563 ins_encode %{ 10564 // TODO: PPC port $archOpcode(ppc64Opcode_extsb); 10565 __ extsb($dst$$Register, $src$$Register); 10566 %} 10567 ins_pipe(pipe_class_default); 10568 %} 10569 10570 instruct extsh(iRegIdst dst, iRegIsrc src) %{ 10571 effect(DEF dst, USE src); 10572 10573 size(4); 10574 ins_encode %{ 10575 __ extsh($dst$$Register, $src$$Register); 10576 %} 10577 ins_pipe(pipe_class_default); 10578 %} 10579 10580 // LShiftI 16 + RShiftI 16 converts short to int. 10581 instruct convS2I_reg(iRegIdst dst, iRegIsrc src, immI_16 amount) %{ 10582 match(Set dst (RShiftI (LShiftI src amount) amount)); 10583 format %{ "EXTSH $dst, $src \t// short->int" %} 10584 size(4); 10585 ins_encode %{ 10586 // TODO: PPC port $archOpcode(ppc64Opcode_extsh); 10587 __ extsh($dst$$Register, $src$$Register); 10588 %} 10589 ins_pipe(pipe_class_default); 10590 %} 10591 10592 // ConvL2I + ConvI2L: Sign extend int in long register. 10593 instruct sxtI_L2L_reg(iRegLdst dst, iRegLsrc src) %{ 10594 match(Set dst (ConvI2L (ConvL2I src))); 10595 10596 format %{ "EXTSW $dst, $src \t// long->long" %} 10597 size(4); 10598 ins_encode %{ 10599 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 10600 __ extsw($dst$$Register, $src$$Register); 10601 %} 10602 ins_pipe(pipe_class_default); 10603 %} 10604 10605 instruct convL2I_reg(iRegIdst dst, iRegLsrc src) %{ 10606 match(Set dst (ConvL2I src)); 10607 format %{ "MR $dst, $src \t// long->int" %} 10608 // variable size, 0 or 4 10609 ins_encode %{ 10610 // TODO: PPC port $archOpcode(ppc64Opcode_or); 10611 __ mr_if_needed($dst$$Register, $src$$Register); 10612 %} 10613 ins_pipe(pipe_class_default); 10614 %} 10615 10616 instruct convD2IRaw_regD(regD dst, regD src) %{ 10617 // no match-rule, false predicate 10618 effect(DEF dst, USE src); 10619 predicate(false); 10620 10621 format %{ "FCTIWZ $dst, $src \t// convD2I, $src != NaN" %} 10622 size(4); 10623 ins_encode %{ 10624 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz);; 10625 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 10626 %} 10627 ins_pipe(pipe_class_default); 10628 %} 10629 10630 instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL src) %{ 10631 // no match-rule, false predicate 10632 effect(DEF dst, USE crx, USE src); 10633 predicate(false); 10634 10635 ins_variable_size_depending_on_alignment(true); 10636 10637 format %{ "cmovI $crx, $dst, $src" %} 10638 // Worst case is branch + move + stop, no stop without scheduler. 10639 size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8); 10640 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 10641 ins_pipe(pipe_class_default); 10642 %} 10643 10644 instruct cmovI_bso_stackSlotL_conLvalue0_Ex(iRegIdst dst, flagsRegSrc crx, stackSlotL mem) %{ 10645 // no match-rule, false predicate 10646 effect(DEF dst, USE crx, USE mem); 10647 predicate(false); 10648 10649 format %{ "CmovI $dst, $crx, $mem \t// postalloc expanded" %} 10650 postalloc_expand %{ 10651 // 10652 // replaces 10653 // 10654 // region dst crx mem 10655 // \ | | / 10656 // dst=cmovI_bso_stackSlotL_conLvalue0 10657 // 10658 // with 10659 // 10660 // region dst 10661 // \ / 10662 // dst=loadConI16(0) 10663 // | 10664 // ^ region dst crx mem 10665 // | \ | | / 10666 // dst=cmovI_bso_stackSlotL 10667 // 10668 10669 // Create new nodes. 10670 MachNode *m1 = new loadConI16Node(); 10671 MachNode *m2 = new cmovI_bso_stackSlotLNode(); 10672 10673 // inputs for new nodes 10674 m1->add_req(n_region); 10675 m2->add_req(n_region, n_crx, n_mem); 10676 10677 // precedences for new nodes 10678 m2->add_prec(m1); 10679 10680 // operands for new nodes 10681 m1->_opnds[0] = op_dst; 10682 m1->_opnds[1] = new immI16Oper(0); 10683 10684 m2->_opnds[0] = op_dst; 10685 m2->_opnds[1] = op_crx; 10686 m2->_opnds[2] = op_mem; 10687 10688 // registers for new nodes 10689 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10690 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10691 10692 // Insert new nodes. 10693 nodes->push(m1); 10694 nodes->push(m2); 10695 %} 10696 %} 10697 10698 // Double to Int conversion, NaN is mapped to 0. 10699 instruct convD2I_reg_ExEx(iRegIdst dst, regD src) %{ 10700 match(Set dst (ConvD2I src)); 10701 ins_cost(DEFAULT_COST); 10702 10703 expand %{ 10704 regD tmpD; 10705 stackSlotL tmpS; 10706 flagsReg crx; 10707 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10708 convD2IRaw_regD(tmpD, src); // Convert float to int (speculated). 10709 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 10710 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 10711 %} 10712 %} 10713 10714 instruct convF2IRaw_regF(regF dst, regF src) %{ 10715 // no match-rule, false predicate 10716 effect(DEF dst, USE src); 10717 predicate(false); 10718 10719 format %{ "FCTIWZ $dst, $src \t// convF2I, $src != NaN" %} 10720 size(4); 10721 ins_encode %{ 10722 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 10723 __ fctiwz($dst$$FloatRegister, $src$$FloatRegister); 10724 %} 10725 ins_pipe(pipe_class_default); 10726 %} 10727 10728 // Float to Int conversion, NaN is mapped to 0. 10729 instruct convF2I_regF_ExEx(iRegIdst dst, regF src) %{ 10730 match(Set dst (ConvF2I src)); 10731 ins_cost(DEFAULT_COST); 10732 10733 expand %{ 10734 regF tmpF; 10735 stackSlotL tmpS; 10736 flagsReg crx; 10737 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10738 convF2IRaw_regF(tmpF, src); // Convert float to int (speculated). 10739 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 10740 cmovI_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 10741 %} 10742 %} 10743 10744 // Convert to Long 10745 10746 instruct convI2L_reg(iRegLdst dst, iRegIsrc src) %{ 10747 match(Set dst (ConvI2L src)); 10748 format %{ "EXTSW $dst, $src \t// int->long" %} 10749 size(4); 10750 ins_encode %{ 10751 // TODO: PPC port $archOpcode(ppc64Opcode_extsw); 10752 __ extsw($dst$$Register, $src$$Register); 10753 %} 10754 ins_pipe(pipe_class_default); 10755 %} 10756 10757 // Zero-extend: convert unsigned int to long (convUI2L). 10758 instruct zeroExtendL_regI(iRegLdst dst, iRegIsrc src, immL_32bits mask) %{ 10759 match(Set dst (AndL (ConvI2L src) mask)); 10760 ins_cost(DEFAULT_COST); 10761 10762 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 10763 size(4); 10764 ins_encode %{ 10765 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10766 __ clrldi($dst$$Register, $src$$Register, 32); 10767 %} 10768 ins_pipe(pipe_class_default); 10769 %} 10770 10771 // Zero-extend: convert unsigned int to long in long register. 10772 instruct zeroExtendL_regL(iRegLdst dst, iRegLsrc src, immL_32bits mask) %{ 10773 match(Set dst (AndL src mask)); 10774 ins_cost(DEFAULT_COST); 10775 10776 format %{ "CLRLDI $dst, $src, #32 \t// zero-extend int to long" %} 10777 size(4); 10778 ins_encode %{ 10779 // TODO: PPC port $archOpcode(ppc64Opcode_rldicl); 10780 __ clrldi($dst$$Register, $src$$Register, 32); 10781 %} 10782 ins_pipe(pipe_class_default); 10783 %} 10784 10785 instruct convF2LRaw_regF(regF dst, regF src) %{ 10786 // no match-rule, false predicate 10787 effect(DEF dst, USE src); 10788 predicate(false); 10789 10790 format %{ "FCTIDZ $dst, $src \t// convF2L, $src != NaN" %} 10791 size(4); 10792 ins_encode %{ 10793 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 10794 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 10795 %} 10796 ins_pipe(pipe_class_default); 10797 %} 10798 10799 instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL src) %{ 10800 // no match-rule, false predicate 10801 effect(DEF dst, USE crx, USE src); 10802 predicate(false); 10803 10804 ins_variable_size_depending_on_alignment(true); 10805 10806 format %{ "cmovL $crx, $dst, $src" %} 10807 // Worst case is branch + move + stop, no stop without scheduler. 10808 size(false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8); 10809 ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) ); 10810 ins_pipe(pipe_class_default); 10811 %} 10812 10813 instruct cmovL_bso_stackSlotL_conLvalue0_Ex(iRegLdst dst, flagsRegSrc crx, stackSlotL mem) %{ 10814 // no match-rule, false predicate 10815 effect(DEF dst, USE crx, USE mem); 10816 predicate(false); 10817 10818 format %{ "CmovL $dst, $crx, $mem \t// postalloc expanded" %} 10819 postalloc_expand %{ 10820 // 10821 // replaces 10822 // 10823 // region dst crx mem 10824 // \ | | / 10825 // dst=cmovL_bso_stackSlotL_conLvalue0 10826 // 10827 // with 10828 // 10829 // region dst 10830 // \ / 10831 // dst=loadConL16(0) 10832 // | 10833 // ^ region dst crx mem 10834 // | \ | | / 10835 // dst=cmovL_bso_stackSlotL 10836 // 10837 10838 // Create new nodes. 10839 MachNode *m1 = new loadConL16Node(); 10840 MachNode *m2 = new cmovL_bso_stackSlotLNode(); 10841 10842 // inputs for new nodes 10843 m1->add_req(n_region); 10844 m2->add_req(n_region, n_crx, n_mem); 10845 m2->add_prec(m1); 10846 10847 // operands for new nodes 10848 m1->_opnds[0] = op_dst; 10849 m1->_opnds[1] = new immL16Oper(0); 10850 m2->_opnds[0] = op_dst; 10851 m2->_opnds[1] = op_crx; 10852 m2->_opnds[2] = op_mem; 10853 10854 // registers for new nodes 10855 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10856 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 10857 10858 // Insert new nodes. 10859 nodes->push(m1); 10860 nodes->push(m2); 10861 %} 10862 %} 10863 10864 // Float to Long conversion, NaN is mapped to 0. 10865 instruct convF2L_reg_ExEx(iRegLdst dst, regF src) %{ 10866 match(Set dst (ConvF2L src)); 10867 ins_cost(DEFAULT_COST); 10868 10869 expand %{ 10870 regF tmpF; 10871 stackSlotL tmpS; 10872 flagsReg crx; 10873 cmpFUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10874 convF2LRaw_regF(tmpF, src); // Convert float to long (speculated). 10875 moveF2L_reg_stack(tmpS, tmpF); // Store float to stack (speculated). 10876 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 10877 %} 10878 %} 10879 10880 instruct convD2LRaw_regD(regD dst, regD src) %{ 10881 // no match-rule, false predicate 10882 effect(DEF dst, USE src); 10883 predicate(false); 10884 10885 format %{ "FCTIDZ $dst, $src \t// convD2L $src != NaN" %} 10886 size(4); 10887 ins_encode %{ 10888 // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz); 10889 __ fctidz($dst$$FloatRegister, $src$$FloatRegister); 10890 %} 10891 ins_pipe(pipe_class_default); 10892 %} 10893 10894 // Double to Long conversion, NaN is mapped to 0. 10895 instruct convD2L_reg_ExEx(iRegLdst dst, regD src) %{ 10896 match(Set dst (ConvD2L src)); 10897 ins_cost(DEFAULT_COST); 10898 10899 expand %{ 10900 regD tmpD; 10901 stackSlotL tmpS; 10902 flagsReg crx; 10903 cmpDUnordered_reg_reg(crx, src, src); // Check whether src is NaN. 10904 convD2LRaw_regD(tmpD, src); // Convert float to long (speculated). 10905 moveD2L_reg_stack(tmpS, tmpD); // Store float to stack (speculated). 10906 cmovL_bso_stackSlotL_conLvalue0_Ex(dst, crx, tmpS); // Cmove based on NaN check. 10907 %} 10908 %} 10909 10910 // Convert to Float 10911 10912 // Placed here as needed in expand. 10913 instruct convL2DRaw_regD(regD dst, regD src) %{ 10914 // no match-rule, false predicate 10915 effect(DEF dst, USE src); 10916 predicate(false); 10917 10918 format %{ "FCFID $dst, $src \t// convL2D" %} 10919 size(4); 10920 ins_encode %{ 10921 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 10922 __ fcfid($dst$$FloatRegister, $src$$FloatRegister); 10923 %} 10924 ins_pipe(pipe_class_default); 10925 %} 10926 10927 // Placed here as needed in expand. 10928 instruct convD2F_reg(regF dst, regD src) %{ 10929 match(Set dst (ConvD2F src)); 10930 format %{ "FRSP $dst, $src \t// convD2F" %} 10931 size(4); 10932 ins_encode %{ 10933 // TODO: PPC port $archOpcode(ppc64Opcode_frsp); 10934 __ frsp($dst$$FloatRegister, $src$$FloatRegister); 10935 %} 10936 ins_pipe(pipe_class_default); 10937 %} 10938 10939 // Integer to Float conversion. 10940 instruct convI2F_ireg_Ex(regF dst, iRegIsrc src) %{ 10941 match(Set dst (ConvI2F src)); 10942 predicate(!VM_Version::has_fcfids()); 10943 ins_cost(DEFAULT_COST); 10944 10945 expand %{ 10946 iRegLdst tmpL; 10947 stackSlotL tmpS; 10948 regD tmpD; 10949 regD tmpD2; 10950 convI2L_reg(tmpL, src); // Sign-extension int to long. 10951 regL_to_stkL(tmpS, tmpL); // Store long to stack. 10952 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 10953 convL2DRaw_regD(tmpD2, tmpD); // Convert to double. 10954 convD2F_reg(dst, tmpD2); // Convert double to float. 10955 %} 10956 %} 10957 10958 instruct convL2FRaw_regF(regF dst, regD src) %{ 10959 // no match-rule, false predicate 10960 effect(DEF dst, USE src); 10961 predicate(false); 10962 10963 format %{ "FCFIDS $dst, $src \t// convL2F" %} 10964 size(4); 10965 ins_encode %{ 10966 // TODO: PPC port $archOpcode(ppc64Opcode_fcfid); 10967 __ fcfids($dst$$FloatRegister, $src$$FloatRegister); 10968 %} 10969 ins_pipe(pipe_class_default); 10970 %} 10971 10972 // Integer to Float conversion. Special version for Power7. 10973 instruct convI2F_ireg_fcfids_Ex(regF dst, iRegIsrc src) %{ 10974 match(Set dst (ConvI2F src)); 10975 predicate(VM_Version::has_fcfids()); 10976 ins_cost(DEFAULT_COST); 10977 10978 expand %{ 10979 iRegLdst tmpL; 10980 stackSlotL tmpS; 10981 regD tmpD; 10982 convI2L_reg(tmpL, src); // Sign-extension int to long. 10983 regL_to_stkL(tmpS, tmpL); // Store long to stack. 10984 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 10985 convL2FRaw_regF(dst, tmpD); // Convert to float. 10986 %} 10987 %} 10988 10989 // L2F to avoid runtime call. 10990 instruct convL2F_ireg_fcfids_Ex(regF dst, iRegLsrc src) %{ 10991 match(Set dst (ConvL2F src)); 10992 predicate(VM_Version::has_fcfids()); 10993 ins_cost(DEFAULT_COST); 10994 10995 expand %{ 10996 stackSlotL tmpS; 10997 regD tmpD; 10998 regL_to_stkL(tmpS, src); // Store long to stack. 10999 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11000 convL2FRaw_regF(dst, tmpD); // Convert to float. 11001 %} 11002 %} 11003 11004 // Moved up as used in expand. 11005 //instruct convD2F_reg(regF dst, regD src) %{%} 11006 11007 // Convert to Double 11008 11009 // Integer to Double conversion. 11010 instruct convI2D_reg_Ex(regD dst, iRegIsrc src) %{ 11011 match(Set dst (ConvI2D src)); 11012 ins_cost(DEFAULT_COST); 11013 11014 expand %{ 11015 iRegLdst tmpL; 11016 stackSlotL tmpS; 11017 regD tmpD; 11018 convI2L_reg(tmpL, src); // Sign-extension int to long. 11019 regL_to_stkL(tmpS, tmpL); // Store long to stack. 11020 moveL2D_stack_reg(tmpD, tmpS); // Load long into double register. 11021 convL2DRaw_regD(dst, tmpD); // Convert to double. 11022 %} 11023 %} 11024 11025 // Long to Double conversion 11026 instruct convL2D_reg_Ex(regD dst, stackSlotL src) %{ 11027 match(Set dst (ConvL2D src)); 11028 ins_cost(DEFAULT_COST + MEMORY_REF_COST); 11029 11030 expand %{ 11031 regD tmpD; 11032 moveL2D_stack_reg(tmpD, src); 11033 convL2DRaw_regD(dst, tmpD); 11034 %} 11035 %} 11036 11037 instruct convF2D_reg(regD dst, regF src) %{ 11038 match(Set dst (ConvF2D src)); 11039 format %{ "FMR $dst, $src \t// float->double" %} 11040 // variable size, 0 or 4 11041 ins_encode %{ 11042 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 11043 __ fmr_if_needed($dst$$FloatRegister, $src$$FloatRegister); 11044 %} 11045 ins_pipe(pipe_class_default); 11046 %} 11047 11048 //----------Control Flow Instructions------------------------------------------ 11049 // Compare Instructions 11050 11051 // Compare Integers 11052 instruct cmpI_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 11053 match(Set crx (CmpI src1 src2)); 11054 size(4); 11055 format %{ "CMPW $crx, $src1, $src2" %} 11056 ins_encode %{ 11057 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 11058 __ cmpw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11059 %} 11060 ins_pipe(pipe_class_compare); 11061 %} 11062 11063 instruct cmpI_reg_imm16(flagsReg crx, iRegIsrc src1, immI16 src2) %{ 11064 match(Set crx (CmpI src1 src2)); 11065 format %{ "CMPWI $crx, $src1, $src2" %} 11066 size(4); 11067 ins_encode %{ 11068 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11069 __ cmpwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11070 %} 11071 ins_pipe(pipe_class_compare); 11072 %} 11073 11074 // (src1 & src2) == 0? 11075 instruct testI_reg_imm(flagsRegCR0 cr0, iRegIsrc src1, uimmI16 src2, immI_0 zero) %{ 11076 match(Set cr0 (CmpI (AndI src1 src2) zero)); 11077 // r0 is killed 11078 format %{ "ANDI R0, $src1, $src2 \t// BTST int" %} 11079 size(4); 11080 ins_encode %{ 11081 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 11082 __ andi_(R0, $src1$$Register, $src2$$constant); 11083 %} 11084 ins_pipe(pipe_class_compare); 11085 %} 11086 11087 instruct cmpL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{ 11088 match(Set crx (CmpL src1 src2)); 11089 format %{ "CMPD $crx, $src1, $src2" %} 11090 size(4); 11091 ins_encode %{ 11092 // TODO: PPC port $archOpcode(ppc64Opcode_cmp); 11093 __ cmpd($crx$$CondRegister, $src1$$Register, $src2$$Register); 11094 %} 11095 ins_pipe(pipe_class_compare); 11096 %} 11097 11098 instruct cmpL_reg_imm16(flagsReg crx, iRegLsrc src1, immL16 src2) %{ 11099 match(Set crx (CmpL src1 src2)); 11100 format %{ "CMPDI $crx, $src1, $src2" %} 11101 size(4); 11102 ins_encode %{ 11103 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11104 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11105 %} 11106 ins_pipe(pipe_class_compare); 11107 %} 11108 11109 instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zero) %{ 11110 match(Set cr0 (CmpL (AndL src1 src2) zero)); 11111 // r0 is killed 11112 format %{ "AND R0, $src1, $src2 \t// BTST long" %} 11113 size(4); 11114 ins_encode %{ 11115 // TODO: PPC port $archOpcode(ppc64Opcode_and_); 11116 __ and_(R0, $src1$$Register, $src2$$Register); 11117 %} 11118 ins_pipe(pipe_class_compare); 11119 %} 11120 11121 instruct testL_reg_imm(flagsRegCR0 cr0, iRegLsrc src1, uimmL16 src2, immL_0 zero) %{ 11122 match(Set cr0 (CmpL (AndL src1 src2) zero)); 11123 // r0 is killed 11124 format %{ "ANDI R0, $src1, $src2 \t// BTST long" %} 11125 size(4); 11126 ins_encode %{ 11127 // TODO: PPC port $archOpcode(ppc64Opcode_andi_); 11128 __ andi_(R0, $src1$$Register, $src2$$constant); 11129 %} 11130 ins_pipe(pipe_class_compare); 11131 %} 11132 11133 instruct cmovI_conIvalueMinus1_conIvalue1(iRegIdst dst, flagsRegSrc crx) %{ 11134 // no match-rule, false predicate 11135 effect(DEF dst, USE crx); 11136 predicate(false); 11137 11138 ins_variable_size_depending_on_alignment(true); 11139 11140 format %{ "cmovI $crx, $dst, -1, 0, +1" %} 11141 // Worst case is branch + move + branch + move + stop, no stop without scheduler. 11142 size(false /* TODO: PPC PORTInsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 20 : 16); 11143 ins_encode %{ 11144 // TODO: PPC port $archOpcode(ppc64Opcode_cmove); 11145 Label done; 11146 // li(Rdst, 0); // equal -> 0 11147 __ beq($crx$$CondRegister, done); 11148 __ li($dst$$Register, 1); // greater -> +1 11149 __ bgt($crx$$CondRegister, done); 11150 __ li($dst$$Register, -1); // unordered or less -> -1 11151 // TODO: PPC port__ endgroup_if_needed(_size == 20); 11152 __ bind(done); 11153 %} 11154 ins_pipe(pipe_class_compare); 11155 %} 11156 11157 instruct cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(iRegIdst dst, flagsRegSrc crx) %{ 11158 // no match-rule, false predicate 11159 effect(DEF dst, USE crx); 11160 predicate(false); 11161 11162 format %{ "CmovI $crx, $dst, -1, 0, +1 \t// postalloc expanded" %} 11163 postalloc_expand %{ 11164 // 11165 // replaces 11166 // 11167 // region crx 11168 // \ | 11169 // dst=cmovI_conIvalueMinus1_conIvalue0_conIvalue1 11170 // 11171 // with 11172 // 11173 // region 11174 // \ 11175 // dst=loadConI16(0) 11176 // | 11177 // ^ region crx 11178 // | \ | 11179 // dst=cmovI_conIvalueMinus1_conIvalue1 11180 // 11181 11182 // Create new nodes. 11183 MachNode *m1 = new loadConI16Node(); 11184 MachNode *m2 = new cmovI_conIvalueMinus1_conIvalue1Node(); 11185 11186 // inputs for new nodes 11187 m1->add_req(n_region); 11188 m2->add_req(n_region, n_crx); 11189 m2->add_prec(m1); 11190 11191 // operands for new nodes 11192 m1->_opnds[0] = op_dst; 11193 m1->_opnds[1] = new immI16Oper(0); 11194 m2->_opnds[0] = op_dst; 11195 m2->_opnds[1] = op_crx; 11196 11197 // registers for new nodes 11198 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11199 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // dst 11200 11201 // Insert new nodes. 11202 nodes->push(m1); 11203 nodes->push(m2); 11204 %} 11205 %} 11206 11207 // Manifest a CmpL3 result in an integer register. Very painful. 11208 // This is the test to avoid. 11209 // (src1 < src2) ? -1 : ((src1 > src2) ? 1 : 0) 11210 instruct cmpL3_reg_reg_ExEx(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{ 11211 match(Set dst (CmpL3 src1 src2)); 11212 ins_cost(DEFAULT_COST*5+BRANCH_COST); 11213 11214 expand %{ 11215 flagsReg tmp1; 11216 cmpL_reg_reg(tmp1, src1, src2); 11217 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 11218 %} 11219 %} 11220 11221 // Implicit range checks. 11222 // A range check in the ideal world has one of the following shapes: 11223 // - (If le (CmpU length index)), (IfTrue throw exception) 11224 // - (If lt (CmpU index length)), (IfFalse throw exception) 11225 // 11226 // Match range check 'If le (CmpU length index)'. 11227 instruct rangeCheck_iReg_uimm15(cmpOp cmp, iRegIsrc src_length, uimmI15 index, label labl) %{ 11228 match(If cmp (CmpU src_length index)); 11229 effect(USE labl); 11230 predicate(TrapBasedRangeChecks && 11231 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le && 11232 PROB_UNLIKELY(_leaf->as_If()->_prob) >= PROB_ALWAYS && 11233 (Matcher::branches_to_uncommon_trap(_leaf))); 11234 11235 ins_is_TrapBasedCheckNode(true); 11236 11237 format %{ "TWI $index $cmp $src_length \t// RangeCheck => trap $labl" %} 11238 size(4); 11239 ins_encode %{ 11240 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 11241 if ($cmp$$cmpcode == 0x1 /* less_equal */) { 11242 __ trap_range_check_le($src_length$$Register, $index$$constant); 11243 } else { 11244 // Both successors are uncommon traps, probability is 0. 11245 // Node got flipped during fixup flow. 11246 assert($cmp$$cmpcode == 0x9, "must be greater"); 11247 __ trap_range_check_g($src_length$$Register, $index$$constant); 11248 } 11249 %} 11250 ins_pipe(pipe_class_trap); 11251 %} 11252 11253 // Match range check 'If lt (CmpU index length)'. 11254 instruct rangeCheck_iReg_iReg(cmpOp cmp, iRegIsrc src_index, iRegIsrc src_length, label labl) %{ 11255 match(If cmp (CmpU src_index src_length)); 11256 effect(USE labl); 11257 predicate(TrapBasedRangeChecks && 11258 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 11259 _leaf->as_If()->_prob >= PROB_ALWAYS && 11260 (Matcher::branches_to_uncommon_trap(_leaf))); 11261 11262 ins_is_TrapBasedCheckNode(true); 11263 11264 format %{ "TW $src_index $cmp $src_length \t// RangeCheck => trap $labl" %} 11265 size(4); 11266 ins_encode %{ 11267 // TODO: PPC port $archOpcode(ppc64Opcode_tw); 11268 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 11269 __ trap_range_check_ge($src_index$$Register, $src_length$$Register); 11270 } else { 11271 // Both successors are uncommon traps, probability is 0. 11272 // Node got flipped during fixup flow. 11273 assert($cmp$$cmpcode == 0x8, "must be less"); 11274 __ trap_range_check_l($src_index$$Register, $src_length$$Register); 11275 } 11276 %} 11277 ins_pipe(pipe_class_trap); 11278 %} 11279 11280 // Match range check 'If lt (CmpU index length)'. 11281 instruct rangeCheck_uimm15_iReg(cmpOp cmp, iRegIsrc src_index, uimmI15 length, label labl) %{ 11282 match(If cmp (CmpU src_index length)); 11283 effect(USE labl); 11284 predicate(TrapBasedRangeChecks && 11285 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt && 11286 _leaf->as_If()->_prob >= PROB_ALWAYS && 11287 (Matcher::branches_to_uncommon_trap(_leaf))); 11288 11289 ins_is_TrapBasedCheckNode(true); 11290 11291 format %{ "TWI $src_index $cmp $length \t// RangeCheck => trap $labl" %} 11292 size(4); 11293 ins_encode %{ 11294 // TODO: PPC port $archOpcode(ppc64Opcode_twi); 11295 if ($cmp$$cmpcode == 0x0 /* greater_equal */) { 11296 __ trap_range_check_ge($src_index$$Register, $length$$constant); 11297 } else { 11298 // Both successors are uncommon traps, probability is 0. 11299 // Node got flipped during fixup flow. 11300 assert($cmp$$cmpcode == 0x8, "must be less"); 11301 __ trap_range_check_l($src_index$$Register, $length$$constant); 11302 } 11303 %} 11304 ins_pipe(pipe_class_trap); 11305 %} 11306 11307 instruct compU_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{ 11308 match(Set crx (CmpU src1 src2)); 11309 format %{ "CMPLW $crx, $src1, $src2 \t// unsigned" %} 11310 size(4); 11311 ins_encode %{ 11312 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11313 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11314 %} 11315 ins_pipe(pipe_class_compare); 11316 %} 11317 11318 instruct compU_reg_uimm16(flagsReg crx, iRegIsrc src1, uimmI16 src2) %{ 11319 match(Set crx (CmpU src1 src2)); 11320 size(4); 11321 format %{ "CMPLWI $crx, $src1, $src2" %} 11322 ins_encode %{ 11323 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 11324 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11325 %} 11326 ins_pipe(pipe_class_compare); 11327 %} 11328 11329 // Implicit zero checks (more implicit null checks). 11330 // No constant pool entries required. 11331 instruct zeroCheckN_iReg_imm0(cmpOp cmp, iRegNsrc value, immN_0 zero, label labl) %{ 11332 match(If cmp (CmpN value zero)); 11333 effect(USE labl); 11334 predicate(TrapBasedNullChecks && 11335 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 11336 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 11337 Matcher::branches_to_uncommon_trap(_leaf)); 11338 ins_cost(1); 11339 11340 ins_is_TrapBasedCheckNode(true); 11341 11342 format %{ "TDI $value $cmp $zero \t// ZeroCheckN => trap $labl" %} 11343 size(4); 11344 ins_encode %{ 11345 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 11346 if ($cmp$$cmpcode == 0xA) { 11347 __ trap_null_check($value$$Register); 11348 } else { 11349 // Both successors are uncommon traps, probability is 0. 11350 // Node got flipped during fixup flow. 11351 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 11352 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 11353 } 11354 %} 11355 ins_pipe(pipe_class_trap); 11356 %} 11357 11358 // Compare narrow oops. 11359 instruct cmpN_reg_reg(flagsReg crx, iRegNsrc src1, iRegNsrc src2) %{ 11360 match(Set crx (CmpN src1 src2)); 11361 11362 size(4); 11363 ins_cost(2); 11364 format %{ "CMPLW $crx, $src1, $src2 \t// compressed ptr" %} 11365 ins_encode %{ 11366 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11367 __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register); 11368 %} 11369 ins_pipe(pipe_class_compare); 11370 %} 11371 11372 instruct cmpN_reg_imm0(flagsReg crx, iRegNsrc src1, immN_0 src2) %{ 11373 match(Set crx (CmpN src1 src2)); 11374 // Make this more expensive than zeroCheckN_iReg_imm0. 11375 ins_cost(2); 11376 11377 format %{ "CMPLWI $crx, $src1, $src2 \t// compressed ptr" %} 11378 size(4); 11379 ins_encode %{ 11380 // TODO: PPC port $archOpcode(ppc64Opcode_cmpli); 11381 __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11382 %} 11383 ins_pipe(pipe_class_compare); 11384 %} 11385 11386 // Implicit zero checks (more implicit null checks). 11387 // No constant pool entries required. 11388 instruct zeroCheckP_reg_imm0(cmpOp cmp, iRegP_N2P value, immP_0 zero, label labl) %{ 11389 match(If cmp (CmpP value zero)); 11390 effect(USE labl); 11391 predicate(TrapBasedNullChecks && 11392 _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne && 11393 _leaf->as_If()->_prob >= PROB_LIKELY_MAG(4) && 11394 Matcher::branches_to_uncommon_trap(_leaf)); 11395 ins_cost(1); // Should not be cheaper than zeroCheckN. 11396 11397 ins_is_TrapBasedCheckNode(true); 11398 11399 format %{ "TDI $value $cmp $zero \t// ZeroCheckP => trap $labl" %} 11400 size(4); 11401 ins_encode %{ 11402 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 11403 if ($cmp$$cmpcode == 0xA) { 11404 __ trap_null_check($value$$Register); 11405 } else { 11406 // Both successors are uncommon traps, probability is 0. 11407 // Node got flipped during fixup flow. 11408 assert($cmp$$cmpcode == 0x2 , "must be equal(0xA) or notEqual(0x2)"); 11409 __ trap_null_check($value$$Register, Assembler::traptoGreaterThanUnsigned); 11410 } 11411 %} 11412 ins_pipe(pipe_class_trap); 11413 %} 11414 11415 // Compare Pointers 11416 instruct cmpP_reg_reg(flagsReg crx, iRegP_N2P src1, iRegP_N2P src2) %{ 11417 match(Set crx (CmpP src1 src2)); 11418 format %{ "CMPLD $crx, $src1, $src2 \t// ptr" %} 11419 size(4); 11420 ins_encode %{ 11421 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11422 __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register); 11423 %} 11424 ins_pipe(pipe_class_compare); 11425 %} 11426 11427 instruct cmpP_reg_null(flagsReg crx, iRegP_N2P src1, immP_0or1 src2) %{ 11428 match(Set crx (CmpP src1 src2)); 11429 format %{ "CMPLDI $crx, $src1, $src2 \t// ptr" %} 11430 size(4); 11431 ins_encode %{ 11432 // TODO: PPC port $archOpcode(ppc64Opcode_cmpl); 11433 __ cmpldi($crx$$CondRegister, $src1$$Register, (int)((short)($src2$$constant & 0xFFFF))); 11434 %} 11435 ins_pipe(pipe_class_compare); 11436 %} 11437 11438 // Used in postalloc expand. 11439 instruct cmpP_reg_imm16(flagsReg crx, iRegPsrc src1, immL16 src2) %{ 11440 // This match rule prevents reordering of node before a safepoint. 11441 // This only makes sense if this instructions is used exclusively 11442 // for the expansion of EncodeP! 11443 match(Set crx (CmpP src1 src2)); 11444 predicate(false); 11445 11446 format %{ "CMPDI $crx, $src1, $src2" %} 11447 size(4); 11448 ins_encode %{ 11449 // TODO: PPC port $archOpcode(ppc64Opcode_cmpi); 11450 __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant); 11451 %} 11452 ins_pipe(pipe_class_compare); 11453 %} 11454 11455 //----------Float Compares---------------------------------------------------- 11456 11457 instruct cmpFUnordered_reg_reg(flagsReg crx, regF src1, regF src2) %{ 11458 // Needs matchrule, see cmpDUnordered. 11459 match(Set crx (CmpF src1 src2)); 11460 // no match-rule, false predicate 11461 predicate(false); 11462 11463 format %{ "cmpFUrd $crx, $src1, $src2" %} 11464 size(4); 11465 ins_encode %{ 11466 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 11467 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 11468 %} 11469 ins_pipe(pipe_class_default); 11470 %} 11471 11472 instruct cmov_bns_less(flagsReg crx) %{ 11473 // no match-rule, false predicate 11474 effect(DEF crx); 11475 predicate(false); 11476 11477 ins_variable_size_depending_on_alignment(true); 11478 11479 format %{ "cmov $crx" %} 11480 // Worst case is branch + move + stop, no stop without scheduler. 11481 size(false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 16 : 12); 11482 ins_encode %{ 11483 // TODO: PPC port $archOpcode(ppc64Opcode_cmovecr); 11484 Label done; 11485 __ bns($crx$$CondRegister, done); // not unordered -> keep crx 11486 __ li(R0, 0); 11487 __ cmpwi($crx$$CondRegister, R0, 1); // unordered -> set crx to 'less' 11488 // TODO PPC port __ endgroup_if_needed(_size == 16); 11489 __ bind(done); 11490 %} 11491 ins_pipe(pipe_class_default); 11492 %} 11493 11494 // Compare floating, generate condition code. 11495 instruct cmpF_reg_reg_Ex(flagsReg crx, regF src1, regF src2) %{ 11496 // FIXME: should we match 'If cmp (CmpF src1 src2))' ?? 11497 // 11498 // The following code sequence occurs a lot in mpegaudio: 11499 // 11500 // block BXX: 11501 // 0: instruct cmpFUnordered_reg_reg (cmpF_reg_reg-0): 11502 // cmpFUrd CCR6, F11, F9 11503 // 4: instruct cmov_bns_less (cmpF_reg_reg-1): 11504 // cmov CCR6 11505 // 8: instruct branchConSched: 11506 // B_FARle CCR6, B56 P=0.500000 C=-1.000000 11507 match(Set crx (CmpF src1 src2)); 11508 ins_cost(DEFAULT_COST+BRANCH_COST); 11509 11510 format %{ "CmpF $crx, $src1, $src2 \t// postalloc expanded" %} 11511 postalloc_expand %{ 11512 // 11513 // replaces 11514 // 11515 // region src1 src2 11516 // \ | | 11517 // crx=cmpF_reg_reg 11518 // 11519 // with 11520 // 11521 // region src1 src2 11522 // \ | | 11523 // crx=cmpFUnordered_reg_reg 11524 // | 11525 // ^ region 11526 // | \ 11527 // crx=cmov_bns_less 11528 // 11529 11530 // Create new nodes. 11531 MachNode *m1 = new cmpFUnordered_reg_regNode(); 11532 MachNode *m2 = new cmov_bns_lessNode(); 11533 11534 // inputs for new nodes 11535 m1->add_req(n_region, n_src1, n_src2); 11536 m2->add_req(n_region); 11537 m2->add_prec(m1); 11538 11539 // operands for new nodes 11540 m1->_opnds[0] = op_crx; 11541 m1->_opnds[1] = op_src1; 11542 m1->_opnds[2] = op_src2; 11543 m2->_opnds[0] = op_crx; 11544 11545 // registers for new nodes 11546 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 11547 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 11548 11549 // Insert new nodes. 11550 nodes->push(m1); 11551 nodes->push(m2); 11552 %} 11553 %} 11554 11555 // Compare float, generate -1,0,1 11556 instruct cmpF3_reg_reg_ExEx(iRegIdst dst, regF src1, regF src2) %{ 11557 match(Set dst (CmpF3 src1 src2)); 11558 ins_cost(DEFAULT_COST*5+BRANCH_COST); 11559 11560 expand %{ 11561 flagsReg tmp1; 11562 cmpFUnordered_reg_reg(tmp1, src1, src2); 11563 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 11564 %} 11565 %} 11566 11567 instruct cmpDUnordered_reg_reg(flagsReg crx, regD src1, regD src2) %{ 11568 // Needs matchrule so that ideal opcode is Cmp. This causes that gcm places the 11569 // node right before the conditional move using it. 11570 // In jck test api/java_awt/geom/QuadCurve2DFloat/index.html#SetCurveTesttestCase7, 11571 // compilation of java.awt.geom.RectangularShape::getBounds()Ljava/awt/Rectangle 11572 // crashed in register allocation where the flags Reg between cmpDUnoredered and a 11573 // conditional move was supposed to be spilled. 11574 match(Set crx (CmpD src1 src2)); 11575 // False predicate, shall not be matched. 11576 predicate(false); 11577 11578 format %{ "cmpFUrd $crx, $src1, $src2" %} 11579 size(4); 11580 ins_encode %{ 11581 // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu); 11582 __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister); 11583 %} 11584 ins_pipe(pipe_class_default); 11585 %} 11586 11587 instruct cmpD_reg_reg_Ex(flagsReg crx, regD src1, regD src2) %{ 11588 match(Set crx (CmpD src1 src2)); 11589 ins_cost(DEFAULT_COST+BRANCH_COST); 11590 11591 format %{ "CmpD $crx, $src1, $src2 \t// postalloc expanded" %} 11592 postalloc_expand %{ 11593 // 11594 // replaces 11595 // 11596 // region src1 src2 11597 // \ | | 11598 // crx=cmpD_reg_reg 11599 // 11600 // with 11601 // 11602 // region src1 src2 11603 // \ | | 11604 // crx=cmpDUnordered_reg_reg 11605 // | 11606 // ^ region 11607 // | \ 11608 // crx=cmov_bns_less 11609 // 11610 11611 // create new nodes 11612 MachNode *m1 = new cmpDUnordered_reg_regNode(); 11613 MachNode *m2 = new cmov_bns_lessNode(); 11614 11615 // inputs for new nodes 11616 m1->add_req(n_region, n_src1, n_src2); 11617 m2->add_req(n_region); 11618 m2->add_prec(m1); 11619 11620 // operands for new nodes 11621 m1->_opnds[0] = op_crx; 11622 m1->_opnds[1] = op_src1; 11623 m1->_opnds[2] = op_src2; 11624 m2->_opnds[0] = op_crx; 11625 11626 // registers for new nodes 11627 ra_->set_pair(m1->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 11628 ra_->set_pair(m2->_idx, ra_->get_reg_second(this), ra_->get_reg_first(this)); // crx 11629 11630 // Insert new nodes. 11631 nodes->push(m1); 11632 nodes->push(m2); 11633 %} 11634 %} 11635 11636 // Compare double, generate -1,0,1 11637 instruct cmpD3_reg_reg_ExEx(iRegIdst dst, regD src1, regD src2) %{ 11638 match(Set dst (CmpD3 src1 src2)); 11639 ins_cost(DEFAULT_COST*5+BRANCH_COST); 11640 11641 expand %{ 11642 flagsReg tmp1; 11643 cmpDUnordered_reg_reg(tmp1, src1, src2); 11644 cmovI_conIvalueMinus1_conIvalue0_conIvalue1_Ex(dst, tmp1); 11645 %} 11646 %} 11647 11648 //----------Branches--------------------------------------------------------- 11649 // Jump 11650 11651 // Direct Branch. 11652 instruct branch(label labl) %{ 11653 match(Goto); 11654 effect(USE labl); 11655 ins_cost(BRANCH_COST); 11656 11657 format %{ "B $labl" %} 11658 size(4); 11659 ins_encode %{ 11660 // TODO: PPC port $archOpcode(ppc64Opcode_b); 11661 Label d; // dummy 11662 __ bind(d); 11663 Label* p = $labl$$label; 11664 // `p' is `NULL' when this encoding class is used only to 11665 // determine the size of the encoded instruction. 11666 Label& l = (NULL == p)? d : *(p); 11667 __ b(l); 11668 %} 11669 ins_pipe(pipe_class_default); 11670 %} 11671 11672 // Conditional Near Branch 11673 instruct branchCon(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 11674 // Same match rule as `branchConFar'. 11675 match(If cmp crx); 11676 effect(USE lbl); 11677 ins_cost(BRANCH_COST); 11678 11679 // If set to 1 this indicates that the current instruction is a 11680 // short variant of a long branch. This avoids using this 11681 // instruction in first-pass matching. It will then only be used in 11682 // the `Shorten_branches' pass. 11683 ins_short_branch(1); 11684 11685 format %{ "B$cmp $crx, $lbl" %} 11686 size(4); 11687 ins_encode( enc_bc(crx, cmp, lbl) ); 11688 ins_pipe(pipe_class_default); 11689 %} 11690 11691 // This is for cases when the ppc64 `bc' instruction does not 11692 // reach far enough. So we emit a far branch here, which is more 11693 // expensive. 11694 // 11695 // Conditional Far Branch 11696 instruct branchConFar(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 11697 // Same match rule as `branchCon'. 11698 match(If cmp crx); 11699 effect(USE crx, USE lbl); 11700 predicate(!false /* TODO: PPC port HB_Schedule*/); 11701 // Higher cost than `branchCon'. 11702 ins_cost(5*BRANCH_COST); 11703 11704 // This is not a short variant of a branch, but the long variant. 11705 ins_short_branch(0); 11706 11707 format %{ "B_FAR$cmp $crx, $lbl" %} 11708 size(8); 11709 ins_encode( enc_bc_far(crx, cmp, lbl) ); 11710 ins_pipe(pipe_class_default); 11711 %} 11712 11713 // Conditional Branch used with Power6 scheduler (can be far or short). 11714 instruct branchConSched(cmpOp cmp, flagsRegSrc crx, label lbl) %{ 11715 // Same match rule as `branchCon'. 11716 match(If cmp crx); 11717 effect(USE crx, USE lbl); 11718 predicate(false /* TODO: PPC port HB_Schedule*/); 11719 // Higher cost than `branchCon'. 11720 ins_cost(5*BRANCH_COST); 11721 11722 // Actually size doesn't depend on alignment but on shortening. 11723 ins_variable_size_depending_on_alignment(true); 11724 // long variant. 11725 ins_short_branch(0); 11726 11727 format %{ "B_FAR$cmp $crx, $lbl" %} 11728 size(8); // worst case 11729 ins_encode( enc_bc_short_far(crx, cmp, lbl) ); 11730 ins_pipe(pipe_class_default); 11731 %} 11732 11733 instruct branchLoopEnd(cmpOp cmp, flagsRegSrc crx, label labl) %{ 11734 match(CountedLoopEnd cmp crx); 11735 effect(USE labl); 11736 ins_cost(BRANCH_COST); 11737 11738 // short variant. 11739 ins_short_branch(1); 11740 11741 format %{ "B$cmp $crx, $labl \t// counted loop end" %} 11742 size(4); 11743 ins_encode( enc_bc(crx, cmp, labl) ); 11744 ins_pipe(pipe_class_default); 11745 %} 11746 11747 instruct branchLoopEndFar(cmpOp cmp, flagsRegSrc crx, label labl) %{ 11748 match(CountedLoopEnd cmp crx); 11749 effect(USE labl); 11750 predicate(!false /* TODO: PPC port HB_Schedule */); 11751 ins_cost(BRANCH_COST); 11752 11753 // Long variant. 11754 ins_short_branch(0); 11755 11756 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 11757 size(8); 11758 ins_encode( enc_bc_far(crx, cmp, labl) ); 11759 ins_pipe(pipe_class_default); 11760 %} 11761 11762 // Conditional Branch used with Power6 scheduler (can be far or short). 11763 instruct branchLoopEndSched(cmpOp cmp, flagsRegSrc crx, label labl) %{ 11764 match(CountedLoopEnd cmp crx); 11765 effect(USE labl); 11766 predicate(false /* TODO: PPC port HB_Schedule */); 11767 // Higher cost than `branchCon'. 11768 ins_cost(5*BRANCH_COST); 11769 11770 // Actually size doesn't depend on alignment but on shortening. 11771 ins_variable_size_depending_on_alignment(true); 11772 // Long variant. 11773 ins_short_branch(0); 11774 11775 format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %} 11776 size(8); // worst case 11777 ins_encode( enc_bc_short_far(crx, cmp, labl) ); 11778 ins_pipe(pipe_class_default); 11779 %} 11780 11781 // ============================================================================ 11782 // Java runtime operations, intrinsics and other complex operations. 11783 11784 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass 11785 // array for an instance of the superklass. Set a hidden internal cache on a 11786 // hit (cache is checked with exposed code in gen_subtype_check()). Return 11787 // not zero for a miss or zero for a hit. The encoding ALSO sets flags. 11788 // 11789 // GL TODO: Improve this. 11790 // - result should not be a TEMP 11791 // - Add match rule as on sparc avoiding additional Cmp. 11792 instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P superklass, 11793 iRegPdst tmp_klass, iRegPdst tmp_arrayptr) %{ 11794 match(Set result (PartialSubtypeCheck subklass superklass)); 11795 effect(TEMP_DEF result, TEMP tmp_klass, TEMP tmp_arrayptr); 11796 ins_cost(DEFAULT_COST*10); 11797 11798 format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %} 11799 ins_encode %{ 11800 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11801 __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register, 11802 $tmp_klass$$Register, NULL, $result$$Register); 11803 %} 11804 ins_pipe(pipe_class_default); 11805 %} 11806 11807 // inlined locking and unlocking 11808 11809 instruct cmpFastLock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2) %{ 11810 match(Set crx (FastLock oop box)); 11811 effect(TEMP tmp1, TEMP tmp2); 11812 predicate(!Compile::current()->use_rtm()); 11813 11814 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2" %} 11815 ins_encode %{ 11816 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11817 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 11818 $tmp1$$Register, $tmp2$$Register, /*tmp3*/ R0, 11819 UseBiasedLocking && !UseOptoBiasInlining); 11820 // If locking was successfull, crx should indicate 'EQ'. 11821 // The compiler generates a branch to the runtime call to 11822 // _complete_monitor_locking_Java for the case where crx is 'NE'. 11823 %} 11824 ins_pipe(pipe_class_compare); 11825 %} 11826 11827 // Separate version for TM. Use bound register for box to enable USE_KILL. 11828 instruct cmpFastLock_tm(flagsReg crx, iRegPdst oop, rarg2RegP box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 11829 match(Set crx (FastLock oop box)); 11830 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL box); 11831 predicate(Compile::current()->use_rtm()); 11832 11833 format %{ "FASTLOCK $oop, $box, $tmp1, $tmp2, $tmp3 (TM)" %} 11834 ins_encode %{ 11835 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11836 __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 11837 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 11838 /*Biased Locking*/ false, 11839 _rtm_counters, _stack_rtm_counters, 11840 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 11841 /*TM*/ true, ra_->C->profile_rtm()); 11842 // If locking was successfull, crx should indicate 'EQ'. 11843 // The compiler generates a branch to the runtime call to 11844 // _complete_monitor_locking_Java for the case where crx is 'NE'. 11845 %} 11846 ins_pipe(pipe_class_compare); 11847 %} 11848 11849 instruct cmpFastUnlock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 11850 match(Set crx (FastUnlock oop box)); 11851 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 11852 predicate(!Compile::current()->use_rtm()); 11853 11854 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2" %} 11855 ins_encode %{ 11856 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11857 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 11858 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 11859 UseBiasedLocking && !UseOptoBiasInlining, 11860 false); 11861 // If unlocking was successfull, crx should indicate 'EQ'. 11862 // The compiler generates a branch to the runtime call to 11863 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 11864 %} 11865 ins_pipe(pipe_class_compare); 11866 %} 11867 11868 instruct cmpFastUnlock_tm(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iRegPdst tmp2, iRegPdst tmp3) %{ 11869 match(Set crx (FastUnlock oop box)); 11870 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3); 11871 predicate(Compile::current()->use_rtm()); 11872 11873 format %{ "FASTUNLOCK $oop, $box, $tmp1, $tmp2 (TM)" %} 11874 ins_encode %{ 11875 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11876 __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register, 11877 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 11878 /*Biased Locking*/ false, /*TM*/ true); 11879 // If unlocking was successfull, crx should indicate 'EQ'. 11880 // The compiler generates a branch to the runtime call to 11881 // _complete_monitor_unlocking_Java for the case where crx is 'NE'. 11882 %} 11883 ins_pipe(pipe_class_compare); 11884 %} 11885 11886 // Align address. 11887 instruct align_addr(iRegPdst dst, iRegPsrc src, immLnegpow2 mask) %{ 11888 match(Set dst (CastX2P (AndL (CastP2X src) mask))); 11889 11890 format %{ "ANDDI $dst, $src, $mask \t// next aligned address" %} 11891 size(4); 11892 ins_encode %{ 11893 // TODO: PPC port $archOpcode(ppc64Opcode_rldicr); 11894 __ clrrdi($dst$$Register, $src$$Register, log2_long((jlong)-$mask$$constant)); 11895 %} 11896 ins_pipe(pipe_class_default); 11897 %} 11898 11899 // Array size computation. 11900 instruct array_size(iRegLdst dst, iRegPsrc end, iRegPsrc start) %{ 11901 match(Set dst (SubL (CastP2X end) (CastP2X start))); 11902 11903 format %{ "SUB $dst, $end, $start \t// array size in bytes" %} 11904 size(4); 11905 ins_encode %{ 11906 // TODO: PPC port $archOpcode(ppc64Opcode_subf); 11907 __ subf($dst$$Register, $start$$Register, $end$$Register); 11908 %} 11909 ins_pipe(pipe_class_default); 11910 %} 11911 11912 // Clear-array with constant short array length. The versions below can use dcbz with cnt > 30. 11913 instruct inlineCallClearArrayShort(immLmax30 cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 11914 match(Set dummy (ClearArray cnt base)); 11915 effect(USE_KILL base, KILL ctr); 11916 ins_cost(2 * MEMORY_REF_COST); 11917 11918 format %{ "ClearArray $cnt, $base" %} 11919 ins_encode %{ 11920 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11921 __ clear_memory_constlen($base$$Register, $cnt$$constant, R0); // kills base, R0 11922 %} 11923 ins_pipe(pipe_class_default); 11924 %} 11925 11926 // Clear-array with constant large array length. 11927 instruct inlineCallClearArrayLarge(immL cnt, rarg2RegP base, Universe dummy, iRegLdst tmp, regCTR ctr) %{ 11928 match(Set dummy (ClearArray cnt base)); 11929 effect(USE_KILL base, TEMP tmp, KILL ctr); 11930 ins_cost(3 * MEMORY_REF_COST); 11931 11932 format %{ "ClearArray $cnt, $base \t// KILL $tmp" %} 11933 ins_encode %{ 11934 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11935 __ clear_memory_doubleword($base$$Register, $tmp$$Register, R0, $cnt$$constant); // kills base, R0 11936 %} 11937 ins_pipe(pipe_class_default); 11938 %} 11939 11940 // Clear-array with dynamic array length. 11941 instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, regCTR ctr) %{ 11942 match(Set dummy (ClearArray cnt base)); 11943 effect(USE_KILL cnt, USE_KILL base, KILL ctr); 11944 ins_cost(4 * MEMORY_REF_COST); 11945 11946 format %{ "ClearArray $cnt, $base" %} 11947 ins_encode %{ 11948 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11949 __ clear_memory_doubleword($base$$Register, $cnt$$Register, R0); // kills cnt, base, R0 11950 %} 11951 ins_pipe(pipe_class_default); 11952 %} 11953 11954 instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 11955 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 11956 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 11957 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11958 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 11959 ins_cost(300); 11960 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 11961 ins_encode %{ 11962 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11963 __ string_compare($str1$$Register, $str2$$Register, 11964 $cnt1$$Register, $cnt2$$Register, 11965 $tmp$$Register, 11966 $result$$Register, StrIntrinsicNode::LL); 11967 %} 11968 ins_pipe(pipe_class_default); 11969 %} 11970 11971 instruct string_compareU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 11972 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 11973 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 11974 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11975 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 11976 ins_cost(300); 11977 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 11978 ins_encode %{ 11979 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11980 __ string_compare($str1$$Register, $str2$$Register, 11981 $cnt1$$Register, $cnt2$$Register, 11982 $tmp$$Register, 11983 $result$$Register, StrIntrinsicNode::UU); 11984 %} 11985 ins_pipe(pipe_class_default); 11986 %} 11987 11988 instruct string_compareLU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 11989 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 11990 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 11991 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11992 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 11993 ins_cost(300); 11994 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 11995 ins_encode %{ 11996 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 11997 __ string_compare($str1$$Register, $str2$$Register, 11998 $cnt1$$Register, $cnt2$$Register, 11999 $tmp$$Register, 12000 $result$$Register, StrIntrinsicNode::LU); 12001 %} 12002 ins_pipe(pipe_class_default); 12003 %} 12004 12005 instruct string_compareUL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result, 12006 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12007 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 12008 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12009 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp); 12010 ins_cost(300); 12011 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %} 12012 ins_encode %{ 12013 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12014 __ string_compare($str2$$Register, $str1$$Register, 12015 $cnt2$$Register, $cnt1$$Register, 12016 $tmp$$Register, 12017 $result$$Register, StrIntrinsicNode::UL); 12018 %} 12019 ins_pipe(pipe_class_default); 12020 %} 12021 12022 instruct string_equalsL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 12023 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12024 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL); 12025 match(Set result (StrEquals (Binary str1 str2) cnt)); 12026 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 12027 ins_cost(300); 12028 format %{ "String Equals byte[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 12029 ins_encode %{ 12030 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12031 __ array_equals(false, $str1$$Register, $str2$$Register, 12032 $cnt$$Register, $tmp$$Register, 12033 $result$$Register, true /* byte */); 12034 %} 12035 ins_pipe(pipe_class_default); 12036 %} 12037 12038 instruct string_equalsU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result, 12039 iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{ 12040 predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU); 12041 match(Set result (StrEquals (Binary str1 str2) cnt)); 12042 effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0); 12043 ins_cost(300); 12044 format %{ "String Equals char[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %} 12045 ins_encode %{ 12046 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12047 __ array_equals(false, $str1$$Register, $str2$$Register, 12048 $cnt$$Register, $tmp$$Register, 12049 $result$$Register, false /* byte */); 12050 %} 12051 ins_pipe(pipe_class_default); 12052 %} 12053 12054 instruct array_equalsB(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 12055 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 12056 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 12057 match(Set result (AryEq ary1 ary2)); 12058 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 12059 ins_cost(300); 12060 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 12061 ins_encode %{ 12062 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12063 __ array_equals(true, $ary1$$Register, $ary2$$Register, 12064 $tmp1$$Register, $tmp2$$Register, 12065 $result$$Register, true /* byte */); 12066 %} 12067 ins_pipe(pipe_class_default); 12068 %} 12069 12070 instruct array_equalsC(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result, 12071 iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{ 12072 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 12073 match(Set result (AryEq ary1 ary2)); 12074 effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1); 12075 ins_cost(300); 12076 format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %} 12077 ins_encode %{ 12078 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12079 __ array_equals(true, $ary1$$Register, $ary2$$Register, 12080 $tmp1$$Register, $tmp2$$Register, 12081 $result$$Register, false /* byte */); 12082 %} 12083 ins_pipe(pipe_class_default); 12084 %} 12085 12086 instruct indexOf_imm1_char_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12087 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12088 iRegIdst tmp1, iRegIdst tmp2, 12089 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12090 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12091 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12092 // Required for EA: check if it is still a type_array. 12093 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 12094 ins_cost(150); 12095 12096 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12097 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12098 12099 ins_encode %{ 12100 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12101 immPOper *needleOper = (immPOper *)$needleImm; 12102 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12103 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12104 jchar chr; 12105 #ifdef VM_LITTLE_ENDIAN 12106 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 12107 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 12108 #else 12109 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 12110 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 12111 #endif 12112 __ string_indexof_char($result$$Register, 12113 $haystack$$Register, $haycnt$$Register, 12114 R0, chr, 12115 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12116 %} 12117 ins_pipe(pipe_class_compare); 12118 %} 12119 12120 instruct indexOf_imm1_char_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12121 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12122 iRegIdst tmp1, iRegIdst tmp2, 12123 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12124 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12125 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12126 // Required for EA: check if it is still a type_array. 12127 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 12128 ins_cost(150); 12129 12130 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12131 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12132 12133 ins_encode %{ 12134 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12135 immPOper *needleOper = (immPOper *)$needleImm; 12136 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12137 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12138 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12139 __ string_indexof_char($result$$Register, 12140 $haystack$$Register, $haycnt$$Register, 12141 R0, chr, 12142 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 12143 %} 12144 ins_pipe(pipe_class_compare); 12145 %} 12146 12147 instruct indexOf_imm1_char_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12148 immP needleImm, immL offsetImm, immI_1 needlecntImm, 12149 iRegIdst tmp1, iRegIdst tmp2, 12150 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12151 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm))); 12152 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12153 // Required for EA: check if it is still a type_array. 12154 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 12155 ins_cost(150); 12156 12157 format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]" 12158 "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12159 12160 ins_encode %{ 12161 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12162 immPOper *needleOper = (immPOper *)$needleImm; 12163 const TypeOopPtr *t = needleOper->type()->isa_oopptr(); 12164 ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char * 12165 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12166 __ string_indexof_char($result$$Register, 12167 $haystack$$Register, $haycnt$$Register, 12168 R0, chr, 12169 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12170 %} 12171 ins_pipe(pipe_class_compare); 12172 %} 12173 12174 instruct indexOf_imm1_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12175 rscratch2RegP needle, immI_1 needlecntImm, 12176 iRegIdst tmp1, iRegIdst tmp2, 12177 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12178 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12179 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12180 // Required for EA: check if it is still a type_array. 12181 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 12182 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12183 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12184 ins_cost(180); 12185 12186 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12187 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12188 ins_encode %{ 12189 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12190 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12191 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12192 guarantee(needle_values, "sanity"); 12193 jchar chr; 12194 #ifdef VM_LITTLE_ENDIAN 12195 chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) | 12196 ((jchar)(unsigned char)needle_values->element_value(0).as_byte()); 12197 #else 12198 chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) | 12199 ((jchar)(unsigned char)needle_values->element_value(1).as_byte()); 12200 #endif 12201 __ string_indexof_char($result$$Register, 12202 $haystack$$Register, $haycnt$$Register, 12203 R0, chr, 12204 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12205 %} 12206 ins_pipe(pipe_class_compare); 12207 %} 12208 12209 instruct indexOf_imm1_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12210 rscratch2RegP needle, immI_1 needlecntImm, 12211 iRegIdst tmp1, iRegIdst tmp2, 12212 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12213 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12214 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12215 // Required for EA: check if it is still a type_array. 12216 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 12217 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12218 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12219 ins_cost(180); 12220 12221 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12222 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12223 ins_encode %{ 12224 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12225 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12226 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12227 guarantee(needle_values, "sanity"); 12228 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12229 __ string_indexof_char($result$$Register, 12230 $haystack$$Register, $haycnt$$Register, 12231 R0, chr, 12232 $tmp1$$Register, $tmp2$$Register, true /*is_byte*/); 12233 %} 12234 ins_pipe(pipe_class_compare); 12235 %} 12236 12237 instruct indexOf_imm1_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12238 rscratch2RegP needle, immI_1 needlecntImm, 12239 iRegIdst tmp1, iRegIdst tmp2, 12240 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12241 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12242 effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12243 // Required for EA: check if it is still a type_array. 12244 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 12245 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12246 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12247 ins_cost(180); 12248 12249 format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12250 " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %} 12251 ins_encode %{ 12252 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12253 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12254 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12255 guarantee(needle_values, "sanity"); 12256 jchar chr = (jchar)needle_values->element_value(0).as_byte(); 12257 __ string_indexof_char($result$$Register, 12258 $haystack$$Register, $haycnt$$Register, 12259 R0, chr, 12260 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12261 %} 12262 ins_pipe(pipe_class_compare); 12263 %} 12264 12265 instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt, 12266 iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2, 12267 flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{ 12268 match(Set result (StrIndexOfChar (Binary haystack haycnt) ch)); 12269 effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr); 12270 ins_cost(180); 12271 12272 format %{ "String IndexOfChar $haystack[0..$haycnt], $ch" 12273 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %} 12274 ins_encode %{ 12275 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12276 __ string_indexof_char($result$$Register, 12277 $haystack$$Register, $haycnt$$Register, 12278 $ch$$Register, 0 /* this is not used if the character is already in a register */, 12279 $tmp1$$Register, $tmp2$$Register, false /*is_byte*/); 12280 %} 12281 ins_pipe(pipe_class_compare); 12282 %} 12283 12284 instruct indexOf_imm_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 12285 iRegPsrc needle, uimmI15 needlecntImm, 12286 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 12287 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12288 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12289 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 12290 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12291 // Required for EA: check if it is still a type_array. 12292 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU && 12293 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12294 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12295 ins_cost(250); 12296 12297 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12298 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 12299 ins_encode %{ 12300 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12301 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12302 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12303 12304 __ string_indexof($result$$Register, 12305 $haystack$$Register, $haycnt$$Register, 12306 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 12307 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 12308 %} 12309 ins_pipe(pipe_class_compare); 12310 %} 12311 12312 instruct indexOf_imm_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 12313 iRegPsrc needle, uimmI15 needlecntImm, 12314 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 12315 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12316 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12317 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 12318 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12319 // Required for EA: check if it is still a type_array. 12320 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL && 12321 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12322 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12323 ins_cost(250); 12324 12325 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12326 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 12327 ins_encode %{ 12328 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12329 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12330 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12331 12332 __ string_indexof($result$$Register, 12333 $haystack$$Register, $haycnt$$Register, 12334 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 12335 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 12336 %} 12337 ins_pipe(pipe_class_compare); 12338 %} 12339 12340 instruct indexOf_imm_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, 12341 iRegPsrc needle, uimmI15 needlecntImm, 12342 iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5, 12343 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12344 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm))); 12345 effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result, 12346 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12347 // Required for EA: check if it is still a type_array. 12348 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL && 12349 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() && 12350 n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array()); 12351 ins_cost(250); 12352 12353 format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]" 12354 " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %} 12355 ins_encode %{ 12356 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12357 Node *ndl = in(operand_index($needle)); // The node that defines needle. 12358 ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array(); 12359 12360 __ string_indexof($result$$Register, 12361 $haystack$$Register, $haycnt$$Register, 12362 $needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant, 12363 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 12364 %} 12365 ins_pipe(pipe_class_compare); 12366 %} 12367 12368 instruct indexOf_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 12369 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 12370 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12371 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 12372 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 12373 TEMP_DEF result, 12374 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12375 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); 12376 ins_cost(300); 12377 12378 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 12379 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 12380 ins_encode %{ 12381 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12382 __ string_indexof($result$$Register, 12383 $haystack$$Register, $haycnt$$Register, 12384 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 12385 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU); 12386 %} 12387 ins_pipe(pipe_class_compare); 12388 %} 12389 12390 instruct indexOf_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 12391 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 12392 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12393 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 12394 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 12395 TEMP_DEF result, 12396 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12397 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); 12398 ins_cost(300); 12399 12400 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 12401 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 12402 ins_encode %{ 12403 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12404 __ string_indexof($result$$Register, 12405 $haystack$$Register, $haycnt$$Register, 12406 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 12407 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL); 12408 %} 12409 ins_pipe(pipe_class_compare); 12410 %} 12411 12412 instruct indexOf_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt, 12413 iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, 12414 flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{ 12415 match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt))); 12416 effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/ 12417 TEMP_DEF result, 12418 TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr); 12419 predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); 12420 ins_cost(300); 12421 12422 format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]" 12423 " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %} 12424 ins_encode %{ 12425 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12426 __ string_indexof($result$$Register, 12427 $haystack$$Register, $haycnt$$Register, 12428 $needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant. 12429 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL); 12430 %} 12431 ins_pipe(pipe_class_compare); 12432 %} 12433 12434 // char[] to byte[] compression 12435 instruct string_compress(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 12436 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 12437 match(Set result (StrCompressedCopy src (Binary dst len))); 12438 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 12439 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 12440 ins_cost(300); 12441 format %{ "String Compress $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 12442 ins_encode %{ 12443 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12444 Label Lskip, Ldone; 12445 __ li($result$$Register, 0); 12446 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 12447 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Ldone); 12448 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 12449 __ beq(CCR0, Lskip); 12450 __ string_compress($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register, Ldone); 12451 __ bind(Lskip); 12452 __ mr($result$$Register, $len$$Register); 12453 __ bind(Ldone); 12454 %} 12455 ins_pipe(pipe_class_default); 12456 %} 12457 12458 // byte[] to char[] inflation 12459 instruct string_inflate(Universe dummy, rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegLdst tmp1, 12460 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 12461 match(Set dummy (StrInflatedCopy src (Binary dst len))); 12462 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 12463 ins_cost(300); 12464 format %{ "String Inflate $src,$dst,$len \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 12465 ins_encode %{ 12466 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12467 Label Ldone; 12468 __ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 12469 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register); 12470 __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. 12471 __ beq(CCR0, Ldone); 12472 __ string_inflate($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register); 12473 __ bind(Ldone); 12474 %} 12475 ins_pipe(pipe_class_default); 12476 %} 12477 12478 // StringCoding.java intrinsics 12479 instruct has_negatives(rarg1RegP ary1, iRegIsrc len, iRegIdst result, iRegLdst tmp1, iRegLdst tmp2, 12480 regCTR ctr, flagsRegCR0 cr0) 12481 %{ 12482 match(Set result (HasNegatives ary1 len)); 12483 effect(TEMP_DEF result, USE_KILL ary1, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0); 12484 ins_cost(300); 12485 format %{ "has negatives byte[] $ary1,$len -> $result \t// KILL $tmp1, $tmp2" %} 12486 ins_encode %{ 12487 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12488 __ has_negatives($ary1$$Register, $len$$Register, $result$$Register, 12489 $tmp1$$Register, $tmp2$$Register); 12490 %} 12491 ins_pipe(pipe_class_default); 12492 %} 12493 12494 // encode char[] to byte[] in ISO_8859_1 12495 instruct encode_iso_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1, 12496 iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{ 12497 match(Set result (EncodeISOArray src (Binary dst len))); 12498 effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, 12499 USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0); 12500 ins_cost(300); 12501 format %{ "Encode array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} 12502 ins_encode %{ 12503 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12504 Label Lslow, Lfailure1, Lfailure2, Ldone; 12505 __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, 12506 $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Lfailure1); 12507 __ rldicl_($result$$Register, $len$$Register, 0, 64-3); // Remaining characters. 12508 __ beq(CCR0, Ldone); 12509 __ bind(Lslow); 12510 __ string_compress($src$$Register, $dst$$Register, $result$$Register, $tmp2$$Register, Lfailure2); 12511 __ li($result$$Register, 0); 12512 __ b(Ldone); 12513 12514 __ bind(Lfailure1); 12515 __ mr($result$$Register, $len$$Register); 12516 __ mfctr($tmp1$$Register); 12517 __ rldimi_($result$$Register, $tmp1$$Register, 3, 0); // Remaining characters. 12518 __ beq(CCR0, Ldone); 12519 __ b(Lslow); 12520 12521 __ bind(Lfailure2); 12522 __ mfctr($result$$Register); // Remaining characters. 12523 12524 __ bind(Ldone); 12525 __ subf($result$$Register, $result$$Register, $len$$Register); 12526 %} 12527 ins_pipe(pipe_class_default); 12528 %} 12529 12530 12531 //---------- Min/Max Instructions --------------------------------------------- 12532 12533 instruct minI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 12534 match(Set dst (MinI src1 src2)); 12535 ins_cost(DEFAULT_COST*6); 12536 12537 expand %{ 12538 iRegLdst src1s; 12539 iRegLdst src2s; 12540 iRegLdst diff; 12541 iRegLdst sm; 12542 iRegLdst doz; // difference or zero 12543 convI2L_reg(src1s, src1); // Ensure proper sign extension. 12544 convI2L_reg(src2s, src2); // Ensure proper sign extension. 12545 subL_reg_reg(diff, src2s, src1s); 12546 // Need to consider >=33 bit result, therefore we need signmaskL. 12547 signmask64L_regL(sm, diff); 12548 andL_reg_reg(doz, diff, sm); // <=0 12549 addI_regL_regL(dst, doz, src1s); 12550 %} 12551 %} 12552 12553 instruct minI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 12554 match(Set dst (MinI src1 src2)); 12555 effect(KILL cr0); 12556 predicate(VM_Version::has_isel()); 12557 ins_cost(DEFAULT_COST*2); 12558 12559 ins_encode %{ 12560 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12561 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 12562 __ isel($dst$$Register, CCR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register); 12563 %} 12564 ins_pipe(pipe_class_default); 12565 %} 12566 12567 instruct maxI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ 12568 match(Set dst (MaxI src1 src2)); 12569 ins_cost(DEFAULT_COST*6); 12570 12571 expand %{ 12572 iRegLdst src1s; 12573 iRegLdst src2s; 12574 iRegLdst diff; 12575 iRegLdst sm; 12576 iRegLdst doz; // difference or zero 12577 convI2L_reg(src1s, src1); // Ensure proper sign extension. 12578 convI2L_reg(src2s, src2); // Ensure proper sign extension. 12579 subL_reg_reg(diff, src2s, src1s); 12580 // Need to consider >=33 bit result, therefore we need signmaskL. 12581 signmask64L_regL(sm, diff); 12582 andcL_reg_reg(doz, diff, sm); // >=0 12583 addI_regL_regL(dst, doz, src1s); 12584 %} 12585 %} 12586 12587 instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{ 12588 match(Set dst (MaxI src1 src2)); 12589 effect(KILL cr0); 12590 predicate(VM_Version::has_isel()); 12591 ins_cost(DEFAULT_COST*2); 12592 12593 ins_encode %{ 12594 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 12595 __ cmpw(CCR0, $src1$$Register, $src2$$Register); 12596 __ isel($dst$$Register, CCR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register); 12597 %} 12598 ins_pipe(pipe_class_default); 12599 %} 12600 12601 //---------- Population Count Instructions ------------------------------------ 12602 12603 // Popcnt for Power7. 12604 instruct popCountI(iRegIdst dst, iRegIsrc src) %{ 12605 match(Set dst (PopCountI src)); 12606 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 12607 ins_cost(DEFAULT_COST); 12608 12609 format %{ "POPCNTW $dst, $src" %} 12610 size(4); 12611 ins_encode %{ 12612 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 12613 __ popcntw($dst$$Register, $src$$Register); 12614 %} 12615 ins_pipe(pipe_class_default); 12616 %} 12617 12618 // Popcnt for Power7. 12619 instruct popCountL(iRegIdst dst, iRegLsrc src) %{ 12620 predicate(UsePopCountInstruction && VM_Version::has_popcntw()); 12621 match(Set dst (PopCountL src)); 12622 ins_cost(DEFAULT_COST); 12623 12624 format %{ "POPCNTD $dst, $src" %} 12625 size(4); 12626 ins_encode %{ 12627 // TODO: PPC port $archOpcode(ppc64Opcode_popcntb); 12628 __ popcntd($dst$$Register, $src$$Register); 12629 %} 12630 ins_pipe(pipe_class_default); 12631 %} 12632 12633 instruct countLeadingZerosI(iRegIdst dst, iRegIsrc src) %{ 12634 match(Set dst (CountLeadingZerosI src)); 12635 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 12636 ins_cost(DEFAULT_COST); 12637 12638 format %{ "CNTLZW $dst, $src" %} 12639 size(4); 12640 ins_encode %{ 12641 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzw); 12642 __ cntlzw($dst$$Register, $src$$Register); 12643 %} 12644 ins_pipe(pipe_class_default); 12645 %} 12646 12647 instruct countLeadingZerosL(iRegIdst dst, iRegLsrc src) %{ 12648 match(Set dst (CountLeadingZerosL src)); 12649 predicate(UseCountLeadingZerosInstructionsPPC64); // See Matcher::match_rule_supported. 12650 ins_cost(DEFAULT_COST); 12651 12652 format %{ "CNTLZD $dst, $src" %} 12653 size(4); 12654 ins_encode %{ 12655 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 12656 __ cntlzd($dst$$Register, $src$$Register); 12657 %} 12658 ins_pipe(pipe_class_default); 12659 %} 12660 12661 instruct countLeadingZerosP(iRegIdst dst, iRegPsrc src) %{ 12662 // no match-rule, false predicate 12663 effect(DEF dst, USE src); 12664 predicate(false); 12665 12666 format %{ "CNTLZD $dst, $src" %} 12667 size(4); 12668 ins_encode %{ 12669 // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd); 12670 __ cntlzd($dst$$Register, $src$$Register); 12671 %} 12672 ins_pipe(pipe_class_default); 12673 %} 12674 12675 instruct countTrailingZerosI_Ex(iRegIdst dst, iRegIsrc src) %{ 12676 match(Set dst (CountTrailingZerosI src)); 12677 predicate(UseCountLeadingZerosInstructionsPPC64); 12678 ins_cost(DEFAULT_COST); 12679 12680 expand %{ 12681 immI16 imm1 %{ (int)-1 %} 12682 immI16 imm2 %{ (int)32 %} 12683 immI_minus1 m1 %{ -1 %} 12684 iRegIdst tmpI1; 12685 iRegIdst tmpI2; 12686 iRegIdst tmpI3; 12687 addI_reg_imm16(tmpI1, src, imm1); 12688 andcI_reg_reg(tmpI2, src, m1, tmpI1); 12689 countLeadingZerosI(tmpI3, tmpI2); 12690 subI_imm16_reg(dst, imm2, tmpI3); 12691 %} 12692 %} 12693 12694 instruct countTrailingZerosL_Ex(iRegIdst dst, iRegLsrc src) %{ 12695 match(Set dst (CountTrailingZerosL src)); 12696 predicate(UseCountLeadingZerosInstructionsPPC64); 12697 ins_cost(DEFAULT_COST); 12698 12699 expand %{ 12700 immL16 imm1 %{ (long)-1 %} 12701 immI16 imm2 %{ (int)64 %} 12702 iRegLdst tmpL1; 12703 iRegLdst tmpL2; 12704 iRegIdst tmpL3; 12705 addL_reg_imm16(tmpL1, src, imm1); 12706 andcL_reg_reg(tmpL2, tmpL1, src); 12707 countLeadingZerosL(tmpL3, tmpL2); 12708 subI_imm16_reg(dst, imm2, tmpL3); 12709 %} 12710 %} 12711 12712 // Expand nodes for byte_reverse_int. 12713 instruct insrwi_a(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 12714 effect(DEF dst, USE src, USE pos, USE shift); 12715 predicate(false); 12716 12717 format %{ "INSRWI $dst, $src, $pos, $shift" %} 12718 size(4); 12719 ins_encode %{ 12720 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 12721 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 12722 %} 12723 ins_pipe(pipe_class_default); 12724 %} 12725 12726 // As insrwi_a, but with USE_DEF. 12727 instruct insrwi(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{ 12728 effect(USE_DEF dst, USE src, USE pos, USE shift); 12729 predicate(false); 12730 12731 format %{ "INSRWI $dst, $src, $pos, $shift" %} 12732 size(4); 12733 ins_encode %{ 12734 // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi); 12735 __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant); 12736 %} 12737 ins_pipe(pipe_class_default); 12738 %} 12739 12740 // Just slightly faster than java implementation. 12741 instruct bytes_reverse_int_Ex(iRegIdst dst, iRegIsrc src) %{ 12742 match(Set dst (ReverseBytesI src)); 12743 ins_cost(7*DEFAULT_COST); 12744 12745 expand %{ 12746 immI16 imm24 %{ (int) 24 %} 12747 immI16 imm16 %{ (int) 16 %} 12748 immI16 imm8 %{ (int) 8 %} 12749 immI16 imm4 %{ (int) 4 %} 12750 immI16 imm0 %{ (int) 0 %} 12751 iRegLdst tmpI1; 12752 iRegLdst tmpI2; 12753 iRegLdst tmpI3; 12754 12755 urShiftI_reg_imm(tmpI1, src, imm24); 12756 insrwi_a(dst, tmpI1, imm24, imm8); 12757 urShiftI_reg_imm(tmpI2, src, imm16); 12758 insrwi(dst, tmpI2, imm8, imm16); 12759 urShiftI_reg_imm(tmpI3, src, imm8); 12760 insrwi(dst, tmpI3, imm8, imm8); 12761 insrwi(dst, src, imm0, imm8); 12762 %} 12763 %} 12764 12765 instruct bytes_reverse_long_Ex(iRegLdst dst, iRegLsrc src) %{ 12766 match(Set dst (ReverseBytesL src)); 12767 ins_cost(15*DEFAULT_COST); 12768 12769 expand %{ 12770 immI16 imm56 %{ (int) 56 %} 12771 immI16 imm48 %{ (int) 48 %} 12772 immI16 imm40 %{ (int) 40 %} 12773 immI16 imm32 %{ (int) 32 %} 12774 immI16 imm24 %{ (int) 24 %} 12775 immI16 imm16 %{ (int) 16 %} 12776 immI16 imm8 %{ (int) 8 %} 12777 immI16 imm0 %{ (int) 0 %} 12778 iRegLdst tmpL1; 12779 iRegLdst tmpL2; 12780 iRegLdst tmpL3; 12781 iRegLdst tmpL4; 12782 iRegLdst tmpL5; 12783 iRegLdst tmpL6; 12784 12785 // src : |a|b|c|d|e|f|g|h| 12786 rldicl(tmpL1, src, imm8, imm24); // tmpL1 : | | | |e|f|g|h|a| 12787 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |a| | | |e| 12788 rldicl(tmpL3, tmpL2, imm32, imm0); // tmpL3 : | | | |e| | | |a| 12789 rldicl(tmpL1, src, imm16, imm24); // tmpL1 : | | | |f|g|h|a|b| 12790 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |b| | | |f| 12791 rldicl(tmpL4, tmpL2, imm40, imm0); // tmpL4 : | | |f| | | |b| | 12792 orL_reg_reg(tmpL5, tmpL3, tmpL4); // tmpL5 : | | |f|e| | |b|a| 12793 rldicl(tmpL1, src, imm24, imm24); // tmpL1 : | | | |g|h|a|b|c| 12794 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |c| | | |g| 12795 rldicl(tmpL3, tmpL2, imm48, imm0); // tmpL3 : | |g| | | |c| | | 12796 rldicl(tmpL1, src, imm32, imm24); // tmpL1 : | | | |h|a|b|c|d| 12797 rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |d| | | |h| 12798 rldicl(tmpL4, tmpL2, imm56, imm0); // tmpL4 : |h| | | |d| | | | 12799 orL_reg_reg(tmpL6, tmpL3, tmpL4); // tmpL6 : |h|g| | |d|c| | | 12800 orL_reg_reg(dst, tmpL5, tmpL6); // dst : |h|g|f|e|d|c|b|a| 12801 %} 12802 %} 12803 12804 instruct bytes_reverse_ushort_Ex(iRegIdst dst, iRegIsrc src) %{ 12805 match(Set dst (ReverseBytesUS src)); 12806 ins_cost(2*DEFAULT_COST); 12807 12808 expand %{ 12809 immI16 imm16 %{ (int) 16 %} 12810 immI16 imm8 %{ (int) 8 %} 12811 12812 urShiftI_reg_imm(dst, src, imm8); 12813 insrwi(dst, src, imm16, imm8); 12814 %} 12815 %} 12816 12817 instruct bytes_reverse_short_Ex(iRegIdst dst, iRegIsrc src) %{ 12818 match(Set dst (ReverseBytesS src)); 12819 ins_cost(3*DEFAULT_COST); 12820 12821 expand %{ 12822 immI16 imm16 %{ (int) 16 %} 12823 immI16 imm8 %{ (int) 8 %} 12824 iRegLdst tmpI1; 12825 12826 urShiftI_reg_imm(tmpI1, src, imm8); 12827 insrwi(tmpI1, src, imm16, imm8); 12828 extsh(dst, tmpI1); 12829 %} 12830 %} 12831 12832 // Load Integer reversed byte order 12833 instruct loadI_reversed(iRegIdst dst, indirect mem) %{ 12834 match(Set dst (ReverseBytesI (LoadI mem))); 12835 ins_cost(MEMORY_REF_COST); 12836 12837 size(4); 12838 ins_encode %{ 12839 __ lwbrx($dst$$Register, $mem$$Register); 12840 %} 12841 ins_pipe(pipe_class_default); 12842 %} 12843 12844 // Load Long - aligned and reversed 12845 instruct loadL_reversed(iRegLdst dst, indirect mem) %{ 12846 match(Set dst (ReverseBytesL (LoadL mem))); 12847 predicate(VM_Version::has_ldbrx()); 12848 ins_cost(MEMORY_REF_COST); 12849 12850 size(4); 12851 ins_encode %{ 12852 __ ldbrx($dst$$Register, $mem$$Register); 12853 %} 12854 ins_pipe(pipe_class_default); 12855 %} 12856 12857 // Load unsigned short / char reversed byte order 12858 instruct loadUS_reversed(iRegIdst dst, indirect mem) %{ 12859 match(Set dst (ReverseBytesUS (LoadUS mem))); 12860 ins_cost(MEMORY_REF_COST); 12861 12862 size(4); 12863 ins_encode %{ 12864 __ lhbrx($dst$$Register, $mem$$Register); 12865 %} 12866 ins_pipe(pipe_class_default); 12867 %} 12868 12869 // Load short reversed byte order 12870 instruct loadS_reversed(iRegIdst dst, indirect mem) %{ 12871 match(Set dst (ReverseBytesS (LoadS mem))); 12872 ins_cost(MEMORY_REF_COST + DEFAULT_COST); 12873 12874 size(8); 12875 ins_encode %{ 12876 __ lhbrx($dst$$Register, $mem$$Register); 12877 __ extsh($dst$$Register, $dst$$Register); 12878 %} 12879 ins_pipe(pipe_class_default); 12880 %} 12881 12882 // Store Integer reversed byte order 12883 instruct storeI_reversed(iRegIsrc src, indirect mem) %{ 12884 match(Set mem (StoreI mem (ReverseBytesI src))); 12885 ins_cost(MEMORY_REF_COST); 12886 12887 size(4); 12888 ins_encode %{ 12889 __ stwbrx($src$$Register, $mem$$Register); 12890 %} 12891 ins_pipe(pipe_class_default); 12892 %} 12893 12894 // Store Long reversed byte order 12895 instruct storeL_reversed(iRegLsrc src, indirect mem) %{ 12896 match(Set mem (StoreL mem (ReverseBytesL src))); 12897 predicate(VM_Version::has_stdbrx()); 12898 ins_cost(MEMORY_REF_COST); 12899 12900 size(4); 12901 ins_encode %{ 12902 __ stdbrx($src$$Register, $mem$$Register); 12903 %} 12904 ins_pipe(pipe_class_default); 12905 %} 12906 12907 // Store unsigned short / char reversed byte order 12908 instruct storeUS_reversed(iRegIsrc src, indirect mem) %{ 12909 match(Set mem (StoreC mem (ReverseBytesUS src))); 12910 ins_cost(MEMORY_REF_COST); 12911 12912 size(4); 12913 ins_encode %{ 12914 __ sthbrx($src$$Register, $mem$$Register); 12915 %} 12916 ins_pipe(pipe_class_default); 12917 %} 12918 12919 // Store short reversed byte order 12920 instruct storeS_reversed(iRegIsrc src, indirect mem) %{ 12921 match(Set mem (StoreC mem (ReverseBytesS src))); 12922 ins_cost(MEMORY_REF_COST); 12923 12924 size(4); 12925 ins_encode %{ 12926 __ sthbrx($src$$Register, $mem$$Register); 12927 %} 12928 ins_pipe(pipe_class_default); 12929 %} 12930 12931 //---------- Replicate Vector Instructions ------------------------------------ 12932 12933 // Insrdi does replicate if src == dst. 12934 instruct repl32(iRegLdst dst) %{ 12935 predicate(false); 12936 effect(USE_DEF dst); 12937 12938 format %{ "INSRDI $dst, #0, $dst, #32 \t// replicate" %} 12939 size(4); 12940 ins_encode %{ 12941 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 12942 __ insrdi($dst$$Register, $dst$$Register, 32, 0); 12943 %} 12944 ins_pipe(pipe_class_default); 12945 %} 12946 12947 // Insrdi does replicate if src == dst. 12948 instruct repl48(iRegLdst dst) %{ 12949 predicate(false); 12950 effect(USE_DEF dst); 12951 12952 format %{ "INSRDI $dst, #0, $dst, #48 \t// replicate" %} 12953 size(4); 12954 ins_encode %{ 12955 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 12956 __ insrdi($dst$$Register, $dst$$Register, 48, 0); 12957 %} 12958 ins_pipe(pipe_class_default); 12959 %} 12960 12961 // Insrdi does replicate if src == dst. 12962 instruct repl56(iRegLdst dst) %{ 12963 predicate(false); 12964 effect(USE_DEF dst); 12965 12966 format %{ "INSRDI $dst, #0, $dst, #56 \t// replicate" %} 12967 size(4); 12968 ins_encode %{ 12969 // TODO: PPC port $archOpcode(ppc64Opcode_rldimi); 12970 __ insrdi($dst$$Register, $dst$$Register, 56, 0); 12971 %} 12972 ins_pipe(pipe_class_default); 12973 %} 12974 12975 instruct repl8B_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 12976 match(Set dst (ReplicateB src)); 12977 predicate(n->as_Vector()->length() == 8); 12978 expand %{ 12979 moveReg(dst, src); 12980 repl56(dst); 12981 repl48(dst); 12982 repl32(dst); 12983 %} 12984 %} 12985 12986 instruct repl8B_immI0(iRegLdst dst, immI_0 zero) %{ 12987 match(Set dst (ReplicateB zero)); 12988 predicate(n->as_Vector()->length() == 8); 12989 format %{ "LI $dst, #0 \t// replicate8B" %} 12990 size(4); 12991 ins_encode %{ 12992 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 12993 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 12994 %} 12995 ins_pipe(pipe_class_default); 12996 %} 12997 12998 instruct repl8B_immIminus1(iRegLdst dst, immI_minus1 src) %{ 12999 match(Set dst (ReplicateB src)); 13000 predicate(n->as_Vector()->length() == 8); 13001 format %{ "LI $dst, #-1 \t// replicate8B" %} 13002 size(4); 13003 ins_encode %{ 13004 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13005 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 13006 %} 13007 ins_pipe(pipe_class_default); 13008 %} 13009 13010 instruct repl4S_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 13011 match(Set dst (ReplicateS src)); 13012 predicate(n->as_Vector()->length() == 4); 13013 expand %{ 13014 moveReg(dst, src); 13015 repl48(dst); 13016 repl32(dst); 13017 %} 13018 %} 13019 13020 instruct repl4S_immI0(iRegLdst dst, immI_0 zero) %{ 13021 match(Set dst (ReplicateS zero)); 13022 predicate(n->as_Vector()->length() == 4); 13023 format %{ "LI $dst, #0 \t// replicate4C" %} 13024 size(4); 13025 ins_encode %{ 13026 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13027 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 13028 %} 13029 ins_pipe(pipe_class_default); 13030 %} 13031 13032 instruct repl4S_immIminus1(iRegLdst dst, immI_minus1 src) %{ 13033 match(Set dst (ReplicateS src)); 13034 predicate(n->as_Vector()->length() == 4); 13035 format %{ "LI $dst, -1 \t// replicate4C" %} 13036 size(4); 13037 ins_encode %{ 13038 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13039 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 13040 %} 13041 ins_pipe(pipe_class_default); 13042 %} 13043 13044 instruct repl2I_reg_Ex(iRegLdst dst, iRegIsrc src) %{ 13045 match(Set dst (ReplicateI src)); 13046 predicate(n->as_Vector()->length() == 2); 13047 ins_cost(2 * DEFAULT_COST); 13048 expand %{ 13049 moveReg(dst, src); 13050 repl32(dst); 13051 %} 13052 %} 13053 13054 instruct repl2I_immI0(iRegLdst dst, immI_0 zero) %{ 13055 match(Set dst (ReplicateI zero)); 13056 predicate(n->as_Vector()->length() == 2); 13057 format %{ "LI $dst, #0 \t// replicate4C" %} 13058 size(4); 13059 ins_encode %{ 13060 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13061 __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF))); 13062 %} 13063 ins_pipe(pipe_class_default); 13064 %} 13065 13066 instruct repl2I_immIminus1(iRegLdst dst, immI_minus1 src) %{ 13067 match(Set dst (ReplicateI src)); 13068 predicate(n->as_Vector()->length() == 2); 13069 format %{ "LI $dst, -1 \t// replicate4C" %} 13070 size(4); 13071 ins_encode %{ 13072 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13073 __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF))); 13074 %} 13075 ins_pipe(pipe_class_default); 13076 %} 13077 13078 // Move float to int register via stack, replicate. 13079 instruct repl2F_reg_Ex(iRegLdst dst, regF src) %{ 13080 match(Set dst (ReplicateF src)); 13081 predicate(n->as_Vector()->length() == 2); 13082 ins_cost(2 * MEMORY_REF_COST + DEFAULT_COST); 13083 expand %{ 13084 stackSlotL tmpS; 13085 iRegIdst tmpI; 13086 moveF2I_reg_stack(tmpS, src); // Move float to stack. 13087 moveF2I_stack_reg(tmpI, tmpS); // Move stack to int reg. 13088 moveReg(dst, tmpI); // Move int to long reg. 13089 repl32(dst); // Replicate bitpattern. 13090 %} 13091 %} 13092 13093 // Replicate scalar constant to packed float values in Double register 13094 instruct repl2F_immF_Ex(iRegLdst dst, immF src) %{ 13095 match(Set dst (ReplicateF src)); 13096 predicate(n->as_Vector()->length() == 2); 13097 ins_cost(5 * DEFAULT_COST); 13098 13099 format %{ "LD $dst, offset, $constanttablebase\t// load replicated float $src $src from table, postalloc expanded" %} 13100 postalloc_expand( postalloc_expand_load_replF_constant(dst, src, constanttablebase) ); 13101 %} 13102 13103 // Replicate scalar zero constant to packed float values in Double register 13104 instruct repl2F_immF0(iRegLdst dst, immF_0 zero) %{ 13105 match(Set dst (ReplicateF zero)); 13106 predicate(n->as_Vector()->length() == 2); 13107 13108 format %{ "LI $dst, #0 \t// replicate2F" %} 13109 ins_encode %{ 13110 // TODO: PPC port $archOpcode(ppc64Opcode_addi); 13111 __ li($dst$$Register, 0x0); 13112 %} 13113 ins_pipe(pipe_class_default); 13114 %} 13115 13116 13117 //----------Overflow Math Instructions----------------------------------------- 13118 13119 // Note that we have to make sure that XER.SO is reset before using overflow instructions. 13120 // Simple Overflow operations can be matched by very few instructions (e.g. addExact: xor, and_, bc). 13121 // Seems like only Long intrinsincs have an advantage. (The only expensive one is OverflowMulL.) 13122 13123 instruct overflowAddL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 13124 match(Set cr0 (OverflowAddL op1 op2)); 13125 13126 format %{ "add_ $op1, $op2\t# overflow check long" %} 13127 ins_encode %{ 13128 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13129 __ li(R0, 0); 13130 __ mtxer(R0); // clear XER.SO 13131 __ addo_(R0, $op1$$Register, $op2$$Register); 13132 %} 13133 ins_pipe(pipe_class_default); 13134 %} 13135 13136 instruct overflowSubL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 13137 match(Set cr0 (OverflowSubL op1 op2)); 13138 13139 format %{ "subfo_ R0, $op2, $op1\t# overflow check long" %} 13140 ins_encode %{ 13141 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13142 __ li(R0, 0); 13143 __ mtxer(R0); // clear XER.SO 13144 __ subfo_(R0, $op2$$Register, $op1$$Register); 13145 %} 13146 ins_pipe(pipe_class_default); 13147 %} 13148 13149 instruct overflowNegL_reg(flagsRegCR0 cr0, immL_0 zero, iRegLsrc op2) %{ 13150 match(Set cr0 (OverflowSubL zero op2)); 13151 13152 format %{ "nego_ R0, $op2\t# overflow check long" %} 13153 ins_encode %{ 13154 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13155 __ li(R0, 0); 13156 __ mtxer(R0); // clear XER.SO 13157 __ nego_(R0, $op2$$Register); 13158 %} 13159 ins_pipe(pipe_class_default); 13160 %} 13161 13162 instruct overflowMulL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{ 13163 match(Set cr0 (OverflowMulL op1 op2)); 13164 13165 format %{ "mulldo_ R0, $op1, $op2\t# overflow check long" %} 13166 ins_encode %{ 13167 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13168 __ li(R0, 0); 13169 __ mtxer(R0); // clear XER.SO 13170 __ mulldo_(R0, $op1$$Register, $op2$$Register); 13171 %} 13172 ins_pipe(pipe_class_default); 13173 %} 13174 13175 13176 // ============================================================================ 13177 // Safepoint Instruction 13178 13179 instruct safePoint_poll(iRegPdst poll) %{ 13180 match(SafePoint poll); 13181 predicate(LoadPollAddressFromThread); 13182 13183 // It caused problems to add the effect that r0 is killed, but this 13184 // effect no longer needs to be mentioned, since r0 is not contained 13185 // in a reg_class. 13186 13187 format %{ "LD R0, #0, $poll \t// Safepoint poll for GC" %} 13188 size(4); 13189 ins_encode( enc_poll(0x0, poll) ); 13190 ins_pipe(pipe_class_default); 13191 %} 13192 13193 // Safepoint without per-thread support. Load address of page to poll 13194 // as constant. 13195 // Rscratch2RegP is R12. 13196 // LoadConPollAddr node is added in pd_post_matching_hook(). It must be 13197 // a seperate node so that the oop map is at the right location. 13198 instruct safePoint_poll_conPollAddr(rscratch2RegP poll) %{ 13199 match(SafePoint poll); 13200 predicate(!LoadPollAddressFromThread); 13201 13202 // It caused problems to add the effect that r0 is killed, but this 13203 // effect no longer needs to be mentioned, since r0 is not contained 13204 // in a reg_class. 13205 13206 format %{ "LD R0, #0, R12 \t// Safepoint poll for GC" %} 13207 ins_encode( enc_poll(0x0, poll) ); 13208 ins_pipe(pipe_class_default); 13209 %} 13210 13211 // ============================================================================ 13212 // Call Instructions 13213 13214 // Call Java Static Instruction 13215 13216 // Schedulable version of call static node. 13217 instruct CallStaticJavaDirect(method meth) %{ 13218 match(CallStaticJava); 13219 effect(USE meth); 13220 ins_cost(CALL_COST); 13221 13222 ins_num_consts(3 /* up to 3 patchable constants: inline cache, 2 call targets. */); 13223 13224 format %{ "CALL,static $meth \t// ==> " %} 13225 size(4); 13226 ins_encode( enc_java_static_call(meth) ); 13227 ins_pipe(pipe_class_call); 13228 %} 13229 13230 // Call Java Dynamic Instruction 13231 13232 // Used by postalloc expand of CallDynamicJavaDirectSchedEx (actual call). 13233 // Loading of IC was postalloc expanded. The nodes loading the IC are reachable 13234 // via fields ins_field_load_ic_hi_node and ins_field_load_ic_node. 13235 // The call destination must still be placed in the constant pool. 13236 instruct CallDynamicJavaDirectSched(method meth) %{ 13237 match(CallDynamicJava); // To get all the data fields we need ... 13238 effect(USE meth); 13239 predicate(false); // ... but never match. 13240 13241 ins_field_load_ic_hi_node(loadConL_hiNode*); 13242 ins_field_load_ic_node(loadConLNode*); 13243 ins_num_consts(1 /* 1 patchable constant: call destination */); 13244 13245 format %{ "BL \t// dynamic $meth ==> " %} 13246 size(4); 13247 ins_encode( enc_java_dynamic_call_sched(meth) ); 13248 ins_pipe(pipe_class_call); 13249 %} 13250 13251 // Schedulable (i.e. postalloc expanded) version of call dynamic java. 13252 // We use postalloc expanded calls if we use inline caches 13253 // and do not update method data. 13254 // 13255 // This instruction has two constants: inline cache (IC) and call destination. 13256 // Loading the inline cache will be postalloc expanded, thus leaving a call with 13257 // one constant. 13258 instruct CallDynamicJavaDirectSched_Ex(method meth) %{ 13259 match(CallDynamicJava); 13260 effect(USE meth); 13261 predicate(UseInlineCaches); 13262 ins_cost(CALL_COST); 13263 13264 ins_num_consts(2 /* 2 patchable constants: inline cache, call destination. */); 13265 13266 format %{ "CALL,dynamic $meth \t// postalloc expanded" %} 13267 postalloc_expand( postalloc_expand_java_dynamic_call_sched(meth, constanttablebase) ); 13268 %} 13269 13270 // Compound version of call dynamic java 13271 // We use postalloc expanded calls if we use inline caches 13272 // and do not update method data. 13273 instruct CallDynamicJavaDirect(method meth) %{ 13274 match(CallDynamicJava); 13275 effect(USE meth); 13276 predicate(!UseInlineCaches); 13277 ins_cost(CALL_COST); 13278 13279 // Enc_java_to_runtime_call needs up to 4 constants (method data oop). 13280 ins_num_consts(4); 13281 13282 format %{ "CALL,dynamic $meth \t// ==> " %} 13283 ins_encode( enc_java_dynamic_call(meth, constanttablebase) ); 13284 ins_pipe(pipe_class_call); 13285 %} 13286 13287 // Call Runtime Instruction 13288 13289 instruct CallRuntimeDirect(method meth) %{ 13290 match(CallRuntime); 13291 effect(USE meth); 13292 ins_cost(CALL_COST); 13293 13294 // Enc_java_to_runtime_call needs up to 3 constants: call target, 13295 // env for callee, C-toc. 13296 ins_num_consts(3); 13297 13298 format %{ "CALL,runtime" %} 13299 ins_encode( enc_java_to_runtime_call(meth) ); 13300 ins_pipe(pipe_class_call); 13301 %} 13302 13303 // Call Leaf 13304 13305 // Used by postalloc expand of CallLeafDirect_Ex (mtctr). 13306 instruct CallLeafDirect_mtctr(iRegLdst dst, iRegLsrc src) %{ 13307 effect(DEF dst, USE src); 13308 13309 ins_num_consts(1); 13310 13311 format %{ "MTCTR $src" %} 13312 size(4); 13313 ins_encode( enc_leaf_call_mtctr(src) ); 13314 ins_pipe(pipe_class_default); 13315 %} 13316 13317 // Used by postalloc expand of CallLeafDirect_Ex (actual call). 13318 instruct CallLeafDirect(method meth) %{ 13319 match(CallLeaf); // To get the data all the data fields we need ... 13320 effect(USE meth); 13321 predicate(false); // but never match. 13322 13323 format %{ "BCTRL \t// leaf call $meth ==> " %} 13324 size(4); 13325 ins_encode %{ 13326 // TODO: PPC port $archOpcode(ppc64Opcode_bctrl); 13327 __ bctrl(); 13328 %} 13329 ins_pipe(pipe_class_call); 13330 %} 13331 13332 // postalloc expand of CallLeafDirect. 13333 // Load adress to call from TOC, then bl to it. 13334 instruct CallLeafDirect_Ex(method meth) %{ 13335 match(CallLeaf); 13336 effect(USE meth); 13337 ins_cost(CALL_COST); 13338 13339 // Postalloc_expand_java_to_runtime_call needs up to 3 constants: call target, 13340 // env for callee, C-toc. 13341 ins_num_consts(3); 13342 13343 format %{ "CALL,runtime leaf $meth \t// postalloc expanded" %} 13344 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 13345 %} 13346 13347 // Call runtime without safepoint - same as CallLeaf. 13348 // postalloc expand of CallLeafNoFPDirect. 13349 // Load adress to call from TOC, then bl to it. 13350 instruct CallLeafNoFPDirect_Ex(method meth) %{ 13351 match(CallLeafNoFP); 13352 effect(USE meth); 13353 ins_cost(CALL_COST); 13354 13355 // Enc_java_to_runtime_call needs up to 3 constants: call target, 13356 // env for callee, C-toc. 13357 ins_num_consts(3); 13358 13359 format %{ "CALL,runtime leaf nofp $meth \t// postalloc expanded" %} 13360 postalloc_expand( postalloc_expand_java_to_runtime_call(meth, constanttablebase) ); 13361 %} 13362 13363 // Tail Call; Jump from runtime stub to Java code. 13364 // Also known as an 'interprocedural jump'. 13365 // Target of jump will eventually return to caller. 13366 // TailJump below removes the return address. 13367 instruct TailCalljmpInd(iRegPdstNoScratch jump_target, inline_cache_regP method_oop) %{ 13368 match(TailCall jump_target method_oop); 13369 ins_cost(CALL_COST); 13370 13371 format %{ "MTCTR $jump_target \t// $method_oop holds method oop\n\t" 13372 "BCTR \t// tail call" %} 13373 size(8); 13374 ins_encode %{ 13375 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13376 __ mtctr($jump_target$$Register); 13377 __ bctr(); 13378 %} 13379 ins_pipe(pipe_class_call); 13380 %} 13381 13382 // Return Instruction 13383 instruct Ret() %{ 13384 match(Return); 13385 format %{ "BLR \t// branch to link register" %} 13386 size(4); 13387 ins_encode %{ 13388 // TODO: PPC port $archOpcode(ppc64Opcode_blr); 13389 // LR is restored in MachEpilogNode. Just do the RET here. 13390 __ blr(); 13391 %} 13392 ins_pipe(pipe_class_default); 13393 %} 13394 13395 // Tail Jump; remove the return address; jump to target. 13396 // TailCall above leaves the return address around. 13397 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2). 13398 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a 13399 // "restore" before this instruction (in Epilogue), we need to materialize it 13400 // in %i0. 13401 instruct tailjmpInd(iRegPdstNoScratch jump_target, rarg1RegP ex_oop) %{ 13402 match(TailJump jump_target ex_oop); 13403 ins_cost(CALL_COST); 13404 13405 format %{ "LD R4_ARG2 = LR\n\t" 13406 "MTCTR $jump_target\n\t" 13407 "BCTR \t// TailJump, exception oop: $ex_oop" %} 13408 size(12); 13409 ins_encode %{ 13410 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13411 __ ld(R4_ARG2/* issuing pc */, _abi(lr), R1_SP); 13412 __ mtctr($jump_target$$Register); 13413 __ bctr(); 13414 %} 13415 ins_pipe(pipe_class_call); 13416 %} 13417 13418 // Create exception oop: created by stack-crawling runtime code. 13419 // Created exception is now available to this handler, and is setup 13420 // just prior to jumping to this handler. No code emitted. 13421 instruct CreateException(rarg1RegP ex_oop) %{ 13422 match(Set ex_oop (CreateEx)); 13423 ins_cost(0); 13424 13425 format %{ " -- \t// exception oop; no code emitted" %} 13426 size(0); 13427 ins_encode( /*empty*/ ); 13428 ins_pipe(pipe_class_default); 13429 %} 13430 13431 // Rethrow exception: The exception oop will come in the first 13432 // argument position. Then JUMP (not call) to the rethrow stub code. 13433 instruct RethrowException() %{ 13434 match(Rethrow); 13435 ins_cost(CALL_COST); 13436 13437 format %{ "Jmp rethrow_stub" %} 13438 ins_encode %{ 13439 // TODO: PPC port $archOpcode(ppc64Opcode_compound); 13440 cbuf.set_insts_mark(); 13441 __ b64_patchable((address)OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type); 13442 %} 13443 ins_pipe(pipe_class_call); 13444 %} 13445 13446 // Die now. 13447 instruct ShouldNotReachHere() %{ 13448 match(Halt); 13449 ins_cost(CALL_COST); 13450 13451 format %{ "ShouldNotReachHere" %} 13452 size(4); 13453 ins_encode %{ 13454 // TODO: PPC port $archOpcode(ppc64Opcode_tdi); 13455 __ trap_should_not_reach_here(); 13456 %} 13457 ins_pipe(pipe_class_default); 13458 %} 13459 13460 // This name is KNOWN by the ADLC and cannot be changed. The ADLC 13461 // forces a 'TypeRawPtr::BOTTOM' output type for this guy. 13462 // Get a DEF on threadRegP, no costs, no encoding, use 13463 // 'ins_should_rematerialize(true)' to avoid spilling. 13464 instruct tlsLoadP(threadRegP dst) %{ 13465 match(Set dst (ThreadLocal)); 13466 ins_cost(0); 13467 13468 ins_should_rematerialize(true); 13469 13470 format %{ " -- \t// $dst=Thread::current(), empty" %} 13471 size(0); 13472 ins_encode( /*empty*/ ); 13473 ins_pipe(pipe_class_empty); 13474 %} 13475 13476 //---Some PPC specific nodes--------------------------------------------------- 13477 13478 // Stop a group. 13479 instruct endGroup() %{ 13480 ins_cost(0); 13481 13482 ins_is_nop(true); 13483 13484 format %{ "End Bundle (ori r1, r1, 0)" %} 13485 size(4); 13486 ins_encode %{ 13487 // TODO: PPC port $archOpcode(ppc64Opcode_endgroup); 13488 __ endgroup(); 13489 %} 13490 ins_pipe(pipe_class_default); 13491 %} 13492 13493 // Nop instructions 13494 13495 instruct fxNop() %{ 13496 ins_cost(0); 13497 13498 ins_is_nop(true); 13499 13500 format %{ "fxNop" %} 13501 size(4); 13502 ins_encode %{ 13503 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 13504 __ nop(); 13505 %} 13506 ins_pipe(pipe_class_default); 13507 %} 13508 13509 instruct fpNop0() %{ 13510 ins_cost(0); 13511 13512 ins_is_nop(true); 13513 13514 format %{ "fpNop0" %} 13515 size(4); 13516 ins_encode %{ 13517 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 13518 __ fpnop0(); 13519 %} 13520 ins_pipe(pipe_class_default); 13521 %} 13522 13523 instruct fpNop1() %{ 13524 ins_cost(0); 13525 13526 ins_is_nop(true); 13527 13528 format %{ "fpNop1" %} 13529 size(4); 13530 ins_encode %{ 13531 // TODO: PPC port $archOpcode(ppc64Opcode_fmr); 13532 __ fpnop1(); 13533 %} 13534 ins_pipe(pipe_class_default); 13535 %} 13536 13537 instruct brNop0() %{ 13538 ins_cost(0); 13539 size(4); 13540 format %{ "brNop0" %} 13541 ins_encode %{ 13542 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 13543 __ brnop0(); 13544 %} 13545 ins_is_nop(true); 13546 ins_pipe(pipe_class_default); 13547 %} 13548 13549 instruct brNop1() %{ 13550 ins_cost(0); 13551 13552 ins_is_nop(true); 13553 13554 format %{ "brNop1" %} 13555 size(4); 13556 ins_encode %{ 13557 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 13558 __ brnop1(); 13559 %} 13560 ins_pipe(pipe_class_default); 13561 %} 13562 13563 instruct brNop2() %{ 13564 ins_cost(0); 13565 13566 ins_is_nop(true); 13567 13568 format %{ "brNop2" %} 13569 size(4); 13570 ins_encode %{ 13571 // TODO: PPC port $archOpcode(ppc64Opcode_mcrf); 13572 __ brnop2(); 13573 %} 13574 ins_pipe(pipe_class_default); 13575 %} 13576 13577 //----------PEEPHOLE RULES----------------------------------------------------- 13578 // These must follow all instruction definitions as they use the names 13579 // defined in the instructions definitions. 13580 // 13581 // peepmatch ( root_instr_name [preceeding_instruction]* ); 13582 // 13583 // peepconstraint %{ 13584 // (instruction_number.operand_name relational_op instruction_number.operand_name 13585 // [, ...] ); 13586 // // instruction numbers are zero-based using left to right order in peepmatch 13587 // 13588 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 13589 // // provide an instruction_number.operand_name for each operand that appears 13590 // // in the replacement instruction's match rule 13591 // 13592 // ---------VM FLAGS--------------------------------------------------------- 13593 // 13594 // All peephole optimizations can be turned off using -XX:-OptoPeephole 13595 // 13596 // Each peephole rule is given an identifying number starting with zero and 13597 // increasing by one in the order seen by the parser. An individual peephole 13598 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 13599 // on the command-line. 13600 // 13601 // ---------CURRENT LIMITATIONS---------------------------------------------- 13602 // 13603 // Only match adjacent instructions in same basic block 13604 // Only equality constraints 13605 // Only constraints between operands, not (0.dest_reg == EAX_enc) 13606 // Only one replacement instruction 13607 // 13608 // ---------EXAMPLE---------------------------------------------------------- 13609 // 13610 // // pertinent parts of existing instructions in architecture description 13611 // instruct movI(eRegI dst, eRegI src) %{ 13612 // match(Set dst (CopyI src)); 13613 // %} 13614 // 13615 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{ 13616 // match(Set dst (AddI dst src)); 13617 // effect(KILL cr); 13618 // %} 13619 // 13620 // // Change (inc mov) to lea 13621 // peephole %{ 13622 // // increment preceeded by register-register move 13623 // peepmatch ( incI_eReg movI ); 13624 // // require that the destination register of the increment 13625 // // match the destination register of the move 13626 // peepconstraint ( 0.dst == 1.dst ); 13627 // // construct a replacement instruction that sets 13628 // // the destination to ( move's source register + one ) 13629 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 13630 // %} 13631 // 13632 // Implementation no longer uses movX instructions since 13633 // machine-independent system no longer uses CopyX nodes. 13634 // 13635 // peephole %{ 13636 // peepmatch ( incI_eReg movI ); 13637 // peepconstraint ( 0.dst == 1.dst ); 13638 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 13639 // %} 13640 // 13641 // peephole %{ 13642 // peepmatch ( decI_eReg movI ); 13643 // peepconstraint ( 0.dst == 1.dst ); 13644 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 13645 // %} 13646 // 13647 // peephole %{ 13648 // peepmatch ( addI_eReg_imm movI ); 13649 // peepconstraint ( 0.dst == 1.dst ); 13650 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 13651 // %} 13652 // 13653 // peephole %{ 13654 // peepmatch ( addP_eReg_imm movP ); 13655 // peepconstraint ( 0.dst == 1.dst ); 13656 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) ); 13657 // %} 13658 13659 // // Change load of spilled value to only a spill 13660 // instruct storeI(memory mem, eRegI src) %{ 13661 // match(Set mem (StoreI mem src)); 13662 // %} 13663 // 13664 // instruct loadI(eRegI dst, memory mem) %{ 13665 // match(Set dst (LoadI mem)); 13666 // %} 13667 // 13668 peephole %{ 13669 peepmatch ( loadI storeI ); 13670 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 13671 peepreplace ( storeI( 1.mem 1.mem 1.src ) ); 13672 %} 13673 13674 peephole %{ 13675 peepmatch ( loadL storeL ); 13676 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 13677 peepreplace ( storeL( 1.mem 1.mem 1.src ) ); 13678 %} 13679 13680 peephole %{ 13681 peepmatch ( loadP storeP ); 13682 peepconstraint ( 1.src == 0.dst, 1.dst == 0.mem ); 13683 peepreplace ( storeP( 1.dst 1.dst 1.src ) ); 13684 %} 13685 13686 //----------SMARTSPILL RULES--------------------------------------------------- 13687 // These must follow all instruction definitions as they use the names 13688 // defined in the instructions definitions.